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 4788 of file predicate.c.

4789{
4792 TwoPhasePredicateXactRecord *xactRecord;
4793 TwoPhasePredicateLockRecord *lockRecord;
4794 dlist_iter iter;
4795
4797 xactRecord = &(record.data.xactRecord);
4798 lockRecord = &(record.data.lockRecord);
4799
4801 return;
4802
4803 /* Generate an xact record for our SERIALIZABLEXACT */
4805 xactRecord->xmin = MySerializableXact->xmin;
4806 xactRecord->flags = MySerializableXact->flags;
4807
4808 /*
4809 * Note that we don't include the list of conflicts in our out in the
4810 * statefile, because new conflicts can be added even after the
4811 * transaction prepares. We'll just make a conservative assumption during
4812 * recovery instead.
4813 */
4814
4816 &record, sizeof(record));
4817
4818 /*
4819 * Generate a lock record for each lock.
4820 *
4821 * To do this, we need to walk the predicate lock list in our sxact rather
4822 * than using the local predicate lock table because the latter is not
4823 * guaranteed to be accurate.
4824 */
4826
4827 /*
4828 * No need to take sxact->perXactPredicateListLock in parallel mode
4829 * because there cannot be any parallel workers running while we are
4830 * preparing a transaction.
4831 */
4833
4834 dlist_foreach(iter, &sxact->predicateLocks)
4835 {
4837 dlist_container(PREDICATELOCK, xactLink, iter.cur);
4838
4840 lockRecord->target = predlock->tag.myTarget->tag;
4841
4843 &record, sizeof(record));
4844 }
4845
4847}
bool ParallelContextActive(void)
Definition parallel.c:1031
#define Assert(condition)
Definition c.h:873
#define dlist_foreach(iter, lhead)
Definition ilist.h:623
#define dlist_container(type, membername, ptr)
Definition ilist.h:593
#define IsParallelWorker()
Definition parallel.h:60
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1176
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1793
@ LW_SHARED
Definition lwlock.h:113
static SERIALIZABLEXACT * MySerializableXact
Definition predicate.c:421
@ TWOPHASEPREDICATERECORD_XACT
@ TWOPHASEPREDICATERECORD_LOCK
#define InvalidSerializableXact
static int fb(int x)
PREDICATELOCKTARGETTAG target
TwoPhasePredicateRecordType type
union TwoPhasePredicateRecord::@130 data
TwoPhasePredicateLockRecord lockRecord
TwoPhasePredicateXactRecord xactRecord
dlist_node * cur
Definition ilist.h:179
void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, const void *data, uint32 len)
Definition twophase.c:1271
#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 5054 of file predicate.c.

5055{
5056
5058
5062}
static void CreateLocalPredicateLockHash(void)
Definition predicate.c:1938

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

Referenced by ParallelWorkerMain().

◆ CheckForSerializableConflictIn()

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

Definition at line 4334 of file predicate.c.

4335{
4337
4338 if (!SerializationNeededForWrite(relation))
4339 return;
4340
4341 /* Check if someone else has already decided that we need to die */
4343 ereport(ERROR,
4345 errmsg("could not serialize access due to read/write dependencies among transactions"),
4346 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict in checking."),
4347 errhint("The transaction might succeed if retried.")));
4348
4349 /*
4350 * We're doing a write which might cause rw-conflicts now or later.
4351 * Memorize that fact.
4352 */
4353 MyXactDidWrite = true;
4354
4355 /*
4356 * It is important that we check for locks from the finest granularity to
4357 * the coarsest granularity, so that granularity promotion doesn't cause
4358 * us to miss a lock. The new (coarser) lock will be acquired before the
4359 * old (finer) locks are released.
4360 *
4361 * It is not possible to take and hold a lock across the checks for all
4362 * granularities because each target could be in a separate partition.
4363 */
4364 if (tid != NULL)
4365 {
4367 relation->rd_locator.dbOid,
4368 relation->rd_id,
4372 }
4373
4374 if (blkno != InvalidBlockNumber)
4375 {
4377 relation->rd_locator.dbOid,
4378 relation->rd_id,
4379 blkno);
4381 }
4382
4384 relation->rd_locator.dbOid,
4385 relation->rd_id);
4387}
#define InvalidBlockNumber
Definition block.h:33
int errdetail_internal(const char *fmt,...)
Definition elog.c:1243
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#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
#define ERRCODE_T_R_SERIALIZATION_FAILURE
Definition pgbench.c:77
static bool MyXactDidWrite
Definition predicate.c:422
static bool SerializationNeededForWrite(Relation relation)
Definition predicate.c:560
static void CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:4164
#define SxactIsDoomed(sxact)
Definition predicate.c:280
#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 4021 of file predicate.c.

