From: Eric Bollengier Date: Tue, 20 Oct 2020 07:51:35 +0000 (+0200) Subject: Add code to retry a MySQL query after a deadlock X-Git-Tag: Release-11.3.2~824 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e413a72b0b2eabc965d942d4a334d7c67083dc05;p=thirdparty%2Fbacula.git Add code to retry a MySQL query after a deadlock --- diff --git a/bacula/src/cats/mysql.c b/bacula/src/cats/mysql.c index ee593403c..ecf4f99f0 100644 --- a/bacula/src/cats/mysql.c +++ b/bacula/src/cats/mysql.c @@ -37,7 +37,8 @@ #include "cats.h" #include -#define __BDB_MYSQL_H_ 1 +#include +#define __BDB_MYSQL_H_ 1 #include "bdb_mysql.h" /* ----------------------------------------------------------------------- @@ -519,7 +520,8 @@ bool BDB_MYSQL::bdb_sql_query(const char *query, DB_RESULT_HANDLER *result_handl SQL_ROW row; bool send = true; bool retval = false; - BDB_MYSQL *mdb = this; + BDB_MYSQL *mdb = this; + int retry=5; Dmsg1(500, "db_sql_query starts with %s\n", query); @@ -527,13 +529,33 @@ bool BDB_MYSQL::bdb_sql_query(const char *query, DB_RESULT_HANDLER *result_handl errmsg[0] = 0; query = enable_pkey(query); - ret = mysql_query(m_db_handle, query); - if (ret != 0) { + do { + ret = mysql_query(m_db_handle, query); + if (ret != 0) { + uint32_t merrno = mysql_errno(m_db_handle); + switch (merrno) { + case ER_LOCK_DEADLOCK: + if (retry > 0) { + Dmsg0(500, "db_sql_query failed because of a deadlock, retrying in few seconds...\n"); + bmicrosleep(2, 0); + /* TODO: When we will manage transactions, it's important to test if we are in or not */ + } + break; + + default: + Dmsg1(50, "db_sql_query failed errno=%d\n", merrno); + retry=0; /* Stop directly here, no retry */ + break; + } + } + } while (ret != 0 && retry-- > 0); + + if (ret != 0) { Mmsg(mdb->errmsg, _("Query failed: %s: ERR=%s\n"), query, sql_strerror()); Dmsg0(500, "db_sql_query failed\n"); goto get_out; - } - + } + Dmsg0(500, "db_sql_query succeeded. checking handler\n"); if (result_handler) {