mirror of
https://github.com/postgres/postgres.git
synced 2025-12-01 12:18:01 +03:00
Support an optional asynchronous commit mode, in which we don't flush WAL
before reporting a transaction committed. Data consistency is still guaranteed (unlike setting fsync = off), but a crash may lose the effects of the last few transactions. Patch by Simon, some editorialization by Tom.
This commit is contained in:
@@ -23,7 +23,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.26 2007/06/12 17:16:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/init/flatfiles.c,v 1.27 2007/08/01 22:45:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -855,6 +855,14 @@ AtEOXact_UpdateFlatFiles(bool isCommit)
|
||||
* Signal the postmaster to reload its caches.
|
||||
*/
|
||||
SendPostmasterSignal(PMSIGNAL_PASSWORD_CHANGE);
|
||||
|
||||
/*
|
||||
* Force synchronous commit, to minimize the window between changing
|
||||
* the flat files on-disk and marking the transaction committed. It's
|
||||
* not great that there is any window at all, but definitely we don't
|
||||
* want to make it larger than necessary.
|
||||
*/
|
||||
ForceSyncCommit();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.407 2007/07/24 04:54:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.408 2007/08/01 22:45:09 tgl Exp $
|
||||
*
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
@@ -553,6 +553,14 @@ static struct config_bool ConfigureNamesBool[] =
|
||||
&enableFsync,
|
||||
true, NULL, NULL
|
||||
},
|
||||
{
|
||||
{"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
|
||||
gettext_noop("Sets immediate fsync at commit."),
|
||||
NULL
|
||||
},
|
||||
&XactSyncCommit,
|
||||
true, NULL, NULL
|
||||
},
|
||||
{
|
||||
{"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS,
|
||||
gettext_noop("Continues processing past damaged page headers."),
|
||||
@@ -1521,7 +1529,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
},
|
||||
|
||||
{
|
||||
{"commit_delay", PGC_USERSET, WAL_CHECKPOINTS,
|
||||
{"commit_delay", PGC_USERSET, WAL_SETTINGS,
|
||||
gettext_noop("Sets the delay in microseconds between transaction commit and "
|
||||
"flushing WAL to disk."),
|
||||
NULL
|
||||
@@ -1531,7 +1539,7 @@ static struct config_int ConfigureNamesInt[] =
|
||||
},
|
||||
|
||||
{
|
||||
{"commit_siblings", PGC_USERSET, WAL_CHECKPOINTS,
|
||||
{"commit_siblings", PGC_USERSET, WAL_SETTINGS,
|
||||
gettext_noop("Sets the minimum concurrent open transactions before performing "
|
||||
"commit_delay."),
|
||||
NULL
|
||||
|
||||
@@ -149,6 +149,7 @@
|
||||
# - Settings -
|
||||
|
||||
#fsync = on # turns forced synchronization on or off
|
||||
#synchronous_commit = on # immediate fsync at commit
|
||||
#wal_sync_method = fsync # the default is the first option
|
||||
# supported by the operating system:
|
||||
# open_datasync
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.102 2007/03/25 19:45:14 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.103 2007/08/01 22:45:09 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -80,6 +80,44 @@ TransactionId RecentGlobalXmin = InvalidTransactionId;
|
||||
static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
|
||||
|
||||
|
||||
/*
|
||||
* HeapTupleSetHintBits()
|
||||
*
|
||||
* Set commit/abort hint bits on a tuple, if appropriate at this time.
|
||||
*
|
||||
* We cannot change the LSN of the page here because we may hold only a share
|
||||
* lock on the buffer, so it is only safe to set a transaction-committed hint
|
||||
* bit if we know the transaction's commit record has been flushed to disk.
|
||||
*
|
||||
* We can always set hint bits when marking a transaction aborted. Also,
|
||||
* if we are cleaning up HEAP_MOVED_IN or HEAP_MOVED_OFF entries, then
|
||||
* we can always set the hint bits, since VACUUM FULL always uses synchronous
|
||||
* commits.
|
||||
*
|
||||
* Normal commits may be asynchronous, so for those we need to get the LSN
|
||||
* of the transaction and then check whether this is flushed.
|
||||
*
|
||||
* The caller should pass xid as the XID of the transaction to check, or
|
||||
* InvalidTransactionId if no check is needed.
|
||||
*/
|
||||
static inline void
|
||||
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
|
||||
uint16 infomask, TransactionId xid)
|
||||
{
|
||||
if (TransactionIdIsValid(xid))
|
||||
{
|
||||
/* NB: xid must be known committed here! */
|
||||
XLogRecPtr commitLSN = TransactionIdGetCommitLSN(xid);
|
||||
|
||||
if (XLogNeedsFlush(commitLSN))
|
||||
return; /* not flushed yet, so don't set hint */
|
||||
}
|
||||
|
||||
tuple->t_infomask |= infomask;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* HeapTupleSatisfiesSelf
|
||||
* True iff heap tuple is valid "for itself".
|
||||
@@ -122,12 +160,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -139,14 +177,12 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -164,8 +200,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -176,15 +212,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -221,8 +255,8 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -230,13 +264,13 @@ HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -299,12 +333,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -316,14 +350,12 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -344,8 +376,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -359,15 +391,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -407,8 +437,8 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -416,13 +446,13 @@ HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -469,12 +499,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -486,14 +516,12 @@ HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -550,12 +578,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -567,14 +595,12 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return HeapTupleInvisible;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
}
|
||||
@@ -595,8 +621,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@@ -610,15 +636,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return HeapTupleInvisible;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleInvisible;
|
||||
}
|
||||
}
|
||||
@@ -642,8 +666,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
|
||||
if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple)))
|
||||
return HeapTupleBeingUpdated;
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@@ -663,8 +687,8 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
@@ -672,13 +696,13 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HeapTupleMayBeUpdated;
|
||||
}
|
||||
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return HeapTupleUpdated; /* updated by other */
|
||||
}
|
||||
|
||||
@@ -723,12 +747,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -740,14 +764,12 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -765,8 +787,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
/* deleting subtransaction aborted? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -781,15 +803,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
return true; /* in insertion by other */
|
||||
}
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -829,8 +849,8 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -838,13 +858,13 @@ HeapTupleSatisfiesDirty(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
|
||||
if (tuple->t_infomask & HEAP_IS_LOCKED)
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
return false; /* updated by other */
|
||||
}
|
||||
|
||||
@@ -888,12 +908,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
{
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
@@ -905,14 +925,12 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return false;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -934,8 +952,8 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
/* FIXME -- is this correct w.r.t. the cmax of the tuple? */
|
||||
if (TransactionIdDidAbort(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -949,15 +967,13 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
else if (TransactionIdIsInProgress(HeapTupleHeaderGetXmin(tuple)))
|
||||
return false;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -998,14 +1014,14 @@ HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
|
||||
if (!TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
/* it must have aborted or crashed */
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* xmax transaction committed */
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1054,12 +1070,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
else if (tuple->t_infomask & HEAP_MOVED_IN)
|
||||
{
|
||||
@@ -1070,14 +1086,12 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
if (TransactionIdIsInProgress(xvac))
|
||||
return HEAPTUPLE_INSERT_IN_PROGRESS;
|
||||
if (TransactionIdDidCommit(xvac))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
InvalidTransactionId);
|
||||
else
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
}
|
||||
@@ -1091,21 +1105,22 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
}
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMIN_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
|
||||
HeapTupleHeaderGetXmin(tuple));
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Not in Progress, Not Committed, so either Aborted or crashed
|
||||
*/
|
||||
tuple->t_infomask |= HEAP_XMIN_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_DEAD;
|
||||
}
|
||||
/* Should only get here if we set XMIN_COMMITTED */
|
||||
Assert(tuple->t_infomask & HEAP_XMIN_COMMITTED);
|
||||
/*
|
||||
* At this point the xmin is known committed, but we might not have
|
||||
* been able to set the hint bit yet; so we can no longer Assert
|
||||
* that it's set.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1143,8 +1158,8 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
* We know that xmax did lock the tuple, but it did not and will
|
||||
* never actually update it.
|
||||
*/
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
}
|
||||
return HEAPTUPLE_LIVE;
|
||||
}
|
||||
@@ -1161,21 +1176,22 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
|
||||
if (TransactionIdIsInProgress(HeapTupleHeaderGetXmax(tuple)))
|
||||
return HEAPTUPLE_DELETE_IN_PROGRESS;
|
||||
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
|
||||
{
|
||||
tuple->t_infomask |= HEAP_XMAX_COMMITTED;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
}
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
|
||||
HeapTupleHeaderGetXmax(tuple));
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Not in Progress, Not Committed, so either Aborted or crashed
|
||||
*/
|
||||
tuple->t_infomask |= HEAP_XMAX_INVALID;
|
||||
SetBufferCommitInfoNeedsSave(buffer);
|
||||
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
|
||||
InvalidTransactionId);
|
||||
return HEAPTUPLE_LIVE;
|
||||
}
|
||||
/* Should only get here if we set XMAX_COMMITTED */
|
||||
Assert(tuple->t_infomask & HEAP_XMAX_COMMITTED);
|
||||
/*
|
||||
* At this point the xmax is known committed, but we might not have
|
||||
* been able to set the hint bit yet; so we can no longer Assert
|
||||
* that it's set.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user