Internals question about buffers - Mailing list pgsql-hackers
From | Bruce Momjian |
---|---|
Subject | Internals question about buffers |
Date | |
Msg-id | 200206072338.g57Nc4l06567@candle.pha.pa.us Whole thread Raw |
Responses |
Re: Internals question about buffers
|
List | pgsql-hackers |
I received this question about buffer management. Can someone answer it? --------------------------------------------------------------------------- nield@usol.com wrote: > > Dear Mr. Momjian: > > First let me thank you for the great work you have done on PostgreSQL. > This is a huge project, and as someone who is just starting to look at > the code I'm grateful for the effort that has gone into commenting and > clean module interfaces. > > Right now, I'm working on a draft proposal involving the WAL system, > in the perhaps vain hope of eliminating VACUUM and allowing > point-in-time recovery and play-forward file recovery from a saved > log-stream. I'm not ready yet to make the proposal, since I'm still > trying to figure out everything I need to know about PostgreSQL > internals, but I hope to have a Request for Comments I can post to the > pgsql-hackers list in the near future. > > The reason I'm writing you is because while looking at the buffer > manager, I had a question about locking and extending relations. There > is surely somthing I don't understand that explains why this scenerio > is not a problem, but if you could point out what I've missed it would > help me understand PostgreSQL better, and move me closer to being able > to contribute to the project. > > Please feel free to forward this to the pgsql-hackers list if you > don't have time to deal with it. > > Regards, > > J.R. Nield <nield@usol.com> > > > > > > > [see the scenerio at bottom first] > > Is there a race condition in ReadBufferInternal() ? > (From bufmgr.c,v 1.123 2002/04/15 23:47:12 momjian Exp) > > When blockNum argument to ReadBufferInternal is 'P_NEW', then > smgrnblocks() is called on the relation to get the last block in the > relation file. This is assigned to blockNum, and the function proceeds > as if ReadBufferInternal() were called with a blockNum equal to > smgrnblocks(). > > Two things to note: > > A) The BufMgrLock is not held when smgrnblocks() is called. (unless > bufferLockHeld was true, which will not be the case when we're > called through ReadBuffer() ) > > B) ReadBufferInternal() then gets an exclusive lock on BufMgrLock > and calls BufferAlloc(). > > If between Time A and B another backend allocates a buffer with P_NEW, > then BufferAlloc() will find the buffer in the block cache. > > If so, it would seem like there is a problem, because later in the > function we will zero this block. > > On line 198, we check if the block was found (Yes), then if we were > expecting it (No) we return. If the buffer is local (It is not) we > do StartBufferIO(). > > The next thing is at 224 where isExtend == true, so we zero the > block. > > *** Why is it OK to zero the block? *** > > Scenerio: > > PROC1 and PROC2 both call ReadBuffer(reln, P_NEW) --> > ReadBufferInternal(reld, P_NEW, false) > > PROC1 gets NOT FOUND from BufferAlloc, so it zero's the buffer and > calls smgrextend. > > PROC2 finds the buffer and waits in WaitIO() for PROC1 to complete. > > PROC1 finishes ReadBuffer and goes on to modify the buffer. > > PROC2 gets a FOUND buffer from BufferAlloc, but was expecting to > extend. It zero's the buffer and calls smgrextend, stomping on PROC1. > > > > > -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 853-3000+ If your life is a hard drive, | 830 Blythe Avenue + Christ can be your backup. | Drexel Hill, Pennsylvania19026
pgsql-hackers by date: