mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
Ensure we have a snapshot when updating pg_index entries.
Creating, reindexing, and dropping an index concurrently could
entail accessing pg_index's TOAST table, which was recently added
in commit b52c4fc3c0. These code paths start and commit their own
transactions, but they do not always set an active snapshot. This
rightfully leads to assertion failures and ERRORs when trying to
access pg_index's TOAST table, such as the following:
ERROR: cannot fetch toast data without an active snapshot
To fix, push an active snapshot just before each section of code
that might require accessing pg_index's TOAST table, and pop it
shortly afterwards.
Reported-by: Alexander Lakhin
Reviewed-by: Michael Paquier
Discussion: https://postgr.es/m/a97d7401-e7c9-f771-6a00-037379f0a8bb%40gmail.com
This commit is contained in:
@@ -2276,9 +2276,17 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
|
||||
*/
|
||||
WaitForLockers(heaplocktag, AccessExclusiveLock, true);
|
||||
|
||||
/*
|
||||
* Updating pg_index might involve TOAST table access, so ensure we
|
||||
* have a valid snapshot.
|
||||
*/
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
|
||||
/* Finish invalidation of index and mark it as dead */
|
||||
index_concurrently_set_dead(heapId, indexId);
|
||||
|
||||
PopActiveSnapshot();
|
||||
|
||||
/*
|
||||
* Again, commit the transaction to make the pg_index update visible
|
||||
* to other sessions.
|
||||
@@ -2326,6 +2334,16 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
|
||||
|
||||
RelationForgetRelation(indexId);
|
||||
|
||||
/*
|
||||
* Updating pg_index might involve TOAST table access, so ensure we have a
|
||||
* valid snapshot. We only expect to get here without a snapshot in the
|
||||
* concurrent path.
|
||||
*/
|
||||
if (concurrent)
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
else
|
||||
Assert(HaveRegisteredOrActiveSnapshot());
|
||||
|
||||
/*
|
||||
* fix INDEX relation, and check for expressional index
|
||||
*/
|
||||
@@ -2343,6 +2361,9 @@ index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode)
|
||||
ReleaseSysCache(tuple);
|
||||
table_close(indexRelation, RowExclusiveLock);
|
||||
|
||||
if (concurrent)
|
||||
PopActiveSnapshot();
|
||||
|
||||
/*
|
||||
* if it has any expression columns, we might have stored statistics about
|
||||
* them.
|
||||
|
||||
Reference in New Issue
Block a user