PostgreSQL Source Code git master
Loading...
Searching...
No Matches
predicate.h File Reference
#include "storage/itemptr.h"
#include "storage/lock.h"
#include "utils/relcache.h"
#include "utils/snapshot.h"
Include dependency graph for predicate.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef voidSerializableXactHandle
 

Functions

void PredicateLockShmemInit (void)
 
Size PredicateLockShmemSize (void)
 
void CheckPointPredicate (void)
 
bool PageIsPredicateLocked (Relation relation, BlockNumber blkno)
 
Snapshot GetSerializableTransactionSnapshot (Snapshot snapshot)
 
void SetSerializableTransactionSnapshot (Snapshot snapshot, VirtualTransactionId *sourcevxid, int sourcepid)
 
void RegisterPredicateLockingXid (TransactionId xid)
 
void PredicateLockRelation (Relation relation, Snapshot snapshot)
 
void PredicateLockPage (Relation relation, BlockNumber blkno, Snapshot snapshot)
 
void PredicateLockTID (Relation relation, const ItemPointerData *tid, Snapshot snapshot, TransactionId tuple_xid)
 
void PredicateLockPageSplit (Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
 
void PredicateLockPageCombine (Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
 
void TransferPredicateLocksToHeapRelation (Relation relation)
 
void ReleasePredicateLocks (bool isCommit, bool isReadOnlySafe)
 
bool CheckForSerializableConflictOutNeeded (Relation relation, Snapshot snapshot)
 
void CheckForSerializableConflictOut (Relation relation, TransactionId xid, Snapshot snapshot)
 
void CheckForSerializableConflictIn (Relation relation, const ItemPointerData *tid, BlockNumber blkno)
 
void CheckTableForSerializableConflictIn (Relation relation)
 
void PreCommit_CheckForSerializationFailure (void)
 
void AtPrepare_PredicateLocks (void)
 
void PostPrepare_PredicateLocks (FullTransactionId fxid)
 
void PredicateLockTwoPhaseFinish (FullTransactionId fxid, bool isCommit)
 
void predicatelock_twophase_recover (FullTransactionId fxid, uint16 info, void *recdata, uint32 len)
 
SerializableXactHandle ShareSerializableXact (void)
 
void AttachSerializableXact (SerializableXactHandle handle)
 

Variables

PGDLLIMPORT int max_predicate_locks_per_xact
 
PGDLLIMPORT int max_predicate_locks_per_relation
 
PGDLLIMPORT int max_predicate_locks_per_page
 

Typedef Documentation

◆ SerializableXactHandle

Definition at line 34 of file predicate.h.

Function Documentation

◆ AtPrepare_PredicateLocks()

void AtPrepare_PredicateLocks ( void  )
extern

Definition at line 4799 of file predicate.c.

4800{
4803 TwoPhasePredicateXactRecord *xactRecord;
4804 TwoPhasePredicateLockRecord *lockRecord;
4805 dlist_iter iter;
4806
4808 xactRecord = &(record.data.xactRecord);
4809 lockRecord = &(record.data.lockRecord);
4810
4812 return;
4813
4814 /* Generate an xact record for our SERIALIZABLEXACT */
4816 xactRecord->xmin = MySerializableXact->xmin;
4817 xactRecord->flags = MySerializableXact->flags;
4818
4819 /*
4820 * Note that we don't include the list of conflicts in our out in the
4821 * statefile, because new conflicts can be added even after the
4822 * transaction prepares. We'll just make a conservative assumption during
4823 * recovery instead.
4824 */
4825
4827 &record, sizeof(record));
4828
4829 /*
4830 * Generate a lock record for each lock.
4831 *
4832 * To do this, we need to walk the predicate lock list in our sxact rather
4833 * than using the local predicate lock table because the latter is not
4834 * guaranteed to be accurate.
4835 */
4837
4838 /*
4839 * No need to take sxact->perXactPredicateListLock in parallel mode
4840 * because there cannot be any parallel workers running while we are
4841 * preparing a transaction.
4842 */
4844
4845 dlist_foreach(iter, &sxact->predicateLocks)
4846 {
4848 dlist_container(PREDICATELOCK, xactLink, iter.cur);
4849
4851 lockRecord->target = predlock->tag.myTarget->tag;
4852
4854 &record, sizeof(record));
4855 }
4856
4858}
bool ParallelContextActive(void)
Definition parallel.c:1033
#define Assert(condition)
Definition c.h:945
#define dlist_foreach(iter, lhead)
Definition ilist.h:623
#define dlist_container(type, membername, ptr)
Definition ilist.h:593
#define IsParallelWorker()
Definition parallel.h:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1177
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1794
@ LW_SHARED
Definition lwlock.h:113
static SERIALIZABLEXACT * MySerializableXact
Definition predicate.c:422
@ TWOPHASEPREDICATERECORD_XACT
@ TWOPHASEPREDICATERECORD_LOCK
#define InvalidSerializableXact
static int fb(int x)
PREDICATELOCKTARGETTAG target
TwoPhasePredicateRecordType type
TwoPhasePredicateLockRecord lockRecord
union TwoPhasePredicateRecord::@132 data
TwoPhasePredicateXactRecord xactRecord
dlist_node * cur
Definition ilist.h:179
void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, const void *data, uint32 len)
Definition twophase.c:1274
#define TWOPHASE_RM_PREDICATELOCK_ID

References Assert, dlist_iter::cur, TwoPhasePredicateRecord::data, dlist_container, dlist_foreach, fb(), SERIALIZABLEXACT::flags, TwoPhasePredicateXactRecord::flags, InvalidSerializableXact, IsParallelWorker, TwoPhasePredicateRecord::lockRecord, LW_SHARED, LWLockAcquire(), LWLockRelease(), MySerializableXact, ParallelContextActive(), RegisterTwoPhaseRecord(), TwoPhasePredicateLockRecord::target, TWOPHASE_RM_PREDICATELOCK_ID, TWOPHASEPREDICATERECORD_LOCK, TWOPHASEPREDICATERECORD_XACT, TwoPhasePredicateRecord::type, TwoPhasePredicateRecord::xactRecord, SERIALIZABLEXACT::xmin, and TwoPhasePredicateXactRecord::xmin.

Referenced by PrepareTransaction().

◆ AttachSerializableXact()

void AttachSerializableXact ( SerializableXactHandle  handle)
extern

Definition at line 5065 of file predicate.c.

5066{
5067
5069
5073}
static void CreateLocalPredicateLockHash(void)
Definition predicate.c:1949

References Assert, CreateLocalPredicateLockHash(), InvalidSerializableXact, and MySerializableXact.

Referenced by ParallelWorkerMain().

◆ CheckForSerializableConflictIn()

void CheckForSerializableConflictIn ( Relation  relation,
const ItemPointerData tid,
BlockNumber  blkno 
)
extern

Definition at line 4345 of file predicate.c.

4346{
4348
4349 if (!SerializationNeededForWrite(relation))
4350 return;
4351
4352 /* Check if someone else has already decided that we need to die */
4354 ereport(ERROR,
4356 errmsg("could not serialize access due to read/write dependencies among transactions"),
4357 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict in checking."),
4358 errhint("The transaction might succeed if retried.")));
4359
4360 /*
4361 * We're doing a write which might cause rw-conflicts now or later.
4362 * Memorize that fact.
4363 */
4364 MyXactDidWrite = true;
4365
4366 /*
4367 * It is important that we check for locks from the finest granularity to
4368 * the coarsest granularity, so that granularity promotion doesn't cause
4369 * us to miss a lock. The new (coarser) lock will be acquired before the
4370 * old (finer) locks are released.
4371 *
4372 * It is not possible to take and hold a lock across the checks for all
4373 * granularities because each target could be in a separate partition.
4374 */
4375 if (tid != NULL)
4376 {
4378 relation->rd_locator.dbOid,
4379 relation->rd_id,
4383 }
4384
4385 if (blkno != InvalidBlockNumber)
4386 {
4388 relation->rd_locator.dbOid,
4389 relation->rd_id,
4390 blkno);
4392 }
4393
4395 relation->rd_locator.dbOid,
4396 relation->rd_id);
4398}
#define InvalidBlockNumber
Definition block.h:33
int errcode(int sqlerrcode)
Definition elog.c:874
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
Definition itemptr.h:124
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
Definition itemptr.h:103
static char * errmsg
#define ERRCODE_T_R_SERIALIZATION_FAILURE
Definition pgbench.c:77
static bool MyXactDidWrite
Definition predicate.c:423
static bool SerializationNeededForWrite(Relation relation)
Definition predicate.c:562
static void CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:4175
#define SxactIsDoomed(sxact)
Definition predicate.c:281
#define SET_PREDICATELOCKTARGETTAG_PAGE(locktag, dboid, reloid, blocknum)
#define SET_PREDICATELOCKTARGETTAG_RELATION(locktag, dboid, reloid)
#define SET_PREDICATELOCKTARGETTAG_TUPLE(locktag, dboid, reloid, blocknum, offnum)
Oid rd_id
Definition rel.h:113
RelFileLocator rd_locator
Definition rel.h:57

References CheckTargetForConflictsIn(), RelFileLocator::dbOid, ereport, errcode(), ERRCODE_T_R_SERIALIZATION_FAILURE, errdetail_internal(), errhint(), errmsg, ERROR, fb(), InvalidBlockNumber, ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), MySerializableXact, MyXactDidWrite, RelationData::rd_id, RelationData::rd_locator, SerializationNeededForWrite(), SET_PREDICATELOCKTARGETTAG_PAGE, SET_PREDICATELOCKTARGETTAG_RELATION, SET_PREDICATELOCKTARGETTAG_TUPLE, and SxactIsDoomed.

Referenced by _bt_check_unique(), _bt_doinsert(), _hash_doinsert(), ginEntryInsert(), ginFindLeafPage(), ginHeapTupleFastInsert(), gistinserttuples(), heap_delete(), heap_insert(), heap_multi_insert(), heap_update(), and index_insert().

◆ CheckForSerializableConflictOut()

void CheckForSerializableConflictOut ( Relation  relation,
TransactionId  xid,
Snapshot  snapshot 
)
extern

Definition at line 4032 of file predicate.c.

4033{
4037
4038 if (!SerializationNeededForRead(relation, snapshot))
4039 return;
4040
4041 /* Check if someone else has already decided that we need to die */
4043 {
4044 ereport(ERROR,
4046 errmsg("could not serialize access due to read/write dependencies among transactions"),
4047 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict out checking."),
4048 errhint("The transaction might succeed if retried.")));
4049 }
4051
4053 return;
4054
4055 /*
4056 * Find sxact or summarized info for the top level xid.
4057 */
4058 sxidtag.xid = xid;
4060 sxid = (SERIALIZABLEXID *)
4062 if (!sxid)
4063 {
4064 /*
4065 * Transaction not found in "normal" SSI structures. Check whether it
4066 * got pushed out to SLRU storage for "old committed" transactions.
4067 */
4069
4071 if (conflictCommitSeqNo != 0)
4072 {
4077 ereport(ERROR,
4079 errmsg("could not serialize access due to read/write dependencies among transactions"),
4080 errdetail_internal("Reason code: Canceled on conflict out to old pivot %u.", xid),
4081 errhint("The transaction might succeed if retried.")));
4082
4085 ereport(ERROR,
4087 errmsg("could not serialize access due to read/write dependencies among transactions"),
4088 errdetail_internal("Reason code: Canceled on identification as a pivot, with conflict out to old committed transaction %u.", xid),
4089 errhint("The transaction might succeed if retried.")));
4090
4092 }
4093
4094 /* It's not serializable or otherwise not important. */
4096 return;
4097 }
4098 sxact = sxid->myXact;
4099 Assert(TransactionIdEquals(sxact->topXid, xid));
4101 {
4102 /* Can't conflict with ourself or a transaction that will roll back. */
4104 return;
4105 }
4106
4107 /*
4108 * We have a conflict out to a transaction which has a conflict out to a
4109 * summarized transaction. That summarized transaction must have
4110 * committed first, and we can't tell when it committed in relation to our
4111 * snapshot acquisition, so something needs to be canceled.
4112 */
4114 {
4115 if (!SxactIsPrepared(sxact))
4116 {
4117 sxact->flags |= SXACT_FLAG_DOOMED;
4119 return;
4120 }
4121 else
4122 {
4124 ereport(ERROR,
4126 errmsg("could not serialize access due to read/write dependencies among transactions"),
4127 errdetail_internal("Reason code: Canceled on conflict out to old pivot."),
4128 errhint("The transaction might succeed if retried.")));
4129 }
4130 }
4131
4132 /*
4133 * If this is a read-only transaction and the writing transaction has
4134 * committed, and it doesn't have a rw-conflict to a transaction which
4135 * committed before it, no conflict.
4136 */
4141 || MySerializableXact->SeqNo.lastCommitBeforeSnapshot < sxact->SeqNo.earliestOutConflictCommit))
4142 {
4143 /* Read-only transaction will appear to run first. No conflict. */
4145 return;
4146 }
4147
4148 if (!XidIsConcurrent(xid))
4149 {
4150 /* This write was already in our snapshot; no conflict. */
4152 return;
4153 }
4154
4156 {
4157 /* We don't want duplicate conflict records in the list. */
4159 return;
4160 }
4161
4162 /*
4163 * Flag the conflict. But first, if this conflict creates a dangerous
4164 * structure, ereport an error.
4165 */
4168}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:952
@ HASH_FIND
Definition hsearch.h:113
static bool dlist_is_empty(const dlist_head *head)
Definition ilist.h:336
@ LW_EXCLUSIVE
Definition lwlock.h:112
static bool RWConflictExists(const SERIALIZABLEXACT *reader, const SERIALIZABLEXACT *writer)
Definition predicate.c:612
static bool SerializationNeededForRead(Relation relation, Snapshot snapshot)
Definition predicate.c:518
#define SxactIsCommitted(sxact)
Definition predicate.c:278
#define SxactIsReadOnly(sxact)
Definition predicate.c:282
#define SxactHasSummaryConflictIn(sxact)
Definition predicate.c:283
#define SxactHasConflictOut(sxact)
Definition predicate.c:290
#define SxactIsPrepared(sxact)
Definition predicate.c:279
static HTAB * SerializableXidHash
Definition predicate.c:397
static void FlagRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer)
Definition predicate.c:4510
static SerCommitSeqNo SerialGetMinConflictCommitSeqNo(TransactionId xid)
Definition predicate.c:960
static bool XidIsConcurrent(TransactionId xid)
Definition predicate.c:3981
#define SxactHasSummaryConflictOut(sxact)
Definition predicate.c:284
#define InvalidSerCommitSeqNo
#define SXACT_FLAG_DOOMED
uint64 SerCommitSeqNo
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT
SerCommitSeqNo lastCommitBeforeSnapshot
union SERIALIZABLEXACT::@131 SeqNo
#define TransactionIdEquals(id1, id2)
Definition transam.h:43
#define TransactionIdIsValid(xid)
Definition transam.h:41
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443

References Assert, dlist_is_empty(), ereport, errcode(), ERRCODE_T_R_SERIALIZATION_FAILURE, errdetail_internal(), errhint(), errmsg, ERROR, fb(), FlagRWConflict(), SERIALIZABLEXACT::flags, GetTopTransactionIdIfAny(), HASH_FIND, hash_search(), SERIALIZABLEXACT::inConflicts, InvalidSerCommitSeqNo, SERIALIZABLEXACT::lastCommitBeforeSnapshot, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MySerializableXact, RWConflictExists(), SERIALIZABLEXACT::SeqNo, SerialGetMinConflictCommitSeqNo(), SerializableXidHash, SerializationNeededForRead(), SXACT_FLAG_DOOMED, SXACT_FLAG_SUMMARY_CONFLICT_OUT, SxactHasConflictOut, SxactHasSummaryConflictIn, SxactHasSummaryConflictOut, SxactIsCommitted, SxactIsDoomed, SxactIsPrepared, SxactIsReadOnly, TransactionIdEquals, TransactionIdIsValid, and XidIsConcurrent().

Referenced by HeapCheckForSerializableConflictOut().

◆ CheckForSerializableConflictOutNeeded()

bool CheckForSerializableConflictOutNeeded ( Relation  relation,
Snapshot  snapshot 
)
extern

Definition at line 4000 of file predicate.c.

4001{
4002 if (!SerializationNeededForRead(relation, snapshot))
4003 return false;
4004
4005 /* Check if someone else has already decided that we need to die */
4007 {
4008 ereport(ERROR,
4010 errmsg("could not serialize access due to read/write dependencies among transactions"),
4011 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict out checking."),
4012 errhint("The transaction might succeed if retried.")));
4013 }
4014
4015 return true;
4016}

References ereport, errcode(), ERRCODE_T_R_SERIALIZATION_FAILURE, errdetail_internal(), errhint(), errmsg, ERROR, MySerializableXact, SerializationNeededForRead(), and SxactIsDoomed.

Referenced by heap_prepare_pagescan(), and HeapCheckForSerializableConflictOut().

◆ CheckPointPredicate()

void CheckPointPredicate ( void  )
extern

Definition at line 1052 of file predicate.c.

