diff --git a/synapse/storage/_base.py b/synapse/storage/_base.py
index 4ac61be895..c15cec0c78 100644
--- a/synapse/storage/_base.py
+++ b/synapse/storage/_base.py
@@ -160,9 +160,19 @@ class LoggingTransaction(object):
start = time.time() * 1000
try:
- return self.txn.execute(
- sql, *args, **kwargs
- )
+ i = 0
+ N = 5
+ while True:
+ try:
+ return self.txn.execute(
+ sql, *args, **kwargs
+ )
+ except self.database_engine.module.DatabaseError as e:
+ if self.database_engine.is_deadlock(e) and i < N:
+ i += 1
+ logger.warn("[SQL DEADLOCK] {%s}", self.name)
+ continue
+ raise
except Exception as e:
logger.debug("[SQL FAIL] {%s} %s", self.name, e)
raise
diff --git a/synapse/storage/engines/maria.py b/synapse/storage/engines/maria.py
index 7fcb706a60..a279bfaf44 100644
--- a/synapse/storage/engines/maria.py
+++ b/synapse/storage/engines/maria.py
@@ -40,3 +40,8 @@ class MariaEngine(object):
)
db_conn.commit()
prepare_database(db_conn, self)
+
+ def is_deadlock(self, error):
+ if isinstance(error, self.module.InternalError):
+ return error.sqlstate == 40001 and error.errno == 1213
+ return False
diff --git a/synapse/storage/engines/sqlite3.py b/synapse/storage/engines/sqlite3.py
index e802b5d5fd..72c11df461 100644
--- a/synapse/storage/engines/sqlite3.py
+++ b/synapse/storage/engines/sqlite3.py
@@ -32,3 +32,6 @@ class Sqlite3Engine(object):
def prepare_database(self, db_conn):
prepare_sqlite3_database(db_conn)
prepare_database(db_conn, self)
+
+ def is_deadlock(self, error):
+ return False
|