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

Commitf12e814

Browse files
committed
Fix commit_ts for standby
Module initialization was still not completely correct after commit6b61955, per crash report from Takashi Ohnishi. To fix, instead oftrying to monkey around with the value of the GUC setting directly, adda separate boolean flag that enables the feature on a standby, but onlyfor the startup (recovery) process, when it sees that its master serverhas the feature enabled.Discussion:http://www.postgresql.org/message-id/ca44c6c7f9314868bdc521aea4f77cbf@MP-MSGSS-MBX004.msg.nttdata.co.jpAlso change the deactivation routine to delete all segment files ratherthan leaving the last one around. (This doesn't need separateWAL-logging, because on recovery we execute the same deactivationroutine anyway.)In passing, clean up the code structure somewhat, particularly so thatxlog.c doesn't know so much about when to activate/deactivate thefeature.Thanks to Fujii Masao for testing and Petr Jelínek for off-list discussion.Back-patch to 9.5, where commit_ts was introduced.
1 parentbf4817e commitf12e814

File tree

5 files changed

+84
-65
lines changed

5 files changed

+84
-65
lines changed

‎src/backend/access/transam/commit_ts.c

Lines changed: 73 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,23 @@ CommitTimestampShared *commitTsShared;
9393
/* GUC variable */
9494
booltrack_commit_timestamp;
9595

96+
/*
97+
* When this is set, commit_ts is force-enabled during recovery. This is so
98+
* that a standby can replay WAL records coming from a master with the setting
99+
* enabled. (Note that this doesn't enable SQL access to the data; it's
100+
* effectively write-only until the GUC itself is enabled.)
101+
*/
102+
staticboolenable_during_recovery;
103+
96104
staticvoidSetXidCommitTsInPage(TransactionIdxid,intnsubxids,
97105
TransactionId*subxids,TimestampTzts,
98106
RepOriginIdnodeid,intpageno);
99107
staticvoidTransactionIdSetCommitTs(TransactionIdxid,TimestampTzts,
100108
RepOriginIdnodeid,intslotno);
101109
staticintZeroCommitTsPage(intpageno,boolwriteXlog);
102110
staticboolCommitTsPagePrecedes(intpage1,intpage2);
111+
staticvoidActivateCommitTs(void);
112+
staticvoidDeactivateCommitTs(booldo_wal);
103113
staticvoidWriteZeroPageXlogRec(intpageno);
104114
staticvoidWriteTruncateXlogRec(intpageno);
105115
staticvoidWriteSetTimestampXlogRec(TransactionIdmainxid,intnsubxids,
@@ -122,10 +132,6 @@ static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids,
122132
* subtrans implementation changes in the future, we might want to revisit the
123133
* decision of storing timestamp info for each subxid.
124134
*
125-
* The replaying_xlog parameter indicates whether the module should execute
126-
* its write even if the feature is nominally disabled, because we're replaying
127-
* a record generated from a master where the feature is enabled.
128-
*
129135
* The write_xlog parameter tells us whether to include an XLog record of this
130136
* or not. Normally, this is called from transaction commit routines (both
131137
* normal and prepared) and the information will be stored in the transaction
@@ -136,18 +142,17 @@ static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids,
136142
void
137143
TransactionTreeSetCommitTsData(TransactionIdxid,intnsubxids,
138144
TransactionId*subxids,TimestampTztimestamp,
139-
RepOriginIdnodeid,
140-
boolreplaying_xlog,boolwrite_xlog)
145+
RepOriginIdnodeid,boolwrite_xlog)
141146
{
142147
inti;
143148
TransactionIdheadxid;
144149
TransactionIdnewestXact;
145150

146-
/* We'd better not try to write xlog during replay */
147-
Assert(!(write_xlog&&replaying_xlog));
148-
149-
/* No-op if feature not enabled, unless replaying WAL */
150-
if (!track_commit_timestamp&& !replaying_xlog)
151+
/*
152+
* No-op if the module is not enabled, but allow writes in a standby
153+
* during recovery.
154+
*/
155+
if (!track_commit_timestamp&& !enable_during_recovery)
151156
return;
152157

153158
/*
@@ -534,40 +539,61 @@ ZeroCommitTsPage(int pageno, bool writeXlog)
534539
/*
535540
* This must be called ONCE during postmaster or standalone-backend startup,
536541
* after StartupXLOG has initialized ShmemVariableCache->nextXid.
542+
*
543+
* Caller may choose to enable the feature even when it is turned off in the
544+
* configuration.
537545
*/
538546
void
539-
StartupCommitTs(void)
547+
StartupCommitTs(boolforce_enable)
540548
{
541-
TransactionIdxid=ShmemVariableCache->nextXid;
542-
intpageno=TransactionIdToCTsPage(xid);
543-
544-
if (track_commit_timestamp)
545-
{
546-
ActivateCommitTs();
547-
return;
548-
}
549-
550-
LWLockAcquire(CommitTsControlLock,LW_EXCLUSIVE);
551-
552549
/*
553-
* Initialize our idea of the latest page number.
550+
* If the module is not enabled, there's nothing to do here. The module
551+
* could still be activated from elsewhere.
554552
*/
555-
CommitTsCtl->shared->latest_page_number=pageno;
556-
557-
LWLockRelease(CommitTsControlLock);
553+
if (track_commit_timestamp||force_enable)
554+
ActivateCommitTs();
558555
}
559556

560557
/*
561558
* This must be called ONCE during postmaster or standalone-backend startup,
562-
*when commit timestamp is enabled,after recovery has finished.
559+
* after recovery has finished.
563560
*/
564561
void
565562
CompleteCommitTsInitialization(void)
566563
{
564+
/*
565+
* If the feature is not enabled, turn it off for good. This also removes
566+
* any leftover data.
567+
*/
567568
if (!track_commit_timestamp)
568569
DeactivateCommitTs(true);
569570
}
570571

572+
/*
573+
* Activate or deactivate CommitTs' upon reception of a XLOG_PARAMETER_CHANGE
574+
* XLog record in a standby.
575+
*/
576+
void
577+
CommitTsParameterChange(boolnewvalue,boololdvalue)
578+
{
579+
/*
580+
* If the commit_ts module is disabled in this server and we get word from
581+
* the master server that it is enabled there, activate it so that we can
582+
* replay future WAL records involving it; also mark it as active on
583+
* pg_control. If the old value was already set, we already did this, so
584+
* don't do anything.
585+
*
586+
* If the module is disabled in the master, disable it here too.
587+
*/
588+
if (newvalue)
589+
{
590+
if (!track_commit_timestamp&& !oldvalue)
591+
ActivateCommitTs();
592+
}
593+
elseif (oldvalue)
594+
DeactivateCommitTs(false);
595+
}
596+
571597
/*
572598
* Activate this module whenever necessary.
573599
*This must happen during postmaster or standalong-backend startup,
@@ -584,7 +610,7 @@ CompleteCommitTsInitialization(void)
584610
* running with this module disabled for a while and thus might have skipped
585611
* the normal creation point.
586612
*/
587-
void
613+
staticvoid
588614
ActivateCommitTs(void)
589615
{
590616
TransactionIdxid=ShmemVariableCache->nextXid;
@@ -629,6 +655,9 @@ ActivateCommitTs(void)
629655
Assert(!CommitTsCtl->shared->page_dirty[slotno]);
630656
LWLockRelease(CommitTsControlLock);
631657
}
658+
659+
/* We can now replay xlog records from this module */
660+
enable_during_recovery= true;
632661
}
633662