4022{
4026
4027 if (!SerializationNeededForRead(relation, snapshot))
4028 return;
4029
4030 /* Check if someone else has already decided that we need to die */
4032 {
4033 ereport(ERROR,
4035 errmsg("could not serialize access due to read/write dependencies among transactions"),
4036 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict out checking."),
4037 errhint("The transaction might succeed if retried.")));
4038 }
4040
4042 return;
4043
4044 /*
4045 * Find sxact or summarized info for the top level xid.
4046 */
4047 sxidtag.xid = xid;
4049 sxid = (SERIALIZABLEXID *)
4051 if (!sxid)
4052 {
4053 /*
4054 * Transaction not found in "normal" SSI structures. Check whether it
4055 * got pushed out to SLRU storage for "old committed" transactions.
4056 */
4058
4060 if (conflictCommitSeqNo != 0)
4061 {
4066 ereport(ERROR,
4068 errmsg("could not serialize access due to read/write dependencies among transactions"),
4069 errdetail_internal("Reason code: Canceled on conflict out to old pivot %u.", xid),
4070 errhint("The transaction might succeed if retried.")));
4071
4074 ereport(ERROR,
4076 errmsg("could not serialize access due to read/write dependencies among transactions"),
4077 errdetail_internal("Reason code: Canceled on identification as a pivot, with conflict out to old committed transaction %u.", xid),
4078 errhint("The transaction might succeed if retried.")));
4079
4081 }
4082
4083 /* It's not serializable or otherwise not important. */
4085 return;
4086 }
4087 sxact = sxid->myXact;
4088 Assert(TransactionIdEquals(sxact->topXid, xid));
4090 {
4091 /* Can't conflict with ourself or a transaction that will roll back. */
4093 return;
4094 }
4095
4096 /*
4097 * We have a conflict out to a transaction which has a conflict out to a
4098 * summarized transaction. That summarized transaction must have
4099 * committed first, and we can't tell when it committed in relation to our
4100 * snapshot acquisition, so something needs to be canceled.
4101 */
4103 {
4104 if (!SxactIsPrepared(sxact))
4105 {
4106 sxact->flags |= SXACT_FLAG_DOOMED;
4108 return;
4109 }
4110 else
4111 {
4113 ereport(ERROR,
4115 errmsg("could not serialize access due to read/write dependencies among transactions"),
4116 errdetail_internal("Reason code: Canceled on conflict out to old pivot."),
4117 errhint("The transaction might succeed if retried.")));
4118 }
4119 }
4120
4121 /*
4122 * If this is a read-only transaction and the writing transaction has
4123 * committed, and it doesn't have a rw-conflict to a transaction which
4124 * committed before it, no conflict.
4125 */
4130 || MySerializableXact->SeqNo.lastCommitBeforeSnapshot < sxact->SeqNo.earliestOutConflictCommit))
4131 {
4132 /* Read-only transaction will appear to run first. No conflict. */
4134 return;
4135 }
4136
4137 if (!XidIsConcurrent(xid))
4138 {
4139 /* This write was already in our snapshot; no conflict. */
4141 return;
4142 }
4143
4145 {
4146 /* We don't want duplicate conflict records in the list. */
4148 return;
4149 }
4150
4151 /*
4152 * Flag the conflict. But first, if this conflict creates a dangerous
4153 * structure, ereport an error.
4154 */
4157}
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:610
static bool SerializationNeededForRead(Relation relation, Snapshot snapshot)
Definition predicate.c:516
#define SxactIsCommitted(sxact)
Definition predicate.c:277
#define SxactIsReadOnly(sxact)
Definition predicate.c:281
#define SxactHasSummaryConflictIn(sxact)
Definition predicate.c:282
#define SxactHasConflictOut(sxact)
Definition predicate.c:289
#define SxactIsPrepared(sxact)
Definition predicate.c:278
static HTAB * SerializableXidHash
Definition predicate.c:396
static void FlagRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer)
Definition predicate.c:4499
static SerCommitSeqNo SerialGetMinConflictCommitSeqNo(TransactionId xid)
Definition predicate.c:949
static bool XidIsConcurrent(TransactionId xid)
Definition predicate.c:3970
#define SxactHasSummaryConflictOut(sxact)
Definition predicate.c:283
#define InvalidSerCommitSeqNo
#define SXACT_FLAG_DOOMED
uint64 SerCommitSeqNo
#define SXACT_FLAG_SUMMARY_CONFLICT_OUT
SerCommitSeqNo lastCommitBeforeSnapshot
union SERIALIZABLEXACT::@129 SeqNo
#define TransactionIdEquals(id1, id2)
Definition transam.h:43
#define TransactionIdIsValid(xid)
Definition transam.h:41
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:442

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 3989 of file predicate.c.

3990{
3991 if (!SerializationNeededForRead(relation, snapshot))
3992 return false;
3993
3994 /* Check if someone else has already decided that we need to die */
3996 {
3997 ereport(ERROR,
3999 errmsg("could not serialize access due to read/write dependencies among transactions"),
4000 errdetail_internal("Reason code: Canceled on identification as a pivot, during conflict out checking."),
4001 errhint("The transaction might succeed if retried.")));
4002 }
4003
4004 return true;
4005}

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 1041 of file predicate.c.

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

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 4417 of file predicate.c.

