v2-0001-Use-atomic-old_snapshot_threshold.patch
application/octet-stream
Filename: v2-0001-Use-atomic-old_snapshot_threshold.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Use atomic old_snapshot_threshold
| File | + | − |
|---|---|---|
| src/backend/utils/time/snapmgr.c | 17 | 19 |
| src/include/utils/old_snapshot.h | 3 | 3 |
From 6bdd3566e9252c4296b0c663786eba6e5bf95c12 Mon Sep 17 00:00:00 2001
From: Maxim Orlov <orlovmg@gmail.com>
Date: Wed, 11 Jan 2023 18:07:10 +0300
Subject: [PATCH v2] Use atomic old_snapshot_threshold
Using spinlock to access old_snapshot_threshold lead to the bottleneck on
replica, since GetOldSnapshotThresholdTimestamp is called too often. So, switch
to an atomic values.
---
src/backend/utils/time/snapmgr.c | 36 +++++++++++++++-----------------
src/include/utils/old_snapshot.h | 6 +++---
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 7d11ae34781..77f32ae468f 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -229,9 +229,8 @@ SnapMgrInit(void)
SpinLockInit(&oldSnapshotControl->mutex_latest_xmin);
oldSnapshotControl->latest_xmin = InvalidTransactionId;
oldSnapshotControl->next_map_update = 0;
- SpinLockInit(&oldSnapshotControl->mutex_threshold);
- oldSnapshotControl->threshold_timestamp = 0;
- oldSnapshotControl->threshold_xid = InvalidTransactionId;
+ pg_atomic_init_u64(&oldSnapshotControl->threshold_timestamp, 0);
+ pg_atomic_init_u32(&oldSnapshotControl->threshold_xid, InvalidTransactionId);
oldSnapshotControl->head_offset = 0;
oldSnapshotControl->head_timestamp = 0;
oldSnapshotControl->count_used = 0;
@@ -1706,9 +1705,7 @@ GetOldSnapshotThresholdTimestamp(void)
{
TimestampTz threshold_timestamp;
- SpinLockAcquire(&oldSnapshotControl->mutex_threshold);
- threshold_timestamp = oldSnapshotControl->threshold_timestamp;
- SpinLockRelease(&oldSnapshotControl->mutex_threshold);
+ threshold_timestamp = pg_atomic_read_u64(&oldSnapshotControl->threshold_timestamp);
return threshold_timestamp;
}
@@ -1716,12 +1713,17 @@ GetOldSnapshotThresholdTimestamp(void)
void
SetOldSnapshotThresholdTimestamp(TimestampTz ts, TransactionId xlimit)
{
- SpinLockAcquire(&oldSnapshotControl->mutex_threshold);
- Assert(oldSnapshotControl->threshold_timestamp <= ts);
- Assert(TransactionIdPrecedesOrEquals(oldSnapshotControl->threshold_xid, xlimit));
- oldSnapshotControl->threshold_timestamp = ts;
- oldSnapshotControl->threshold_xid = xlimit;
- SpinLockRelease(&oldSnapshotControl->mutex_threshold);
+ TimestampTz threshold_timestamp;
+ TransactionId threshold_xid;
+
+ threshold_timestamp = pg_atomic_read_u64(&oldSnapshotControl->threshold_timestamp);
+ threshold_xid = pg_atomic_read_u32(&oldSnapshotControl->threshold_xid);
+
+ Assert(threshold_timestamp <= ts);
+ Assert(TransactionIdPrecedesOrEquals(threshold_xid, xlimit));
+
+ pg_atomic_write_u64(&oldSnapshotControl->threshold_timestamp, ts);
+ pg_atomic_write_u32(&oldSnapshotControl->threshold_xid, xlimit);
}
/*
@@ -1739,9 +1741,7 @@ SnapshotTooOldMagicForTest(void)
ts -= 5 * USECS_PER_SEC;
- SpinLockAcquire(&oldSnapshotControl->mutex_threshold);
- oldSnapshotControl->threshold_timestamp = ts;
- SpinLockRelease(&oldSnapshotControl->mutex_threshold);
+ pg_atomic_write_u64(&oldSnapshotControl->threshold_timestamp, ts);
}
/*
@@ -1845,10 +1845,8 @@ TransactionIdLimitedForOldSnapshots(TransactionId recentXmin,
- (old_snapshot_threshold * USECS_PER_MINUTE);
/* Check for fast exit without LW locking. */
- SpinLockAcquire(&oldSnapshotControl->mutex_threshold);
- threshold_timestamp = oldSnapshotControl->threshold_timestamp;
- threshold_xid = oldSnapshotControl->threshold_xid;
- SpinLockRelease(&oldSnapshotControl->mutex_threshold);
+ threshold_timestamp = pg_atomic_read_u64(&oldSnapshotControl->threshold_timestamp);
+ threshold_xid = pg_atomic_read_u32(&oldSnapshotControl->threshold_xid);
if (ts == threshold_timestamp)
{
diff --git a/src/include/utils/old_snapshot.h b/src/include/utils/old_snapshot.h
index f1978a28e1c..979189a143f 100644
--- a/src/include/utils/old_snapshot.h
+++ b/src/include/utils/old_snapshot.h
@@ -16,6 +16,7 @@
#define OLD_SNAPSHOT_H
#include "datatype/timestamp.h"
+#include "port/atomics.h"
#include "storage/s_lock.h"
/*
@@ -32,9 +33,8 @@ typedef struct OldSnapshotControlData
slock_t mutex_latest_xmin; /* protect latest_xmin and next_map_update */
TransactionId latest_xmin; /* latest snapshot xmin */
TimestampTz next_map_update; /* latest snapshot valid up to */
- slock_t mutex_threshold; /* protect threshold fields */
- TimestampTz threshold_timestamp; /* earlier snapshot is old */
- TransactionId threshold_xid; /* earlier xid may be gone */
+ pg_atomic_uint64 threshold_timestamp; /* earlier snapshot is old */
+ pg_atomic_uint32 threshold_xid; /* earlier xid may be gone */
/*
* Keep one xid per minute for old snapshot error handling.
--
2.38.1