Journal: Fall back to DELETE on IO error #5723
authorChristian Kamm <mail@ckamm.de>
Tue, 12 Sep 2017 11:39:45 +0000 (13:39 +0200)
committerRoeland Jago Douma <roeland@famdouma.nl>
Thu, 5 Oct 2017 20:01:05 +0000 (22:01 +0200)
Also add logging of extended error codes for this IO error, maybe we can
become more specific about which situations should trigger a journal
mode switch.

src/libsync/ownsql.cpp
src/libsync/syncjournaldb.cpp

index 759f1981dcad6502d9c5031afadeefdbd98fe6a1..e66fdfb3e3fdaee4b415880cd1d7af80418e26dd 100644 (file)
@@ -280,6 +280,12 @@ bool SqlQuery::exec()
         if (_errId != SQLITE_DONE && _errId != SQLITE_ROW) {
             _error = QString::fromUtf8(sqlite3_errmsg(_db));
             qCWarning(lcSql) << "Sqlite exec statement error:" << _errId << _error << "in" << _sql;
+            if (_errId == SQLITE_IOERR) {
+                qCWarning(lcSql) << "IOERR extended errcode: " << sqlite3_extended_errcode(_db);
+#if SQLITE_VERSION_NUMBER >= 3012000
+                qCWarning(lcSql) << "IOERR system errno: " << sqlite3_system_errno(_db);
+#endif
+            }
         } else {
             qCDebug(lcSql) << "Last exec affected" << numRowsAffected() << "rows.";
         }
index 6706fb65e23166b72e3bde0c7e76efa2bf90f1e9..f4d3510dd3440298f318915e4d94617a24a7027c 100644 (file)
@@ -323,7 +323,26 @@ bool SyncJournalDb::checkConnect()
                         ");");
 
     if (!createQuery.exec()) {
-        return sqlFail("Create table metadata", createQuery);
+        bool fail = true;
+
+        // In certain situations the io error can be avoided by switching
+        // to the DELETE journal mode, see #5723
+        if (createQuery.errorId() == SQLITE_IOERR) {
+            qCWarning(lcDb) << "IO error on table creation, attempting with DELETE journal mode";
+
+            pragma1.prepare(QString("PRAGMA journal_mode=DELETE;"));
+            if (!pragma1.exec()) {
+                return sqlFail("Set PRAGMA journal_mode", pragma1);
+            }
+            pragma1.next();
+            qCInfo(lcDb) << "sqlite3 journal_mode=" << pragma1.stringValue(0);
+
+            if (createQuery.exec()) {
+                fail = false;
+            }
+        }
+        if (fail)
+            return sqlFail("Create table metadata", createQuery);
     }
 
     createQuery.prepare("CREATE TABLE IF NOT EXISTS downloadinfo("