4418{
4420 PREDICATELOCKTARGET *target;
4421 Oid dbId;
4422 Oid heapId;
4423 int i;
4424
4425 /*
4426 * Bail out quickly if there are no serializable transactions running.
4427 * It's safe to check this without taking locks because the caller is
4428 * holding an ACCESS EXCLUSIVE lock on the relation. No new locks which
4429 * would matter here can be acquired while that is held.
4430 */
4432 return;
4433
4434 if (!SerializationNeededForWrite(relation))
4435 return;
4436
4437 /*
4438 * We're doing a write which might cause rw-conflicts now or later.
4439 * Memorize that fact.
4440 */
4441 MyXactDidWrite = true;
4442
4443 Assert(relation->rd_index == NULL); /* not an index relation */
4444
4445 dbId = relation->rd_locator.dbOid;
4446 heapId = relation->rd_id;
4447
4449 for (i = 0; i < NUM_PREDICATELOCK_PARTITIONS; i++)
4452
4453 /* Scan through target list */
4455
4456 while ((target = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat)))
4457 {
4458 dlist_mutable_iter iter;
4459
4460 /*
4461 * Check whether this is a target which needs attention.
4462 */
4464 continue; /* wrong relation id */
4465 if (GET_PREDICATELOCKTARGETTAG_DB(target->tag) != dbId)
4466 continue; /* wrong database id */
4467
4468 /*
4469 * Loop through locks for this target and flag conflicts.
4470 */
4471 dlist_foreach_modify(iter, &target->predicateLocks)
4472 {
4474 dlist_container(PREDICATELOCK, targetLink, iter.cur);
4475
4476 if (predlock->tag.myXact != MySerializableXact
4478 {
4480 }
4481 }
4482 }
4483
4484 /* Release locks in reverse order */
4486 for (i = NUM_PREDICATELOCK_PARTITIONS - 1; i >= 0; i--)
4489}
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:384
#define PredicateLockHashPartitionLockByIndex(i)
Definition predicate.c:261
static HTAB * PredicateLockTargetHash
Definition predicate.c:397
#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 1680 of file predicate.c.

1681{
1683
1684 /*
1685 * Can't use serializable mode while recovery is still active, as it is,
1686 * for example, on a hot standby. We could get here despite the check in
1687 * check_transaction_isolation() if default_transaction_isolation is set
1688 * to serializable, so phrase the hint accordingly.
1689 */
1690 if (RecoveryInProgress())
1691 ereport(ERROR,
1693 errmsg("cannot use serializable mode in a hot standby"),
1694 errdetail("\"default_transaction_isolation\" is set to \"serializable\"."),
1695 errhint("You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default.")));
1696
1697 /*
1698 * A special optimization is available for SERIALIZABLE READ ONLY
1699 * DEFERRABLE transactions -- we can wait for a suitable snapshot and
1700 * thereby avoid all SSI overhead once it's running.
1701 */
1703 return GetSafeSnapshot(snapshot);
1704
1706 NULL, InvalidPid);
1707}
int errdetail(const char *fmt,...)
Definition elog.c:1216
#define InvalidPid
Definition miscadmin.h:32
static Snapshot GetSafeSnapshot(Snapshot origSnapshot)
Definition predicate.c:1556
static Snapshot GetSerializableTransactionSnapshotInt(Snapshot snapshot, VirtualTransactionId *sourcevxid, int sourcepid)
Definition predicate.c:1762
bool XactDeferrable
Definition xact.c:86
bool XactReadOnly
Definition xact.c:83
#define IsolationIsSerializable()
Definition xact.h:53
bool RecoveryInProgress(void)
Definition xlog.c:6460

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 2006 of file predicate.c.

2007{
2011 PREDICATELOCKTARGET *target;
2012
2014 relation->rd_locator.dbOid,
2015 relation->rd_id,
2016 blkno);
2017
2021 target = (PREDICATELOCKTARGET *)
2024 HASH_FIND, NULL);
2026
2027 return (target != NULL);
2028}
uint32_t uint32
Definition c.h:546
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:303
#define PredicateLockHashPartitionLock(hashcode)
Definition predicate.c:258

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 4701 of file predicate.c.

4702{
4704
4706 return;
4707
4709
4711
4712 /*
4713 * Check if someone else has already decided that we need to die. Since
4714 * we set our own DOOMED flag when partially releasing, ignore in that
4715 * case.
4716 */
4719 {
4721 ereport(ERROR,
4723 errmsg("could not serialize access due to read/write dependencies among transactions"),
4724 errdetail_internal("Reason code: Canceled on identification as a pivot, during commit attempt."),
4725 errhint("The transaction might succeed if retried.")));
4726 }
4727
4729 {
4732
4733 if (!SxactIsCommitted(nearConflict->sxactOut)
4734 && !SxactIsDoomed(nearConflict->sxactOut))
4735 {
4737
4738 dlist_foreach(far_iter, &nearConflict->sxactOut->inConflicts)
4739 {
4742
4743 if (farConflict->sxactOut == MySerializableXact
4744 || (!SxactIsCommitted(farConflict->sxactOut)
4745 && !SxactIsReadOnly(farConflict->sxactOut)
4746 && !SxactIsDoomed(farConflict->sxactOut)))
4747 {
4748 /*
4749 * Normally, we kill the pivot transaction to make sure we
4750 * make progress if the failing transaction is retried.
4751 * However, we can't kill it if it's already prepared, so
4752 * in that case we commit suicide instead.
4753 */
4754 if (SxactIsPrepared(nearConflict->sxactOut))
4755 {
4757 ereport(ERROR,
4759 errmsg("could not serialize access due to read/write dependencies among transactions"),
4760 errdetail_internal("Reason code: Canceled on commit attempt with conflict in from prepared pivot."),
4761 errhint("The transaction might succeed if retried.")));
4762 }
4763 nearConflict->sxactOut->flags |= SXACT_FLAG_DOOMED;
4764 break;
4765 }
4766 }
4767 }
4768 }
4769
4772
4774}
#define SxactIsPartiallyReleased(sxact)
Definition predicate.c:293
#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 4907 of file predicate.c.

4909{
4912
4914
4915 record = (TwoPhasePredicateRecord *) recdata;
4916
4918 (record->type == TWOPHASEPREDICATERECORD_LOCK));
4919
4920 if (record->type == TWOPHASEPREDICATERECORD_XACT)
4921 {
4922 /* Per-transaction record. Set up a SERIALIZABLEXACT. */
4923 TwoPhasePredicateXactRecord *xactRecord;
4927 bool found;
4928
4929 xactRecord = (TwoPhasePredicateXactRecord *) &record->data.xactRecord;
4930
4933 if (!sxact)
4934 ereport(ERROR,
4936 errmsg("out of shared memory")));
4937
4938 /* vxid for a prepared xact is INVALID_PROC_NUMBER/xid; no pid */
4939 sxact->vxid.procNumber = INVALID_PROC_NUMBER;
4940 sxact->vxid.localTransactionId = (LocalTransactionId) xid;
4941 sxact->pid = 0;
4942 sxact->pgprocno = INVALID_PROC_NUMBER;
4943
4944 /* a prepared xact hasn't committed yet */
4945 sxact->prepareSeqNo = RecoverySerCommitSeqNo;
4946 sxact->commitSeqNo = InvalidSerCommitSeqNo;
4947 sxact->finishedBefore = InvalidTransactionId;
4948
4949 sxact->SeqNo.lastCommitBeforeSnapshot = RecoverySerCommitSeqNo;
4950
4951 /*
4952 * Don't need to track this; no transactions running at the time the
4953 * recovered xact started are still active, except possibly other
4954 * prepared xacts and we don't care whether those are RO_SAFE or not.
4955 */
4956 dlist_init(&(sxact->possibleUnsafeConflicts));
4957
4958 dlist_init(&(sxact->predicateLocks));
4959 dlist_node_init(&sxact->finishedLink);
4960
4961 sxact->topXid = xid;
4962 sxact->xmin = xactRecord->xmin;
4963 sxact->flags = xactRecord->flags;
4965 if (!SxactIsReadOnly(sxact))
4966 {
4970 }
4971
4972 /*
4973 * We don't know whether the transaction had any conflicts or not, so
4974 * we'll conservatively assume that it had both a conflict in and a
4975 * conflict out, and represent that with the summary conflict flags.
4976 */
4977 dlist_init(&(sxact->outConflicts));
4978 dlist_init(&(sxact->inConflicts));
4981
4982 /* Register the transaction's xid */
4983 sxidtag.xid = xid;
4985 &sxidtag,
4986 HASH_ENTER, &found);
4987 Assert(sxid != NULL);
4988 Assert(!found);
4989 sxid->myXact = sxact;
4990
4991 /*
4992 * Update global xmin. Note that this is a special case compared to
4993 * registering a normal transaction, because the global xmin might go
4994 * backwards. That's OK, because until recovery is over we're not
4995 * going to complete any transactions or create any non-prepared
4996 * transactions, so there's no danger of throwing away.
4997 */
5000 {
5004 }
5006 {
5009 }
5010
5012 }
5013 else if (record->type == TWOPHASEPREDICATERECORD_LOCK)
5014 {
5015 /* Lock record. Recreate the PREDICATELOCK */
5016 TwoPhasePredicateLockRecord *lockRecord;
5021
5022 lockRecord = (TwoPhasePredicateLockRecord *) &record->data.lockRecord;
5023 targettaghash = PredicateLockTargetTagHashCode(&lockRecord->target);
5024
5026 sxidtag.xid = xid;
5027 sxid = (SERIALIZABLEXID *)
5030
5031 Assert(sxid != NULL);
5032 sxact = sxid->myXact;
5034
5035 CreatePredicateLock(&lockRecord->target, targettaghash, sxact);
5036 }
5037}
uint32 LocalTransactionId
Definition c.h:668
uint32 TransactionId
Definition c.h:666
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:2451
static SERIALIZABLEXACT * CreatePredXact(void)
Definition predicate.c:582
static void SerialSetActiveSerXmin(TransactionId xid)
Definition predicate.c:990
#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:116

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 2597 of file predicate.c.

2598{
2600
2601 if (!SerializationNeededForRead(relation, snapshot))
2602 return;
2603
2605 relation->rd_locator.dbOid,
2606 relation->rd_id,
2607 blkno);
2609}
static void PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:2515

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 3227 of file predicate.c.

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

References fb(), and PredicateLockPageSplit().

Referenced by _bt_mark_page_halfdead(), and ginDeletePage().

◆ PredicateLockPageSplit()

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

Definition at line 3142 of file predicate.c.

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

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 1145 of file predicate.c.

1146{
1147 HASHCTL info;
1150 bool found;
1151
1152#ifndef EXEC_BACKEND
1154#endif
1155
1156 /*
1157 * Compute size of predicate lock target hashtable. Note these
1158 * calculations must agree with PredicateLockShmemSize!
1159 */
1161
1162 /*
1163 * Allocate hash table for PREDICATELOCKTARGET structs. This stores
1164 * per-predicate-lock-target information.
1165 */
1166 info.keysize = sizeof(PREDICATELOCKTARGETTAG);
1167 info.entrysize = sizeof(PREDICATELOCKTARGET);
1169
1170 PredicateLockTargetHash = ShmemInitHash("PREDICATELOCKTARGET hash",
1173 &info,
1176
1177 /*
1178 * Reserve a dummy entry in the hash table; we use it to make sure there's
1179 * always one entry available when we need to split or combine a page,
1180 * because running out of space there could mean aborting a
1181 * non-serializable transaction.
1182 */
1183 if (!IsUnderPostmaster)
1184 {
1186 HASH_ENTER, &found);
1187 Assert(!found);
1188 }
1189
1190 /* Pre-calculate the hash and partition lock of the scratch entry */
1193
1194 /*
1195 * Allocate hash table for PREDICATELOCK structs. This stores per
1196 * xact-lock-of-a-target information.
1197 */
1198 info.keysize = sizeof(PREDICATELOCKTAG);
1199 info.entrysize = sizeof(PREDICATELOCK);
1200 info.hash = predicatelock_hash;
1202
1203 /* Assume an average of 2 xacts per target */
1204 max_table_size *= 2;
1205
1206 PredicateLockHash = ShmemInitHash("PREDICATELOCK hash",
1209 &info,
1212
1213 /*
1214 * Compute size for serializable transaction hashtable. Note these
1215 * calculations must agree with PredicateLockShmemSize!
1216 */
1218
1219 /*
1220 * Allocate a list to hold information on transactions participating in
1221 * predicate locking.
1222 *
1223 * Assume an average of 10 predicate locking transactions per backend.
1224 * This allows aggressive cleanup while detail is present before data must
1225 * be summarized for storage in SLRU and the "dummy" transaction.
1226 */
1227 max_table_size *= 10;
1228
1231 sizeof(SERIALIZABLEXACT))));
1232
1233 PredXact = ShmemInitStruct("PredXactList",
1235 &found);
1236 Assert(found == IsUnderPostmaster);
1237 if (!found)
1238 {
1239 int i;
1240
1241 /* clean everything, both the header and the element */
1243
1254 /* Add all elements to available list, clean. */
1255 for (i = 0; i < max_table_size; i++)
1256 {
1260 }
1277 }
1278 /* This never changes, so let's keep a local copy. */
1280
1281 /*
1282 * Allocate hash table for SERIALIZABLEXID structs. This stores per-xid
1283 * information for serializable transactions which have accessed data.
1284 */
1285 info.keysize = sizeof(SERIALIZABLEXIDTAG);
1286 info.entrysize = sizeof(SERIALIZABLEXID);
1287
1288 SerializableXidHash = ShmemInitHash("SERIALIZABLEXID hash",
1291 &info,
1294
1295 /*
1296 * Allocate space for tracking rw-conflicts in lists attached to the
1297 * transactions.
1298 *
1299 * Assume an average of 5 conflicts per transaction. Calculations suggest
1300 * that this will prevent resource exhaustion in even the most pessimal
1301 * loads up to max_connections = 200 with all 200 connections pounding the
1302 * database with serializable transactions. Beyond that, there may be
1303 * occasional transactions canceled when trying to flag conflicts. That's
1304 * probably OK.
1305 */
1306 max_table_size *= 5;
1307
1311
1312 RWConflictPool = ShmemInitStruct("RWConflictPool",
1314 &found);
1315 Assert(found == IsUnderPostmaster);
1316 if (!found)
1317 {
1318 int i;
1319
1320 /* clean everything, including the elements */
1322
1326 /* Add all elements to available list, clean. */
1327 for (i = 0; i < max_table_size; i++)
1328 {
1331 }
1332 }
1333
1334 /*
1335 * Create or attach to the header for the list of finished serializable
1336 * transactions.
1337 */
1339 ShmemInitStruct("FinishedSerializableTransactions",
1340 sizeof(dlist_head),
1341 &found);
1342 Assert(found == IsUnderPostmaster);
1343 if (!found)
1345
1346 /*
1347 * Initialize the SLRU storage for old committed serializable
1348 * transactions.
1349 */
1350 SerialInit();
1351}
size_t Size
Definition c.h:619
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:698
static HTAB * PredicateLockHash
Definition predicate.c:398
static LWLock * ScratchPartitionLock
Definition predicate.c:408
static uint32 ScratchTargetTagHash
Definition predicate.c:407
static uint32 predicatelock_hash(const void *key, Size keysize)
Definition predicate.c:1419
static SERIALIZABLEXACT * OldCommittedSxact
Definition predicate.c:362
static void SerialInit(void)
Definition predicate.c:806
static dlist_head * FinishedSerializableTransactions
Definition predicate.c:399
static const PREDICATELOCKTARGETTAG ScratchTargetTag
Definition predicate.c:406
#define NPREDICATELOCKTARGETENTS()
Definition predicate.c:264
static RWConflictPoolHeader RWConflictPool
Definition predicate.c:390
#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:482
Size mul_size(Size s1, Size s2)
Definition shmem.c:497
HTAB * ShmemInitHash(const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)
Definition shmem.c:323
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:378
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 1357 of file predicate.c.

1358{
1359 Size size = 0;
1360 long max_table_size;
1361
1362 /* predicate lock target hash table */
1365 sizeof(PREDICATELOCKTARGET)));
1366
1367 /* predicate lock hash table */
1368 max_table_size *= 2;
1370 sizeof(PREDICATELOCK)));
1371
1372 /*
1373 * Since NPREDICATELOCKTARGETENTS is only an estimate, add 10% safety
1374 * margin.
1375 */
1376 size = add_size(size, size / 10);
1377
1378 /* transaction list */
1380 max_table_size *= 10;
1381 size = add_size(size, PredXactListDataSize);
1382 size = add_size(size, mul_size((Size) max_table_size,
1383 sizeof(SERIALIZABLEXACT)));
1384
1385 /* transaction xid table */
1387 sizeof(SERIALIZABLEXID)));
1388
1389 /* rw-conflict pool */
1390 max_table_size *= 5;
1392 size = add_size(size, mul_size((Size) max_table_size,
1394
1395 /* Head for list of finished serializable transactions. */
1396 size = add_size(size, sizeof(dlist_head));
1397
1398 /* Shared memory structures for SLRU tracking of old committed xids. */
1399 size = add_size(size, sizeof(SerialControlData));
1401
1402 return size;
1403}
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:198

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 2619 of file predicate.c.

2621{
2623
2624 if (!SerializationNeededForRead(relation, snapshot))
2625 return;
2626
2627 /*
2628 * Return if this xact wrote it.
2629 */
2630 if (relation->rd_index == NULL)
2631 {
2632 /* If we wrote it; we already have a write lock. */
2634 return;
2635 }
2636
2637 /*
2638 * Do quick-but-not-definitive test for a relation lock first. This will
2639 * never cause a return when the relation is *not* locked, but will
2640 * occasionally let the check continue when there really *is* a relation
2641 * level lock.
2642 */
2644 relation->rd_locator.dbOid,
2645 relation->rd_id);
2646 if (PredicateLockExists(&tag))
2647 return;
2648
2650 relation->rd_locator.dbOid,
2651 relation->rd_id,
2655}
static bool PredicateLockExists(const PREDICATELOCKTARGETTAG *targettag)
Definition predicate.c:2043
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition xact.c:942

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 4880 of file predicate.c.

4881{
4884
4886
4888 sxid = (SERIALIZABLEXID *)
4891
4892 /* xid will not be found if it wasn't a serializable transaction */
4893 if (sxid == NULL)
4894 return;
4895
4896 /* Release its locks */
4897 MySerializableXact = sxid->myXact;
4898 MyXactDidWrite = true; /* conservatively assume that we wrote
4899 * something */
4901}
void ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe)
Definition predicate.c:3310

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 1957 of file predicate.c.

1958{
1961 bool found;
1962
1963 /*
1964 * If we're not tracking predicate lock data for this transaction, we
1965 * should ignore the request and return quickly.
1966 */
1968 return;
1969
1970 /* We should have a valid XID and be at the top level. */
1972
1974
1975 /* This should only be done once per transaction. */
1977
1979
1980 sxidtag.xid = xid;
1982 &sxidtag,
1983 HASH_ENTER, &found);
1984 Assert(!found);
1985
1986 /* Initialize the structure. */
1987 sxid->myXact = MySerializableXact;
1989}

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 3310 of file predicate.c.

3311{
3312 bool partiallyReleasing = false;
3313 bool needToClear;
3315 dlist_mutable_iter iter;
3316
3317 /*
3318 * We can't trust XactReadOnly here, because a transaction which started
3319 * as READ WRITE can show as READ ONLY later, e.g., within
3320 * subtransactions. We want to flag a transaction as READ ONLY if it
3321 * commits without writing so that de facto READ ONLY transactions get the
3322 * benefit of some RO optimizations, so we will use this local variable to
3323 * get some cleanup logic right which is based on whether the transaction
3324 * was declared READ ONLY at the top level.
3325 */
3327
3328 /* We can't be both committing and releasing early due to RO_SAFE. */
3330
3331 /* Are we at the end of a transaction, that is, a commit or abort? */
3332 if (!isReadOnlySafe)
3333 {
3334 /*
3335 * Parallel workers mustn't release predicate locks at the end of
3336 * their transaction. The leader will do that at the end of its
3337 * transaction.
3338 */
3339 if (IsParallelWorker())
3340 {
3342 return;
3343 }
3344
3345 /*
3346 * By the time the leader in a parallel query reaches end of
3347 * transaction, it has waited for all workers to exit.
3348 */
3350
3351 /*
3352 * If the leader in a parallel query earlier stashed a partially
3353 * released SERIALIZABLEXACT for final clean-up at end of transaction
3354 * (because workers might still have been accessing it), then it's
3355 * time to restore it.
3356 */
3358 {
3363 }
3364 }
3365
3367 {
3369 return;
3370 }
3371
3373
3374 /*
3375 * If the transaction is committing, but it has been partially released
3376 * already, then treat this as a roll back. It was marked as rolled back.
3377 */
3379 isCommit = false;
3380
3381 /*
3382 * If we're called in the middle of a transaction because we discovered
3383 * that the SXACT_FLAG_RO_SAFE flag was set, then we'll partially release
3384 * it (that is, release the predicate locks and conflicts, but not the
3385 * SERIALIZABLEXACT itself) if we're the first backend to have noticed.
3386 */
3388 {
3389 /*
3390 * The leader needs to stash a pointer to it, so that it can
3391 * completely release it at end-of-transaction.
3392 */
3393 if (!IsParallelWorker())
3395
3396 /*
3397 * The first backend to reach this condition will partially release
3398 * the SERIALIZABLEXACT. All others will just clear their
3399 * backend-local state so that they stop doing SSI checks for the rest
3400 * of the transaction.
3401 */
3403 {
3406 return;
3407 }
3408 else
3409 {
3411 partiallyReleasing = true;
3412 /* ... and proceed to perform the partial release below. */
3413 }
3414 }
3420
3421 /* may not be serializable during COMMIT/ROLLBACK PREPARED */
3423
3424 /* We'd better not already be on the cleanup list. */
3426
3428
3429 /*
3430 * We don't hold XidGenLock lock here, assuming that TransactionId is
3431 * atomic!
3432 *
3433 * If this value is changing, we don't care that much whether we get the
3434 * old or new value -- it is just used to determine how far
3435 * SxactGlobalXmin must advance before this transaction can be fully
3436 * cleaned up. The worst that could happen is we wait for one more
3437 * transaction to complete before freeing some RAM; correctness of visible
3438 * behavior is not affected.
3439 */
3441
3442 /*
3443 * If it's not a commit it's either a rollback or a read-only transaction
3444 * flagged SXACT_FLAG_RO_SAFE, and we can clear our locks immediately.
3445 */
3446 if (isCommit)
3447 {
3450 /* Recognize implicit read-only transaction (commit without write). */
3451 if (!MyXactDidWrite)
3453 }
3454 else
3455 {
3456 /*
3457 * The DOOMED flag indicates that we intend to roll back this
3458 * transaction and so it should not cause serialization failures for
3459 * other transactions that conflict with it. Note that this flag might
3460 * already be set, if another backend marked this transaction for
3461 * abort.
3462 *
3463 * The ROLLED_BACK flag further indicates that ReleasePredicateLocks
3464 * has been called, and so the SerializableXact is eligible for
3465 * cleanup. This means it should not be considered when calculating
3466 * SxactGlobalXmin.
3467 */
3470
3471 /*
3472 * If the transaction was previously prepared, but is now failing due
3473 * to a ROLLBACK PREPARED or (hopefully very rare) error after the
3474 * prepare, clear the prepared flag. This simplifies conflict
3475 * checking.
3476 */
3478 }
3479
3481 {
3483 if (--(PredXact->WritableSxactCount) == 0)
3484 {
3485 /*
3486 * Release predicate locks and rw-conflicts in for all committed
3487 * transactions. There are no longer any transactions which might
3488 * conflict with the locks and no chance for new transactions to
3489 * overlap. Similarly, existing conflicts in can't cause pivots,
3490 * and any conflicts in which could have completed a dangerous
3491 * structure would already have caused a rollback, so any
3492 * remaining ones must be benign.
3493 */
3495 }
3496 }
3497 else
3498 {
3499 /*
3500 * Read-only transactions: clear the list of transactions that might
3501 * make us unsafe. Note that we use 'inLink' for the iteration as
3502 * opposed to 'outLink' for the r/w xacts.
3503 */
3505 {
3507 dlist_container(RWConflictData, inLink, iter.cur);
3508
3511
3513 }
3514 }
3515
3516 /* Check for conflict out to old committed transactions. */
3517 if (isCommit
3520 {
3521 /*
3522 * we don't know which old committed transaction we conflicted with,
3523 * so be conservative and use FirstNormalSerCommitSeqNo here
3524 */
3528 }
3529
3530 /*
3531 * Release all outConflicts to committed transactions. If we're rolling
3532 * back clear them all. Set SXACT_FLAG_CONFLICT_OUT if any point to
3533 * previously committed transactions.
3534 */
3536 {
3538 dlist_container(RWConflictData, outLink, iter.cur);
3539
3540 if (isCommit
3542 && SxactIsCommitted(conflict->sxactIn))
3543 {
3545 || conflict->sxactIn->prepareSeqNo < MySerializableXact->SeqNo.earliestOutConflictCommit)
3548 }
3549
3550 if (!isCommit
3551 || SxactIsCommitted(conflict->sxactIn)
3552 || (conflict->sxactIn->SeqNo.lastCommitBeforeSnapshot >= PredXact->LastSxactCommitSeqNo))
3554 }
3555
3556 /*
3557 * Release all inConflicts from committed and read-only transactions. If
3558 * we're rolling back, clear them all.
3559 */
3561 {
3563 dlist_container(RWConflictData, inLink, iter.cur);
3564
3565 if (!isCommit
3566 || SxactIsCommitted(conflict->sxactOut)
3567 || SxactIsReadOnly(conflict->sxactOut))
3569 }
3570
3572 {
3573 /*
3574 * Remove ourselves from the list of possible conflicts for concurrent
3575 * READ ONLY transactions, flagging them as unsafe if we have a
3576 * conflict out. If any are waiting DEFERRABLE transactions, wake them
3577 * up if they are known safe or known unsafe.
3578 */
3580 {
3582 dlist_container(RWConflictData, outLink, iter.cur);
3583
3584 roXact = possibleUnsafeConflict->sxactIn;
3587
3588 /* Mark conflicted if necessary. */
3589 if (isCommit
3593 <= roXact->SeqNo.lastCommitBeforeSnapshot))
3594 {
3595 /*
3596 * This releases possibleUnsafeConflict (as well as all other
3597 * possible conflicts for roXact)
3598 */
3600 }
3601 else
3602 {
3604
3605 /*
3606 * If we were the last possible conflict, flag it safe. The
3607 * transaction can now safely release its predicate locks (but
3608 * that transaction's backend has to do that itself).
3609 */
3610 if (dlist_is_empty(&roXact->possibleUnsafeConflicts))
3611 roXact->flags |= SXACT_FLAG_RO_SAFE;
3612 }
3613
3614 /*
3615 * Wake up the process for a waiting DEFERRABLE transaction if we
3616 * now know it's either safe or conflicted.
3617 */
3620 ProcSendSignal(roXact->pgprocno);
3621 }
3622 }
3623
3624 /*
3625 * Check whether it's time to clean up old transactions. This can only be
3626 * done when the last serializable transaction with the oldest xmin among
3627 * serializable transactions completes. We then find the "new oldest"
3628 * xmin and purge any transactions which finished before this transaction
3629 * was launched.
3630 *
3631 * For parallel queries in read-only transactions, it might run twice. We
3632 * only release the reference on the first call.
3633 */
3634 needToClear = false;
3635 if ((partiallyReleasing ||
3639 {
3641 if (--(PredXact->SxactGlobalXminCount) == 0)
3642 {
3644 needToClear = true;
3645 }
3646 }
3647
3649
3651
3652 /* Add this to the list of transactions to check for later cleanup. */
3653 if (isCommit)
3656
3657 /*
3658 * If we're releasing a RO_SAFE transaction in parallel mode, we'll only
3659 * partially release it. That's necessary because other backends may have
3660 * a reference to it. The leader will release the SERIALIZABLEXACT itself
3661 * at the end of the transaction after workers have stopped running.
3662 */
3663 if (!isCommit)
3666 false);
3667
3669
3670 if (needToClear)
3672
3674}
static void SetNewSxactGlobalXmin(void)
Definition predicate.c:3249
#define SxactIsROUnsafe(sxact)
Definition predicate.c:292
#define SxactIsDeferrableWaiting(sxact)
Definition predicate.c:290
static void ReleasePredicateLocksLocal(void)
Definition predicate.c:3677
static void ClearOldPredicateLocks(void)
Definition predicate.c:3695
static void FlagSxactUnsafe(SERIALIZABLEXACT *sxact)
Definition predicate.c:699
#define SxactIsOnFinishedList(sxact)
Definition predicate.c:267
#define SxactIsROSafe(sxact)
Definition predicate.c:291
static void ReleaseRWConflict(RWConflict conflict)
Definition predicate.c:691
static void ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, bool summarize)
Definition predicate.c:3833
#define SxactIsRolledBack(sxact)
Definition predicate.c:279
static SERIALIZABLEXACT * SavedSerializableXact
Definition predicate.c:431
#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:1992
SerCommitSeqNo earliestOutConflictCommit
FullTransactionId nextXid
Definition transam.h:220
TransamVariablesData * TransamVariables
Definition varsup.c:34
bool IsInParallelMode(void)
Definition xact.c:1090

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 1720 of file predicate.c.

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

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

Referenced by SetTransactionSnapshot().

◆ ShareSerializableXact()

SerializableXactHandle ShareSerializableXact ( void  )
extern

Definition at line 5045 of file predicate.c.

5046{
5047 return MySerializableXact;
5048}

References MySerializableXact.

Referenced by InitializeParallelDSM().

◆ TransferPredicateLocksToHeapRelation()

void TransferPredicateLocksToHeapRelation ( Relation  relation)
extern

Definition at line 3121 of file predicate.c.

3122{
3123 DropAllPredicateLocksFromTable(relation, true);
3124}
static void DropAllPredicateLocksFromTable(Relation relation, bool transfer)
Definition predicate.c:2935

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 373 of file predicate.c.

Referenced by MaxPredicateChildLocks().

◆ max_predicate_locks_per_relation

PGDLLIMPORT int max_predicate_locks_per_relation
extern

Definition at line 372 of file predicate.c.

Referenced by MaxPredicateChildLocks().

◆ max_predicate_locks_per_xact

PGDLLIMPORT int max_predicate_locks_per_xact
extern

Definition at line 371 of file predicate.c.

Referenced by CreateLocalPredicateLockHash(), and MaxPredicateChildLocks().