1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Improve performance of replay of AccessExclusiveLocks

A hot standby replica keeps a list of Access Exclusive locks for a top
level transaction. These locks are released when the top level transaction
ends. Searching of this list is O(N^2), and each transaction had to pay the
price of searching this list for locks, even if it didn't take any AE
locks itself.

This patch optimizes this case by having the master server track which
transactions took AE locks, and passes that along to the standby server in
the commit/abort record. This allows the standby to only try to release
locks for transactions which actually took any, avoiding the majority of
the performance issue.

Refactor MyXactAccessedTempRel into MyXactFlags to allow minimal additional
cruft with this.

Analysis and initial patch by David Rowley
Author: David Rowley and Simon Riggs
This commit is contained in:
Simon Riggs
2017-03-22 13:09:36 +00:00
parent 1148e22a82
commit 9b013dc238
6 changed files with 59 additions and 20 deletions

View File

@@ -2065,11 +2065,15 @@ RecordTransactionCommitPrepared(TransactionId xid,
/* See notes in RecordTransactionCommit */
MyPgXact->delayChkpt = true;
/* Emit the XLOG commit record */
/*
* Emit the XLOG commit record. Note that we mark 2PC commits as potentially
* having AccessExclusiveLocks since we don't know whether or not they do.
*/
recptr = XactLogCommitRecord(committs,
nchildren, children, nrels, rels,
ninvalmsgs, invalmsgs,
initfileinval, false,
MyXactFlags | XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK,
xid);
@@ -2146,10 +2150,14 @@ RecordTransactionAbortPrepared(TransactionId xid,
START_CRIT_SECTION();
/* Emit the XLOG abort record */
/*
* Emit the XLOG commit record. Note that we mark 2PC aborts as potentially
* having AccessExclusiveLocks since we don't know whether or not they do.
*/
recptr = XactLogAbortRecord(GetCurrentTimestamp(),
nchildren, children,
nrels, rels,
MyXactFlags | XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK,
xid);
/* Always flush, since we're about to remove the 2PC state file */