1053{
1055
1057
1058 /* Exit quickly if the SLRU is currently not in use. */
1059 if (serialControl->headPage < 0)
1060 {
1062 return;
1063 }
1064
1066 {
1068
1070
1071 /*
1072 * It is possible for the tailXid to be ahead of the headXid. This
1073 * occurs if we checkpoint while there are in-progress serializable
1074 * transaction(s) advancing the tail but we are yet to summarize the
1075 * transactions. In this case, we cutoff up to the headPage and the
1076 * next summary will advance the headXid.
1077 */
1079 {
1080 /* We can truncate the SLRU up to the page containing tailXid */
1082 }
1083 else
1085 }
1086 else
1087 {
1088 /*----------
1089 * The SLRU is no longer needed. Truncate to head before we set head
1090 * invalid.
1091 *
1092 * XXX: It's possible that the SLRU is not needed again until XID
1093 * wrap-around has happened, so that the segment containing headPage
1094 * that we leave behind will appear to be new again. In that case it
1095 * won't be removed until XID horizon advances enough to make it
1096 * current again.
1097 *
1098 * XXX: This should happen in vac_truncate_clog(), not in checkpoints.
1099 * Consider this scenario, starting from a system with no in-progress
1100 * transactions and VACUUM FREEZE having maximized oldestXact:
1101 * - Start a SERIALIZABLE transaction.
1102 * - Start, finish, and summarize a SERIALIZABLE transaction, creating
1103 * one SLRU page.
1104 * - Consume XIDs to reach xidStopLimit.
1105 * - Finish all transactions. Due to the long-running SERIALIZABLE
1106 * transaction, earlier checkpoints did not touch headPage. The
1107 * next checkpoint will change it, but that checkpoint happens after
1108 * the end of the scenario.
1109 * - VACUUM to advance XID limits.
1110 * - Consume ~2M XIDs, crossing the former xidWrapLimit.
1111 * - Start, finish, and summarize a SERIALIZABLE transaction.
1112 * SerialAdd() declines to create the targetPage, because headPage
1113 * is not regarded as in the past relative to that targetPage. The
1114 * transaction instigating the summarize fails in
1115 * SimpleLruReadPage().
1116 */
1118 serialControl->headPage = -1;
1119 }
1120
1122
1123 /*
1124 * Truncate away pages that are no longer required. Note that no
1125 * additional locking is required, because this is only called as part of
1126 * a checkpoint, and the validity limits have already been determined.
1127 */
1129
1130 /*
1131 * Write dirty SLRU pages to disk
1132 *
1133 * This is not actually necessary from a correctness point of view. We do
1134 * it merely as a debugging aid.
1135 *
1136 * We're doing this after the truncation to avoid writing pages right
1137 * before deleting the file in which they sit, which would be completely
1138 * pointless.
1139 */
1141}
int64_t int64
Definition c.h:615
#define SerialPage(xid)
Definition predicate.c:344
static SerialControl serialControl
Definition predicate.c:355
static bool SerialPagePrecedesLogically(int64 page1, int64 page2)
Definition predicate.c:733
#define SerialSlruCtl
Definition predicate.c:327
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition slru.c:1355
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition slru.c:1441
TransactionId tailXid
Definition predicate.c:350

References fb(), SerialControlData::headPage, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), serialControl, SerialPage, SerialPagePrecedesLogically(), SerialSlruCtl, SimpleLruTruncate(), SimpleLruWriteAll(), SerialControlData::tailXid, and TransactionIdIsValid.

Referenced by CheckPointGuts().

◆ CheckTableForSerializableConflictIn()

void CheckTableForSerializableConflictIn ( Relation  relation)
extern

Definition at line 4428 of file predicate.c.

4429{
4431 PREDICATELOCKTARGET *target;
4432 Oid dbId;
4433 Oid heapId;
4434 int i;
4435
4436 /*
4437 * Bail out quickly if there are no serializable transactions running.
4438 * It's safe to check this without taking locks because the caller is
4439 * holding an ACCESS EXCLUSIVE lock on the relation. No new locks which
4440 * would matter here can be acquired while that is held.
4441 */
4443 return;
4444
4445 if (!SerializationNeededForWrite(relation))
4446 return;
4447
4448 /*
4449 * We're doing a write which might cause rw-conflicts now or later.
4450 * Memorize that fact.
4451 */
4452 MyXactDidWrite = true;
4453
4454 Assert(relation->rd_index == NULL); /* not an index relation */
4455
4456 dbId = relation->rd_locator.dbOid;
4457 heapId = relation->rd_id;
4458
4460 for (i = 0; i < NUM_PREDICATELOCK_PARTITIONS; i++)
4463
4464 /* Scan through target list */
4466
4467 while ((target = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat)))
4468 {
4469 dlist_mutable_iter iter;
4470
4471 /*
4472 * Check whether this is a target which needs attention.
4473 */
4475 continue; /* wrong relation id */
4476 if (GET_PREDICATELOCKTARGETTAG_DB(target->tag) != dbId)
4477 continue; /* wrong database id */
4478
4479 /*
4480 * Loop through locks for this target and flag conflicts.
4481 */
4482 dlist_foreach_modify(iter, &target->predicateLocks)
4483 {
4485 dlist_container(PREDICATELOCK, targetLink, iter.cur);
4486
4487 if (predlock->tag.myXact != MySerializableXact
4489 {
4491 }
4492 }
4493 }
4494
4495 /* Release locks in reverse order */
4497 for (i = NUM_PREDICATELOCK_PARTITIONS - 1; i >= 0; i--)
4500}
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition dynahash.c:1415
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition dynahash.c:1380
#define dlist_foreach_modify(iter, lhead)
Definition ilist.h:640
int i
Definition isn.c:77
#define NUM_PREDICATELOCK_PARTITIONS
Definition lwlock.h:99
unsigned int Oid
static PredXactList PredXact
Definition predicate.c:385
#define PredicateLockHashPartitionLockByIndex(i)
Definition predicate.c:262
static HTAB * PredicateLockTargetHash
Definition predicate.c:398
#define GET_PREDICATELOCKTARGETTAG_DB(locktag)
#define GET_PREDICATELOCKTARGETTAG_RELATION(locktag)
PREDICATELOCKTARGETTAG tag
TransactionId SxactGlobalXmin
Form_pg_index rd_index
Definition rel.h:192
dlist_node * cur
Definition ilist.h:200

References Assert, dlist_mutable_iter::cur, RelFileLocator::dbOid, dlist_container, dlist_foreach_modify, fb(), FlagRWConflict(), GET_PREDICATELOCKTARGETTAG_DB, GET_PREDICATELOCKTARGETTAG_RELATION, hash_seq_init(), hash_seq_search(), i, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MySerializableXact, MyXactDidWrite, NUM_PREDICATELOCK_PARTITIONS, PredicateLockHashPartitionLockByIndex, PREDICATELOCKTARGET::predicateLocks, PredicateLockTargetHash, PredXact, RelationData::rd_id, RelationData::rd_index, RelationData::rd_locator, RWConflictExists(), SerializationNeededForWrite(), PredXactListData::SxactGlobalXmin, PREDICATELOCKTARGET::tag, and TransactionIdIsValid.

Referenced by ExecuteTruncateGuts(), and heap_drop_with_catalog().

◆ GetSerializableTransactionSnapshot()

Snapshot GetSerializableTransactionSnapshot ( Snapshot  snapshot)
extern

Definition at line 1691 of file predicate.c.

1692{
1694
1695 /*
1696 * Can't use serializable mode while recovery is still active, as it is,
1697 * for example, on a hot standby. We could get here despite the check in
1698 * check_transaction_isolation() if default_transaction_isolation is set
1699 * to serializable, so phrase the hint accordingly.
1700 */
1701 if (RecoveryInProgress())
1702 ereport(ERROR,
1704 errmsg("cannot use serializable mode in a hot standby"),
1705 errdetail("\"default_transaction_isolation\" is set to \"serializable\"."),
1706 errhint("You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default.")));
1707
1708 /*
1709 * A special optimization is available for SERIALIZABLE READ ONLY
1710 * DEFERRABLE transactions -- we can wait for a suitable snapshot and
1711 * thereby avoid all SSI overhead once it's running.
1712 */
1714 return GetSafeSnapshot(snapshot);
1715
1717 NULL, InvalidPid);
1718}
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define InvalidPid
Definition miscadmin.h:32
static Snapshot GetSafeSnapshot(Snapshot origSnapshot)
Definition predicate.c:1567
static Snapshot GetSerializableTransactionSnapshotInt(Snapshot snapshot, VirtualTransactionId *sourcevxid, int sourcepid)
Definition predicate.c:1773
bool XactDeferrable
Definition xact.c:87
bool XactReadOnly
Definition xact.c:84
#define IsolationIsSerializable()
Definition xact.h:53
bool RecoveryInProgress(void)
Definition xlog.c:6444

References Assert, ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, fb(), GetSafeSnapshot(), GetSerializableTransactionSnapshotInt(), InvalidPid, IsolationIsSerializable, RecoveryInProgress(), XactDeferrable, and XactReadOnly.

Referenced by GetTransactionSnapshot().

◆ PageIsPredicateLocked()

bool PageIsPredicateLocked ( Relation  relation,
BlockNumber  blkno 
)
extern

Definition at line 2017 of file predicate.c.

2018{
2022 PREDICATELOCKTARGET *target;
2023
2025 relation->rd_locator.dbOid,
2026 relation->rd_id,
2027 blkno);
2028
2032 target = (PREDICATELOCKTARGET *)
2035 HASH_FIND, NULL);
2037
2038 return (target != NULL);
2039}
uint32_t uint32
Definition c.h:618
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
Definition dynahash.c:965
#define PredicateLockTargetTagHashCode(predicatelocktargettag)
Definition predicate.c:304
#define PredicateLockHashPartitionLock(hashcode)
Definition predicate.c:259

References RelFileLocator::dbOid, fb(), HASH_FIND, hash_search_with_hash_value(), LW_SHARED, LWLockAcquire(), LWLockRelease(), PredicateLockHashPartitionLock, PredicateLockTargetHash, PredicateLockTargetTagHashCode, RelationData::rd_id, RelationData::rd_locator, and SET_PREDICATELOCKTARGETTAG_PAGE.

◆ PostPrepare_PredicateLocks()

◆ PreCommit_CheckForSerializationFailure()

void PreCommit_CheckForSerializationFailure ( void  )
extern

Definition at line 4712 of file predicate.c.

4713{
4715
4717 return;
4718
4720
4722
4723 /*
4724 * Check if someone else has already decided that we need to die. Since
4725 * we set our own DOOMED flag when partially releasing, ignore in that
4726 * case.
4727 */
4730 {
4732 ereport(ERROR,
4734 errmsg("could not serialize access due to read/write dependencies among transactions"),
4735 errdetail_internal("Reason code: Canceled on identification as a pivot, during commit attempt."),
4736 errhint("The transaction might succeed if retried.")));
4737 }
4738
4740 {
4743
4744 if (!SxactIsCommitted(nearConflict->sxactOut)
4745 && !SxactIsDoomed(nearConflict->sxactOut))
4746 {
4748
4749 dlist_foreach(far_iter, &nearConflict->sxactOut->inConflicts)
4750 {
4753
4754 if (farConflict->sxactOut == MySerializableXact
4755 || (!SxactIsCommitted(farConflict->sxactOut)
4756 && !SxactIsReadOnly(farConflict->sxactOut)
4757 && !SxactIsDoomed(farConflict->sxactOut)))
4758 {
4759 /*
4760 * Normally, we kill the pivot transaction to make sure we
4761 * make progress if the failing transaction is retried.
4762 * However, we can't kill it if it's already prepared, so
4763 * in that case we commit suicide instead.
4764 */
4765 if (SxactIsPrepared(nearConflict->sxactOut))
4766 {
4768 ereport(ERROR,
4770 errmsg("could not serialize access due to read/write dependencies among transactions"),
4771 errdetail_internal("Reason code: Canceled on commit attempt with conflict in from prepared pivot."),
4772 errhint("The transaction might succeed if retried.")));
4773 }
4774 nearConflict->sxactOut->flags |= SXACT_FLAG_DOOMED;
4775 break;
4776 }
4777 }
4778 }
4779 }
4780
4783
4785}
#define SxactIsPartiallyReleased(sxact)
Definition predicate.c:294
#define SXACT_FLAG_PREPARED
SerCommitSeqNo LastSxactCommitSeqNo
SerCommitSeqNo prepareSeqNo

References Assert, dlist_container, dlist_foreach, ereport, errcode(), ERRCODE_T_R_SERIALIZATION_FAILURE, errdetail_internal(), errhint(), errmsg, ERROR, fb(), SERIALIZABLEXACT::flags, SERIALIZABLEXACT::inConflicts, InvalidSerializableXact, IsolationIsSerializable, PredXactListData::LastSxactCommitSeqNo, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MySerializableXact, PredXact, SERIALIZABLEXACT::prepareSeqNo, SXACT_FLAG_DOOMED, SXACT_FLAG_PREPARED, SxactIsCommitted, SxactIsDoomed, SxactIsPartiallyReleased, SxactIsPrepared, and SxactIsReadOnly.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ predicatelock_twophase_recover()

void predicatelock_twophase_recover ( FullTransactionId  fxid,
uint16  info,
void recdata,
uint32  len 
)
extern

Definition at line 4918 of file predicate.c.

4920{
4923
4925
4926 record = (TwoPhasePredicateRecord *) recdata;
4927
4929 (record->type == TWOPHASEPREDICATERECORD_LOCK));
4930
4931 if (record->type == TWOPHASEPREDICATERECORD_XACT)
4932 {
4933 /* Per-transaction record. Set up a SERIALIZABLEXACT. */
4934 TwoPhasePredicateXactRecord *xactRecord;
4938 bool found;
4939
4940 xactRecord = (TwoPhasePredicateXactRecord *) &record->data.xactRecord;
4941
4944 if (!sxact)
4945 ereport(ERROR,
4947 errmsg("out of shared memory")));
4948
4949 /* vxid for a prepared xact is INVALID_PROC_NUMBER/xid; no pid */
4950 sxact->vxid.procNumber = INVALID_PROC_NUMBER;
4951 sxact->vxid.localTransactionId = (LocalTransactionId) xid;
4952 sxact->pid = 0;
4953 sxact->pgprocno = INVALID_PROC_NUMBER;
4954
4955 /* a prepared xact hasn't committed yet */
4956 sxact->prepareSeqNo = RecoverySerCommitSeqNo;
4957 sxact->commitSeqNo = InvalidSerCommitSeqNo;
4958 sxact->finishedBefore = InvalidTransactionId;
4959
4960 sxact->SeqNo.lastCommitBeforeSnapshot = RecoverySerCommitSeqNo;
4961
4962 /*
4963 * Don't need to track this; no transactions running at the time the
4964 * recovered xact started are still active, except possibly other
4965 * prepared xacts and we don't care whether those are RO_SAFE or not.
4966 */
4967 dlist_init(&(sxact->possibleUnsafeConflicts));
4968
4969 dlist_init(&(sxact->predicateLocks));
4970 dlist_node_init(&sxact->finishedLink);
4971
4972 sxact->topXid = xid;
4973 sxact->xmin = xactRecord->xmin;
4974 sxact->flags = xactRecord->flags;
4976 if (!SxactIsReadOnly(sxact))
4977 {
4981 }
4982
4983 /*
4984 * We don't know whether the transaction had any conflicts or not, so
4985 * we'll conservatively assume that it had both a conflict in and a
4986 * conflict out, and represent that with the summary conflict flags.
4987 */
4988 dlist_init(&(sxact->outConflicts));
4989 dlist_init(&(sxact->inConflicts));
4992
4993 /* Register the transaction's xid */
4994 sxidtag.xid = xid;
4996 &sxidtag,
4997 HASH_ENTER, &found);
4998 Assert(sxid != NULL);
4999 Assert(!found);
5000 sxid->myXact = sxact;
5001
5002 /*
5003 * Update global xmin. Note that this is a special case compared to
5004 * registering a normal transaction, because the global xmin might go
5005 * backwards. That's OK, because until recovery is over we're not
5006 * going to complete any transactions or create any non-prepared
5007 * transactions, so there's no danger of throwing away.
5008 */
5011 {
5015 }
5017 {
5020 }
5021
5023 }
5024 else if (record->type == TWOPHASEPREDICATERECORD_LOCK)
5025 {
5026 /* Lock record. Recreate the PREDICATELOCK */
5027 TwoPhasePredicateLockRecord *lockRecord;
5032
5033 lockRecord = (TwoPhasePredicateLockRecord *) &record->data.lockRecord;
5034 targettaghash = PredicateLockTargetTagHashCode(&lockRecord->target);
5035
5037 sxidtag.xid = xid;
5038 sxid = (SERIALIZABLEXID *)
5041
5042 Assert(sxid != NULL);
5043 sxact = sxid->myXact;
5045
5046 CreatePredicateLock(&lockRecord->target, targettaghash, sxact);
5047 }
5048}
uint32 LocalTransactionId
Definition c.h:740
uint32 TransactionId
Definition c.h:738
int MaxBackends
Definition globals.c:146
@ HASH_ENTER
Definition hsearch.h:114
static void dlist_init(dlist_head *head)
Definition ilist.h:314
static void dlist_node_init(dlist_node *node)
Definition ilist.h:325
const void size_t len
static void CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag, uint32 targettaghash, SERIALIZABLEXACT *sxact)
Definition predicate.c:2462
static SERIALIZABLEXACT * CreatePredXact(void)
Definition predicate.c:584
static void SerialSetActiveSerXmin(TransactionId xid)
Definition predicate.c:1001
#define SXACT_FLAG_SUMMARY_CONFLICT_IN
#define RecoverySerCommitSeqNo
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition transam.h:297
#define InvalidTransactionId
Definition transam.h:31
#define XidFromFullTransactionId(x)
Definition transam.h:48
int max_prepared_xacts
Definition twophase.c:117

References Assert, CreatePredicateLock(), CreatePredXact(), TwoPhasePredicateRecord::data, dlist_init(), dlist_node_init(), ereport, errcode(), errmsg, ERROR, fb(), TwoPhasePredicateXactRecord::flags, HASH_ENTER, HASH_FIND, hash_search(), INVALID_PROC_NUMBER, InvalidSerCommitSeqNo, InvalidSerializableXact, InvalidTransactionId, len, TwoPhasePredicateRecord::lockRecord, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), max_prepared_xacts, MaxBackends, PredicateLockTargetTagHashCode, PredXact, RecoverySerCommitSeqNo, SerializableXidHash, SerialSetActiveSerXmin(), SXACT_FLAG_SUMMARY_CONFLICT_IN, SXACT_FLAG_SUMMARY_CONFLICT_OUT, PredXactListData::SxactGlobalXmin, PredXactListData::SxactGlobalXminCount, SxactIsPrepared, SxactIsReadOnly, TwoPhasePredicateLockRecord::target, TransactionIdEquals, TransactionIdFollows(), TransactionIdIsValid, TWOPHASEPREDICATERECORD_LOCK, TWOPHASEPREDICATERECORD_XACT, TwoPhasePredicateRecord::type, PredXactListData::WritableSxactCount, TwoPhasePredicateRecord::xactRecord, XidFromFullTransactionId, and TwoPhasePredicateXactRecord::xmin.

