mirror of
https://github.com/postgres/postgres.git
synced 2025-06-11 20:28:21 +03:00
Flush unlogged table's buffers when copying or moving databases.
CREATE DATABASE and ALTER DATABASE .. SET TABLESPACE copy the source database directory on the filesystem level. To ensure the on disk state is consistent they block out users of the affected database and force a checkpoint to flush out all data to disk. Unfortunately, up to now, that checkpoint didn't flush out dirty buffers from unlogged relations. That bug means there could be leftover dirty buffers in either the template database, or the database in its old location. Leading to problems when accessing relations in an inconsistent state; and to possible problems during shutdown in the SET TABLESPACE case because buffers belonging files that don't exist anymore are flushed. This was reported in bug #10675 by Maxim Boguk. Fix by Pavan Deolasee, modified somewhat by me. Reviewed by MauMau and Fujii Masao. Backpatch to 9.1 where unlogged tables were introduced.
This commit is contained in:
@ -1493,9 +1493,10 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner)
|
||||
*
|
||||
* This is called at checkpoint time to write out all dirty shared buffers.
|
||||
* The checkpoint request flags should be passed in. If CHECKPOINT_IMMEDIATE
|
||||
* is set, we disable delays between writes; if CHECKPOINT_IS_SHUTDOWN is
|
||||
* set, we write even unlogged buffers, which are otherwise skipped. The
|
||||
* remaining flags currently have no effect here.
|
||||
* is set, we disable delays between writes; if CHECKPOINT_IS_SHUTDOWN,
|
||||
* CHECKPOINT_END_OF_RECOVERY or CHECKPOINT_FLUSH_ALL is set, we write even
|
||||
* unlogged buffers, which are otherwise skipped. The remaining flags
|
||||
* currently have no effect here.
|
||||
*/
|
||||
static void
|
||||
BufferSync(int flags)
|
||||
@ -1510,11 +1511,12 @@ BufferSync(int flags)
|
||||
ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
|
||||
|
||||
/*
|
||||
* Unless this is a shutdown checkpoint, we write only permanent, dirty
|
||||
* buffers. But at shutdown or end of recovery, we write all dirty
|
||||
* buffers.
|
||||
* Unless this is a shutdown checkpoint or we have been explicitly told,
|
||||
* we write only permanent, dirty buffers. But at shutdown or end of
|
||||
* recovery, we write all dirty buffers.
|
||||
*/
|
||||
if (!((flags & CHECKPOINT_IS_SHUTDOWN) || (flags & CHECKPOINT_END_OF_RECOVERY)))
|
||||
if (!((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
|
||||
CHECKPOINT_FLUSH_ALL))))
|
||||
mask |= BM_PERMANENT;
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user