mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
localbuf: Introduce FlushLocalBuffer()
Previously we had two paths implementing writing out temporary table buffers. For shared buffers, the logic for that is centralized in FlushBuffer(). Introduce FlushLocalBuffer() to do the same for local buffers. Besides being a nice cleanup on its own, it also makes an upcoming change slightly easier. Reviewed-by: Melanie Plageman <melanieplageman@gmail.com> Discussion: https://postgr.es/m/CAAKRu_b9anbWzEs5AAF9WCvcEVmgz-1AkHSQ-CLLy-p7WHzvFw@mail.gmail.com
This commit is contained in:
@ -4453,7 +4453,6 @@ FlushRelationBuffers(Relation rel)
|
||||
for (i = 0; i < NLocBuffer; i++)
|
||||
{
|
||||
uint32 buf_state;
|
||||
instr_time io_start;
|
||||
|
||||
bufHdr = GetLocalBufferDescriptor(i);
|
||||
if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator) &&
|
||||
@ -4461,9 +4460,6 @@ FlushRelationBuffers(Relation rel)
|
||||
(BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
|
||||
{
|
||||
ErrorContextCallback errcallback;
|
||||
Page localpage;
|
||||
|
||||
localpage = (char *) LocalBufHdrGetBlock(bufHdr);
|
||||
|
||||
/* Setup error traceback support for ereport() */
|
||||
errcallback.callback = local_buffer_write_error_callback;
|
||||
@ -4471,23 +4467,7 @@ FlushRelationBuffers(Relation rel)
|
||||
errcallback.previous = error_context_stack;
|
||||
error_context_stack = &errcallback;
|
||||
|
||||
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
|
||||
|
||||
io_start = pgstat_prepare_io_time(track_io_timing);
|
||||
|
||||
smgrwrite(srel,
|
||||
BufTagGetForkNum(&bufHdr->tag),
|
||||
bufHdr->tag.blockNum,
|
||||
localpage,
|
||||
false);
|
||||
|
||||
pgstat_count_io_op_time(IOOBJECT_TEMP_RELATION,
|
||||
IOCONTEXT_NORMAL, IOOP_WRITE,
|
||||
io_start, 1, BLCKSZ);
|
||||
|
||||
TerminateLocalBufferIO(bufHdr, true, 0);
|
||||
|
||||
pgBufferUsage.local_blks_written++;
|
||||
FlushLocalBuffer(bufHdr, srel);
|
||||
|
||||
/* Pop the error context stack */
|
||||
error_context_stack = errcallback.previous;
|
||||
|
@ -174,6 +174,41 @@ LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum,
|
||||
return bufHdr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Like FlushBuffer(), just for local buffers.
|
||||
*/
|
||||
void
|
||||
FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
|
||||
{
|
||||
instr_time io_start;
|
||||
Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);
|
||||
|
||||
/* Find smgr relation for buffer */
|
||||
if (reln == NULL)
|
||||
reln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag),
|
||||
MyProcNumber);
|
||||
|
||||
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
|
||||
|
||||
io_start = pgstat_prepare_io_time(track_io_timing);
|
||||
|
||||
/* And write... */
|
||||
smgrwrite(reln,
|
||||
BufTagGetForkNum(&bufHdr->tag),
|
||||
bufHdr->tag.blockNum,
|
||||
localpage,
|
||||
false);
|
||||
|
||||
/* Temporary table I/O does not use Buffer Access Strategies */
|
||||
pgstat_count_io_op_time(IOOBJECT_TEMP_RELATION, IOCONTEXT_NORMAL,
|
||||
IOOP_WRITE, io_start, 1, BLCKSZ);
|
||||
|
||||
/* Mark not-dirty */
|
||||
TerminateLocalBufferIO(bufHdr, true, 0);
|
||||
|
||||
pgBufferUsage.local_blks_written++;
|
||||
}
|
||||
|
||||
static Buffer
|
||||
GetLocalVictimBuffer(void)
|
||||
{
|
||||
@ -234,34 +269,7 @@ GetLocalVictimBuffer(void)
|
||||
* the case, write it out before reusing it!
|
||||
*/
|
||||
if (pg_atomic_read_u32(&bufHdr->state) & BM_DIRTY)
|
||||
{
|
||||
instr_time io_start;
|
||||
SMgrRelation oreln;
|
||||
Page localpage = (char *) LocalBufHdrGetBlock(bufHdr);
|
||||
|
||||
/* Find smgr relation for buffer */
|
||||
oreln = smgropen(BufTagGetRelFileLocator(&bufHdr->tag), MyProcNumber);
|
||||
|
||||
PageSetChecksumInplace(localpage, bufHdr->tag.blockNum);
|
||||
|
||||
io_start = pgstat_prepare_io_time(track_io_timing);
|
||||
|
||||
/* And write... */
|
||||
smgrwrite(oreln,
|
||||
BufTagGetForkNum(&bufHdr->tag),
|
||||
bufHdr->tag.blockNum,
|
||||
localpage,
|
||||
false);
|
||||
|
||||
/* Temporary table I/O does not use Buffer Access Strategies */
|
||||
pgstat_count_io_op_time(IOOBJECT_TEMP_RELATION, IOCONTEXT_NORMAL,
|
||||
IOOP_WRITE, io_start, 1, BLCKSZ);
|
||||
|
||||
/* Mark not-dirty now in case we error out below */
|
||||
TerminateLocalBufferIO(bufHdr, true, 0);
|
||||
|
||||
pgBufferUsage.local_blks_written++;
|
||||
}
|
||||
FlushLocalBuffer(bufHdr, NULL);
|
||||
|
||||
/*
|
||||
* Remove the victim buffer from the hashtable and mark as invalid.
|
||||
|
@ -473,6 +473,7 @@ extern BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr,
|
||||
extern void MarkLocalBufferDirty(Buffer buffer);
|
||||
extern void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty,
|
||||
uint32 set_flag_bits);
|
||||
extern void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln);
|
||||
extern void DropRelationLocalBuffers(RelFileLocator rlocator,
|
||||
ForkNumber forkNum,
|
||||
BlockNumber firstDelBlock);
|
||||
|
Reference in New Issue
Block a user