v66-0006-FetchTableStates-performance-improvements.patch
application/octet-stream
Filename: v66-0006-FetchTableStates-performance-improvements.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v66-0006
Subject: FetchTableStates performance improvements.
| File | + | − |
|---|---|---|
| src/backend/catalog/pg_subscription.c | 34 | 0 |
| src/backend/replication/logical/tablesync.c | 18 | 13 |
| src/include/catalog/pg_subscription_rel.h | 1 | 0 |
From 5276031713c3dfb98d31d159d8933b0499839126 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Thu, 25 Mar 2021 17:55:58 +1100
Subject: [PATCH v66] FetchTableStates performance improvements.
Instead of calling the GetSubscriptionRelations every time to find
if the subscription has any tables, now we call a new function
HasSubscriptionRelations.
And even this is called only when we are unsure do tables exist or not.
---
src/backend/catalog/pg_subscription.c | 34 +++++++++++++++++++++++++++++
src/backend/replication/logical/tablesync.c | 31 +++++++++++++++-----------
src/include/catalog/pg_subscription_rel.h | 1 +
3 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index 658d9f8..0f725fb 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -450,6 +450,40 @@ RemoveSubscriptionRel(Oid subid, Oid relid)
table_close(rel, RowExclusiveLock);
}
+/*
+ * Does the subscription have any relations?
+ *
+ * Use this function only to know true/false, and when you have no need for the
+ * the List returned by GetSubscriptionRelations.
+ */
+bool
+HasSubscriptionRelations(Oid subid)
+{
+ Relation rel;
+ int nkeys = 0;
+ ScanKeyData skey[2];
+ SysScanDesc scan;
+ bool has_subrels = false;
+
+ rel = table_open(SubscriptionRelRelationId, AccessShareLock);
+
+ ScanKeyInit(&skey[nkeys++],
+ Anum_pg_subscription_rel_srsubid,
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(subid));
+
+ scan = systable_beginscan(rel, InvalidOid, false,
+ NULL, nkeys, skey);
+
+ /* If even a single tuple exists then the subscription has tables. */
+ has_subrels = HeapTupleIsValid(systable_getnext(scan));
+
+ /* Cleanup */
+ systable_endscan(scan);
+ table_close(rel, AccessShareLock);
+
+ return has_subrels;
+}
/*
* Get all relations for subscription.
diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index a1c9949..14c52e3 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -119,7 +119,7 @@
static bool table_states_valid = false;
static List *table_states_not_ready = NIL;
-static int FetchTableStates(bool *started_tx);
+static bool FetchTableStates(bool *started_tx);
StringInfo copybuf = NULL;
@@ -1144,19 +1144,18 @@ copy_table_done:
/*
* Common code to fetch the up-to-date sync state info into the static lists.
*
- * Returns how many tables belong to the subscription.
+ * Returns true if subscription has 1 or more tables, else false.
*/
-static int
+static bool
FetchTableStates(bool *started_tx)
{
- static int n_subrels = 0;
+ static int has_subrels = false;
*started_tx = false;
if (!table_states_valid)
{
MemoryContext oldctx;
- List *subrels = NIL;
List *rstates;
ListCell *lc;
SubscriptionRelState *rstate;
@@ -1171,10 +1170,6 @@ FetchTableStates(bool *started_tx)
*started_tx = true;
}
- /* count all subscription tables. */
- subrels = GetSubscriptionRelations(MySubscription->oid);
- n_subrels = list_length(subrels);
-
/* Fetch all non-ready tables. */
rstates = GetSubscriptionNotReadyRelations(MySubscription->oid);
@@ -1188,10 +1183,20 @@ FetchTableStates(bool *started_tx)
}
MemoryContextSwitchTo(oldctx);
+ /*
+ * Does the subscription have tables?
+ *
+ * If there were not-READY relations found then we know it does. But if
+ * table_state_no_ready was empty we still need to check again to see
+ * if there are 0 tables.
+ */
+ has_subrels = (list_length(table_states_not_ready) > 0) ||
+ HasSubscriptionRelations(MySubscription->oid);
+
table_states_valid = true;
}
- return n_subrels;
+ return has_subrels;
}
/*
@@ -1207,10 +1212,10 @@ AllTablesyncsReady(void)
{
bool found_busy = false;
bool started_tx = false;
- int n_subrels = 0;
+ bool has_subrels = false;
/* We need up-to-date sync state info for subscription tables here. */
- n_subrels = FetchTableStates(&started_tx);
+ has_subrels = FetchTableStates(&started_tx);
found_busy = list_length(table_states_not_ready) > 0;
@@ -1224,7 +1229,7 @@ AllTablesyncsReady(void)
* When there are no tables, then return false.
* When no tablesyncs are busy, then all are READY
*/
- return n_subrels > 0 && !found_busy;
+ return has_subrels && !found_busy;
}
/*
diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h
index ed94f57..765e9b5 100644
--- a/src/include/catalog/pg_subscription_rel.h
+++ b/src/include/catalog/pg_subscription_rel.h
@@ -88,6 +88,7 @@ extern void UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
extern char GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn);
extern void RemoveSubscriptionRel(Oid subid, Oid relid);
+extern bool HasSubscriptionRelations(Oid subid);
extern List *GetSubscriptionRelations(Oid subid);
extern List *GetSubscriptionNotReadyRelations(Oid subid);
--
1.8.3.1