233#define TargetTagIsCoveredBy(covered_target, covering_target) \
234 ((GET_PREDICATELOCKTARGETTAG_RELATION(covered_target) == \
235 GET_PREDICATELOCKTARGETTAG_RELATION(covering_target)) \
236 && (GET_PREDICATELOCKTARGETTAG_OFFSET(covering_target) == \
237 InvalidOffsetNumber) \
238 && (((GET_PREDICATELOCKTARGETTAG_OFFSET(covered_target) != \
239 InvalidOffsetNumber) \
240 && (GET_PREDICATELOCKTARGETTAG_PAGE(covering_target) == \
241 GET_PREDICATELOCKTARGETTAG_PAGE(covered_target))) \
242 || ((GET_PREDICATELOCKTARGETTAG_PAGE(covering_target) == \
243 InvalidBlockNumber) \
244 && (GET_PREDICATELOCKTARGETTAG_PAGE(covered_target) \
245 != InvalidBlockNumber))) \
246 && (GET_PREDICATELOCKTARGETTAG_DB(covered_target) == \
247 GET_PREDICATELOCKTARGETTAG_DB(covering_target)))
256#define PredicateLockHashPartition(hashcode) \
257 ((hashcode) % NUM_PREDICATELOCK_PARTITIONS)
258#define PredicateLockHashPartitionLock(hashcode) \
259 (&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + \
260 PredicateLockHashPartition(hashcode)].lock)
261#define PredicateLockHashPartitionLockByIndex(i) \
262 (&MainLWLockArray[PREDICATELOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
264#define NPREDICATELOCKTARGETENTS() \
265 mul_size(max_predicate_locks_per_xact, add_size(MaxBackends, max_prepared_xacts))
267#define SxactIsOnFinishedList(sxact) (!dlist_node_is_detached(&(sxact)->finishedLink))
277#define SxactIsCommitted(sxact) (((sxact)->flags & SXACT_FLAG_COMMITTED) != 0)
278#define SxactIsPrepared(sxact) (((sxact)->flags & SXACT_FLAG_PREPARED) != 0)
279#define SxactIsRolledBack(sxact) (((sxact)->flags & SXACT_FLAG_ROLLED_BACK) != 0)
280#define SxactIsDoomed(sxact) (((sxact)->flags & SXACT_FLAG_DOOMED) != 0)
281#define SxactIsReadOnly(sxact) (((sxact)->flags & SXACT_FLAG_READ_ONLY) != 0)
282#define SxactHasSummaryConflictIn(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_IN) != 0)
283#define SxactHasSummaryConflictOut(sxact) (((sxact)->flags & SXACT_FLAG_SUMMARY_CONFLICT_OUT) != 0)
289#define SxactHasConflictOut(sxact) (((sxact)->flags & SXACT_FLAG_CONFLICT_OUT) != 0)
290#define SxactIsDeferrableWaiting(sxact) (((sxact)->flags & SXACT_FLAG_DEFERRABLE_WAITING) != 0)
291#define SxactIsROSafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_SAFE) != 0)
292#define SxactIsROUnsafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_UNSAFE) != 0)
293#define SxactIsPartiallyReleased(sxact) (((sxact)->flags & SXACT_FLAG_PARTIALLY_RELEASED) != 0)
303#define PredicateLockTargetTagHashCode(predicatelocktargettag) \
304 get_hash_value(PredicateLockTargetHash, predicatelocktargettag)
316#define PredicateLockHashCodeFromTargetHashCode(predicatelocktag, targethash) \
317 ((targethash) ^ ((uint32) PointerGetDatum((predicatelocktag)->myXact)) \
318 << LOG2_NUM_PREDICATELOCK_PARTITIONS)
326#define SerialSlruCtl (&SerialSlruCtlData)
328#define SERIAL_PAGESIZE BLCKSZ
329#define SERIAL_ENTRYSIZE sizeof(SerCommitSeqNo)
330#define SERIAL_ENTRIESPERPAGE (SERIAL_PAGESIZE / SERIAL_ENTRYSIZE)
335#define SERIAL_MAX_PAGE (MaxTransactionId / SERIAL_ENTRIESPERPAGE)
337#define SerialNextPage(page) (((page) >= SERIAL_MAX_PAGE) ? 0 : (page) + 1)
339#define SerialValue(slotno, xid) (*((SerCommitSeqNo *) \
340 (SerialSlruCtl->shared->page_buffer[slotno] + \
341 ((((uint32) (xid)) % SERIAL_ENTRIESPERPAGE) * SERIAL_ENTRYSIZE))))
343#define SerialPage(xid) (((uint32) (xid)) / SERIAL_ENTRIESPERPAGE)
634 if (conflict->
sxactIn == writer)
652 (
errcode(ERRCODE_OUT_OF_MEMORY),
653 errmsg(
"not enough elements in RWConflictPool to record a read/write conflict"),
654 errhint(
"You might need to run fewer transactions at a time or increase \"max_connections\".")));
671 Assert(roXact != activeXact);
677 (
errcode(ERRCODE_OUT_OF_MEMORY),
678 errmsg(
"not enough elements in RWConflictPool to record a potential read/write conflict"),
679 errhint(
"You might need to run fewer transactions at a time or increase \"max_connections\".")));
745#ifdef USE_ASSERT_CHECKING
747SerialPagePrecedesLogicallyUnitTests(
void)
750 offset = per_page / 2;
760 newestXact = newestPage * per_page + offset;
761 Assert(newestXact / per_page == newestPage);
762 oldestXact = newestXact + 1;
763 oldestXact -= 1U << 31;
764 oldestPage = oldestXact / per_page;
776 targetPage = oldestPage;
794 targetPage = newestPage;
818#ifdef USE_ASSERT_CHECKING
819 SerialPagePrecedesLogicallyUnitTests();
924 if (firstZeroPage == targetPage)
1043 int64 truncateCutoffPage;
1070 truncateCutoffPage = tailPage;
1148 long max_table_size;
1204 max_table_size *= 2;
1227 max_table_size *= 10;
1250 for (
i = 0;
i < max_table_size;
i++)
1301 max_table_size *= 5;
1317 for (
i = 0;
i < max_table_size;
i++)
1350 long max_table_size;
1358 max_table_size *= 2;
1370 max_table_size *= 10;
1380 max_table_size *= 5;
1456 data->nelements = els;
1595 errmsg_internal(
"deferrable snapshot was unsafe; trying a new one")));
1620 int num_written = 0;
1632 if (sxact->
pid == blocked_pid)
1634 blocking_sxact = sxact;
1650 if (num_written >= output_size)
1684 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1685 errmsg(
"cannot use serializable mode in a hot standby"),
1686 errdetail(
"\"default_transaction_isolation\" is set to \"serializable\"."),
1687 errhint(
"You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default.")));
1737 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1738 errmsg(
"a snapshot-importing transaction must not be READ ONLY DEFERRABLE")));
1774 elog(
ERROR,
"cannot establish serializable snapshot during a parallel operation");
1792#ifdef TEST_SUMMARIZE_SERIAL
1816 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1817 errmsg(
"could not import the requested snapshot"),
1818 errdetail(
"The source process with PID %d is not running anymore.",
2015 &targettag, targettaghash,
2019 return (target != NULL);
2106 targettag = *newtargettag;
2111 targettag = parenttag;
2188 Assert(rmtarget == target);
2223 oldlocktag = predlock->
tag;
2226 oldtargettag = oldtarget->
tag;
2247 Assert(rmpredlock == predlock);
2327 targettag = *reqtag;
2332 targettag = nexttag;
2339 parentlock->
held =
false;
2354 promotiontag = targettag;
2386 parenttag = *targettag;
2394 parenttag = nexttag;
2398 &parenttag, targettaghash,
2406 if (parentlock == NULL)
2426 &parenttag, targettaghash,
2428 Assert(rmlock == parentlock);
2463 targettag, targettaghash,
2467 (
errcode(ERRCODE_OUT_OF_MEMORY),
2468 errmsg(
"out of shared memory"),
2469 errhint(
"You might need to increase \"%s\".",
"max_pred_locks_per_transaction")));
2482 (
errcode(ERRCODE_OUT_OF_MEMORY),
2483 errmsg(
"out of shared memory"),
2484 errhint(
"You might need to increase \"%s\".",
"max_pred_locks_per_transaction")));
2526 targettag, targettaghash,
2528 locallock->
held =
true;
2725 LWLock *oldpartitionLock;
2728 LWLock *newpartitionLock;
2730 bool outOfShmem =
false;
2754 if (oldpartitionLock < newpartitionLock)
2760 else if (oldpartitionLock > newpartitionLock)
2802 newpredlocktag.
myTarget = newtarget;
2878 if (oldpartitionLock < newpartitionLock)
2883 else if (oldpartitionLock > newpartitionLock)
2938 uint32 heaptargettaghash;
2953 relId = relation->
rd_id;
2962 heapId = relation->
rd_index->indrelid;
2965 Assert(transfer || !isIndex);
2969 heaptargettaghash = 0;
2999 if (transfer && !isIndex
3014 if (transfer && heaptarget == NULL)
3062 newpredlocktag.
myTarget = heaptarget;
3063 newpredlocktag.
myXact = oldXact;
3157 Assert(oldblkno != newblkno);
3304 bool partiallyReleasing =
false;
3318 bool topLevelIsDeclaredReadOnly;
3321 Assert(!(isCommit && isReadOnlySafe));
3324 if (!isReadOnlySafe)
3403 partiallyReleasing =
true;
3472 if (!topLevelIsDeclaredReadOnly)
3563 if (!topLevelIsDeclaredReadOnly)
3576 roXact = possibleUnsafeConflict->
sxactIn;
3626 needToClear =
false;
3627 if ((partiallyReleasing ||
3760 bool canDoPartialCleanup;
3772 if (canDoPartialCleanup)
3780 tag = predlock->
tag;
3782 targettag = target->
tag;
3853 tag = predlock->
tag;
3855 targettag = target->
tag;
3879 (
errcode(ERRCODE_OUT_OF_MEMORY),
3880 errmsg(
"out of shared memory"),
3881 errhint(
"You might need to increase \"%s\".",
"max_pred_locks_per_transaction")));
3991 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
3992 errdetail_internal(
"Reason code: Canceled on identification as a pivot, during conflict out checking."),
3993 errhint(
"The transaction might succeed if retried.")));
4027 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4028 errdetail_internal(
"Reason code: Canceled on identification as a pivot, during conflict out checking."),
4029 errhint(
"The transaction might succeed if retried.")));
4052 if (conflictCommitSeqNo != 0)
4056 || conflictCommitSeqNo
4060 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4062 errhint(
"The transaction might succeed if retried.")));
4068 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4069 errdetail_internal(
"Reason code: Canceled on identification as a pivot, with conflict out to old committed transaction %u.", xid),
4070 errhint(
"The transaction might succeed if retried.")));
4107 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4109 errhint(
"The transaction might succeed if retried.")));
4175 targettag, targettaghash,
4211 mypredlock = predlock;
4212 mypredlocktag = predlock->
tag;
4252 if (mypredlock != NULL)
4269 (&mypredlocktag, targettaghash);
4275 if (rmpredlock != NULL)
4277 Assert(rmpredlock == mypredlock);
4287 Assert(rmpredlock == mypredlock);
4298 if (rmpredlock != NULL)
4306 targettag, targettaghash,
4337 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4338 errdetail_internal(
"Reason code: Canceled on identification as a pivot, during conflict in checking."),
4339 errhint(
"The transaction might succeed if retried.")));
4438 heapId = relation->
rd_id;
4493 Assert(reader != writer);
4656 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4657 errdetail_internal(
"Reason code: Canceled on identification as a pivot, during write."),
4658 errhint(
"The transaction might succeed if retried.")));
4668 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4670 errhint(
"The transaction might succeed if retried.")));
4715 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4716 errdetail_internal(
"Reason code: Canceled on identification as a pivot, during commit attempt."),
4717 errhint(
"The transaction might succeed if retried.")));
4751 errmsg(
"could not serialize access due to read/write dependencies among transactions"),
4752 errdetail_internal(
"Reason code: Canceled on commit attempt with conflict in from prepared pivot."),
4753 errhint(
"The transaction might succeed if retried.")));
4808 &record,
sizeof(record));
4835 &record,
sizeof(record));
4926 (
errcode(ERRCODE_OUT_OF_MEMORY),
4927 errmsg(
"out of shared memory")));
bool ParallelContextActive(void)
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
#define unconstify(underlying_type, expr)
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
uint32 LocalTransactionId
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
void hash_destroy(HTAB *hashp)
void * hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, uint32 hashvalue, HASHACTION action, bool *foundPtr)
void * hash_seq_search(HASH_SEQ_STATUS *status)
long hash_get_num_entries(HTAB *hashp)
Size hash_estimate_size(long num_entries, Size entrysize)
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
static dlist_node * dlist_pop_head_node(dlist_head *head)
#define dlist_foreach(iter, lhead)
static void dlist_init(dlist_head *head)
#define dlist_head_element(type, membername, lhead)
static void dlist_delete_thoroughly(dlist_node *node)
static void dlist_delete(dlist_node *node)
#define dlist_foreach_modify(iter, lhead)
static bool dlist_is_empty(const dlist_head *head)
static void dlist_push_tail(dlist_head *head, dlist_node *node)
static void dlist_node_init(dlist_node *node)
#define dlist_container(type, membername, ptr)
#define IsParallelWorker()
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
#define GET_VXID_FROM_PGPROC(vxid_dst, proc)
#define SetInvalidVirtualTransactionId(vxid)
bool LWLockHeldByMe(LWLock *lock)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void LWLockInitialize(LWLock *lock, int tranche_id)
@ LWTRANCHE_SERIAL_BUFFER
@ LWTRANCHE_PER_XACT_PREDICATE_LIST
#define NUM_PREDICATELOCK_PARTITIONS
static bool pg_lfind32(uint32 key, const uint32 *base, uint32 nelem)
static rewind_source * source
#define ERRCODE_T_R_SERIALIZATION_FAILURE
PredicateLockData * GetPredicateLockStatusData(void)
void CheckPointPredicate(void)
void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno)
static void DecrementParentLocks(const PREDICATELOCKTARGETTAG *targettag)
static HTAB * PredicateLockHash
static void SetPossibleUnsafeConflict(SERIALIZABLEXACT *roXact, SERIALIZABLEXACT *activeXact)
#define PredicateLockTargetTagHashCode(predicatelocktargettag)
static void SetNewSxactGlobalXmin(void)
void PredicateLockTwoPhaseFinish(TransactionId xid, bool isCommit)
static void ReleasePredXact(SERIALIZABLEXACT *sxact)
void SetSerializableTransactionSnapshot(Snapshot snapshot, VirtualTransactionId *sourcevxid, int sourcepid)
static bool RWConflictExists(const SERIALIZABLEXACT *reader, const SERIALIZABLEXACT *writer)
static bool PredicateLockingNeededForRelation(Relation relation)
static bool SerializationNeededForRead(Relation relation, Snapshot snapshot)
static Snapshot GetSafeSnapshot(Snapshot origSnapshot)
#define SxactIsCommitted(sxact)
static SerialControl serialControl
void PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)