◆ PredicateLockPage()

void PredicateLockPage ( Relation  relation,
BlockNumber  blkno,
Snapshot  snapshot 
)
extern

Definition at line 2608 of file predicate.c.

2609{
2611
2612 if (!SerializationNeededForRead(relation, snapshot))
2613 return;
2614
2616 relation->rd_locator.dbOid,
2617 relation->rd_id,
2618 blkno);
2620}
static void PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:2526

References RelFileLocator::dbOid, PredicateLockAcquire(), RelationData::rd_id, RelationData::rd_locator, SerializationNeededForRead(), and SET_PREDICATELOCKTARGETTAG_PAGE.

Referenced by _bt_readpage(), _hash_first(), _hash_readnext(), collectMatchBitmap(), gistScanPage(), IndexOnlyNext(), moveRightIfItNeeded(), scanPendingInsert(), and startScanEntry().

◆ PredicateLockPageCombine()

void PredicateLockPageCombine ( Relation  relation,
BlockNumber  oldblkno,
BlockNumber  newblkno 
)
extern

Definition at line 3238 of file predicate.c.

3240{
3241 /*
3242 * Page combines differ from page splits in that we ought to be able to
3243 * remove the locks on the old page after transferring them to the new
3244 * page, instead of duplicating them. However, because we can't edit other
3245 * backends' local lock tables, removing the old lock would leave them
3246 * with an entry in their LocalPredicateLockHash for a lock they're not
3247 * holding, which isn't acceptable. So we wind up having to do the same
3248 * work as a page split, acquiring a lock on the new page and keeping the
3249 * old page locked too. That can lead to some false positives, but should
3250 * be rare in practice.
3251 */
3253}
void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
Definition predicate.c:3153

References fb(), and PredicateLockPageSplit().

Referenced by _bt_mark_page_halfdead(), and ginDeletePostingPage().

◆ PredicateLockPageSplit()

void PredicateLockPageSplit ( Relation  relation,
BlockNumber  oldblkno,
BlockNumber  newblkno 
)
extern

Definition at line 3153 of file predicate.c.

3155{
3158 bool success;
3159
3160 /*
3161 * Bail out quickly if there are no serializable transactions running.
3162 *
3163 * It's safe to do this check without taking any additional locks. Even if
3164 * a serializable transaction starts concurrently, we know it can't take
3165 * any SIREAD locks on the page being split because the caller is holding
3166 * the associated buffer page lock. Memory reordering isn't an issue; the
3167 * memory barrier in the LWLock acquisition guarantees that this read
3168 * occurs while the buffer page lock is held.
3169 */
3171 return;
3172
3173 if (!PredicateLockingNeededForRelation(relation))
3174 return;
3175
3179
3181 relation->rd_locator.dbOid,
3182 relation->rd_id,
3183 oldblkno);
3185 relation->rd_locator.dbOid,
3186 relation->rd_id,
3187 newblkno);
3188
3190
3191 /*
3192 * Try copying the locks over to the new page's tag, creating it if
3193 * necessary.
3194 */
3197 false);
3198
3199 if (!success)
3200 {
3201 /*
3202 * No more predicate lock entries are available. Failure isn't an
3203 * option here, so promote the page lock to a relation lock.
3204 */
3205
3206 /* Get the parent relation lock's lock tag */
3208 &newtargettag);
3209 Assert(success);
3210
3211 /*
3212 * Move the locks to the parent. This shouldn't fail.
3213 *
3214 * Note that here we are removing locks held by other backends,
3215 * leading to a possible inconsistency in their local lock hash table.
3216 * This is OK because we're replacing it with a lock that covers the
3217 * old one.
3218 */
3221 true);
3222 Assert(success);
3223 }
3224
3226}
static bool BlockNumberIsValid(BlockNumber blockNumber)
Definition block.h:71
static bool success
Definition initdb.c:188
static bool PredicateLockingNeededForRelation(Relation relation)
Definition predicate.c:500
static bool GetParentPredicateLockTag(const PREDICATELOCKTARGETTAG *tag, PREDICATELOCKTARGETTAG *parent)
Definition predicate.c:2081
static bool TransferPredicateLocksToNewTarget(PREDICATELOCKTARGETTAG oldtargettag, PREDICATELOCKTARGETTAG newtargettag, bool removeOld)
Definition predicate.c:2739

References Assert, BlockNumberIsValid(), RelFileLocator::dbOid, fb(), GetParentPredicateLockTag(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), PredicateLockingNeededForRelation(), PredXact, RelationData::rd_id, RelationData::rd_locator, SET_PREDICATELOCKTARGETTAG_PAGE, success, PredXactListData::SxactGlobalXmin, TransactionIdIsValid, and TransferPredicateLocksToNewTarget().

Referenced by _bt_insertonpg(), _hash_splitbucket(), createPostingTree(), ginPlaceToPage(), gistplacetopage(), and PredicateLockPageCombine().

◆ PredicateLockRelation()

void PredicateLockRelation ( Relation  relation,
Snapshot  snapshot 
)
extern

◆ PredicateLockShmemInit()

void PredicateLockShmemInit ( void  )
extern

Definition at line 1156 of file predicate.c.

1157{
1158 HASHCTL info;
1161 bool found;
1162
1163#ifndef EXEC_BACKEND
1165#endif
1166
1167 /*
1168 * Compute size of predicate lock target hashtable. Note these
1169 * calculations must agree with PredicateLockShmemSize!
1170 */
1172
1173 /*
1174 * Allocate hash table for PREDICATELOCKTARGET structs. This stores
1175 * per-predicate-lock-target information.
1176 */
1177 info.keysize = sizeof(PREDICATELOCKTARGETTAG);
1178 info.entrysize = sizeof(PREDICATELOCKTARGET);
1180
1181 PredicateLockTargetHash = ShmemInitHash("PREDICATELOCKTARGET hash",
1184 &info,
1187
1188 /*
1189 * Reserve a dummy entry in the hash table; we use it to make sure there's
1190 * always one entry available when we need to split or combine a page,
1191 * because running out of space there could mean aborting a
1192 * non-serializable transaction.
1193 */
1194 if (!IsUnderPostmaster)
1195 {
1197 HASH_ENTER, &found);
1198 Assert(!found);
1199 }
1200
1201 /* Pre-calculate the hash and partition lock of the scratch entry */
1204
1205 /*
1206 * Allocate hash table for PREDICATELOCK structs. This stores per
1207 * xact-lock-of-a-target information.
1208 */
1209 info.keysize = sizeof(PREDICATELOCKTAG);
1210 info.entrysize = sizeof(PREDICATELOCK);
1211 info.hash = predicatelock_hash;
1213
1214 /* Assume an average of 2 xacts per target */
1215 max_table_size *= 2;
1216
1217 PredicateLockHash = ShmemInitHash("PREDICATELOCK hash",
1220 &info,
1223
1224 /*
1225 * Compute size for serializable transaction hashtable. Note these
1226 * calculations must agree with PredicateLockShmemSize!
1227 */
1229
1230 /*
1231 * Allocate a list to hold information on transactions participating in
1232 * predicate locking.
1233 *
1234 * Assume an average of 10 predicate locking transactions per backend.
1235 * This allows aggressive cleanup while detail is present before data must
1236 * be summarized for storage in SLRU and the "dummy" transaction.
1237 */
1238 max_table_size *= 10;
1239
1242 sizeof(SERIALIZABLEXACT))));
1243
1244 PredXact = ShmemInitStruct("PredXactList",
1246 &found);
1247 Assert(found == IsUnderPostmaster);
1248 if (!found)
1249 {
1250 int i;
1251
1252 /* clean everything, both the header and the element */
1254
1265 /* Add all elements to available list, clean. */
1266 for (i = 0; i < max_table_size; i++)
1267 {
1271 }
1288 }
1289 /* This never changes, so let's keep a local copy. */
1291
1292 /*
1293 * Allocate hash table for SERIALIZABLEXID structs. This stores per-xid
1294 * information for serializable transactions which have accessed data.
1295 */
1296 info.keysize = sizeof(SERIALIZABLEXIDTAG);
1297 info.entrysize = sizeof(SERIALIZABLEXID);
1298
1299 SerializableXidHash = ShmemInitHash("SERIALIZABLEXID hash",
1302 &info,
1305
1306 /*
1307 * Allocate space for tracking rw-conflicts in lists attached to the
1308 * transactions.
1309 *
1310 * Assume an average of 5 conflicts per transaction. Calculations suggest
1311 * that this will prevent resource exhaustion in even the most pessimal
1312 * loads up to max_connections = 200 with all 200 connections pounding the
1313 * database with serializable transactions. Beyond that, there may be
1314 * occasional transactions canceled when trying to flag conflicts. That's
1315 * probably OK.
1316 */
1317 max_table_size *= 5;
1318
1322
1323 RWConflictPool = ShmemInitStruct("RWConflictPool",
1325 &found);
1326 Assert(found == IsUnderPostmaster);
1327 if (!found)
1328 {
1329 int i;
1330
1331 /* clean everything, including the elements */
1333
1337 /* Add all elements to available list, clean. */
1338 for (i = 0; i < max_table_size; i++)
1339 {
1342 }
1343 }
1344
1345 /*
1346 * Create or attach to the header for the list of finished serializable
1347 * transactions.
1348 */
1350 ShmemInitStruct("FinishedSerializableTransactions",
1351 sizeof(dlist_head),
1352 &found);
1353 Assert(found == IsUnderPostmaster);
1354 if (!found)
1356
1357 /*
1358 * Initialize the SLRU storage for old committed serializable
1359 * transactions.
1360 */
1361 SerialInit();
1362}
size_t Size
Definition c.h:691
bool IsUnderPostmaster
Definition globals.c:120
#define HASH_ELEM
Definition hsearch.h:95
#define HASH_FUNCTION
Definition hsearch.h:98
#define HASH_BLOBS
Definition hsearch.h:97
#define HASH_FIXED_SIZE
Definition hsearch.h:105
#define HASH_PARTITION
Definition hsearch.h:92
static void dlist_push_tail(dlist_head *head, dlist_node *node)
Definition ilist.h:364
#define SetInvalidVirtualTransactionId(vxid)
Definition lock.h:76
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition lwlock.c:699
static HTAB * PredicateLockHash
Definition predicate.c:399
static LWLock * ScratchPartitionLock
Definition predicate.c:409
static uint32 ScratchTargetTagHash
Definition predicate.c:408
static uint32 predicatelock_hash(const void *key, Size keysize)
Definition predicate.c:1430
static SERIALIZABLEXACT * OldCommittedSxact
Definition predicate.c:363
static void SerialInit(void)
Definition predicate.c:816
static dlist_head * FinishedSerializableTransactions
Definition predicate.c:400
static const PREDICATELOCKTARGETTAG ScratchTargetTag
Definition predicate.c:407
#define NPREDICATELOCKTARGETENTS()
Definition predicate.c:265
static RWConflictPoolHeader RWConflictPool
Definition predicate.c:391
#define RWConflictDataSize
#define FirstNormalSerCommitSeqNo
#define PredXactListDataSize
#define RWConflictPoolHeaderDataSize
struct RWConflictData * RWConflict
#define SXACT_FLAG_COMMITTED
Size add_size(Size s1, Size s2)
Definition shmem.c:485
Size mul_size(Size s1, Size s2)
Definition shmem.c:500
HTAB * ShmemInitHash(const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)
Definition shmem.c:326
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:381
Size keysize
Definition hsearch.h:75
HashValueFunc hash
Definition hsearch.h:78
Size entrysize
Definition hsearch.h:76
int64 num_partitions
Definition hsearch.h:68
SERIALIZABLEXACT * element
SerCommitSeqNo CanPartialClearThrough
SERIALIZABLEXACT * OldCommittedSxact
SerCommitSeqNo HavePartialClearedThrough
VirtualTransactionId vxid
dlist_head possibleUnsafeConflicts
SerCommitSeqNo commitSeqNo
TransactionId finishedBefore

