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

Commit4835458

Browse files
committed
Allow Pin/UnpinBuffer to operate in a lockfree manner.
Pinning/Unpinning a buffer is a very frequent operation; especially inread-mostly cache resident workloads. Benchmarking shows that in variousscenarios the spinlock protecting a buffer header's state becomes asignificant bottleneck. The problem can be reproduced with pgbench -S onlarger machines, but can be considerably worse for queries which touchthe same buffers over and over at a high frequency (e.g. nested loopsover a small inner table).To allow atomic operations to be used, cram BufferDesc's flags,usage_count, buf_hdr_lock, refcount into a single 32bit atomic variable;that allows to manipulate them together using 32bit compare-and-swapoperations. This requires reducing MAX_BACKENDS to 2^18-1 (which couldbe lifted by using a 64bit field, but it's not a realistic configurationatm).As not all operations can easily implemented in a lockfree manner,implement the previous buf_hdr_lock via a flag bit in the atomicvariable. That way we can continue to lock the header in places whereit's needed, but can get away without acquiring it in the more frequenthot-paths. There's some additional operations which can be done withoutthe lock, but aren't in this patch; but the most important places arecovered.As bufmgr.c now essentially re-implements spinlocks, abstract the delaylogic from s_lock.c into something more generic. It now has already twousers, and more are coming up; there's a follupw patch for lwlock.c atleast.This patch is based on a proof-of-concept written by me, which AlexanderKorotkov made into a fully working patch; the committed version is againrevised by me. Benchmarking and testing has, amongst others, beenprovided by Dilip Kumar, Alexander Korotkov, Robert Haas.On a large x86 system improvements for readonly pgbench, with a highclient count, of a factor of 8 have been observed.Author: Alexander Korotkov and Andres FreundDiscussion:2400449.GjM57CE0Yg@dinodell
1 parentcf223c3 commit4835458

File tree

10 files changed

+622
-357
lines changed

10 files changed

+622
-357
lines changed

‎contrib/pg_buffercache/pg_buffercache_pages.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,33 +148,34 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
148148
*/
149149
for (i=0;i<NBuffers;i++)
150150
{
151-
volatileBufferDesc*bufHdr;
151+
BufferDesc*bufHdr;
152+
uint32buf_state;
152153

153154
bufHdr=GetBufferDescriptor(i);
154155
/* Lock each buffer header before inspecting. */
155-
LockBufHdr(bufHdr);
156+
buf_state=LockBufHdr(bufHdr);
156157

157158
fctx->record[i].bufferid=BufferDescriptorGetBuffer(bufHdr);
158159
fctx->record[i].relfilenode=bufHdr->tag.rnode.relNode;
159160
fctx->record[i].reltablespace=bufHdr->tag.rnode.spcNode;
160161
fctx->record[i].reldatabase=bufHdr->tag.rnode.dbNode;
161162
fctx->record[i].forknum=bufHdr->tag.forkNum;
162163
fctx->record[i].blocknum=bufHdr->tag.blockNum;
163-
fctx->record[i].usagecount=bufHdr->usage_count;
164-
fctx->record[i].pinning_backends=bufHdr->refcount;
164+
fctx->record[i].usagecount=BUF_STATE_GET_USAGECOUNT(buf_state);
165+
fctx->record[i].pinning_backends=BUF_STATE_GET_REFCOUNT(buf_state);
165166

166-
if (bufHdr->flags&BM_DIRTY)
167+
if (buf_state&BM_DIRTY)
167168
fctx->record[i].isdirty= true;
168169
else
169170
fctx->record[i].isdirty= false;
170171

171172
/* Note if the buffer is valid, and has storage created */
172-
if ((bufHdr->flags&BM_VALID)&& (bufHdr->flags&BM_TAG_VALID))
173+
if ((buf_state&BM_VALID)&& (buf_state&BM_TAG_VALID))
173174
fctx->record[i].isvalid= true;
174175
else
175176
fctx->record[i].isvalid= false;
176177

177-
UnlockBufHdr(bufHdr);
178+
UnlockBufHdr(bufHdr,buf_state);
178179
}
179180

180181
/*

‎src/backend/storage/buffer/buf_init.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,9 @@ InitBufferPool(void)
135135
BufferDesc*buf=GetBufferDescriptor(i);
136136

137137
CLEAR_BUFFERTAG(buf->tag);
138-
buf->flags=0;
139-
buf->usage_count=0;
140-
buf->refcount=0;
141-
buf->wait_backend_pid=0;
142138

143-
SpinLockInit(&buf->buf_hdr_lock);
139+
pg_atomic_init_u32(&buf->state,0);
140+
buf->wait_backend_pid=0;
144141

145142
buf->buf_id=i;
146143

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp