v2-0001-Reindex-the-toast-table-if-any-before-the-main-ta.patch
application/x-patch
Filename: v2-0001-Reindex-the-toast-table-if-any-before-the-main-ta.patch
Type: application/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v2-0001
Subject: Reindex the toast table before the main table
| File | + | − |
|---|---|---|
| src/backend/catalog/index.c | 34 | 24 |
From 64d646105383e8f47394f4ee7e169ffde727da3c Mon Sep 17 00:00:00 2001
From: Gurjeet Singh <gurjeet@singh.im>
Date: Wed, 29 Nov 2023 13:17:39 -0800
Subject: [PATCH v2] Reindex the toast table before the main table
This helps in cases where a corruption in toast table's index would
otherwise error and stop REINDEX TABLE command when it tries to fetch a
toasted datum. This way toast table's index is rebuilt and fixed before
it is used for reindexing the main table.
---
src/backend/catalog/index.c | 58 ++++++++++++++++++++++---------------
1 file changed, 34 insertions(+), 24 deletions(-)
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 143fae01eb..ea751299c2 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3871,7 +3871,7 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
Oid toast_relid;
List *indexIds;
char persistence;
- bool result;
+ bool result = false;
ListCell *indexId;
int i;
@@ -3901,7 +3901,7 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
toast_relid = rel->rd_rel->reltoastrelid;
/*
- * Get the list of index OIDs for this relation. (We trust to the
+ * Get the list of index OIDs for this relation. (We trust the
* relcache to get this with a sequential scan if ignoring system
* indexes.)
*/
@@ -3919,6 +3919,35 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
CommandCounterIncrement();
}
+ /*
+ * Reindex the toast table, if any, before the main table.
+ *
+ * This helps in cases where a corruption in toast table's index would
+ * otherwise error and stop REINDEX TABLE command when it tries to fetch a
+ * toasted datum. This way toast table's index is rebuilt and fixed before
+ * it is used for reindexing the main table.
+ *
+ * We must call reindex_relation() _after_ the RelationGetIndexList(),
+ * because the reindex_relation() will call CommandCounterIncrement() after
+ * every reindex_index(). Performing CCI before the RelationGetIndexList()
+ * call may produce wrong results. Refer to the description of
+ * REINDEX_REL_SUPPRESS_INDEX_USE flag.
+ */
+ if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
+ {
+ /*
+ * Note that this should fail if the toast relation is missing, so
+ * reset REINDEXOPT_MISSING_OK. Even if a new tablespace is set for
+ * the parent relation, the indexes on its toast table are not moved.
+ * This rule is enforced by setting tablespaceOid to InvalidOid.
+ */
+ ReindexParams newparams = *params;
+
+ newparams.options &= ~(REINDEXOPT_MISSING_OK);
+ newparams.tablespaceOid = InvalidOid;
+ result |= reindex_relation(toast_relid, flags, &newparams);
+ }
+
/*
* Compute persistence of indexes: same as that of owning rel, unless
* caller specified otherwise.
@@ -3934,8 +3963,8 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
i = 1;
foreach(indexId, indexIds)
{
- Oid indexOid = lfirst_oid(indexId);
- Oid indexNamespaceId = get_rel_namespace(indexOid);
+ Oid indexOid = lfirst_oid(indexId);
+ Oid indexNamespaceId = get_rel_namespace(indexOid);
/*
* Skip any invalid indexes on a TOAST table. These can only be
@@ -3972,26 +4001,7 @@ reindex_relation(Oid relid, int flags, const ReindexParams *params)
*/
table_close(rel, NoLock);
- result = (indexIds != NIL);
-
- /*
- * If the relation has a secondary toast rel, reindex that too while we
- * still hold the lock on the main table.
- */
- if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
- {
- /*
- * Note that this should fail if the toast relation is missing, so
- * reset REINDEXOPT_MISSING_OK. Even if a new tablespace is set for
- * the parent relation, the indexes on its toast table are not moved.
- * This rule is enforced by setting tablespaceOid to InvalidOid.
- */
- ReindexParams newparams = *params;
-
- newparams.options &= ~(REINDEXOPT_MISSING_OK);
- newparams.tablespaceOid = InvalidOid;
- result |= reindex_relation(toast_relid, flags, &newparams);
- }
+ result |= (indexIds != NIL);
return result;
}
--
2.34.1