References PredXactListData::activeList, add_size(), Assert, PredXactListData::availableList, RWConflictPoolHeaderData::availableList, PredXactListData::CanPartialClearThrough, SERIALIZABLEXACT::commitSeqNo, CreatePredXact(), dlist_init(), dlist_node_init(), dlist_push_tail(), PredXactListData::element, RWConflictPoolHeaderData::element, HASHCTL::entrysize, fb(), SERIALIZABLEXACT::finishedBefore, SERIALIZABLEXACT::finishedLink, FinishedSerializableTransactions, FirstNormalSerCommitSeqNo, SERIALIZABLEXACT::flags, HASHCTL::hash, HASH_BLOBS, HASH_ELEM, HASH_ENTER, HASH_FIXED_SIZE, HASH_FUNCTION, HASH_PARTITION, hash_search(), PredXactListData::HavePartialClearedThrough, i, SERIALIZABLEXACT::inConflicts, INVALID_PROC_NUMBER, InvalidTransactionId, IsUnderPostmaster, HASHCTL::keysize, SERIALIZABLEXACT::lastCommitBeforeSnapshot, PredXactListData::LastSxactCommitSeqNo, LWLockInitialize(), max_prepared_xacts, MaxBackends, mul_size(), NPREDICATELOCKTARGETENTS, HASHCTL::num_partitions, NUM_PREDICATELOCK_PARTITIONS, OldCommittedSxact, PredXactListData::OldCommittedSxact, SERIALIZABLEXACT::outConflicts, RWConflictData::outLink, SERIALIZABLEXACT::perXactPredicateListLock, SERIALIZABLEXACT::pgprocno, SERIALIZABLEXACT::pid, SERIALIZABLEXACT::possibleUnsafeConflicts, predicatelock_hash(), PredicateLockHash, PredicateLockHashPartitionLock, SERIALIZABLEXACT::predicateLocks, PredicateLockTargetHash, PredicateLockTargetTagHashCode, PredXact, PredXactListDataSize, SERIALIZABLEXACT::prepareSeqNo, RWConflictDataSize, RWConflictPool, RWConflictPoolHeaderDataSize, ScratchPartitionLock, ScratchTargetTag, ScratchTargetTagHash, SERIALIZABLEXACT::SeqNo, SerialInit(), SerializableXidHash, SetInvalidVirtualTransactionId, ShmemInitHash(), ShmemInitStruct(), SXACT_FLAG_COMMITTED, PredXactListData::SxactGlobalXmin, PredXactListData::SxactGlobalXminCount, SERIALIZABLEXACT::topXid, SERIALIZABLEXACT::vxid, PredXactListData::WritableSxactCount, SERIALIZABLEXACT::xactLink, and SERIALIZABLEXACT::xmin.

Referenced by CreateOrAttachShmemStructs().

◆ PredicateLockShmemSize()

Size PredicateLockShmemSize ( void  )
extern

Definition at line 1368 of file predicate.c.

1369{
1370 Size size = 0;
1371 long max_table_size;
1372
1373 /* predicate lock target hash table */
1376 sizeof(PREDICATELOCKTARGET)));
1377
1378 /* predicate lock hash table */
1379 max_table_size *= 2;
1381 sizeof(PREDICATELOCK)));
1382
1383 /*
1384 * Since NPREDICATELOCKTARGETENTS is only an estimate, add 10% safety
1385 * margin.
1386 */
1387 size = add_size(size, size / 10);
1388
1389 /* transaction list */
1391 max_table_size *= 10;
1392 size = add_size(size, PredXactListDataSize);
1393 size = add_size(size, mul_size((Size) max_table_size,
1394 sizeof(SERIALIZABLEXACT)));
1395
1396 /* transaction xid table */
1398 sizeof(SERIALIZABLEXID)));
1399
1400 /* rw-conflict pool */
1401 max_table_size *= 5;
1403 size = add_size(size, mul_size((Size) max_table_size,
1405
1406 /* Head for list of finished serializable transactions. */
1407 size = add_size(size, sizeof(dlist_head));
1408
1409 /* Shared memory structures for SLRU tracking of old committed xids. */
1410 size = add_size(size, sizeof(SerialControlData));
1412
1413 return size;
1414}
Size hash_estimate_size(int64 num_entries, Size entrysize)
Definition dynahash.c:783
int serializable_buffers
Definition globals.c:165
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition slru.c:200

References add_size(), fb(), hash_estimate_size(), max_prepared_xacts, MaxBackends, mul_size(), NPREDICATELOCKTARGETENTS, PredXactListDataSize, RWConflictDataSize, RWConflictPoolHeaderDataSize, serializable_buffers, and SimpleLruShmemSize().

Referenced by CalculateShmemSize().

◆ PredicateLockTID()

void PredicateLockTID ( Relation  relation,
const ItemPointerData tid,
Snapshot  snapshot,
TransactionId  tuple_xid 
)
extern

Definition at line 2630 of file predicate.c.

2632{
2634
2635 if (!SerializationNeededForRead(relation, snapshot))
2636 return;
2637
2638 /*
2639 * Return if this xact wrote it.
2640 */
2641 if (relation->rd_index == NULL)
2642 {
2643 /* If we wrote it; we already have a write lock. */
2645 return;
2646 }
2647
2648 /*
2649 * Do quick-but-not-definitive test for a relation lock first. This will
2650 * never cause a return when the relation is *not* locked, but will
2651 * occasionally let the check continue when there really *is* a relation
2652 * level lock.
2653 */
2655 relation->rd_locator.dbOid,
2656 relation->rd_id);
2657 if (PredicateLockExists(&tag))
2658 return;
2659
2661 relation->rd_locator.dbOid,
2662 relation->rd_id,
2666}
static bool PredicateLockExists(const PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:2054
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition xact.c:943

References RelFileLocator::dbOid, fb(), ItemPointerGetBlockNumber(), ItemPointerGetOffsetNumber(), PredicateLockAcquire(), PredicateLockExists(), RelationData::rd_id, RelationData::rd_index, RelationData::rd_locator, SerializationNeededForRead(), SET_PREDICATELOCKTARGETTAG_RELATION, SET_PREDICATELOCKTARGETTAG_TUPLE, and TransactionIdIsCurrentTransactionId().

Referenced by BitmapHeapScanNextBlock(), heap_fetch(), and heap_hot_search_buffer().

◆ PredicateLockTwoPhaseFinish()

void PredicateLockTwoPhaseFinish ( FullTransactionId  fxid,
bool  isCommit 
)
extern

Definition at line 4891 of file predicate.c.

4892{
4895
4897
4899 sxid = (SERIALIZABLEXID *)
4902
4903 /* xid will not be found if it wasn't a serializable transaction */
4904 if (sxid == NULL)
4905 return;
4906
4907 /* Release its locks */
4908 MySerializableXact = sxid->myXact;
4909 MyXactDidWrite = true; /* conservatively assume that we wrote
4910 * something */
4912}
void ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
Definition predicate.c:3321

References fb(), HASH_FIND, hash_search(), LW_SHARED, LWLockAcquire(), LWLockRelease(), MySerializableXact, MyXactDidWrite, ReleasePredicateLocks(), SerializableXidHash, SERIALIZABLEXIDTAG::xid, and XidFromFullTransactionId.

Referenced by FinishPreparedTransaction().

◆ RegisterPredicateLockingXid()

void RegisterPredicateLockingXid ( TransactionId  xid)
extern

Definition at line 1968 of file predicate.c.

1969{
1972 bool found;
1973
1974 /*
1975 * If we're not tracking predicate lock data for this transaction, we
1976 * should ignore the request and return quickly.
1977 */
1979 return;
1980
1981 /* We should have a valid XID and be at the top level. */
1983
1985
1986 /* This should only be done once per transaction. */
1988
1990
1991 sxidtag.xid = xid;
1993 &sxidtag,
1994 HASH_ENTER, &found);
1995 Assert(!found);
1996
1997 /* Initialize the structure. */
1998 sxid->myXact = MySerializableXact;
2000}

