Skip to content

Commit f2bf8fb

Browse files
committed
Reindex toast before its main relation in reindex_relation()
This commit changes the order of reindex on a relation so as a toast relation is processed before its main relation. The original order, where a rebuild was first done for the indexes on the main table, could be a problem in the event of a corruption of a toast index, because, as scans of a toast index may be required to rebuild the indexes on the main relation, this could lead to failures with REINDEX TABLE without being able to fix anything. Rebuilding corrupted toast indexes before this change was possible but troublesome, as it was necessary to issue a REINDEX on the toast relation first, followed by a REINDEX on the main relation. Changing the order of these operations should make things easier when rebuilding corrupted indexes, as toast indexes would be rebuilt before they are used for the indexes on the main relation. Per request from Richard Vesely. Author: Gurjeet Singh Reviewed-by: Nathan Bossart, Michael Paquier Discussion: https://postgr.es/m/18016-2bd9b549b1fe49b3@postgresql.org
1 parent bc397e5 commit f2bf8fb

File tree

1 file changed

+31
-21
lines changed

1 file changed

+31
-21
lines changed

src/backend/catalog/index.c

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3917,7 +3917,7 @@ reindex_relation(const ReindexStmt *stmt, Oid relid, int flags,
39173917
Oid toast_relid;
39183918
List *indexIds;
39193919
char persistence;
3920-
bool result;
3920+
bool result = false;
39213921
ListCell *indexId;
39223922
int i;
39233923

@@ -3964,6 +3964,35 @@ reindex_relation(const ReindexStmt *stmt, Oid relid, int flags,
39643964
CommandCounterIncrement();
39653965
}
39663966

3967+
/*
3968+
* Reindex the toast table, if any, before the main table.
3969+
*
3970+
* This helps in cases where a corruption in the toast table's index would
3971+
* otherwise error and stop REINDEX TABLE command when it tries to fetch a
3972+
* toasted datum. This way. the toast table's index is rebuilt and fixed
3973+
* before it is used for reindexing the main table.
3974+
*
3975+
* It is critical to call reindex_relation() *after* the call to
3976+
* RelationGetIndexList() returning the list of indexes on the relation,
3977+
* because reindex_relation() will call CommandCounterIncrement() after
3978+
* every reindex_index(). See REINDEX_REL_SUPPRESS_INDEX_USE for more
3979+
* details.
3980+
*/
3981+
if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
3982+
{
3983+
/*
3984+
* Note that this should fail if the toast relation is missing, so
3985+
* reset REINDEXOPT_MISSING_OK. Even if a new tablespace is set for
3986+
* the parent relation, the indexes on its toast table are not moved.
3987+
* This rule is enforced by setting tablespaceOid to InvalidOid.
3988+
*/
3989+
ReindexParams newparams = *params;
3990+
3991+
newparams.options &= ~(REINDEXOPT_MISSING_OK);
3992+
newparams.tablespaceOid = InvalidOid;
3993+
result |= reindex_relation(stmt, toast_relid, flags, &newparams);
3994+
}
3995+
39673996
/*
39683997
* Compute persistence of indexes: same as that of owning rel, unless
39693998
* caller specified otherwise.
@@ -4017,26 +4046,7 @@ reindex_relation(const ReindexStmt *stmt, Oid relid, int flags,
40174046
*/
40184047
table_close(rel, NoLock);
40194048

4020-
result = (indexIds != NIL);
4021-
4022-
/*
4023-
* If the relation has a secondary toast rel, reindex that too while we
4024-
* still hold the lock on the main table.
4025-
*/
4026-
if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
4027-
{
4028-
/*
4029-
* Note that this should fail if the toast relation is missing, so
4030-
* reset REINDEXOPT_MISSING_OK. Even if a new tablespace is set for
4031-
* the parent relation, the indexes on its toast table are not moved.
4032-
* This rule is enforced by setting tablespaceOid to InvalidOid.
4033-
*/
4034-
ReindexParams newparams = *params;
4035-
4036-
newparams.options &= ~(REINDEXOPT_MISSING_OK);
4037-
newparams.tablespaceOid = InvalidOid;
4038-
result |= reindex_relation(stmt, toast_relid, flags, &newparams);
4039-
}
4049+
result |= (indexIds != NIL);
40404050

40414051
return result;
40424052
}

0 commit comments

Comments
 (0)