From 4f3635e3546cbf86ca066da05f5702d19d26bdbb Mon Sep 17 00:00:00 2001 From: Julien BLACHE Date: Sat, 28 May 2011 10:48:31 +0200 Subject: [PATCH] Handle SQLITE_SCHEMA error in db_exec() This happens under database load with many concurrent threads doing updates; queries failing with SQLITE_SCHEMA at step time need to retried from scratch until they succeeded or hit a best-effort limit of 5 retries. --- src/db.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/db.c b/src/db.c index 9e66e0d4..13289577 100644 --- a/src/db.c +++ b/src/db.c @@ -535,30 +535,35 @@ static int db_exec(const char *query, char **errmsg) { sqlite3_stmt *stmt; + int try; int ret; *errmsg = NULL; - ret = db_blocking_prepare_v2(query, -1, &stmt, NULL); - if (ret != SQLITE_OK) + for (try = 0; try < 5; try++) { - *errmsg = sqlite3_mprintf("prepare failed: %s", sqlite3_errmsg(hdl)); - return ret; - } + ret = db_blocking_prepare_v2(query, -1, &stmt, NULL); + if (ret != SQLITE_OK) + { + *errmsg = sqlite3_mprintf("prepare failed: %s", sqlite3_errmsg(hdl)); + return ret; + } - while ((ret = db_blocking_step(stmt)) == SQLITE_ROW) - ; /* EMPTY */ + while ((ret = db_blocking_step(stmt)) == SQLITE_ROW) + ; /* EMPTY */ + + sqlite3_finalize(stmt); + + if (ret != SQLITE_SCHEMA) + break; + } if (ret != SQLITE_DONE) { *errmsg = sqlite3_mprintf("step failed: %s", sqlite3_errmsg(hdl)); - - sqlite3_finalize(stmt); return ret; } - sqlite3_finalize(stmt); - return SQLITE_OK; }