References Assert, fb(), HASH_ENTER, hash_search(), InvalidSerializableXact, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MySerializableXact, SerializableXidHash, SERIALIZABLEXACT::topXid, and TransactionIdIsValid.

Referenced by AssignTransactionId().

◆ ReleasePredicateLocks()

void ReleasePredicateLocks ( bool  isCommit,
bool  isReadOnlySafe 
)
extern

Definition at line 3321 of file predicate.c.

3322{
3323 bool partiallyReleasing = false;
3324 bool needToClear;
3326 dlist_mutable_iter iter;
3327
3328 /*
3329 * We can't trust XactReadOnly here, because a transaction which started
3330 * as READ WRITE can show as READ ONLY later, e.g., within
3331 * subtransactions. We want to flag a transaction as READ ONLY if it
3332 * commits without writing so that de facto READ ONLY transactions get the
3333 * benefit of some RO optimizations, so we will use this local variable to
3334 * get some cleanup logic right which is based on whether the transaction
3335 * was declared READ ONLY at the top level.
3336 */
3338
3339 /* We can't be both committing and releasing early due to RO_SAFE. */
3341
3342 /* Are we at the end of a transaction, that is, a commit or abort? */
3343 if (!isReadOnlySafe)
3344 {
3345 /*
3346 * Parallel workers mustn't release predicate locks at the end of
3347 * their transaction. The leader will do that at the end of its
3348 * transaction.
3349 */
3350 if (IsParallelWorker())
3351 {
3353 return;
3354 }
3355
3356 /*
3357 * By the time the leader in a parallel query reaches end of
3358 * transaction, it has waited for all workers to exit.
3359 */
3361
3362 /*
3363 * If the leader in a parallel query earlier stashed a partially
3364 * released SERIALIZABLEXACT for final clean-up at end of transaction
3365 * (because workers might still have been accessing it), then it's
3366 * time to restore it.
3367 */
3369 {
3374 }
3375 }
3376
3378 {
3380 return;
3381 }
3382
3384
3385 /*
3386 * If the transaction is committing, but it has been partially released
3387 * already, then treat this as a roll back. It was marked as rolled back.
3388 */
3390 isCommit = false;
3391
3392 /*
3393 * If we're called in the middle of a transaction because we discovered
3394 * that the SXACT_FLAG_RO_SAFE flag was set, then we'll partially release
3395 * it (that is, release the predicate locks and conflicts, but not the
3396 * SERIALIZABLEXACT itself) if we're the first backend to have noticed.
3397 */
3399 {
3400 /*
3401 * The leader needs to stash a pointer to it, so that it can
3402 * completely release it at end-of-transaction.
3403 */
3404 if (!IsParallelWorker())
3406
3407 /*
3408 * The first backend to reach this condition will partially release
3409 * the SERIALIZABLEXACT. All others will just clear their
3410 * backend-local state so that they stop doing SSI checks for the rest
3411 * of the transaction.
3412 */
3414 {
3417 return;
3418 }
3419 else
3420 {
3422 partiallyReleasing = true;
3423 /* ... and proceed to perform the partial release below. */
3424 }
3425 }
3431
3432 /* may not be serializable during COMMIT/ROLLBACK PREPARED */
3434
3435 /* We'd better not already be on the cleanup list. */
3437
3439
3440 /*
3441 * We don't hold XidGenLock lock here, assuming that TransactionId is
3442 * atomic!
3443 *
3444 * If this value is changing, we don't care that much whether we get the
3445 * old or new value -- it is just used to determine how far
3446 * SxactGlobalXmin must advance before this transaction can be fully
3447 * cleaned up. The worst that could happen is we wait for one more
3448 * transaction to complete before freeing some RAM; correctness of visible
3449 * behavior is not affected.
3450 */
3452
3453 /*
3454 * If it's not a commit it's either a rollback or a read-only transaction
3455 * flagged SXACT_FLAG_RO_SAFE, and we can clear our locks immediately.
3456 */
3457 if (isCommit)
3458 {
3461 /* Recognize implicit read-only transaction (commit without write). */
3462 if (!MyXactDidWrite)
3464 }
3465 else
3466 {
3467 /*
3468 * The DOOMED flag indicates that we intend to roll back this
3469 * transaction and so it should not cause serialization failures for
3470 * other transactions that conflict with it. Note that this flag might
3471 * already be set, if another backend marked this transaction for
3472 * abort.
3473 *
3474 * The ROLLED_BACK flag further indicates that ReleasePredicateLocks
3475 * has been called, and so the SerializableXact is eligible for
3476 * cleanup. This means it should not be considered when calculating
3477 * SxactGlobalXmin.
3478 */
3481
3482 /*
3483 * If the transaction was previously prepared, but is now failing due
3484 * to a ROLLBACK PREPARED or (hopefully very rare) error after the
3485 * prepare, clear the prepared flag. This simplifies conflict
3486 * checking.
3487 */
3489 }
3490
3492 {
3494 if (--(PredXact->WritableSxactCount) == 0)
3495 {
3496 /*
3497 * Release predicate locks and rw-conflicts in for all committed
3498 * transactions. There are no longer any transactions which might
3499 * conflict with the locks and no chance for new transactions to
3500 * overlap. Similarly, existing conflicts in can't cause pivots,
3501 * and any conflicts in which could have completed a dangerous
3502 * structure would already have caused a rollback, so any
3503 * remaining ones must be benign.
3504 */
3506 }
3507 }
3508 else
3509 {
3510 /*
3511 * Read-only transactions: clear the list of transactions that might
3512 * make us unsafe. Note that we use 'inLink' for the iteration as
3513 * opposed to 'outLink' for the r/w xacts.
3514 */
3516 {
3518 dlist_container(RWConflictData, inLink, iter.cur);
3519
3522
3524 }
3525 }
3526
3527 /* Check for conflict out to old committed transactions. */
3528 if (isCommit
3531 {
3532 /*
3533 * we don't know which old committed transaction we conflicted with,
3534 * so be conservative and use FirstNormalSerCommitSeqNo here
3535 */
3539 }
3540
3541 /*
3542 * Release all outConflicts to committed transactions. If we're rolling
3543 * back clear them all. Set SXACT_FLAG_CONFLICT_OUT if any point to
3544 * previously committed transactions.
3545 */
3547 {
3549 dlist_container(RWConflictData, outLink, iter.cur);
3550
3551 if (isCommit
3553 && SxactIsCommitted(conflict->sxactIn))
3554 {
3556 || conflict->sxactIn->prepareSeqNo < MySerializableXact->SeqNo.earliestOutConflictCommit)
3559 }
3560
3561 if (!isCommit
3562 || SxactIsCommitted(conflict->sxactIn)
3563 || (conflict->sxactIn->SeqNo.lastCommitBeforeSnapshot >= PredXact->LastSxactCommitSeqNo))
3565 }
3566
3567 /*
3568 * Release all inConflicts from committed and read-only transactions. If
3569 * we're rolling back, clear them all.
3570 */
3572 {
3574 dlist_container(RWConflictData, inLink, iter.cur);
3575
3576 if (!isCommit
3577 || SxactIsCommitted(conflict->sxactOut)
3578 || SxactIsReadOnly(conflict->sxactOut))
3580 }
3581
3583 {
3584 /*
3585 * Remove ourselves from the list of possible conflicts for concurrent
3586 * READ ONLY transactions, flagging them as unsafe if we have a
3587 * conflict out. If any are waiting DEFERRABLE transactions, wake them
3588 * up if they are known safe or known unsafe.
3589 */
3591 {
3593 dlist_container(RWConflictData, outLink, iter.cur);
3594
3595 roXact = possibleUnsafeConflict->sxactIn;
3598
3599 /* Mark conflicted if necessary. */
3600 if (isCommit
3604 <= roXact->SeqNo.lastCommitBeforeSnapshot))
3605 {
3606 /*
3607 * This releases possibleUnsafeConflict (as well as all other
3608 * possible conflicts for roXact)
3609 */
3611 }
3612 else
3613 {
3615
3616 /*
3617 * If we were the last possible conflict, flag it safe. The
3618 * transaction can now safely release its predicate locks (but
3619 * that transaction's backend has to do that itself).
3620 */
3621 if (dlist_is_empty(&roXact->possibleUnsafeConflicts))
3622 roXact->flags |= SXACT_FLAG_RO_SAFE;
3623 }
3624
3625 /*
3626 * Wake up the process for a waiting DEFERRABLE transaction if we
3627 * now know it's either safe or conflicted.
3628 */
3631 ProcSendSignal(roXact->pgprocno);
3632 }
3633 }
3634
3635 /*
3636 * Check whether it's time to clean up old transactions. This can only be
3637 * done when the last serializable transaction with the oldest xmin among
3638 * serializable transactions completes. We then find the "new oldest"
3639 * xmin and purge any transactions which finished before this transaction
3640 * was launched.
3641 *
3642 * For parallel queries in read-only transactions, it might run twice. We
3643 * only release the reference on the first call.
3644 */
3645 needToClear = false;
3646 if ((partiallyReleasing ||
3650 {
3652 if (--(PredXact->SxactGlobalXminCount) == 0)
3653 {
3655 needToClear = true;
3656 }
3657 }
3658
3660
3662
3663 /* Add this to the list of transactions to check for later cleanup. */
3664 if (isCommit)
3667
3668 /*
3669 * If we're releasing a RO_SAFE transaction in parallel mode, we'll only
3670 * partially release it. That's necessary because other backends may have
3671 * a reference to it. The leader will release the SERIALIZABLEXACT itself
3672 * at the end of the transaction after workers have stopped running.
3673 */
3674 if (!isCommit)
3677 false);
3678
3680
3681 if (needToClear)
3683
3685}
static void SetNewSxactGlobalXmin(void)
Definition predicate.c:3260
#define SxactIsROUnsafe(sxact)
Definition predicate.c:293
#define SxactIsDeferrableWaiting(sxact)
Definition predicate.c:291
static void ReleasePredicateLocksLocal(void)
Definition predicate.c:3688
static void ClearOldPredicateLocks(void)
Definition predicate.c:3706
static void FlagSxactUnsafe(SERIALIZABLEXACT *sxact)
Definition predicate.c:701
#define SxactIsOnFinishedList(sxact)
Definition predicate.c:268
#define SxactIsROSafe(sxact)
Definition predicate.c:292
static void ReleaseRWConflict(RWConflict conflict)
Definition predicate.c:693
static void ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, bool summarize)
Definition predicate.c:3844
#define SxactIsRolledBack(sxact)
Definition predicate.c:280
static SERIALIZABLEXACT * SavedSerializableXact
Definition predicate.c:432
#define SXACT_FLAG_CONFLICT_OUT
#define SXACT_FLAG_READ_ONLY
#define SXACT_FLAG_ROLLED_BACK
#define SXACT_FLAG_PARTIALLY_RELEASED
#define SXACT_FLAG_RO_SAFE
void ProcSendSignal(ProcNumber procNumber)
Definition proc.c:2003
SerCommitSeqNo earliestOutConflictCommit
FullTransactionId nextXid
Definition transam.h:220
TransamVariablesData * TransamVariables
Definition varsup.c:34
bool IsInParallelMode(void)
Definition xact.c:1091

