PostgreSQL Source Code git master
Loading...
Searching...
No Matches
commit_ts.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * commit_ts.c
4 * PostgreSQL commit timestamp manager
5 *
6 * This module is a pg_xact-like system that stores the commit timestamp
7 * for each transaction.
8 *
9 * XLOG interactions: this module generates an XLOG record whenever a new
10 * CommitTs page is initialized to zeroes. Other writes of CommitTS come
11 * from recording of transaction commit in xact.c, which generates its own
12 * XLOG records for these events and will re-perform the status update on
13 * redo; so we need make no additional XLOG entry here.
14 *
15 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
16 * Portions Copyright (c) 1994, Regents of the University of California
17 *
18 * src/backend/access/transam/commit_ts.c
19 *
20 *-------------------------------------------------------------------------
21 */
22#include "postgres.h"
23
24#include "access/commit_ts.h"
25#include "access/htup_details.h"
26#include "access/slru.h"
27#include "access/transam.h"
28#include "access/xloginsert.h"
29#include "access/xlogutils.h"
30#include "funcapi.h"
31#include "miscadmin.h"
32#include "storage/shmem.h"
33#include "utils/fmgrprotos.h"
34#include "utils/guc_hooks.h"
35#include "utils/timestamp.h"
36
37/*
38 * Defines for CommitTs page sizes. A page is the same BLCKSZ as is used
39 * everywhere else in Postgres.
40 *
41 * Note: because TransactionIds are 32 bits and wrap around at 0xFFFFFFFF,
42 * CommitTs page numbering also wraps around at
43 * 0xFFFFFFFF/COMMIT_TS_XACTS_PER_PAGE, and CommitTs segment numbering at
44 * 0xFFFFFFFF/COMMIT_TS_XACTS_PER_PAGE/SLRU_PAGES_PER_SEGMENT. We need take no
45 * explicit notice of that fact in this module, except when comparing segment
46 * and page numbers in TruncateCommitTs (see CommitTsPagePrecedes).
47 */
48
49/*
50 * We need 8+2 bytes per xact. Note that enlarging this struct might mean
51 * the largest possible file name is more than 5 chars long; see
52 * SlruScanDirectory.
53 */
59
60#define SizeOfCommitTimestampEntry (offsetof(CommitTimestampEntry, nodeid) + \
61 sizeof(ReplOriginId))
62
63#define COMMIT_TS_XACTS_PER_PAGE \
64 (BLCKSZ / SizeOfCommitTimestampEntry)
65
66
67/*
68 * Although we return an int64 the actual value can't currently exceed
69 * 0xFFFFFFFF/COMMIT_TS_XACTS_PER_PAGE.
70 */
71static inline int64
76
77#define TransactionIdToCTsEntry(xid) \
78 ((xid) % (TransactionId) COMMIT_TS_XACTS_PER_PAGE)
79
80/*
81 * Link to shared-memory data structures for CommitTs control
82 */
84
85#define CommitTsCtl (&CommitTsCtlData)
86
87/*
88 * We keep a cache of the last value set in shared memory.
89 *
90 * This is also good place to keep the activation status. We keep this
91 * separate from the GUC so that the standby can activate the module if the
92 * primary has it active independently of the value of the GUC.
93 *
94 * This is protected by CommitTsLock. In some places, we use commitTsActive
95 * without acquiring the lock; where this happens, a comment explains the
96 * rationale for it.
97 */
104
106
107
108/* GUC variable */
110
111static void SetXidCommitTsInPage(TransactionId xid, int nsubxids,
112 TransactionId *subxids, TimestampTz ts,
113 ReplOriginId nodeid, int64 pageno);
115 ReplOriginId nodeid, int slotno);
116static void error_commit_ts_disabled(void);
118static int commit_ts_errdetail_for_io_error(const void *opaque_data);
119static void ActivateCommitTs(void);
120static void DeactivateCommitTs(void);
121static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXid);
122
123/*
124 * TransactionTreeSetCommitTsData
125 *
126 * Record the final commit timestamp of transaction entries in the commit log
127 * for a transaction and its subtransaction tree, as efficiently as possible.
128 *
129 * xid is the top level transaction id.
130 *
131 * subxids is an array of xids of length nsubxids, representing subtransactions
132 * in the tree of xid. In various cases nsubxids may be zero.
133 * The reason why tracking just the parent xid commit timestamp is not enough
134 * is that the subtrans SLRU does not stay valid across crashes (it's not
135 * permanent) so we need to keep the information about them here. If the
136 * subtrans implementation changes in the future, we might want to revisit the
137 * decision of storing timestamp info for each subxid.
138 */
139void
142 ReplOriginId nodeid)
143{
144 int i;
147
148 /*
149 * No-op if the module is not active.
150 *
151 * An unlocked read here is fine, because in a standby (the only place
152 * where the flag can change in flight) this routine is only called by the
153 * recovery process, which is also the only process which can change the
154 * flag.
155 */
157 return;
158
159 /*
160 * Figure out the latest Xid in this batch: either the last subxid if
161 * there's any, otherwise the parent xid.
162 */
163 if (nsubxids > 0)
164 newestXact = subxids[nsubxids - 1];
165 else
166 newestXact = xid;
167
168 /*
169 * We split the xids to set the timestamp to in groups belonging to the
170 * same SLRU page; the first element in each such set is its head. The
171 * first group has the main XID as the head; subsequent sets use the first
172 * subxid not on the previous page as head. This way, we only have to
173 * lock/modify each SLRU page once.
174 */
175 headxid = xid;
176 i = 0;
177 for (;;)
178 {
180 int j;
181
182 for (j = i; j < nsubxids; j++)
183 {
184 if (TransactionIdToCTsPage(subxids[j]) != pageno)
185 break;
186 }
187 /* subxids[i..j] are on the same page as the head */
188
189 SetXidCommitTsInPage(headxid, j - i, subxids + i, timestamp, nodeid,
190 pageno);
191
192 /* if we wrote out all subxids, we're done. */
193 if (j >= nsubxids)
194 break;
195
196 /*
197 * Set the new head and skip over it, as well as over the subxids we
198 * just wrote.
199 */
200 headxid = subxids[j];
201 i = j + 1;
202 }
203
204 /* update the cached value in shared memory */
209
210 /* and move forwards our endpoint, if needed */
214}
215
216/*
217 * Record the commit timestamp of transaction entries in the commit log for all
218 * entries on a single page. Atomic only on this page.
219 */
220static void
222 TransactionId *subxids, TimestampTz ts,
223 ReplOriginId nodeid, int64 pageno)
224{
225 LWLock *lock = SimpleLruGetBankLock(CommitTsCtl, pageno);
226 int slotno;
227 int i;
228
230
231 slotno = SimpleLruReadPage(CommitTsCtl, pageno, true, &xid);
232
233 TransactionIdSetCommitTs(xid, ts, nodeid, slotno);
234 for (i = 0; i < nsubxids; i++)
235 TransactionIdSetCommitTs(subxids[i], ts, nodeid, slotno);
236
237 CommitTsCtl->shared->page_dirty[slotno] = true;
238
239 LWLockRelease(lock);
240}
241
242/*
243 * Sets the commit timestamp of a single transaction.
244 *
245 * Caller must hold the correct SLRU bank lock, will be held at exit
246 */
247static void
249 ReplOriginId nodeid, int slotno)
250{
253
255
256 entry.time = ts;
257 entry.nodeid = nodeid;
258
259 memcpy(CommitTsCtl->shared->page_buffer[slotno] +
262}
263
264/*
265 * Interrogate the commit timestamp of a transaction.
266 *
267 * The return value indicates whether a commit timestamp record was found for
268 * the given xid. The timestamp value is returned in *ts (which may not be
269 * null), and the origin node for the Xid is returned in *nodeid, if it's not
270 * null.
271 */
272bool
274 ReplOriginId *nodeid)
275{
276 int64 pageno = TransactionIdToCTsPage(xid);
278 int slotno;
280 TransactionId oldestCommitTsXid;
281 TransactionId newestCommitTsXid;
282
283 if (!TransactionIdIsValid(xid))
286 errmsg("cannot retrieve commit timestamp for transaction %u", xid)));
287 else if (!TransactionIdIsNormal(xid))
288 {
289 /* frozen and bootstrap xids are always committed far in the past */
290 *ts = 0;
291 if (nodeid)
292 *nodeid = 0;
293 return false;
294 }
295
297
298 /* Error if module not enabled */
301
302 /*
303 * If we're asked for the cached value, return that. Otherwise, fall
304 * through to read from SLRU.
305 */
306 if (commitTsShared->xidLastCommit == xid)
307 {
309 if (nodeid)
311
313 return *ts != 0;
314 }
315
316 oldestCommitTsXid = TransamVariables->oldestCommitTsXid;
317 newestCommitTsXid = TransamVariables->newestCommitTsXid;
318 /* neither is invalid, or both are */
319 Assert(TransactionIdIsValid(oldestCommitTsXid) == TransactionIdIsValid(newestCommitTsXid));
321
322 /*
323 * Return empty if the requested value is outside our valid range.
324 */
325 if (!TransactionIdIsValid(oldestCommitTsXid) ||
326 TransactionIdPrecedes(xid, oldestCommitTsXid) ||
327 TransactionIdPrecedes(newestCommitTsXid, xid))
328 {
329 *ts = 0;
330 if (nodeid)
331 *nodeid = InvalidReplOriginId;
332 return false;
333 }
334
335 /* lock is acquired by SimpleLruReadPage_ReadOnly */
337 memcpy(&entry,
338 CommitTsCtl->shared->page_buffer[slotno] +
341
342 *ts = entry.time;
343 if (nodeid)
344 *nodeid = entry.nodeid;
345
347 return *ts != 0;
348}
349
350/*
351 * Return the Xid of the latest committed transaction. (As far as this module
352 * is concerned, anyway; it's up to the caller to ensure the value is useful
353 * for its purposes.)
354 *
355 * ts and nodeid are filled with the corresponding data; they can be passed
356 * as NULL if not wanted.
357 */
360{
361 TransactionId xid;
362
364
365 /* Error if module not enabled */
368
370 if (ts)
372 if (nodeid)
375
376 return xid;
377}
378
379static void
381{
384 errmsg("could not get commit timestamp data"),
386 errhint("Make sure the configuration parameter \"%s\" is set on the primary server.",
387 "track_commit_timestamp") :
388 errhint("Make sure the configuration parameter \"%s\" is set.",
389 "track_commit_timestamp")));
390}
391
392/*
393 * SQL-callable wrapper to obtain commit time of a transaction
394 */
395Datum
397{
399 TimestampTz ts;
400 bool found;
401
402 found = TransactionIdGetCommitTsData(xid, &ts, NULL);
403
404 if (!found)
406
408}
409
410
411/*
412 * pg_last_committed_xact
413 *
414 * SQL-callable wrapper to obtain some information about the latest
415 * committed transaction: transaction ID, timestamp and replication
416 * origin.
417 */
418Datum
420{
421 TransactionId xid;
422 ReplOriginId nodeid;
423 TimestampTz ts;
424 Datum values[3];
425 bool nulls[3];
426 TupleDesc tupdesc;
427 HeapTuple htup;
428
429 /* and construct a tuple with our data */
430 xid = GetLatestCommitTsData(&ts, &nodeid);
431
432 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
433 elog(ERROR, "return type must be a row type");
434
435 if (!TransactionIdIsNormal(xid))
436 {
437 memset(nulls, true, sizeof(nulls));
438 }
439 else
440 {
442 nulls[0] = false;
443
445 nulls[1] = false;
446
447 values[2] = ObjectIdGetDatum((Oid) nodeid);
448 nulls[2] = false;
449 }
450
451 htup = heap_form_tuple(tupdesc, values, nulls);
452
454}
455
456/*
457 * pg_xact_commit_timestamp_origin
458 *
459 * SQL-callable wrapper to obtain commit timestamp and replication origin
460 * of a given transaction.
461 */
462Datum
464{
466 ReplOriginId nodeid;
467 TimestampTz ts;
468 Datum values[2];
469 bool nulls[2];
470 TupleDesc tupdesc;
471 HeapTuple htup;
472 bool found;
473
474 found = TransactionIdGetCommitTsData(xid, &ts, &nodeid);
475
476 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
477 elog(ERROR, "return type must be a row type");
478
479 if (!found)
480 {
481 memset(nulls, true, sizeof(nulls));
482 }
483 else
484 {
486 nulls[0] = false;
487
488 values[1] = ObjectIdGetDatum((Oid) nodeid);
489 nulls[1] = false;
490 }
491
492 htup = heap_form_tuple(tupdesc, values, nulls);
493
495}
496
497/*
498 * Number of shared CommitTS buffers.
499 *
500 * If asked to autotune, use 2MB for every 1GB of shared buffers, up to 8MB.
501 * Otherwise just cap the configured amount to be between 16 and the maximum
502 * allowed.
503 */
504static int
506{
507 /* auto-tune based on shared buffers */
509 return SimpleLruAutotuneBuffers(512, 1024);
510
512}
513
514/*
515 * Shared memory sizing for CommitTs
516 */
517Size
523
524/*
525 * Initialize CommitTs at system startup (postmaster start or standalone
526 * backend)
527 */
528void
530{
531 bool found;
532
533 /* If auto-tuning is requested, now is the time to do it */
535 {
536 char buf[32];
537
538 snprintf(buf, sizeof(buf), "%d", CommitTsShmemBuffers());
539 SetConfigOption("commit_timestamp_buffers", buf, PGC_POSTMASTER,
541
542 /*
543 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
544 * However, if the DBA explicitly set commit_timestamp_buffers = 0 in
545 * the config file, then PGC_S_DYNAMIC_DEFAULT will fail to override
546 * that and we must force the matter with PGC_S_OVERRIDE.
547 */
548 if (commit_timestamp_buffers == 0) /* failed to apply it? */
549 SetConfigOption("commit_timestamp_buffers", buf, PGC_POSTMASTER,
551 }
553
554 CommitTsCtl->PagePrecedes = CommitTsPagePrecedes;
555 CommitTsCtl->errdetail_for_io_error = commit_ts_errdetail_for_io_error;
556 SimpleLruInit(CommitTsCtl, "commit_timestamp", CommitTsShmemBuffers(), 0,
557 "pg_commit_ts", LWTRANCHE_COMMITTS_BUFFER,
560 false);
562
563 commitTsShared = ShmemInitStruct("CommitTs shared",
564 sizeof(CommitTimestampShared),
565 &found);
566
568 {
569 Assert(!found);
570
575 }
576 else
577 Assert(found);
578}
579
580/*
581 * GUC check_hook for commit_timestamp_buffers
582 */
583bool
585{
586 return check_slru_buffers("commit_timestamp_buffers", newval);
587}
588
589/*
590 * This function must be called ONCE on system install.
591 *
592 * (The CommitTs directory is assumed to have been created by initdb, and
593 * CommitTsShmemInit must have been called already.)
594 */
595void
597{
598 /*
599 * Nothing to do here at present, unlike most other SLRU modules; segments
600 * are created when the server is started with this module enabled. See
601 * ActivateCommitTs.
602 */
603}
604
605/*
606 * This must be called ONCE during postmaster or standalone-backend startup,
607 * after StartupXLOG has initialized TransamVariables->nextXid.
608 */
609void
611{
613}
614
615/*
616 * This must be called ONCE during postmaster or standalone-backend startup,
617 * after recovery has finished.
618 */
619void
621{
622 /*
623 * If the feature is not enabled, turn it off for good. This also removes
624 * any leftover data.
625 *
626 * Conversely, we activate the module if the feature is enabled. This is
627 * necessary for primary and standby as the activation depends on the
628 * control file contents at the beginning of recovery or when a
629 * XLOG_PARAMETER_CHANGE is replayed.
630 */
633 else
635}
636
637/*
638 * Activate or deactivate CommitTs' upon reception of a XLOG_PARAMETER_CHANGE
639 * XLog record during recovery.
640 */
641void
643{
644 /*
645 * If the commit_ts module is disabled in this server and we get word from
646 * the primary server that it is enabled there, activate it so that we can
647 * replay future WAL records involving it; also mark it as active on
648 * pg_control. If the old value was already set, we already did this, so
649 * don't do anything.
650 *
651 * If the module is disabled in the primary, disable it here too, unless
652 * the module is enabled locally.
653 *
654 * Note this only runs in the recovery process, so an unlocked read is
655 * fine.
656 */
657 if (newvalue)
658 {
661 }
664}
665
666/*
667 * Activate this module whenever necessary.
668 * This must happen during postmaster or standalone-backend startup,
669 * or during WAL replay anytime the track_commit_timestamp setting is
670 * changed in the primary.
671 *
672 * The reason why this SLRU needs separate activation/deactivation functions is
673 * that it can be enabled/disabled during start and the activation/deactivation
674 * on the primary is propagated to the standby via replay. Other SLRUs don't
675 * have this property and they can be just initialized during normal startup.
676 *
677 * This is in charge of creating the currently active segment, if it's not
678 * already there. The reason for this is that the server might have been
679 * running with this module disabled for a while and thus might have skipped
680 * the normal creation point.
681 */
682static void
684{
685 TransactionId xid;
686 int64 pageno;
687
688 /*
689 * During bootstrap, we should not register commit timestamps so skip the
690 * activation in this case.
691 */
693 return;
694
695 /* If we've done this already, there's nothing to do */
698 {
700 return;
701 }
703
705 pageno = TransactionIdToCTsPage(xid);
706
707 /*
708 * Re-Initialize our idea of the latest page number.
709 */
710 pg_atomic_write_u64(&CommitTsCtl->shared->latest_page_number, pageno);
711
712 /*
713 * If CommitTs is enabled, but it wasn't in the previous server run, we
714 * need to set the oldest and newest values to the next Xid; that way, we
715 * will not try to read data that might not have been set.
716 *
717 * XXX does this have a problem if a server is started with commitTs
718 * enabled, then started with commitTs disabled, then restarted with it
719 * enabled again? It doesn't look like it does, because there should be a
720 * checkpoint that sets the value to InvalidTransactionId at end of
721 * recovery; and so any chance of injecting new transactions without
722 * CommitTs values would occur after the oldestCommitTsXid has been set to
723 * Invalid temporarily.
724 */
727 {
730 }
732
733 /* Create the current segment file, if necessary */
736
737 /* Change the activation status in shared memory. */
741}
742
743/*
744 * Deactivate this module.
745 *
746 * This must be called when the track_commit_timestamp parameter is turned off.
747 * This happens during postmaster or standalone-backend startup, or during WAL
748 * replay.
749 *
750 * Resets CommitTs into invalid state to make sure we don't hand back
751 * possibly-invalid data; also removes segments of old data.
752 */
753static void
755{
756 /*
757 * Cleanup the status in the shared memory.
758 *
759 * We reset everything in the commitTsShared record to prevent user from
760 * getting confusing data about last committed transaction on the standby
761 * when the module was activated repeatedly on the primary.
762 */
764
769
772
773 /*
774 * Remove *all* files. This is necessary so that there are no leftover
775 * files; in the case where this feature is later enabled after running
776 * with it disabled for some time there may be a gap in the file sequence.
777 * (We can probably tolerate out-of-sequence files, as they are going to
778 * be overwritten anyway when we wrap around, but it seems better to be
779 * tidy.)
780 *
781 * Note that we do this with CommitTsLock acquired in exclusive mode. This
782 * is very heavy-handed, but since this routine can only be called in the
783 * replica and should happen very rarely, we don't worry too much about
784 * it. Note also that no process should be consulting this SLRU if we
785 * have just deactivated it.
786 */
788
790}
791
792/*
793 * Perform a checkpoint --- either during shutdown, or on-the-fly
794 */
795void
797{
798 /*
799 * Write dirty CommitTs pages to disk. This may result in sync requests
800 * queued for later handling by ProcessSyncRequests(), as part of the
801 * checkpoint.
802 */
804}
805
806/*
807 * Make sure that CommitTs has room for a newly-allocated XID.
808 *
809 * NB: this is called while holding XidGenLock. We want it to be very fast
810 * most of the time; even when it's not so fast, no actual I/O need happen
811 * unless we're forced to write out a dirty CommitTs or xlog page to make room
812 * in shared memory.
813 *
814 * NB: the current implementation relies on track_commit_timestamp being
815 * PGC_POSTMASTER.
816 */
817void
819{
820 int64 pageno;
821 LWLock *lock;
822
823 /*
824 * Nothing to do if module not enabled. Note we do an unlocked read of
825 * the flag here, which is okay because this routine is only called from
826 * GetNewTransactionId, which is never called in a standby.
827 */
830 return;
831
832 /*
833 * No work except at first XID of a page. But beware: just after
834 * wraparound, the first XID of page zero is FirstNormalTransactionId.
835 */
838 return;
839
841
842 lock = SimpleLruGetBankLock(CommitTsCtl, pageno);
843
845
846 /* Zero the page ... */
848
849 /* and make a WAL entry about that, unless we're in REDO */
850 if (!InRecovery)
852
853 LWLockRelease(lock);
854}
855
856/*
857 * Remove all CommitTs segments before the one holding the passed
858 * transaction ID.
859 *
860 * Note that we don't need to flush XLOG here.
861 */
862void
864{
866
867 /*
868 * The cutoff point is the start of the segment containing oldestXact. We
869 * pass the *page* containing oldestXact to SimpleLruTruncate.
870 */
872
873 /* Check to see if there's any files that could be removed */
875 &cutoffPage))
876 return; /* nothing to remove */
877
878 /* Write XLOG record */
879 WriteTruncateXlogRec(cutoffPage, oldestXact);
880
881 /* Now we can remove the old CommitTs segment(s) */
883}
884
885/*
886 * Set the limit values between which commit TS can be consulted.
887 */
888void
890{
891 /*
892 * Be careful not to overwrite values that are either further into the
893 * "future" or signal a disabled committs.
894 */
897 {
902 }
903 else
904 {
908 }
910}
911
912/*
913 * Move forwards the oldest commitTS value that can be consulted
914 */
915void
924
925
926/*
927 * Decide whether a commitTS page number is "older" for truncation purposes.
928 * Analogous to CLOGPagePrecedes().
929 *
930 * At default BLCKSZ, (1 << 31) % COMMIT_TS_XACTS_PER_PAGE == 128. This
931 * introduces differences compared to CLOG and the other SLRUs having (1 <<
932 * 31) % per_page == 0. This function never tests exactly
933 * TransactionIdPrecedes(x-2^31, x). When the system reaches xidStopLimit,
934 * there are two possible counts of page boundaries between oldestXact and the
935 * latest XID assigned, depending on whether oldestXact is within the first
936 * 128 entries of its page. Since this function doesn't know the location of
937 * oldestXact within page2, it returns false for one page that actually is
938 * expendable. This is a wider (yet still negligible) version of the
939 * truncation opportunity that CLOGPagePrecedes() cannot recognize.
940 *
941 * For the sake of a worked example, number entries with decimal values such
942 * that page1==1 entries range from 1.0 to 1.999. Let N+0.15 be the number of
943 * pages that 2^31 entries will span (N is an integer). If oldestXact=N+2.1,
944 * then the final safe XID assignment leaves newestXact=1.95. We keep page 2,
945 * because entry=2.85 is the border that toggles whether entries precede the
946 * last entry of the oldestXact page. While page 2 is expendable at
947 * oldestXact=N+2.1, it would be precious at oldestXact=N+2.9.
948 */
949static bool
963
964static int
966{
967 TransactionId xid = *(const TransactionId *) opaque_data;
968
969 return errdetail("Could not access commit timestamp of transaction %u.", xid);
970}
971
972/*
973 * Write a TRUNCATE xlog record
974 */
975static void
987
988/*
989 * CommitTS resource manager's routines
990 */
991void
993{
994 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
995
996 /* Backup blocks are not used in commit_ts records */
998
999 if (info == COMMIT_TS_ZEROPAGE)
1000 {
1001 int64 pageno;
1002
1003 memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
1005 }
1006 else if (info == COMMIT_TS_TRUNCATE)
1007 {
1009
1010 AdvanceOldestCommitTsXid(trunc->oldestXid);
1011
1012 /*
1013 * During XLOG replay, latest_page_number isn't set up yet; insert a
1014 * suitable value to bypass the sanity test in SimpleLruTruncate.
1015 */
1016 pg_atomic_write_u64(&CommitTsCtl->shared->latest_page_number,
1017 trunc->pageno);
1018
1020 }
1021 else
1022 elog(PANIC, "commit_ts_redo: unknown op code %u", info);
1023}
1024
1025/*
1026 * Entrypoint for sync.c to sync commit_ts files.
1027 */
1028int
1029committssyncfiletag(const FileTag *ftag, char *path)
1030{
1031 return SlruSyncFileTag(CommitTsCtl, ftag, path);
1032}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:485
static Datum values[MAXATTR]
Definition bootstrap.c:188
#define Min(x, y)
Definition c.h:1093
uint8_t uint8
Definition c.h:616
#define Max(x, y)
Definition c.h:1087
#define Assert(condition)
Definition c.h:945
int64_t int64
Definition c.h:615
uint32 TransactionId
Definition c.h:738
size_t Size
Definition c.h:691
static void SetXidCommitTsInPage(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz ts, ReplOriginId nodeid, int64 pageno)
Definition commit_ts.c:221
void StartupCommitTs(void)
Definition commit_ts.c:610
static SlruCtlData CommitTsCtlData
Definition commit_ts.c:83
Datum pg_xact_commit_timestamp_origin(PG_FUNCTION_ARGS)
Definition commit_ts.c:463
static int commit_ts_errdetail_for_io_error(const void *opaque_data)
Definition commit_ts.c:965
Datum pg_last_committed_xact(PG_FUNCTION_ARGS)
Definition commit_ts.c:419
void CommitTsParameterChange(bool newvalue, bool oldvalue)
Definition commit_ts.c:642
#define COMMIT_TS_XACTS_PER_PAGE
Definition commit_ts.c:63
#define TransactionIdToCTsEntry(xid)
Definition commit_ts.c:77
static void DeactivateCommitTs(void)
Definition commit_ts.c:754
Size CommitTsShmemSize(void)
Definition commit_ts.c:518
bool track_commit_timestamp
Definition commit_ts.c:109
void AdvanceOldestCommitTsXid(TransactionId oldestXact)
Definition commit_ts.c:916
static CommitTimestampShared * commitTsShared
Definition commit_ts.c:105
int committssyncfiletag(const FileTag *ftag, char *path)
Definition commit_ts.c:1029
void CompleteCommitTsInitialization(void)
Definition commit_ts.c:620
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, ReplOriginId nodeid)
Definition commit_ts.c:140
bool check_commit_ts_buffers(int *newval, void **extra, GucSource source)
Definition commit_ts.c:584
static void ActivateCommitTs(void)
Definition commit_ts.c:683
static int64 TransactionIdToCTsPage(TransactionId xid)
Definition commit_ts.c:72
void TruncateCommitTs(TransactionId oldestXact)
Definition commit_ts.c:863
void commit_ts_redo(XLogReaderState *record)
Definition commit_ts.c:992
Datum pg_xact_commit_timestamp(PG_FUNCTION_ARGS)
Definition commit_ts.c:396
static int CommitTsShmemBuffers(void)
Definition commit_ts.c:505
static void error_commit_ts_disabled(void)
Definition commit_ts.c:380
static bool CommitTsPagePrecedes(int64 page1, int64 page2)
Definition commit_ts.c:950
#define SizeOfCommitTimestampEntry
Definition commit_ts.c:60
void BootStrapCommitTs(void)
Definition commit_ts.c:596
void CommitTsShmemInit(void)
Definition commit_ts.c:529
void SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
Definition commit_ts.c:889
#define CommitTsCtl
Definition commit_ts.c:85
TransactionId GetLatestCommitTsData(TimestampTz *ts, ReplOriginId *nodeid)
Definition commit_ts.c:359
void ExtendCommitTs(TransactionId newestXact)
Definition commit_ts.c:818
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, ReplOriginId *nodeid)
Definition commit_ts.c:273
static void TransactionIdSetCommitTs(TransactionId xid, TimestampTz ts, ReplOriginId nodeid, int slotno)
Definition commit_ts.c:248
static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXid)
Definition commit_ts.c:976
void CheckPointCommitTs(void)
Definition commit_ts.c:796
#define COMMIT_TS_ZEROPAGE
Definition commit_ts.h:46
#define SizeOfCommitTsTruncate
Definition commit_ts.h:55
#define COMMIT_TS_TRUNCATE
Definition commit_ts.h:47
int64 TimestampTz
Definition timestamp.h:39
#define TIMESTAMP_NOBEGIN(j)
Definition timestamp.h:159
int errcode(int sqlerrcode)
Definition elog.c:874
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define PANIC
Definition elog.h:42
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_GETARG_TRANSACTIONID(n)
Definition fmgr.h:280
#define PG_RETURN_DATUM(x)
Definition fmgr.h:354
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition funcapi.h:149
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition funcapi.h:230
bool IsUnderPostmaster
Definition globals.c:120
int commit_timestamp_buffers
Definition globals.c:161
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition guc.c:4228
#define newval
GucSource
Definition guc.h:112
@ PGC_S_DYNAMIC_DEFAULT
Definition guc.h:114
@ PGC_S_OVERRIDE
Definition guc.h:123
@ PGC_POSTMASTER
Definition guc.h:74
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
int j
Definition isn.c:78
int i
Definition isn.c:77
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1177
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1794
@ LW_SHARED
Definition lwlock.h:113
@ LW_EXCLUSIVE
Definition lwlock.h:112
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
static char * errmsg
#define InvalidReplOriginId
Definition origin.h:33
static rewind_source * source
Definition pg_rewind.c:89
static char buf[DEFAULT_XLOG_SEG_SIZE]
int64 timestamp
#define snprintf
Definition port.h:260
static Datum TransactionIdGetDatum(TransactionId X)
Definition postgres.h:292
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition shmem.c:381
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, const char *subdir, int buffer_tranche_id, int bank_tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition slru.c:254
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition slru.c:1355
int SimpleLruAutotuneBuffers(int divisor, int max)
Definition slru.c:233
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, const void *opaque_data)
Definition slru.c:533
bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int64 pageno)
Definition slru.c:778
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition slru.c:1824
bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition slru.c:1777
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition slru.c:1864
int SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
Definition slru.c:380
void SimpleLruZeroAndWritePage(SlruCtl ctl, int64 pageno)
Definition slru.c:449
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition slru.c:1441
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, const void *opaque_data)
Definition slru.c:637
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition slru.c:200
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition slru.c:1745
bool check_slru_buffers(const char *name, int *newval)
Definition slru.c:360
static LWLock * SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
Definition slru.h:171
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition slru.h:196
#define SLRU_MAX_ALLOWED_BUFFERS
Definition slru.h:25
TimestampTz time
Definition commit_ts.c:56
ReplOriginId nodeid
Definition commit_ts.c:57
CommitTimestampEntry dataLastCommit
Definition commit_ts.c:101
TransactionId xidLastCommit
Definition commit_ts.c:100
Definition sync.h:51
TransactionId oldestCommitTsXid
Definition transam.h:232
TransactionId newestCommitTsXid
Definition transam.h:233
FullTransactionId nextXid
Definition transam.h:220
@ SYNC_HANDLER_COMMIT_TS
Definition sync.h:39
static TransactionId ReadNextTransactionId(void)
Definition transam.h:377
#define InvalidTransactionId
Definition transam.h:31
#define TransactionIdEquals(id1, id2)
Definition transam.h:43
#define XidFromFullTransactionId(x)
Definition transam.h:48
#define FirstNormalTransactionId
Definition transam.h:34
#define TransactionIdIsValid(xid)
Definition transam.h:41
#define TransactionIdIsNormal(xid)
Definition transam.h:42
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition transam.h:263
static Datum TimestampTzGetDatum(TimestampTz X)
Definition timestamp.h:52
#define PG_RETURN_TIMESTAMPTZ(x)
Definition timestamp.h:68
TransamVariablesData * TransamVariables
Definition varsup.c:34
bool RecoveryInProgress(void)
Definition xlog.c:6444
uint16 ReplOriginId
Definition xlogdefs.h:69
XLogRecPtr XLogSimpleInsertInt64(RmgrId rmid, uint8 info, int64 value)
Definition xloginsert.c:544
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition xloginsert.c:479
void XLogRegisterData(const void *data, uint32 len)
Definition xloginsert.c:369
void XLogBeginInsert(void)
Definition xloginsert.c:153
#define XLogRecGetInfo(decoder)
Definition xlogreader.h:409
#define XLogRecGetData(decoder)
Definition xlogreader.h:414
#define XLogRecHasAnyBlockRefs(decoder)
Definition xlogreader.h:416
bool InRecovery
Definition xlogutils.c:50