]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Add code to retry a MySQL query after a deadlock
authorEric Bollengier <eric@baculasystems.com>
Tue, 20 Oct 2020 07:51:35 +0000 (09:51 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:02:59 +0000 (09:02 +0100)
bacula/src/cats/mysql.c

index ee593403ca7709aef37e4ba1b4462f981d9e827d..ecf4f99f00483f43a7a3796f0a8a500fdd346684 100644 (file)
@@ -37,7 +37,8 @@
  
 #include "cats.h" 
 #include <mysql.h> 
-#define __BDB_MYSQL_H_ 1 
+#include <mysqld_error.h>
+#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) {