634663
/*
@@ -641,7 +670,7 @@ ActivateCommitTs(void)
641670
* Resets CommitTs into invalid state to make sure we don't hand back
642671
* possibly-invalid data; also removes segments of old data.
643672
*/
644-
void
673+
staticvoid
645674
DeactivateCommitTs(booldo_wal)
646675
{
647676
TransactionIdxid=ShmemVariableCache->nextXid;
@@ -659,7 +688,18 @@ DeactivateCommitTs(bool do_wal)
659688
ShmemVariableCache->newestCommitTs=InvalidTransactionId;
660689
LWLockRelease(CommitTsLock);
661690

662-
TruncateCommitTs(ReadNewTransactionId(),do_wal);
691+
/*
692+
* Remove *all* files. This is necessary so that there are no leftover
693+
* files; in the case where this feature is later enabled after running
694+
* with it disabled for some time there may be a gap in the file sequence.
695+
* (We can probably tolerate out-of-sequence files, as they are going to
696+
* be overwritten anyway when we wrap around, but it seems better to be
697+
* tidy.)
698+
*/
699+
(void)SlruScanDirectory(CommitTsCtl,SlruScanDirCbDeleteAll,NULL);
700+
701+
/* No longer enabled on recovery */
702+
enable_during_recovery= false;
663703
}
664704

665705
/*
@@ -699,7 +739,7 @@ ExtendCommitTs(TransactionId newestXact)
699739
intpageno;
700740

701741
/* nothing to do if module not enabled */
702-
if (!track_commit_timestamp)
742+
if (!track_commit_timestamp&& !enable_during_recovery)
703743
return;
704744

705745
/*
@@ -916,8 +956,7 @@ commit_ts_redo(XLogReaderState *record)
916956
subxids=NULL;
917957

918958
TransactionTreeSetCommitTsData(setts->mainxid,nsubxids,subxids,
919-
setts->timestamp,setts->nodeid, false,
920-
true);
959+
setts->timestamp,setts->nodeid, true);
921960
if (subxids)
922961
pfree(subxids);
923962
}

‎src/backend/access/transam/twophase.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2131,7 +2131,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
21312131

21322132
TransactionTreeSetCommitTsData(xid,nchildren,children,
21332133
replorigin_session_origin_timestamp,
2134-
replorigin_session_origin, false, false);
2134+
replorigin_session_origin, false);
21352135

21362136
/*
21372137
* We don't currently try to sleep before flush here ... nor is there any

‎src/backend/access/transam/xact.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,8 +1237,7 @@ RecordTransactionCommit(void)
12371237

12381238
TransactionTreeSetCommitTsData(xid,nchildren,children,
12391239
replorigin_session_origin_timestamp,
1240-
replorigin_session_origin,
1241-
false, false);
1240+
replorigin_session_origin, false);
12421241
}
12431242

12441243
/*
@@ -5333,8 +5332,7 @@ xact_redo_commit(xl_xact_parsed_commit *parsed,
53335332

53345333
/* Set the transaction commit timestamp and metadata */
53355334
TransactionTreeSetCommitTsData(xid,parsed->nsubxacts,parsed->subxacts,
5336-
commit_time,origin_id,
5337-
true, false);
5335+
commit_time,origin_id, false);
53385336

53395337
if (standbyState==STANDBY_DISABLED)
53405338
{

‎src/backend/access/transam/xlog.c

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6567,7 +6567,7 @@ StartupXLOG(void)
65676567
* maintained during recovery and need not be started yet.
65686568
*/
65696569
StartupCLOG();
6570-
StartupCommitTs();
6570+
StartupCommitTs(ControlFile->track_commit_timestamp);
65716571
StartupSUBTRANS(oldestActiveXID);
65726572

65736573
/*
@@ -7336,7 +7336,7 @@ StartupXLOG(void)
73367336
if (standbyState==STANDBY_DISABLED)
73377337
{
73387338
StartupCLOG();
7339-
StartupCommitTs();
7339+
StartupCommitTs(false);
73407340
StartupSUBTRANS(oldestActiveXID);
73417341
}
73427342

@@ -9456,25 +9456,9 @@ xlog_redo(XLogReaderState *record)
94569456
ControlFile->minRecoveryPointTLI=ThisTimeLineID;
94579457
}
94589458

9459-
/*
9460-
* Update the commit timestamp tracking. If there was a change it
9461-
* needs to be activated or deactivated accordingly.
9462-
*/
9463-
if (track_commit_timestamp!=xlrec.track_commit_timestamp)
9464-
{
9465-
track_commit_timestamp=xlrec.track_commit_timestamp;
9466-
ControlFile->track_commit_timestamp=track_commit_timestamp;
9467-
if (track_commit_timestamp)
9468-
ActivateCommitTs();
9469-
else
9470-
9471-
/*
9472-
* We can't create a new WAL record here, but that's OK as
9473-
* master did the WAL logging already and we will replay the
9474-
* record from master in case we crash.
9475-
*/
9476-
DeactivateCommitTs(false);
9477-
}
9459+
CommitTsParameterChange(xlrec.track_commit_timestamp,
9460+
ControlFile->track_commit_timestamp);
9461+
ControlFile->track_commit_timestamp=xlrec.track_commit_timestamp;
94789462

94799463
UpdateControlFile();
94809464
LWLockRelease(ControlFileLock);

‎src/include/access/commit_ts.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ extern bool check_track_commit_timestamp(bool *newval, void **extra,
2424

2525
externvoidTransactionTreeSetCommitTsData(TransactionIdxid,intnsubxids,
2626
TransactionId*subxids,TimestampTztimestamp,
27-
RepOriginIdnodeid,
28-
boolreplaying_xlog,boolwrite_xlog);
27+
RepOriginIdnodeid,boolwrite_xlog);
2928
externboolTransactionIdGetCommitTsData(TransactionIdxid,
3029
TimestampTz*ts,RepOriginId*nodeid);
3130
externTransactionIdGetLatestCommitTsData(TimestampTz*ts,
@@ -35,9 +34,8 @@ extern Size CommitTsShmemBuffers(void);
3534
externSizeCommitTsShmemSize(void);
3635
externvoidCommitTsShmemInit(void);
3736
externvoidBootStrapCommitTs(void);
38-
externvoidStartupCommitTs(void);
39-
externvoidActivateCommitTs(void);
40-
externvoidDeactivateCommitTs(booldo_wal);
37+
externvoidStartupCommitTs(boolforce_enable);
38+
externvoidCommitTsParameterChange(boolxlrecvalue,boolpgcontrolvalue);
4139
externvoidCompleteCommitTsInitialization(void);
4240
externvoidShutdownCommitTs(void);
4341
externvoidCheckPointCommitTs(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp