diff --git a/racket/collects/db/private/sqlite3/connection.rkt b/racket/collects/db/private/sqlite3/connection.rkt index 5f033ab396..59f01c7f6f 100644 --- a/racket/collects/db/private/sqlite3/connection.rkt +++ b/racket/collects/db/private/sqlite3/connection.rkt @@ -453,7 +453,8 @@ (define (simplify-status s) (cond [(or (= SQLITE_IOERR_BLOCKED s) - (= SQLITE_IOERR_LOCK s)) + (= SQLITE_IOERR_LOCK s) + (= SQLITE_READONLY_ROLLBACK s)) ;; Kept in extended form, because these indicate ;; cases where retry is appropriate s] @@ -468,6 +469,7 @@ [,SQLITE_LOCKED locked "table in the database is locked"] [,SQLITE_NOMEM nomem "malloc() failed"] [,SQLITE_READONLY readonly "attempt to write a readonly database"] + [,SQLITE_READONLY_ROLLBACK readonly-rollback "attempt to write a readonly database (hot journal)"] [,SQLITE_INTERRUPT interrupt "operation terminated by sqlite3_interrupt()"] [,SQLITE_IOERR ioerr "some kind of disk I/O error occurred"] [,SQLITE_IOERR_BLOCKED ioerr-blocked "some kind of disk I/O error occurred (blocked)"] @@ -495,7 +497,7 @@ SQLITE_IOERR_BLOCKED SQLITE_IOERR_LOCK)) (define include-db-file-status-list - (list SQLITE_READONLY SQLITE_PERM SQLITE_ABORT SQLITE_BUSY SQLITE_LOCKED + (list SQLITE_READONLY SQLITE_READONLY_ROLLBACK SQLITE_PERM SQLITE_ABORT SQLITE_BUSY SQLITE_LOCKED SQLITE_IOERR SQLITE_IOERR_BLOCKED SQLITE_IOERR_LOCK SQLITE_CORRUPT SQLITE_NOTFOUND SQLITE_FULL SQLITE_CANTOPEN SQLITE_PROTOCOL SQLITE_EMPTY SQLITE_FORMAT SQLITE_NOTADB)) diff --git a/racket/collects/db/private/sqlite3/ffi-constants.rkt b/racket/collects/db/private/sqlite3/ffi-constants.rkt index a3559d4fb0..59f0465476 100644 --- a/racket/collects/db/private/sqlite3/ffi-constants.rkt +++ b/racket/collects/db/private/sqlite3/ffi-constants.rkt @@ -35,6 +35,7 @@ ;; Extended error codes: (define SQLITE_IOERR_BLOCKED (bitwise-ior SQLITE_IOERR (arithmetic-shift 11 8))) (define SQLITE_IOERR_LOCK (bitwise-ior SQLITE_IOERR (arithmetic-shift 15 8))) +(define SQLITE_READONLY_ROLLBACK (bitwise-ior SQLITE_READONLY (arithmetic-shift 3 8))) (define SQLITE_INTEGER 1) (define SQLITE_FLOAT 2) diff --git a/racket/collects/setup/doc-db.rkt b/racket/collects/setup/doc-db.rkt index 127ba9cbf5..f5c7aafd17 100644 --- a/racket/collects/setup/doc-db.rkt +++ b/racket/collects/setup/doc-db.rkt @@ -487,7 +487,12 @@ (let ([s (exn:fail:sql-sqlstate v)]) (or (eq? s 'busy) (eq? s 'ioerr-blocked) - (eq? s 'ioerr-lock))))) + (eq? s 'ioerr-lock) + ;; The `SQLITE_READONLY_ROLLBACK` result is supposed + ;; to mean that a hot journal exists due to a crash, + ;; but it seems to happen even without crashes, so + ;; treat it is a reason to retry: + (eq? s 'readonly-rollback))))) (define (call-with-lock-handler handler thunk) (with-handlers* ([exn:fail:retry?