References Assert, PredXactListData::CanPartialClearThrough, ClearOldPredicateLocks(), SERIALIZABLEXACT::commitSeqNo, dlist_mutable_iter::cur, dlist_container, dlist_foreach_modify, dlist_is_empty(), dlist_push_tail(), SERIALIZABLEXACT::earliestOutConflictCommit, fb(), SERIALIZABLEXACT::finishedBefore, SERIALIZABLEXACT::finishedLink, FinishedSerializableTransactions, FirstNormalSerCommitSeqNo, SERIALIZABLEXACT::flags, FlagSxactUnsafe(), SERIALIZABLEXACT::inConflicts, InvalidSerializableXact, IsInParallelMode(), IsolationIsSerializable, IsParallelWorker, PredXactListData::LastSxactCommitSeqNo, LocalPredicateLockHash, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MySerializableXact, MyXactDidWrite, TransamVariablesData::nextXid, SERIALIZABLEXACT::outConflicts, ParallelContextActive(), SERIALIZABLEXACT::pid, SERIALIZABLEXACT::possibleUnsafeConflicts, PredXact, ProcSendSignal(), ReleaseOneSerializableXact(), ReleasePredicateLocksLocal(), ReleaseRWConflict(), SavedSerializableXact, SERIALIZABLEXACT::SeqNo, SetNewSxactGlobalXmin(), SXACT_FLAG_COMMITTED, SXACT_FLAG_CONFLICT_OUT, SXACT_FLAG_DOOMED, SXACT_FLAG_PARTIALLY_RELEASED, SXACT_FLAG_READ_ONLY, SXACT_FLAG_RO_SAFE, SXACT_FLAG_ROLLED_BACK, PredXactListData::SxactGlobalXmin, PredXactListData::SxactGlobalXminCount, SxactHasConflictOut, SxactHasSummaryConflictOut, SxactIsCommitted, SxactIsDeferrableWaiting, SxactIsDoomed, SxactIsOnFinishedList, SxactIsPartiallyReleased, SxactIsPrepared, SxactIsReadOnly, SxactIsRolledBack, SxactIsROSafe, SxactIsROUnsafe, TransactionIdEquals, TransamVariables, PredXactListData::WritableSxactCount, XidFromFullTransactionId, and SERIALIZABLEXACT::xmin.

Referenced by GetSafeSnapshot(), PredicateLockTwoPhaseFinish(), ResourceOwnerReleaseInternal(), and SerializationNeededForRead().

◆ SetSerializableTransactionSnapshot()

void SetSerializableTransactionSnapshot ( Snapshot  snapshot,
VirtualTransactionId sourcevxid,
int  sourcepid 
)
extern

Definition at line 1731 of file predicate.c.

1734{
1736
1737 /*
1738 * If this is called by parallel.c in a parallel worker, we don't want to
1739 * create a SERIALIZABLEXACT just yet because the leader's
1740 * SERIALIZABLEXACT will be installed with AttachSerializableXact(). We
1741 * also don't want to reject SERIALIZABLE READ ONLY DEFERRABLE in this
1742 * case, because the leader has already determined that the snapshot it
1743 * has passed us is safe. So there is nothing for us to do.
1744 */
1745 if (IsParallelWorker())
1746 return;
1747
1748 /*
1749 * We do not allow SERIALIZABLE READ ONLY DEFERRABLE transactions to
1750 * import snapshots, since there's no way to wait for a safe snapshot when
1751 * we're using the snap we're told to. (XXX instead of throwing an error,
1752 * we could just ignore the XactDeferrable flag?)
1753 */
1755 ereport(ERROR,
1757 errmsg("a snapshot-importing transaction must not be READ ONLY DEFERRABLE")));
1758
1760 sourcepid);
1761}

References Assert, ereport, errcode(), errmsg, ERROR, fb(), GetSerializableTransactionSnapshotInt(), IsolationIsSerializable, IsParallelWorker, XactDeferrable, and XactReadOnly.

Referenced by SetTransactionSnapshot().

◆ ShareSerializableXact()

SerializableXactHandle ShareSerializableXact ( void  )
extern

Definition at line 5056 of file predicate.c.

5057{
5058 return MySerializableXact;
5059}

References MySerializableXact.

Referenced by InitializeParallelDSM().

◆ TransferPredicateLocksToHeapRelation()

void TransferPredicateLocksToHeapRelation ( Relation  relation)
extern

Definition at line 3132 of file predicate.c.

3133{
3134 DropAllPredicateLocksFromTable(relation, true);
3135}
static void DropAllPredicateLocksFromTable(Relation relation, bool transfer)
Definition predicate.c:2946

References DropAllPredicateLocksFromTable().

Referenced by ATRewriteTable(), cluster_rel(), index_concurrently_set_dead(), index_drop(), and reindex_index().

Variable Documentation

◆ max_predicate_locks_per_page

PGDLLIMPORT int max_predicate_locks_per_page
extern

Definition at line 374 of file predicate.c.

Referenced by MaxPredicateChildLocks().

◆ max_predicate_locks_per_relation

PGDLLIMPORT int max_predicate_locks_per_relation
extern

Definition at line 373 of file predicate.c.

Referenced by MaxPredicateChildLocks().

◆ max_predicate_locks_per_xact

PGDLLIMPORT int max_predicate_locks_per_xact
extern

Definition at line 372 of file predicate.c.

Referenced by CreateLocalPredicateLockHash(), and MaxPredicateChildLocks().