mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-08-30 14:07:19 +02:00
Make index_set_state_flags() transactional
3c84046
is the original commit that introduced index_set_state_flags(), where the presence of SnapshotNow made necessary the use of an in-place update. SnapshotNow has been removed in813fb03
, so there is no actual reasons to not make this operation transactional. As reported by Andrey, it is possible to trigger the assertion of this routine expecting no transactional updates when switching the pg_index state flags, using a predicate mark as immutable but calling stable or volatile functions.83158f7
has been around for a couple of months on HEAD now with no issues found related to it, so it looks safe enough for a backpatch. Reported-by: Andrey Lepikhov Author: Michael Paquier Reviewed-by: Anastasia Lubennikova Discussion: https://postgr.es/m/20200903080440.GA8559@paquier.xyz Discussion: https://postgr.es/m/9b905019-5297-7372-0ad2-e1a4bb66a719@postgrespro.ru Backpatch-through: 9.6
This commit is contained in:
parent
2d09448654
commit
acb60edf02
@ -3375,18 +3375,10 @@ validate_index_callback(ItemPointer itemptr, void *opaque)
|
|||||||
* index_set_state_flags - adjust pg_index state flags
|
* index_set_state_flags - adjust pg_index state flags
|
||||||
*
|
*
|
||||||
* This is used during CREATE/DROP INDEX CONCURRENTLY to adjust the pg_index
|
* This is used during CREATE/DROP INDEX CONCURRENTLY to adjust the pg_index
|
||||||
* flags that denote the index's state. Because the update is not
|
* flags that denote the index's state.
|
||||||
* transactional and will not roll back on error, this must only be used as
|
|
||||||
* the last step in a transaction that has not made any transactional catalog
|
|
||||||
* updates!
|
|
||||||
*
|
*
|
||||||
* Note that heap_inplace_update does send a cache inval message for the
|
* Note that CatalogTupleUpdate() sends a cache invalidation message for the
|
||||||
* tuple, so other sessions will hear about the update as soon as we commit.
|
* tuple, so other sessions will hear about the update as soon as we commit.
|
||||||
*
|
|
||||||
* NB: In releases prior to PostgreSQL 9.4, the use of a non-transactional
|
|
||||||
* update here would have been unsafe; now that MVCC rules apply even for
|
|
||||||
* system catalog scans, we could potentially use a transactional update here
|
|
||||||
* instead.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
|
index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
|
||||||
@ -3395,9 +3387,6 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
|
|||||||
HeapTuple indexTuple;
|
HeapTuple indexTuple;
|
||||||
Form_pg_index indexForm;
|
Form_pg_index indexForm;
|
||||||
|
|
||||||
/* Assert that current xact hasn't done any transactional updates */
|
|
||||||
Assert(GetTopTransactionIdIfAny() == InvalidTransactionId);
|
|
||||||
|
|
||||||
/* Open pg_index and fetch a writable copy of the index's tuple */
|
/* Open pg_index and fetch a writable copy of the index's tuple */
|
||||||
pg_index = table_open(IndexRelationId, RowExclusiveLock);
|
pg_index = table_open(IndexRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
@ -3456,8 +3445,8 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ... and write it back in-place */
|
/* ... and update it */
|
||||||
heap_inplace_update(pg_index, indexTuple);
|
CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple);
|
||||||
|
|
||||||
table_close(pg_index, RowExclusiveLock);
|
table_close(pg_index, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user