Commit a2555571 authored by Simon Riggs's avatar Simon Riggs

Optimise btree delete processing when no active backends.

Clarify comments, downgrade a message to DEBUG and remove some
debug counters. Direct from ideas by Heikki Linnakangas.
parent 781ec6b7
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.66 2010/04/19 17:54:48 tgl Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtxlog.c,v 1.67 2010/04/22 08:04:24 sriggs Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -578,9 +578,17 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record) ...@@ -578,9 +578,17 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record)
OffsetNumber hoffnum; OffsetNumber hoffnum;
TransactionId latestRemovedXid = InvalidTransactionId; TransactionId latestRemovedXid = InvalidTransactionId;
TransactionId htupxid = InvalidTransactionId; TransactionId htupxid = InvalidTransactionId;
int num_unused = 0, num_redirect = 0, num_dead = 0;
int i; int i;
/*
* If there's nothing running on the standby we don't need to derive
* a full latestRemovedXid value, so use a fast path out of here.
* That returns InvalidTransactionId, and so will conflict with
* users, but since we just worked out that's zero people, its OK.
*/
if (CountDBBackends(InvalidOid) == 0)
return latestRemovedXid;
/* /*
* Get index page * Get index page
*/ */
...@@ -629,7 +637,6 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record) ...@@ -629,7 +637,6 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record)
*/ */
while (ItemIdIsRedirected(hitemid)) while (ItemIdIsRedirected(hitemid))
{ {
num_redirect++;
hoffnum = ItemIdGetRedirect(hitemid); hoffnum = ItemIdGetRedirect(hitemid);
hitemid = PageGetItemId(hpage, hoffnum); hitemid = PageGetItemId(hpage, hoffnum);
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
...@@ -662,25 +669,23 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record) ...@@ -662,25 +669,23 @@ btree_xlog_delete_get_latestRemovedXid(XLogRecord *record)
* marked on LP_NORMAL items. So we just ignore this item and move * marked on LP_NORMAL items. So we just ignore this item and move
* onto the next, for the purposes of calculating latestRemovedxids. * onto the next, for the purposes of calculating latestRemovedxids.
*/ */
num_dead++;
} }
else else
{
Assert(!ItemIdIsUsed(hitemid)); Assert(!ItemIdIsUsed(hitemid));
num_unused++;
}
UnlockReleaseBuffer(hbuffer); UnlockReleaseBuffer(hbuffer);
} }
UnlockReleaseBuffer(ibuffer); UnlockReleaseBuffer(ibuffer);
Assert(num_unused == 0);
/* /*
* Note that if all heap tuples were LP_DEAD then we will be * Note that if all heap tuples were LP_DEAD then we will be
* returning InvalidTransactionId here. This seems very unlikely * returning InvalidTransactionId here. That can happen if we are
* in practice. * re-replaying this record type, though that will be before the
* consistency point and will not cause problems. It should
* happen very rarely after the consistency point, though note
* that we can't tell the difference between this and the fast
* path exit above. May need to change that in future.
*/ */
return latestRemovedXid; return latestRemovedXid;
} }
...@@ -963,13 +968,6 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record) ...@@ -963,13 +968,6 @@ btree_redo(XLogRecPtr lsn, XLogRecord *record)
TransactionId latestRemovedXid = btree_xlog_delete_get_latestRemovedXid(record); TransactionId latestRemovedXid = btree_xlog_delete_get_latestRemovedXid(record);
xl_btree_delete *xlrec = (xl_btree_delete *) XLogRecGetData(record); xl_btree_delete *xlrec = (xl_btree_delete *) XLogRecGetData(record);
/*
* XXX Currently we put everybody on death row, because
* currently _bt_delitems() supplies InvalidTransactionId.
* This can be fairly painful, so providing a better value
* here is worth some thought and possibly some effort to
* improve.
*/
ResolveRecoveryConflictWithSnapshot(latestRemovedXid, xlrec->node); ResolveRecoveryConflictWithSnapshot(latestRemovedXid, xlrec->node);
} }
break; break;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.65 2010/04/21 19:08:14 sriggs Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.66 2010/04/22 08:04:25 sriggs Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -1839,7 +1839,8 @@ CountDBBackends(Oid databaseid) ...@@ -1839,7 +1839,8 @@ CountDBBackends(Oid databaseid)
if (proc->pid == 0) if (proc->pid == 0)
continue; /* do not count prepared xacts */ continue; /* do not count prepared xacts */
if (proc->databaseId == databaseid) if (!OidIsValid(databaseid) ||
proc->databaseId == databaseid)
count++; count++;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.17 2010/04/21 19:08:14 sriggs Exp $ * $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.18 2010/04/22 08:04:25 sriggs Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -248,7 +248,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode ...@@ -248,7 +248,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
/* /*
* If we get passed InvalidTransactionId then we are a little surprised, * If we get passed InvalidTransactionId then we are a little surprised,
* but it is theoretically possible, so spit out a LOG message, but not * but it is theoretically possible, so spit out a DEBUG1 message, but not
* one that needs translating. * one that needs translating.
* *
* We grab latestCompletedXid instead because this is the very latest * We grab latestCompletedXid instead because this is the very latest
...@@ -256,7 +256,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode ...@@ -256,7 +256,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
*/ */
if (!TransactionIdIsValid(latestRemovedXid)) if (!TransactionIdIsValid(latestRemovedXid))
{ {
elog(LOG, "Invalid latestRemovedXid reported, using latestCompletedXid instead"); elog(DEBUG1, "Invalid latestremovexXid reported, using latestcompletedxid instead");
LWLockAcquire(ProcArrayLock, LW_SHARED); LWLockAcquire(ProcArrayLock, LW_SHARED);
latestRemovedXid = ShmemVariableCache->latestCompletedXid; latestRemovedXid = ShmemVariableCache->latestCompletedXid;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment