mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
Make DDL operations play nicely with Serializable Snapshot Isolation.
Truncating or dropping a table is treated like deletion of all tuples, and check for conflicts accordingly. If a table is clustered or rewritten by ALTER TABLE, all predicate locks on the heap are promoted to relation-level locks, because the tuple or page ids of any existing tuples will change and won't be valid after rewriting the table. Arguably ALTER TABLE should be treated like a mass-UPDATE of every row, but if you e.g change the datatype of a column, you could also argue that it's just a change to the physical layout, not a logical change. Reindexing promotes all locks on the index to relation-level lock on the heap. Kevin Grittner, with a lot of cosmetic changes by me.
This commit is contained in:
@ -70,6 +70,7 @@
|
||||
#include "storage/bufmgr.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "storage/lock.h"
|
||||
#include "storage/predicate.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/acl.h"
|
||||
#include "utils/builtins.h"
|
||||
@ -1039,6 +1040,14 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||
Oid heap_relid;
|
||||
Oid toast_relid;
|
||||
|
||||
/*
|
||||
* This effectively deletes all rows in the table, and may be done
|
||||
* in a serializable transaction. In that case we must record a
|
||||
* rw-conflict in to this transaction from each transaction
|
||||
* holding a predicate lock on the table.
|
||||
*/
|
||||
CheckTableForSerializableConflictIn(rel);
|
||||
|
||||
/*
|
||||
* Need the full transaction-safe pushups.
|
||||
*
|
||||
@ -3529,6 +3538,16 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
|
||||
(errmsg("verifying table \"%s\"",
|
||||
RelationGetRelationName(oldrel))));
|
||||
|
||||
if (newrel)
|
||||
{
|
||||
/*
|
||||
* All predicate locks on the tuples or pages are about to be made
|
||||
* invalid, because we move tuples around. Promote them to
|
||||
* relation locks.
|
||||
*/
|
||||
TransferPredicateLocksToHeapRelation(oldrel);
|
||||
}
|
||||
|
||||
econtext = GetPerTupleExprContext(estate);
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user