summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2020-02-18 15:39:09 +0000
committerGitHub <noreply@github.com>2020-02-18 15:39:09 +0000
commit8a380d0fe24edd746256d652836ec27003a05e7e (patch)
tree36455f9110107bbb5f961876af7758d478f94107
parentFix worker docs to point `/publicised_groups` API correctly. (#6938) (diff)
downloadsynapse-8a380d0fe24edd746256d652836ec27003a05e7e.tar.xz
Increase perf of `get_auth_chain_ids` used in state res v2. (#6937)
We do this by moving the recursive query to be fully in the DB.
-rw-r--r--changelog.d/6937.misc1
-rw-r--r--synapse/storage/data_stores/main/event_federation.py23
2 files changed, 24 insertions, 0 deletions
diff --git a/changelog.d/6937.misc b/changelog.d/6937.misc
new file mode 100644
index 0000000000..6d00e58654
--- /dev/null
+++ b/changelog.d/6937.misc
@@ -0,0 +1 @@
+Increase perf of `get_auth_chain_ids` used in state res v2.
diff --git a/synapse/storage/data_stores/main/event_federation.py b/synapse/storage/data_stores/main/event_federation.py
index 60c67457b4..1746f40adf 100644
--- a/synapse/storage/data_stores/main/event_federation.py
+++ b/synapse/storage/data_stores/main/event_federation.py
@@ -26,6 +26,7 @@ from synapse.storage._base import SQLBaseStore, make_in_list_sql_clause
 from synapse.storage.data_stores.main.events_worker import EventsWorkerStore
 from synapse.storage.data_stores.main.signatures import SignatureWorkerStore
 from synapse.storage.database import Database
+from synapse.storage.engines import PostgresEngine
 from synapse.util.caches.descriptors import cached
 
 logger = logging.getLogger(__name__)
@@ -61,6 +62,28 @@ class EventFederationWorkerStore(EventsWorkerStore, SignatureWorkerStore, SQLBas
         )
 
     def _get_auth_chain_ids_txn(self, txn, event_ids, include_given):
+        if isinstance(self.database_engine, PostgresEngine):
+            # For efficiency we make the database do this if we can.
+            sql = """
+                WITH RECURSIVE auth_chain(event_id) AS (
+                    SELECT auth_id FROM event_auth WHERE event_id = ANY(?)
+                    UNION
+                    SELECT auth_id FROM event_auth
+                    INNER JOIN auth_chain USING (event_id)
+                )
+                SELECT event_id FROM auth_chain
+            """
+            txn.execute(sql, (list(event_ids),))
+
+            results = set(event_id for event_id, in txn)
+
+            if include_given:
+                results.update(event_ids)
+
+            return list(results)
+
+        # Database doesn't necessarily support recursive CTE, so we fall
+        # back to do doing it manually.
         if include_given:
             results = set(event_ids)
         else: