Hi, On Wed, Dec 24, 2008 at 7:58 PM, Fujii Masao <masao.fu...@gmail.com> wrote: > Hi, > > On Wed, Dec 24, 2008 at 6:57 PM, Simon Riggs <si...@2ndquadrant.com> wrote: >> Yes, OK. So I think it would only work when full_page_writes = on, and >> has been on since last checkpoint. So two changes: >> >> * We just need a boolean that starts at true every checkpoint and gets >> set to false anytime someone resets full_page_writes or archive_command. >> If the flag is set && full_page_writes = on then we skip the checkpoint >> entirely and use the value from the last checkpoint. > > Sounds good.
I attached the self-contained patch to skip checkpoint at pg_start_backup. > > pg_start_backup on the standby (probably you are planning?) also needs > this logic? If so, resetting full_page_writes or archive_command should > generate its xlog. Now, the patch doesn't care about this. > > I have another thought: should we forbid the reset of archive_command > during online backup? Currently we can do. If we don't need to do so, > we also don't need to track the reset of archiving for fast pg_start_backup. Now, doesn't care too. Happy Holidays! -- Fujii Masao NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center
? GNUmakefile ? config.log ? config.status ? contrib/pgbench/pgbench ? src/Makefile.global ? src/backend/postgres ? src/backend/catalog/postgres.bki ? src/backend/catalog/postgres.description ? src/backend/catalog/postgres.shdescription ? src/backend/postmaster/walreceiver.c ? src/backend/postmaster/walsender.c ? src/backend/snowball/snowball_create.sql ? src/backend/utils/probes.h ? src/backend/utils/mb/conversion_procs/conversion_create.sql ? src/bin/initdb/initdb ? src/bin/pg_config/pg_config ? src/bin/pg_controldata/pg_controldata ? src/bin/pg_ctl/pg_ctl ? src/bin/pg_dump/pg_dump ? src/bin/pg_dump/pg_dumpall ? src/bin/pg_dump/pg_restore ? src/bin/pg_resetxlog/pg_resetxlog ? src/bin/psql/psql ? src/bin/scripts/clusterdb ? src/bin/scripts/createdb ? src/bin/scripts/createlang ? src/bin/scripts/createuser ? src/bin/scripts/dropdb ? src/bin/scripts/droplang ? src/bin/scripts/dropuser ? src/bin/scripts/reindexdb ? src/bin/scripts/vacuumdb ? src/include/pg_config.h ? src/include/stamp-h ? src/include/postmaster/walreceiver.h ? src/include/postmaster/walsender.h ? src/interfaces/ecpg/compatlib/exports.list ? src/interfaces/ecpg/compatlib/libecpg_compat.so.3.1 ? src/interfaces/ecpg/ecpglib/exports.list ? src/interfaces/ecpg/ecpglib/libecpg.so.6.1 ? src/interfaces/ecpg/include/ecpg_config.h ? src/interfaces/ecpg/pgtypeslib/exports.list ? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.3.1 ? src/interfaces/ecpg/preproc/ecpg ? src/interfaces/libpq/exports.list ? src/interfaces/libpq/libpq.so.5.2 ? src/port/pg_config_paths.h ? src/test/regress/pg_regress ? src/test/regress/testtablespace ? src/timezone/zic Index: src/backend/access/transam/xlog.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v retrieving revision 1.324 diff -c -r1.324 xlog.c *** src/backend/access/transam/xlog.c 17 Dec 2008 01:39:03 -0000 1.324 --- src/backend/access/transam/xlog.c 24 Dec 2008 14:57:27 -0000 *************** *** 295,300 **** --- 295,302 ---- /* Protected by info_lck: */ XLogwrtRqst LogwrtRqst; XLogwrtResult LogwrtResult; + uint32 bkpCount; /* ID of bkp using the same ckpt */ + bool bkpForceCkpt; /* reset full_page_writes since last ckpt? */ uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */ TransactionId ckptXid; XLogRecPtr asyncCommitLSN; /* LSN of newest async commit */ *************** *** 6025,6036 **** UpdateControlFile(); LWLockRelease(ControlFileLock); ! /* Update shared-memory copy of checkpoint XID/epoch */ { /* use volatile pointer to prevent code rearrangement */ volatile XLogCtlData *xlogctl = XLogCtl; SpinLockAcquire(&xlogctl->info_lck); xlogctl->ckptXidEpoch = checkPoint.nextXidEpoch; xlogctl->ckptXid = checkPoint.nextXid; SpinLockRelease(&xlogctl->info_lck); --- 6027,6043 ---- UpdateControlFile(); LWLockRelease(ControlFileLock); ! /* ! * Update shared-memory copy of checkpoint XID/epoch and reset the ! * variables of backup ID/flag. ! */ { /* use volatile pointer to prevent code rearrangement */ volatile XLogCtlData *xlogctl = XLogCtl; SpinLockAcquire(&xlogctl->info_lck); + xlogctl->bkpCount = 0; + xlogctl->bkpForceCkpt = true; xlogctl->ckptXidEpoch = checkPoint.nextXidEpoch; xlogctl->ckptXid = checkPoint.nextXid; SpinLockRelease(&xlogctl->info_lck); *************** *** 6502,6507 **** --- 6509,6535 ---- } } + bool + assign_full_page_writes(bool newval, bool doit, GucSource source) + { + /* + * If full_page_writes is reset, since all indispensable full pages + * might not be written since last checkpoint, we force a checkpoint + * at pg_start_backup. + */ + if (doit && fullPageWrites != newval) + { + /* use volatile pointer to prevent code rearrangement */ + volatile XLogCtlData *xlogctl = XLogCtl; + + SpinLockAcquire(&xlogctl->info_lck); + xlogctl->bkpForceCkpt = false; + SpinLockRelease(&xlogctl->info_lck); + } + + return true; + } + /* * pg_start_backup: set up for taking an on-line backup dump *************** *** 6519,6524 **** --- 6547,6554 ---- char *backupidstr; XLogRecPtr checkpointloc; XLogRecPtr startpoint; + uint32 bkpCount; + bool bkpForceCkpt; pg_time_t stamp_time; char strfbuf[128]; char xlogfilename[MAXFNAMELEN]; *************** *** 6579,6593 **** /* Ensure we release forcePageWrites if fail below */ PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0); { /* ! * Force a CHECKPOINT. Aside from being necessary to prevent torn ! * page problems, this guarantees that two successive backup runs will ! * have different checkpoint positions and hence different history ! * file names, even if nothing happened in between. * * We don't use CHECKPOINT_IMMEDIATE, hence this can take awhile. */ ! RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT); /* * Now we need to fetch the checkpoint record location, and also its --- 6609,6644 ---- /* Ensure we release forcePageWrites if fail below */ PG_ENSURE_ERROR_CLEANUP(pg_start_backup_callback, (Datum) 0); { + { + /* use volatile pointer to prevent code rearrangement */ + volatile XLogCtlData *xlogctl = XLogCtl; + + SpinLockAcquire(&xlogctl->info_lck); + bkpCount = ++xlogctl->bkpCount; + bkpForceCkpt = xlogctl->bkpForceCkpt; + SpinLockRelease(&xlogctl->info_lck); + } + /* ! * If all indispensable full pages might not be written since ! * last checkpoint, we force a CHECKPOINT now. This is necessary ! * to prevent torn page problems. * * We don't use CHECKPOINT_IMMEDIATE, hence this can take awhile. */ ! if (!fullPageWrites || !bkpForceCkpt) ! { ! RequestCheckpoint(CHECKPOINT_FORCE | CHECKPOINT_WAIT); ! ! { ! /* use volatile pointer to prevent code rearrangement */ ! volatile XLogCtlData *xlogctl = XLogCtl; ! ! SpinLockAcquire(&xlogctl->info_lck); ! bkpCount = ++xlogctl->bkpCount; ! SpinLockRelease(&xlogctl->info_lck); ! } ! } /* * Now we need to fetch the checkpoint record location, and also its *************** *** 6637,6644 **** (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", BACKUP_LABEL_FILE))); ! fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n", ! startpoint.xlogid, startpoint.xrecoff, xlogfilename); fprintf(fp, "CHECKPOINT LOCATION: %X/%X\n", checkpointloc.xlogid, checkpointloc.xrecoff); fprintf(fp, "START TIME: %s\n", strfbuf); --- 6688,6695 ---- (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", BACKUP_LABEL_FILE))); ! fprintf(fp, "START WAL LOCATION: %X/%X (file %s id %X)\n", ! startpoint.xlogid, startpoint.xrecoff, xlogfilename, bkpCount); fprintf(fp, "CHECKPOINT LOCATION: %X/%X\n", checkpointloc.xlogid, checkpointloc.xrecoff); fprintf(fp, "START TIME: %s\n", strfbuf); *************** *** 6683,6688 **** --- 6734,6740 ---- { XLogRecPtr startpoint; XLogRecPtr stoppoint; + uint32 bkpCount; pg_time_t stamp_time; char strfbuf[128]; char histfilepath[MAXPGPATH]; *************** *** 6753,6761 **** * Read and parse the START WAL LOCATION line (this code is pretty crude, * but we are not expecting any variability in the file format). */ ! if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %24s)%c", &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename, ! &ch) != 4 || ch != '\n') ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); --- 6805,6813 ---- * Read and parse the START WAL LOCATION line (this code is pretty crude, * but we are not expecting any variability in the file format). */ ! if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %24s id %X)%c", &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename, ! &bkpCount, &ch) != 5 || ch != '\n') ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); *************** *** 6765,6779 **** */ XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize); fp = AllocateFile(histfilepath, "w"); if (!fp) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", histfilepath))); ! fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n", ! startpoint.xlogid, startpoint.xrecoff, startxlogfilename); fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n", stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename); /* transfer remaining lines from label to history file */ --- 6817,6831 ---- */ XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize, bkpCount); fp = AllocateFile(histfilepath, "w"); if (!fp) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", histfilepath))); ! fprintf(fp, "START WAL LOCATION: %X/%X (file %s id %X)\n", ! startpoint.xlogid, startpoint.xrecoff, startxlogfilename, bkpCount); fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n", stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename); /* transfer remaining lines from label to history file */ *************** *** 6822,6828 **** XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFileName(histfilename, ThisTimeLineID, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize); seconds_before_warning = 60; waits = 0; --- 6874,6880 ---- XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFileName(histfilename, ThisTimeLineID, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize, bkpCount); seconds_before_warning = 60; waits = 0; *************** *** 7060,7065 **** --- 7112,7118 ---- { XLogRecPtr startpoint; XLogRecPtr stoppoint; + uint32 bkpCount; char histfilename[MAXFNAMELEN]; char histfilepath[MAXPGPATH]; char startxlogfilename[MAXFNAMELEN]; *************** *** 7094,7102 **** * is pretty crude, but we are not expecting any variability in the file * format). */ ! if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s)%c", &startpoint.xlogid, &startpoint.xrecoff, &tli, ! startxlogfilename, &ch) != 5 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); --- 7147,7155 ---- * is pretty crude, but we are not expecting any variability in the file * format). */ ! if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s id %X)%c", &startpoint.xlogid, &startpoint.xrecoff, &tli, ! startxlogfilename, &bkpCount, &ch) != 6 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); *************** *** 7117,7129 **** */ XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFileName(histfilename, tli, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize); if (InArchiveRecovery) RestoreArchivedFile(histfilepath, histfilename, "RECOVERYHISTORY", 0); else BackupHistoryFilePath(histfilepath, tli, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize); fp = AllocateFile(histfilepath, "r"); if (fp) --- 7170,7182 ---- */ XLByteToSeg(startpoint, _logId, _logSeg); BackupHistoryFileName(histfilename, tli, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize, bkpCount); if (InArchiveRecovery) RestoreArchivedFile(histfilepath, histfilename, "RECOVERYHISTORY", 0); else BackupHistoryFilePath(histfilepath, tli, _logId, _logSeg, ! startpoint.xrecoff % XLogSegSize, bkpCount); fp = AllocateFile(histfilepath, "r"); if (fp) *************** *** 7131,7139 **** /* * Parse history file to identify stop point. */ ! if (fscanf(fp, "START WAL LOCATION: %X/%X (file %24s)%c", &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename, ! &ch) != 4 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", histfilename))); --- 7184,7192 ---- /* * Parse history file to identify stop point. */ ! if (fscanf(fp, "START WAL LOCATION: %X/%X (file %24s id %X)%c", &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename, ! &bkpCount, &ch) != 5 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", histfilename))); Index: src/backend/postmaster/pgarch.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/postmaster/pgarch.c,v retrieving revision 1.38 diff -c -r1.38 pgarch.c *** src/backend/postmaster/pgarch.c 11 Jan 2008 00:54:08 -0000 1.38 --- src/backend/postmaster/pgarch.c 24 Dec 2008 14:57:39 -0000 *************** *** 66,72 **** * ---------- */ #define MIN_XFN_CHARS 16 ! #define MAX_XFN_CHARS 40 #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup" #define NUM_ARCHIVE_RETRIES 3 --- 66,72 ---- * ---------- */ #define MIN_XFN_CHARS 16 ! #define MAX_XFN_CHARS 49 #define VALID_XFN_CHARS "0123456789ABCDEF.history.backup" #define NUM_ARCHIVE_RETRIES 3 Index: src/backend/utils/misc/guc.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/misc/guc.c,v retrieving revision 1.483 diff -c -r1.483 guc.c *** src/backend/utils/misc/guc.c 13 Dec 2008 19:13:44 -0000 1.483 --- src/backend/utils/misc/guc.c 24 Dec 2008 14:57:54 -0000 *************** *** 57,62 **** --- 57,63 ---- #include "regex/regex.h" #include "storage/bufmgr.h" #include "storage/fd.h" + #include "storage/spin.h" #include "tcop/tcopprot.h" #include "tsearch/ts_cache.h" #include "utils/builtins.h" *************** *** 713,719 **** "is possible.") }, &fullPageWrites, ! true, NULL, NULL }, { {"silent_mode", PGC_POSTMASTER, LOGGING_WHEN, --- 714,720 ---- "is possible.") }, &fullPageWrites, ! true, assign_full_page_writes, NULL }, { {"silent_mode", PGC_POSTMASTER, LOGGING_WHEN, Index: src/include/access/xlog_internal.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/access/xlog_internal.h,v retrieving revision 1.24 diff -c -r1.24 xlog_internal.h *** src/include/access/xlog_internal.h 11 Aug 2008 11:05:11 -0000 1.24 --- src/include/access/xlog_internal.h 24 Dec 2008 14:57:59 -0000 *************** *** 215,225 **** #define StatusFilePath(path, xlog, suffix) \ snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) ! #define BackupHistoryFileName(fname, tli, log, seg, offset) \ ! snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, log, seg, offset) ! #define BackupHistoryFilePath(path, tli, log, seg, offset) \ ! snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, log, seg, offset) /* --- 215,225 ---- #define StatusFilePath(path, xlog, suffix) \ snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix) ! #define BackupHistoryFileName(fname, tli, log, seg, offset, id) \ ! snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.%08X.backup", tli, log, seg, offset, id) ! #define BackupHistoryFilePath(path, tli, log, seg, offset, id) \ ! snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.%08X.backup", tli, log, seg, offset, id) /* Index: src/include/utils/guc.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/guc.h,v retrieving revision 1.99 diff -c -r1.99 guc.h *** src/include/utils/guc.h 19 Nov 2008 01:10:23 -0000 1.99 --- src/include/utils/guc.h 24 Dec 2008 14:58:01 -0000 *************** *** 308,312 **** --- 308,314 ---- /* in access/transam/xlog.c */ extern bool assign_xlog_sync_method(int newval, bool doit, GucSource source); + extern bool assign_full_page_writes(bool newval, + bool doit, GucSource source); #endif /* GUC_H */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers