Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd172b71

Browse files
committed
Use atomic access for SlruShared->latest_page_number
The new concurrency model proposed for slru.c to improve performancedoes not include any single lock that would coordinate processesdoing concurrent reads/writes on SlruShared->latest_page_number.We can instead use atomic reads and writes for that variable.Author: Dilip Kumar <dilipbalaut@gmail.com>Reviewed-by: Andrey M. Borodin <x4mmm@yandex-team.ru>Discussion:https://postgr.es/m/CAFiTN-vzDvNz=ExGXz6gdyjtzGixKSqs0mKHMmaQ8sOSEFZ33A@mail.gmail.com
1 parentb83033c commitd172b71

File tree

5 files changed

+53
-32
lines changed

5 files changed

+53
-32
lines changed

‎src/backend/access/transam/clog.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -766,14 +766,10 @@ StartupCLOG(void)
766766
TransactionIdxid=XidFromFullTransactionId(TransamVariables->nextXid);
767767
int64pageno=TransactionIdToPage(xid);
768768

769-
LWLockAcquire(XactSLRULock,LW_EXCLUSIVE);
770-
771769
/*
772770
* Initialize our idea of the latest page number.
773771
*/
774-
XactCtl->shared->latest_page_number=pageno;
775-
776-
LWLockRelease(XactSLRULock);
772+
pg_atomic_write_u64(&XactCtl->shared->latest_page_number,pageno);
777773
}
778774

779775
/*

‎src/backend/access/transam/commit_ts.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -689,9 +689,7 @@ ActivateCommitTs(void)
689689
/*
690690
* Re-Initialize our idea of the latest page number.
691691
*/
692-
LWLockAcquire(CommitTsSLRULock,LW_EXCLUSIVE);
693-
CommitTsCtl->shared->latest_page_number=pageno;
694-
LWLockRelease(CommitTsSLRULock);
692+
pg_atomic_write_u64(&CommitTsCtl->shared->latest_page_number,pageno);
695693

696694
/*
697695
* If CommitTs is enabled, but it wasn't in the previous server run, we
@@ -1006,7 +1004,8 @@ commit_ts_redo(XLogReaderState *record)
10061004
* During XLOG replay, latest_page_number isn't set up yet; insert a
10071005
* suitable value to bypass the sanity test in SimpleLruTruncate.
10081006
*/
1009-
CommitTsCtl->shared->latest_page_number=trunc->pageno;
1007+
pg_atomic_write_u64(&CommitTsCtl->shared->latest_page_number,
1008+
trunc->pageno);
10101009

10111010
SimpleLruTruncate(CommitTsCtl,trunc->pageno);
10121011
}

‎src/backend/access/transam/multixact.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,13 +2017,15 @@ StartupMultiXact(void)
20172017
* Initialize offset's idea of the latest page number.
20182018
*/
20192019
pageno=MultiXactIdToOffsetPage(multi);
2020-
MultiXactOffsetCtl->shared->latest_page_number=pageno;
2020+
pg_atomic_write_u64(&MultiXactOffsetCtl->shared->latest_page_number,
2021+
pageno);
20212022

20222023
/*
20232024
* Initialize member's idea of the latest page number.
20242025
*/
20252026
pageno=MXOffsetToMemberPage(offset);
2026-
MultiXactMemberCtl->shared->latest_page_number=pageno;
2027+
pg_atomic_write_u64(&MultiXactMemberCtl->shared->latest_page_number,
2028+
pageno);
20272029
}
20282030

20292031
/*
@@ -2047,14 +2049,15 @@ TrimMultiXact(void)
20472049
oldestMXactDB=MultiXactState->oldestMultiXactDB;
20482050
LWLockRelease(MultiXactGenLock);
20492051

2050-
/* Clean up offsets state */
2051-
LWLockAcquire(MultiXactOffsetSLRULock,LW_EXCLUSIVE);
2052-
20532052
/*
20542053
* (Re-)Initialize our idea of the latest page number for offsets.
20552054
*/
20562055
pageno=MultiXactIdToOffsetPage(nextMXact);
2057-
MultiXactOffsetCtl->shared->latest_page_number=pageno;
2056+
pg_atomic_write_u64(&MultiXactOffsetCtl->shared->latest_page_number,
2057+
pageno);
2058+
2059+
/* Clean up offsets state */
2060+
LWLockAcquire(MultiXactOffsetSLRULock,LW_EXCLUSIVE);
20582061

20592062
/*
20602063
* Zero out the remainder of the current offsets page. See notes in
@@ -2081,14 +2084,16 @@ TrimMultiXact(void)
20812084

20822085
LWLockRelease(MultiXactOffsetSLRULock);
20832086

2084-
/* And the same for members */
2085-
LWLockAcquire(MultiXactMemberSLRULock,LW_EXCLUSIVE);
2086-
20872087
/*
2088+
* And the same for members.
2089+
*
20882090
* (Re-)Initialize our idea of the latest page number for members.
20892091
*/
20902092
pageno=MXOffsetToMemberPage(offset);
2091-
MultiXactMemberCtl->shared->latest_page_number=pageno;
2093+
pg_atomic_write_u64(&MultiXactMemberCtl->shared->latest_page_number,
2094+
pageno);
2095+
2096+
LWLockAcquire(MultiXactMemberSLRULock,LW_EXCLUSIVE);
20922097

20932098
/*
20942099
* Zero out the remainder of the current members page. See notes in
@@ -3333,7 +3338,8 @@ multixact_redo(XLogReaderState *record)
33333338
* SimpleLruTruncate.
33343339
*/
33353340
pageno=MultiXactIdToOffsetPage(xlrec.endTruncOff);
3336-
MultiXactOffsetCtl->shared->latest_page_number=pageno;
3341+
pg_atomic_write_u64(&MultiXactOffsetCtl->shared->latest_page_number,
3342+
pageno);
33373343
PerformOffsetsTruncation(xlrec.startTruncOff,xlrec.endTruncOff);
33383344

33393345
LWLockRelease(MultiXactTruncationLock);

‎src/backend/access/transam/slru.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
* per-buffer LWLocks that synchronize I/O for each buffer. The control lock
1818
* must be held to examine or modify any shared state. A process that is
1919
* reading in or writing out a page buffer does not hold the control lock,
20-
* only the per-buffer lock for the buffer it is working on.
20+
* only the per-buffer lock for the buffer it is working on. One exception
21+
* is latest_page_number, which is read and written using atomic ops.
2122
*
2223
* "Holding the control lock" means exclusive lock in all cases except for
2324
* SimpleLruReadPage_ReadOnly(); see comments for SlruRecentlyUsed() for
@@ -239,8 +240,7 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
239240
shared->lsn_groups_per_page=nlsns;
240241

241242
shared->cur_lru_count=0;
242-
243-
/* shared->latest_page_number will be set later */
243+
pg_atomic_write_u64(&shared->latest_page_number,0);
244244

245245
shared->slru_stats_idx=pgstat_get_slru_index(name);
246246

@@ -329,8 +329,15 @@ SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
329329
/* Set the LSNs for this new page to zero */
330330
SimpleLruZeroLSNs(ctl,slotno);
331331

332-
/* Assume this page is now the latest active page */
333-
shared->latest_page_number=pageno;
332+
/*
333+
* Assume this page is now the latest active page.
334+
*
335+
* Note that because both this routine and SlruSelectLRUPage run with
336+
* ControlLock held, it is not possible for this to be zeroing a page that
337+
* SlruSelectLRUPage is going to evict simultaneously. Therefore, there's
338+
* no memory barrier here.
339+
*/
340+
pg_atomic_write_u64(&shared->latest_page_number,pageno);
334341

335342
/* update the stats counter of zeroed pages */
336343
pgstat_count_slru_page_zeroed(shared->slru_stats_idx);
@@ -1113,9 +1120,17 @@ SlruSelectLRUPage(SlruCtl ctl, int64 pageno)
11131120
shared->page_lru_count[slotno]=cur_count;
11141121
this_delta=0;
11151122
}
1123+
1124+
/*
1125+
* If this page is the one most recently zeroed, don't consider it
1126+
* an eviction candidate. See comments in SimpleLruZeroPage for an
1127+
* explanation about the lack of a memory barrier here.
1128+
*/
11161129
this_page_number=shared->page_number[slotno];
1117-
if (this_page_number==shared->latest_page_number)
1130+
if (this_page_number==
1131+
pg_atomic_read_u64(&shared->latest_page_number))
11181132
continue;
1133+
11191134
if (shared->page_status[slotno]==SLRU_PAGE_VALID)
11201135
{
11211136
if (this_delta>best_valid_delta||
@@ -1254,7 +1269,6 @@ void
12541269
SimpleLruTruncate(SlruCtlctl,int64cutoffPage)
12551270
{
12561271
SlruSharedshared=ctl->shared;
1257-
intslotno;
12581272

12591273
/* update the stats counter of truncates */
12601274
pgstat_count_slru_truncate(shared->slru_stats_idx);
@@ -1270,10 +1284,13 @@ SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
12701284
restart:
12711285

12721286
/*
1273-
* While we are holding the lock, make an important safety check: the
1274-
* current endpoint page must not be eligible for removal.
1287+
* An important safety check: the current endpoint page must not be
1288+
* eligible for removal. This check is just a backstop against wraparound
1289+
* bugs elsewhere in SLRU handling, so we don't care if we read a slightly
1290+
* outdated value; therefore we don't add a memory barrier.
12751291
*/
1276-
if (ctl->PagePrecedes(shared->latest_page_number,cutoffPage))
1292+
if (ctl->PagePrecedes(pg_atomic_read_u64(&shared->latest_page_number),
1293+
cutoffPage))
12771294
{
12781295
LWLockRelease(shared->ControlLock);
12791296
ereport(LOG,
@@ -1282,7 +1299,7 @@ SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
12821299
return;
12831300
}
12841301

1285-
for (slotno=0;slotno<shared->num_slots;slotno++)
1302+
for (intslotno=0;slotno<shared->num_slots;slotno++)
12861303
{
12871304
if (shared->page_status[slotno]==SLRU_PAGE_EMPTY)
12881305
continue;

‎src/include/access/slru.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ typedef enum
4949

5050
/*
5151
* Shared-memory state
52+
*
53+
* ControlLock is used to protect access to the other fields, except
54+
* latest_page_number, which uses atomics; see comment in slru.c.
5255
*/
5356
typedefstructSlruSharedData
5457
{
@@ -95,7 +98,7 @@ typedef struct SlruSharedData
9598
* this is not critical data, since we use it only to avoid swapping out
9699
* the latest page.
97100
*/
98-
int64latest_page_number;
101+
pg_atomic_uint64latest_page_number;
99102

100103
/* SLRU's index for statistics purposes (might not be unique) */
101104
intslru_stats_idx;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp