1 /*-------------------------------------------------------------------------
4 * Two-phase commit support functions.
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/backend/access/transam/twophase.c,v 1.40 2008/03/17 02:18:55 tgl Exp $
13 * Each global transaction is associated with a global transaction
14 * identifier (GID). The client assigns a GID to a postgres
15 * transaction with the PREPARE TRANSACTION command.
17 * We keep all active global transactions in a shared memory array.
18 * When the PREPARE TRANSACTION command is issued, the GID is
19 * reserved for the transaction in the array. This is done before
20 * a WAL entry is made, because the reservation checks for duplicate
21 * GIDs and aborts the transaction if there already is a global
22 * transaction in prepared state with the same GID.
24 * A global transaction (gxact) also has a dummy PGPROC that is entered
25 * into the ProcArray array; this is what keeps the XID considered
26 * running by TransactionIdIsInProgress. It is also convenient as a
27 * PGPROC to hook the gxact's locks to.
29 * In order to survive crashes and shutdowns, all prepared
30 * transactions must be stored in permanent storage. This includes
31 * locking information, pending notifications etc. All that state
32 * information is written to the per-transaction state file in
33 * the pg_twophase directory.
35 *-------------------------------------------------------------------------
41 #include <sys/types.h>
45 #include "access/heapam.h"
46 #include "access/subtrans.h"
47 #include "access/transam.h"
48 #include "access/twophase.h"
49 #include "access/twophase_rmgr.h"
50 #include "access/xact.h"
51 #include "catalog/pg_type.h"
53 #include "miscadmin.h"
55 #include "storage/fd.h"
56 #include "storage/procarray.h"
57 #include "storage/smgr.h"
58 #include "utils/builtins.h"
62 * Directory where Two-phase commit files reside within PGDATA
64 #define TWOPHASE_DIR "pg_twophase"
66 /* GUC variable, can't be changed after startup */
67 int max_prepared_xacts = 5;
70 * This struct describes one global transaction that is in prepared state
71 * or attempting to become prepared.
73 * The first component of the struct is a dummy PGPROC that is inserted
74 * into the global ProcArray so that the transaction appears to still be
75 * running and holding locks. It must be first because we cast pointers
76 * to PGPROC and pointers to GlobalTransactionData back and forth.
78 * The lifecycle of a global transaction is:
80 * 1. After checking that the requested GID is not in use, set up an
81 * entry in the TwoPhaseState->prepXacts array with the correct XID and GID,
82 * with locking_xid = my own XID and valid = false.
84 * 2. After successfully completing prepare, set valid = true and enter the
85 * contained PGPROC into the global ProcArray.
87 * 3. To begin COMMIT PREPARED or ROLLBACK PREPARED, check that the entry
88 * is valid and its locking_xid is no longer active, then store my current
89 * XID into locking_xid. This prevents concurrent attempts to commit or
90 * rollback the same prepared xact.
92 * 4. On completion of COMMIT PREPARED or ROLLBACK PREPARED, remove the entry
93 * from the ProcArray and the TwoPhaseState->prepXacts array and return it to
96 * Note that if the preparing transaction fails between steps 1 and 2, the
97 * entry will remain in prepXacts until recycled. We can detect recyclable
98 * entries by checking for valid = false and locking_xid no longer active.
100 * typedef struct GlobalTransactionData *GlobalTransaction appears in
105 typedef struct GlobalTransactionData
107 PGPROC proc; /* dummy proc */
108 TimestampTz prepared_at; /* time of preparation */
109 XLogRecPtr prepare_lsn; /* XLOG offset of prepare record */
110 Oid owner; /* ID of user that executed the xact */
111 TransactionId locking_xid; /* top-level XID of backend working on xact */
112 bool valid; /* TRUE if fully prepared */
113 char gid[GIDSIZE]; /* The GID assigned to the prepared xact */
114 } GlobalTransactionData;
117 * Two Phase Commit shared state. Access to this struct is protected
118 * by TwoPhaseStateLock.
120 typedef struct TwoPhaseStateData
122 /* Head of linked list of free GlobalTransactionData structs */
123 SHMEM_OFFSET freeGXacts;
125 /* Number of valid prepXacts entries. */
129 * There are max_prepared_xacts items in this array, but C wants a
132 GlobalTransaction prepXacts[1]; /* VARIABLE LENGTH ARRAY */
133 } TwoPhaseStateData; /* VARIABLE LENGTH STRUCT */
135 static TwoPhaseStateData *TwoPhaseState;
138 static void RecordTransactionCommitPrepared(TransactionId xid,
140 TransactionId *children,
143 static void RecordTransactionAbortPrepared(TransactionId xid,
145 TransactionId *children,
148 static void ProcessRecords(char *bufptr, TransactionId xid,
149 const TwoPhaseCallback callbacks[]);
153 * Initialization of shared memory
156 TwoPhaseShmemSize(void)
160 /* Need the fixed struct, the array of pointers, and the GTD structs */
161 size = offsetof(TwoPhaseStateData, prepXacts);
162 size = add_size(size, mul_size(max_prepared_xacts,
163 sizeof(GlobalTransaction)));
164 size = MAXALIGN(size);
165 size = add_size(size, mul_size(max_prepared_xacts,
166 sizeof(GlobalTransactionData)));
172 TwoPhaseShmemInit(void)
176 TwoPhaseState = ShmemInitStruct("Prepared Transaction Table",
179 if (!IsUnderPostmaster)
181 GlobalTransaction gxacts;
185 TwoPhaseState->freeGXacts = INVALID_OFFSET;
186 TwoPhaseState->numPrepXacts = 0;
189 * Initialize the linked list of free GlobalTransactionData structs
191 gxacts = (GlobalTransaction)
192 ((char *) TwoPhaseState +
193 MAXALIGN(offsetof(TwoPhaseStateData, prepXacts) +
194 sizeof(GlobalTransaction) * max_prepared_xacts));
195 for (i = 0; i < max_prepared_xacts; i++)
197 gxacts[i].proc.links.next = TwoPhaseState->freeGXacts;
198 TwoPhaseState->freeGXacts = MAKE_OFFSET(&gxacts[i]);
208 * Reserve the GID for the given transaction.
210 * Internally, this creates a gxact struct and puts it into the active array.
211 * NOTE: this is also used when reloading a gxact after a crash; so avoid
212 * assuming that we can use very much backend context.
215 MarkAsPreparing(TransactionId xid, const char *gid,
216 TimestampTz prepared_at, Oid owner, Oid databaseid)
218 GlobalTransaction gxact;
221 if (strlen(gid) >= GIDSIZE)
223 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
224 errmsg("transaction identifier \"%s\" is too long",
227 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
230 * First, find and recycle any gxacts that failed during prepare. We do
231 * this partly to ensure we don't mistakenly say their GIDs are still
232 * reserved, and partly so we don't fail on out-of-slots unnecessarily.
234 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
236 gxact = TwoPhaseState->prepXacts[i];
237 if (!gxact->valid && !TransactionIdIsActive(gxact->locking_xid))
239 /* It's dead Jim ... remove from the active array */
240 TwoPhaseState->numPrepXacts--;
241 TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
242 /* and put it back in the freelist */
243 gxact->proc.links.next = TwoPhaseState->freeGXacts;
244 TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
245 /* Back up index count too, so we don't miss scanning one */
250 /* Check for conflicting GID */
251 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
253 gxact = TwoPhaseState->prepXacts[i];
254 if (strcmp(gxact->gid, gid) == 0)
257 (errcode(ERRCODE_DUPLICATE_OBJECT),
258 errmsg("transaction identifier \"%s\" is already in use",
263 /* Get a free gxact from the freelist */
264 if (TwoPhaseState->freeGXacts == INVALID_OFFSET)
266 (errcode(ERRCODE_OUT_OF_MEMORY),
267 errmsg("maximum number of prepared transactions reached"),
268 errhint("Increase max_prepared_transactions (currently %d).",
269 max_prepared_xacts)));
270 gxact = (GlobalTransaction) MAKE_PTR(TwoPhaseState->freeGXacts);
271 TwoPhaseState->freeGXacts = gxact->proc.links.next;
274 MemSet(&gxact->proc, 0, sizeof(PGPROC));
275 SHMQueueElemInit(&(gxact->proc.links));
276 gxact->proc.waitStatus = STATUS_OK;
277 /* We set up the gxact's VXID as InvalidBackendId/XID */
278 gxact->proc.lxid = (LocalTransactionId) xid;
279 gxact->proc.xid = xid;
280 gxact->proc.xmin = InvalidTransactionId;
282 gxact->proc.backendId = InvalidBackendId;
283 gxact->proc.databaseId = databaseid;
284 gxact->proc.roleId = owner;
285 gxact->proc.inCommit = false;
286 gxact->proc.vacuumFlags = 0;
287 gxact->proc.lwWaiting = false;
288 gxact->proc.lwExclusive = false;
289 gxact->proc.lwWaitLink = NULL;
290 gxact->proc.waitLock = NULL;
291 gxact->proc.waitProcLock = NULL;
292 for (i = 0; i < NUM_LOCK_PARTITIONS; i++)
293 SHMQueueInit(&(gxact->proc.myProcLocks[i]));
294 /* subxid data must be filled later by GXactLoadSubxactData */
295 gxact->proc.subxids.overflowed = false;
296 gxact->proc.subxids.nxids = 0;
298 gxact->prepared_at = prepared_at;
299 /* initialize LSN to 0 (start of WAL) */
300 gxact->prepare_lsn.xlogid = 0;
301 gxact->prepare_lsn.xrecoff = 0;
302 gxact->owner = owner;
303 gxact->locking_xid = xid;
304 gxact->valid = false;
305 strcpy(gxact->gid, gid);
307 /* And insert it into the active array */
308 Assert(TwoPhaseState->numPrepXacts < max_prepared_xacts);
309 TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts++] = gxact;
311 LWLockRelease(TwoPhaseStateLock);
317 * GXactLoadSubxactData
319 * If the transaction being persisted had any subtransactions, this must
320 * be called before MarkAsPrepared() to load information into the dummy
324 GXactLoadSubxactData(GlobalTransaction gxact, int nsubxacts,
325 TransactionId *children)
327 /* We need no extra lock since the GXACT isn't valid yet */
328 if (nsubxacts > PGPROC_MAX_CACHED_SUBXIDS)
330 gxact->proc.subxids.overflowed = true;
331 nsubxacts = PGPROC_MAX_CACHED_SUBXIDS;
335 memcpy(gxact->proc.subxids.xids, children,
336 nsubxacts * sizeof(TransactionId));
337 gxact->proc.subxids.nxids = nsubxacts;
343 * Mark the GXACT as fully valid, and enter it into the global ProcArray.
346 MarkAsPrepared(GlobalTransaction gxact)
348 /* Lock here may be overkill, but I'm not convinced of that ... */
349 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
350 Assert(!gxact->valid);
352 LWLockRelease(TwoPhaseStateLock);
355 * Put it into the global ProcArray so TransactionIdIsInProgress considers
356 * the XID as still running.
358 ProcArrayAdd(&gxact->proc);
363 * Locate the prepared transaction and mark it busy for COMMIT or PREPARE.
365 static GlobalTransaction
366 LockGXact(const char *gid, Oid user)
370 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
372 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
374 GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
376 /* Ignore not-yet-valid GIDs */
379 if (strcmp(gxact->gid, gid) != 0)
382 /* Found it, but has someone else got it locked? */
383 if (TransactionIdIsValid(gxact->locking_xid))
385 if (TransactionIdIsActive(gxact->locking_xid))
387 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
388 errmsg("prepared transaction with identifier \"%s\" is busy",
390 gxact->locking_xid = InvalidTransactionId;
393 if (user != gxact->owner && !superuser_arg(user))
395 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
396 errmsg("permission denied to finish prepared transaction"),
397 errhint("Must be superuser or the user that prepared the transaction.")));
400 * Note: it probably would be possible to allow committing from
401 * another database; but at the moment NOTIFY is known not to work and
402 * there may be some other issues as well. Hence disallow until
403 * someone gets motivated to make it work.
405 if (MyDatabaseId != gxact->proc.databaseId)
407 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
408 errmsg("prepared transaction belongs to another database"),
409 errhint("Connect to the database where the transaction was prepared to finish it.")));
411 /* OK for me to lock it */
412 gxact->locking_xid = GetTopTransactionId();
414 LWLockRelease(TwoPhaseStateLock);
419 LWLockRelease(TwoPhaseStateLock);
422 (errcode(ERRCODE_UNDEFINED_OBJECT),
423 errmsg("prepared transaction with identifier \"%s\" does not exist",
432 * Remove the prepared transaction from the shared memory array.
434 * NB: caller should have already removed it from ProcArray
437 RemoveGXact(GlobalTransaction gxact)
441 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
443 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
445 if (gxact == TwoPhaseState->prepXacts[i])
447 /* remove from the active array */
448 TwoPhaseState->numPrepXacts--;
449 TwoPhaseState->prepXacts[i] = TwoPhaseState->prepXacts[TwoPhaseState->numPrepXacts];
451 /* and put it back in the freelist */
452 gxact->proc.links.next = TwoPhaseState->freeGXacts;
453 TwoPhaseState->freeGXacts = MAKE_OFFSET(gxact);
455 LWLockRelease(TwoPhaseStateLock);
461 LWLockRelease(TwoPhaseStateLock);
463 elog(ERROR, "failed to find %p in GlobalTransaction array", gxact);
467 * TransactionIdIsPrepared
468 * True iff transaction associated with the identifier is prepared
469 * for two-phase commit
471 * Note: only gxacts marked "valid" are considered; but notice we do not
472 * check the locking status.
474 * This is not currently exported, because it is only needed internally.
477 TransactionIdIsPrepared(TransactionId xid)
482 LWLockAcquire(TwoPhaseStateLock, LW_SHARED);
484 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
486 GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
488 if (gxact->valid && gxact->proc.xid == xid)
495 LWLockRelease(TwoPhaseStateLock);
501 * Returns an array of all prepared transactions for the user-level
502 * function pg_prepared_xact.
504 * The returned array and all its elements are copies of internal data
505 * structures, to minimize the time we need to hold the TwoPhaseStateLock.
507 * WARNING -- we return even those transactions that are not fully prepared
508 * yet. The caller should filter them out if he doesn't want them.
510 * The returned array is palloc'd.
513 GetPreparedTransactionList(GlobalTransaction *gxacts)
515 GlobalTransaction array;
519 LWLockAcquire(TwoPhaseStateLock, LW_SHARED);
521 if (TwoPhaseState->numPrepXacts == 0)
523 LWLockRelease(TwoPhaseStateLock);
529 num = TwoPhaseState->numPrepXacts;
530 array = (GlobalTransaction) palloc(sizeof(GlobalTransactionData) * num);
532 for (i = 0; i < num; i++)
533 memcpy(array + i, TwoPhaseState->prepXacts[i],
534 sizeof(GlobalTransactionData));
536 LWLockRelease(TwoPhaseStateLock);
542 /* Working status for pg_prepared_xact */
545 GlobalTransaction array;
552 * Produce a view with one row per prepared transaction.
554 * This function is here so we don't have to export the
555 * GlobalTransactionData struct definition.
558 pg_prepared_xact(PG_FUNCTION_ARGS)
560 FuncCallContext *funcctx;
561 Working_State *status;
563 if (SRF_IS_FIRSTCALL())
566 MemoryContext oldcontext;
568 /* create a function context for cross-call persistence */
569 funcctx = SRF_FIRSTCALL_INIT();
572 * Switch to memory context appropriate for multiple function calls
574 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
576 /* build tupdesc for result tuples */
577 /* this had better match pg_prepared_xacts view in system_views.sql */
578 tupdesc = CreateTemplateTupleDesc(5, false);
579 TupleDescInitEntry(tupdesc, (AttrNumber) 1, "transaction",
581 TupleDescInitEntry(tupdesc, (AttrNumber) 2, "gid",
583 TupleDescInitEntry(tupdesc, (AttrNumber) 3, "prepared",
584 TIMESTAMPTZOID, -1, 0);
585 TupleDescInitEntry(tupdesc, (AttrNumber) 4, "ownerid",
587 TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
590 funcctx->tuple_desc = BlessTupleDesc(tupdesc);
593 * Collect all the 2PC status information that we will format and send
594 * out as a result set.
596 status = (Working_State *) palloc(sizeof(Working_State));
597 funcctx->user_fctx = (void *) status;
599 status->ngxacts = GetPreparedTransactionList(&status->array);
602 MemoryContextSwitchTo(oldcontext);
605 funcctx = SRF_PERCALL_SETUP();
606 status = (Working_State *) funcctx->user_fctx;
608 while (status->array != NULL && status->currIdx < status->ngxacts)
610 GlobalTransaction gxact = &status->array[status->currIdx++];
620 * Form tuple with appropriate data.
622 MemSet(values, 0, sizeof(values));
623 MemSet(nulls, 0, sizeof(nulls));
625 values[0] = TransactionIdGetDatum(gxact->proc.xid);
626 values[1] = DirectFunctionCall1(textin, CStringGetDatum(gxact->gid));
627 values[2] = TimestampTzGetDatum(gxact->prepared_at);
628 values[3] = ObjectIdGetDatum(gxact->owner);
629 values[4] = ObjectIdGetDatum(gxact->proc.databaseId);
631 tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
632 result = HeapTupleGetDatum(tuple);
633 SRF_RETURN_NEXT(funcctx, result);
636 SRF_RETURN_DONE(funcctx);
640 * TwoPhaseGetDummyProc
641 * Get the PGPROC that represents a prepared transaction specified by XID
644 TwoPhaseGetDummyProc(TransactionId xid)
646 PGPROC *result = NULL;
649 static TransactionId cached_xid = InvalidTransactionId;
650 static PGPROC *cached_proc = NULL;
653 * During a recovery, COMMIT PREPARED, or ABORT PREPARED, we'll be called
654 * repeatedly for the same XID. We can save work with a simple cache.
656 if (xid == cached_xid)
659 LWLockAcquire(TwoPhaseStateLock, LW_SHARED);
661 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
663 GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
665 if (gxact->proc.xid == xid)
667 result = &gxact->proc;
672 LWLockRelease(TwoPhaseStateLock);
674 if (result == NULL) /* should not happen */
675 elog(ERROR, "failed to find dummy PGPROC for xid %u", xid);
678 cached_proc = result;
683 /************************************************************************/
684 /* State file support */
685 /************************************************************************/
687 #define TwoPhaseFilePath(path, xid) \
688 snprintf(path, MAXPGPATH, TWOPHASE_DIR "/%08X", xid)
691 * 2PC state file format:
693 * 1. TwoPhaseFileHeader
694 * 2. TransactionId[] (subtransactions)
695 * 3. RelFileNode[] (files to be deleted at commit)
696 * 4. RelFileNode[] (files to be deleted at abort)
697 * 5. TwoPhaseRecordOnDisk
699 * 7. TwoPhaseRecordOnDisk (end sentinel, rmid == TWOPHASE_RM_END_ID)
702 * Each segment except the final CRC32 is MAXALIGN'd.
706 * Header for a 2PC state file
708 #define TWOPHASE_MAGIC 0x57F94531 /* format identifier */
710 typedef struct TwoPhaseFileHeader
712 uint32 magic; /* format identifier */
713 uint32 total_len; /* actual file length */
714 TransactionId xid; /* original transaction XID */
715 Oid database; /* OID of database it was in */
716 TimestampTz prepared_at; /* time of preparation */
717 Oid owner; /* user running the transaction */
718 int32 nsubxacts; /* number of following subxact XIDs */
719 int32 ncommitrels; /* number of delete-on-commit rels */
720 int32 nabortrels; /* number of delete-on-abort rels */
721 char gid[GIDSIZE]; /* GID for transaction */
722 } TwoPhaseFileHeader;
725 * Header for each record in a state file
727 * NOTE: len counts only the rmgr data, not the TwoPhaseRecordOnDisk header.
728 * The rmgr data will be stored starting on a MAXALIGN boundary.
730 typedef struct TwoPhaseRecordOnDisk
732 uint32 len; /* length of rmgr data */
733 TwoPhaseRmgrId rmid; /* resource manager for this record */
734 uint16 info; /* flag bits for use by rmgr */
735 } TwoPhaseRecordOnDisk;
738 * During prepare, the state file is assembled in memory before writing it
739 * to WAL and the actual state file. We use a chain of XLogRecData blocks
740 * so that we will be able to pass the state file contents directly to
745 XLogRecData *head; /* first data block in the chain */
746 XLogRecData *tail; /* last block in chain */
747 uint32 bytes_free; /* free bytes left in tail block */
748 uint32 total_len; /* total data bytes in chain */
753 * Append a block of data to records data structure.
755 * NB: each block is padded to a MAXALIGN multiple. This must be
756 * accounted for when the file is later read!
758 * The data is copied, so the caller is free to modify it afterwards.
761 save_state_data(const void *data, uint32 len)
763 uint32 padlen = MAXALIGN(len);
765 if (padlen > records.bytes_free)
767 records.tail->next = palloc0(sizeof(XLogRecData));
768 records.tail = records.tail->next;
769 records.tail->buffer = InvalidBuffer;
770 records.tail->len = 0;
771 records.tail->next = NULL;
773 records.bytes_free = Max(padlen, 512);
774 records.tail->data = palloc(records.bytes_free);
777 memcpy(((char *) records.tail->data) + records.tail->len, data, len);
778 records.tail->len += padlen;
779 records.bytes_free -= padlen;
780 records.total_len += padlen;
784 * Start preparing a state file.
786 * Initializes data structure and inserts the 2PC file header record.
789 StartPrepare(GlobalTransaction gxact)
791 TransactionId xid = gxact->proc.xid;
792 TwoPhaseFileHeader hdr;
793 TransactionId *children;
794 RelFileNode *commitrels;
795 RelFileNode *abortrels;
797 /* Initialize linked list */
798 records.head = palloc0(sizeof(XLogRecData));
799 records.head->buffer = InvalidBuffer;
800 records.head->len = 0;
801 records.head->next = NULL;
803 records.bytes_free = Max(sizeof(TwoPhaseFileHeader), 512);
804 records.head->data = palloc(records.bytes_free);
806 records.tail = records.head;
808 records.total_len = 0;
811 hdr.magic = TWOPHASE_MAGIC;
812 hdr.total_len = 0; /* EndPrepare will fill this in */
814 hdr.database = gxact->proc.databaseId;
815 hdr.prepared_at = gxact->prepared_at;
816 hdr.owner = gxact->owner;
817 hdr.nsubxacts = xactGetCommittedChildren(&children);
818 hdr.ncommitrels = smgrGetPendingDeletes(true, &commitrels, NULL);
819 hdr.nabortrels = smgrGetPendingDeletes(false, &abortrels, NULL);
820 StrNCpy(hdr.gid, gxact->gid, GIDSIZE);
822 save_state_data(&hdr, sizeof(TwoPhaseFileHeader));
824 /* Add the additional info about subxacts and deletable files */
825 if (hdr.nsubxacts > 0)
827 save_state_data(children, hdr.nsubxacts * sizeof(TransactionId));
828 /* While we have the child-xact data, stuff it in the gxact too */
829 GXactLoadSubxactData(gxact, hdr.nsubxacts, children);
831 if (hdr.ncommitrels > 0)
833 save_state_data(commitrels, hdr.ncommitrels * sizeof(RelFileNode));
836 if (hdr.nabortrels > 0)
838 save_state_data(abortrels, hdr.nabortrels * sizeof(RelFileNode));
844 * Finish preparing state file.
846 * Calculates CRC and writes state file to WAL and in pg_twophase directory.
849 EndPrepare(GlobalTransaction gxact)
851 TransactionId xid = gxact->proc.xid;
852 TwoPhaseFileHeader *hdr;
853 char path[MAXPGPATH];
855 pg_crc32 statefile_crc;
859 /* Add the end sentinel to the list of 2PC records */
860 RegisterTwoPhaseRecord(TWOPHASE_RM_END_ID, 0,
863 /* Go back and fill in total_len in the file header record */
864 hdr = (TwoPhaseFileHeader *) records.head->data;
865 Assert(hdr->magic == TWOPHASE_MAGIC);
866 hdr->total_len = records.total_len + sizeof(pg_crc32);
869 * Create the 2PC state file.
871 * Note: because we use BasicOpenFile(), we are responsible for ensuring
872 * the FD gets closed in any error exit path. Once we get into the
873 * critical section, though, it doesn't matter since any failure causes
876 TwoPhaseFilePath(path, xid);
878 fd = BasicOpenFile(path,
879 O_CREAT | O_EXCL | O_WRONLY | PG_BINARY,
883 (errcode_for_file_access(),
884 errmsg("could not create two-phase state file \"%s\": %m",
887 /* Write data to file, and calculate CRC as we pass over it */
888 INIT_CRC32(statefile_crc);
890 for (record = records.head; record != NULL; record = record->next)
892 COMP_CRC32(statefile_crc, record->data, record->len);
893 if ((write(fd, record->data, record->len)) != record->len)
897 (errcode_for_file_access(),
898 errmsg("could not write two-phase state file: %m")));
902 FIN_CRC32(statefile_crc);
905 * Write a deliberately bogus CRC to the state file; this is just paranoia
906 * to catch the case where four more bytes will run us out of disk space.
908 bogus_crc = ~statefile_crc;
910 if ((write(fd, &bogus_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
914 (errcode_for_file_access(),
915 errmsg("could not write two-phase state file: %m")));
918 /* Back up to prepare for rewriting the CRC */
919 if (lseek(fd, -((off_t) sizeof(pg_crc32)), SEEK_CUR) < 0)
923 (errcode_for_file_access(),
924 errmsg("could not seek in two-phase state file: %m")));
928 * The state file isn't valid yet, because we haven't written the correct
929 * CRC yet. Before we do that, insert entry in WAL and flush it to disk.
931 * Between the time we have written the WAL entry and the time we write
932 * out the correct state file CRC, we have an inconsistency: the xact is
933 * prepared according to WAL but not according to our on-disk state. We
934 * use a critical section to force a PANIC if we are unable to complete
935 * the write --- then, WAL replay should repair the inconsistency. The
936 * odds of a PANIC actually occurring should be very tiny given that we
937 * were able to write the bogus CRC above.
939 * We have to set inCommit here, too; otherwise a checkpoint starting
940 * immediately after the WAL record is inserted could complete without
941 * fsync'ing our state file. (This is essentially the same kind of race
942 * condition as the COMMIT-to-clog-write case that RecordTransactionCommit
943 * uses inCommit for; see notes there.)
945 * We save the PREPARE record's location in the gxact for later use by
946 * CheckPointTwoPhase.
948 START_CRIT_SECTION();
950 MyProc->inCommit = true;
952 gxact->prepare_lsn = XLogInsert(RM_XACT_ID, XLOG_XACT_PREPARE,
954 XLogFlush(gxact->prepare_lsn);
956 /* If we crash now, we have prepared: WAL replay will fix things */
958 /* write correct CRC and close file */
959 if ((write(fd, &statefile_crc, sizeof(pg_crc32))) != sizeof(pg_crc32))
963 (errcode_for_file_access(),
964 errmsg("could not write two-phase state file: %m")));
969 (errcode_for_file_access(),
970 errmsg("could not close two-phase state file: %m")));
973 * Mark the prepared transaction as valid. As soon as xact.c marks MyProc
974 * as not running our XID (which it will do immediately after this
975 * function returns), others can commit/rollback the xact.
977 * NB: a side effect of this is to make a dummy ProcArray entry for the
978 * prepared XID. This must happen before we clear the XID from MyProc,
979 * else there is a window where the XID is not running according to
980 * TransactionIdIsInProgress, and onlookers would be entitled to assume
981 * the xact crashed. Instead we have a window where the same XID appears
982 * twice in ProcArray, which is OK.
984 MarkAsPrepared(gxact);
987 * Now we can mark ourselves as out of the commit critical section: a
988 * checkpoint starting after this will certainly see the gxact as a
989 * candidate for fsyncing.
991 MyProc->inCommit = false;
995 records.tail = records.head = NULL;
999 * Register a 2PC record to be written to state file.
1002 RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info,
1003 const void *data, uint32 len)
1005 TwoPhaseRecordOnDisk record;
1010 save_state_data(&record, sizeof(TwoPhaseRecordOnDisk));
1012 save_state_data(data, len);
1017 * Read and validate the state file for xid.
1019 * If it looks OK (has a valid magic number and CRC), return the palloc'd
1020 * contents of the file. Otherwise return NULL.
1023 ReadTwoPhaseFile(TransactionId xid)
1025 char path[MAXPGPATH];
1027 TwoPhaseFileHeader *hdr;
1034 TwoPhaseFilePath(path, xid);
1036 fd = BasicOpenFile(path, O_RDONLY | PG_BINARY, 0);
1040 (errcode_for_file_access(),
1041 errmsg("could not open two-phase state file \"%s\": %m",
1047 * Check file length. We can determine a lower bound pretty easily. We
1048 * set an upper bound mainly to avoid palloc() failure on a corrupt file.
1050 if (fstat(fd, &stat))
1054 (errcode_for_file_access(),
1055 errmsg("could not stat two-phase state file \"%s\": %m",
1060 if (stat.st_size < (MAXALIGN(sizeof(TwoPhaseFileHeader)) +
1061 MAXALIGN(sizeof(TwoPhaseRecordOnDisk)) +
1062 sizeof(pg_crc32)) ||
1063 stat.st_size > 10000000)
1069 crc_offset = stat.st_size - sizeof(pg_crc32);
1070 if (crc_offset != MAXALIGN(crc_offset))
1077 * OK, slurp in the file.
1079 buf = (char *) palloc(stat.st_size);
1081 if (read(fd, buf, stat.st_size) != stat.st_size)
1085 (errcode_for_file_access(),
1086 errmsg("could not read two-phase state file \"%s\": %m",
1094 hdr = (TwoPhaseFileHeader *) buf;
1095 if (hdr->magic != TWOPHASE_MAGIC || hdr->total_len != stat.st_size)
1101 INIT_CRC32(calc_crc);
1102 COMP_CRC32(calc_crc, buf, crc_offset);
1103 FIN_CRC32(calc_crc);
1105 file_crc = *((pg_crc32 *) (buf + crc_offset));
1107 if (!EQ_CRC32(calc_crc, file_crc))
1118 * FinishPreparedTransaction: execute COMMIT PREPARED or ROLLBACK PREPARED
1121 FinishPreparedTransaction(const char *gid, bool isCommit)
1123 GlobalTransaction gxact;
1127 TwoPhaseFileHeader *hdr;
1128 TransactionId latestXid;
1129 TransactionId *children;
1130 RelFileNode *commitrels;
1131 RelFileNode *abortrels;
1135 * Validate the GID, and lock the GXACT to ensure that two backends do not
1136 * try to commit the same GID at once.
1138 gxact = LockGXact(gid, GetUserId());
1139 xid = gxact->proc.xid;
1142 * Read and validate the state file
1144 buf = ReadTwoPhaseFile(xid);
1147 (errcode(ERRCODE_DATA_CORRUPTED),
1148 errmsg("two-phase state file for transaction %u is corrupt",
1152 * Disassemble the header area
1154 hdr = (TwoPhaseFileHeader *) buf;
1155 Assert(TransactionIdEquals(hdr->xid, xid));
1156 bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
1157 children = (TransactionId *) bufptr;
1158 bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
1159 commitrels = (RelFileNode *) bufptr;
1160 bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileNode));
1161 abortrels = (RelFileNode *) bufptr;
1162 bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileNode));
1164 /* compute latestXid among all children */
1165 latestXid = TransactionIdLatest(xid, hdr->nsubxacts, children);
1168 * The order of operations here is critical: make the XLOG entry for
1169 * commit or abort, then mark the transaction committed or aborted in
1170 * pg_clog, then remove its PGPROC from the global ProcArray (which means
1171 * TransactionIdIsInProgress will stop saying the prepared xact is in
1172 * progress), then run the post-commit or post-abort callbacks. The
1173 * callbacks will release the locks the transaction held.
1176 RecordTransactionCommitPrepared(xid,
1177 hdr->nsubxacts, children,
1178 hdr->ncommitrels, commitrels);
1180 RecordTransactionAbortPrepared(xid,
1181 hdr->nsubxacts, children,
1182 hdr->nabortrels, abortrels);
1184 ProcArrayRemove(&gxact->proc, latestXid);
1187 * In case we fail while running the callbacks, mark the gxact invalid so
1188 * no one else will try to commit/rollback, and so it can be recycled
1189 * properly later. It is still locked by our XID so it won't go away yet.
1191 * (We assume it's safe to do this without taking TwoPhaseStateLock.)
1193 gxact->valid = false;
1196 * We have to remove any files that were supposed to be dropped. For
1197 * consistency with the regular xact.c code paths, must do this before
1198 * releasing locks, so do it before running the callbacks.
1200 * NB: this code knows that we couldn't be dropping any temp rels ...
1204 for (i = 0; i < hdr->ncommitrels; i++)
1205 smgrdounlink(smgropen(commitrels[i]), false, false);
1209 for (i = 0; i < hdr->nabortrels; i++)
1210 smgrdounlink(smgropen(abortrels[i]), false, false);
1213 /* And now do the callbacks */
1215 ProcessRecords(bufptr, xid, twophase_postcommit_callbacks);
1217 ProcessRecords(bufptr, xid, twophase_postabort_callbacks);
1219 /* Count the prepared xact as committed or aborted */
1220 AtEOXact_PgStat(isCommit);
1223 * And now we can clean up our mess.
1225 RemoveTwoPhaseFile(xid, true);
1233 * Scan a 2PC state file (already read into memory by ReadTwoPhaseFile)
1234 * and call the indicated callbacks for each 2PC record.
1237 ProcessRecords(char *bufptr, TransactionId xid,
1238 const TwoPhaseCallback callbacks[])
1242 TwoPhaseRecordOnDisk *record = (TwoPhaseRecordOnDisk *) bufptr;
1244 Assert(record->rmid <= TWOPHASE_RM_MAX_ID);
1245 if (record->rmid == TWOPHASE_RM_END_ID)
1248 bufptr += MAXALIGN(sizeof(TwoPhaseRecordOnDisk));
1250 if (callbacks[record->rmid] != NULL)
1251 callbacks[record->rmid] (xid, record->info,
1252 (void *) bufptr, record->len);
1254 bufptr += MAXALIGN(record->len);
1259 * Remove the 2PC file for the specified XID.
1261 * If giveWarning is false, do not complain about file-not-present;
1262 * this is an expected case during WAL replay.
1265 RemoveTwoPhaseFile(TransactionId xid, bool giveWarning)
1267 char path[MAXPGPATH];
1269 TwoPhaseFilePath(path, xid);
1271 if (errno != ENOENT || giveWarning)
1273 (errcode_for_file_access(),
1274 errmsg("could not remove two-phase state file \"%s\": %m",
1279 * Recreates a state file. This is used in WAL replay.
1281 * Note: content and len don't include CRC.
1284 RecreateTwoPhaseFile(TransactionId xid, void *content, int len)
1286 char path[MAXPGPATH];
1287 pg_crc32 statefile_crc;
1291 INIT_CRC32(statefile_crc);
1292 COMP_CRC32(statefile_crc, content, len);
1293 FIN_CRC32(statefile_crc);
1295 TwoPhaseFilePath(path, xid);
1297 fd = BasicOpenFile(path,
1298 O_CREAT | O_TRUNC | O_WRONLY | PG_BINARY,
1302 (errcode_for_file_access(),
1303 errmsg("could not recreate two-phase state file \"%s\": %m",
1306 /* Write content and CRC */
1307 if (write(fd, content, len) != len)
1311 (errcode_for_file_access(),
1312 errmsg("could not write two-phase state file: %m")));
1314 if (write(fd, &statefile_crc, sizeof(pg_crc32)) != sizeof(pg_crc32))
1318 (errcode_for_file_access(),
1319 errmsg("could not write two-phase state file: %m")));
1323 * We must fsync the file because the end-of-replay checkpoint will not do
1324 * so, there being no GXACT in shared memory yet to tell it to.
1326 if (pg_fsync(fd) != 0)
1330 (errcode_for_file_access(),
1331 errmsg("could not fsync two-phase state file: %m")));
1336 (errcode_for_file_access(),
1337 errmsg("could not close two-phase state file: %m")));
1341 * CheckPointTwoPhase -- handle 2PC component of checkpointing.
1343 * We must fsync the state file of any GXACT that is valid and has a PREPARE
1344 * LSN <= the checkpoint's redo horizon. (If the gxact isn't valid yet or
1345 * has a later LSN, this checkpoint is not responsible for fsyncing it.)
1347 * This is deliberately run as late as possible in the checkpoint sequence,
1348 * because GXACTs ordinarily have short lifespans, and so it is quite
1349 * possible that GXACTs that were valid at checkpoint start will no longer
1350 * exist if we wait a little bit.
1352 * If a GXACT remains valid across multiple checkpoints, it'll be fsynced
1353 * each time. This is considered unusual enough that we don't bother to
1354 * expend any extra code to avoid the redundant fsyncs. (They should be
1355 * reasonably cheap anyway, since they won't cause I/O.)
1358 CheckPointTwoPhase(XLogRecPtr redo_horizon)
1360 TransactionId *xids;
1362 char path[MAXPGPATH];
1366 * We don't want to hold the TwoPhaseStateLock while doing I/O, so we grab
1367 * it just long enough to make a list of the XIDs that require fsyncing,
1368 * and then do the I/O afterwards.
1370 * This approach creates a race condition: someone else could delete a
1371 * GXACT between the time we release TwoPhaseStateLock and the time we try
1372 * to open its state file. We handle this by special-casing ENOENT
1373 * failures: if we see that, we verify that the GXACT is no longer valid,
1374 * and if so ignore the failure.
1376 if (max_prepared_xacts <= 0)
1377 return; /* nothing to do */
1378 xids = (TransactionId *) palloc(max_prepared_xacts * sizeof(TransactionId));
1381 LWLockAcquire(TwoPhaseStateLock, LW_SHARED);
1383 for (i = 0; i < TwoPhaseState->numPrepXacts; i++)
1385 GlobalTransaction gxact = TwoPhaseState->prepXacts[i];
1388 XLByteLE(gxact->prepare_lsn, redo_horizon))
1389 xids[nxids++] = gxact->proc.xid;
1392 LWLockRelease(TwoPhaseStateLock);
1394 for (i = 0; i < nxids; i++)
1396 TransactionId xid = xids[i];
1399 TwoPhaseFilePath(path, xid);
1401 fd = BasicOpenFile(path, O_RDWR | PG_BINARY, 0);
1404 if (errno == ENOENT)
1406 /* OK if gxact is no longer valid */
1407 if (!TransactionIdIsPrepared(xid))
1409 /* Restore errno in case it was changed */
1413 (errcode_for_file_access(),
1414 errmsg("could not open two-phase state file \"%s\": %m",
1418 if (pg_fsync(fd) != 0)
1422 (errcode_for_file_access(),
1423 errmsg("could not fsync two-phase state file \"%s\": %m",
1429 (errcode_for_file_access(),
1430 errmsg("could not close two-phase state file \"%s\": %m",
1438 * PrescanPreparedTransactions
1440 * Scan the pg_twophase directory and determine the range of valid XIDs
1441 * present. This is run during database startup, after we have completed
1442 * reading WAL. ShmemVariableCache->nextXid has been set to one more than
1443 * the highest XID for which evidence exists in WAL.
1445 * We throw away any prepared xacts with main XID beyond nextXid --- if any
1446 * are present, it suggests that the DBA has done a PITR recovery to an
1447 * earlier point in time without cleaning out pg_twophase. We dare not
1448 * try to recover such prepared xacts since they likely depend on database
1449 * state that doesn't exist now.
1451 * However, we will advance nextXid beyond any subxact XIDs belonging to
1452 * valid prepared xacts. We need to do this since subxact commit doesn't
1453 * write a WAL entry, and so there might be no evidence in WAL of those
1456 * Our other responsibility is to determine and return the oldest valid XID
1457 * among the prepared xacts (if none, return ShmemVariableCache->nextXid).
1458 * This is needed to synchronize pg_subtrans startup properly.
1461 PrescanPreparedTransactions(void)
1463 TransactionId origNextXid = ShmemVariableCache->nextXid;
1464 TransactionId result = origNextXid;
1466 struct dirent *clde;
1468 cldir = AllocateDir(TWOPHASE_DIR);
1469 while ((clde = ReadDir(cldir, TWOPHASE_DIR)) != NULL)
1471 if (strlen(clde->d_name) == 8 &&
1472 strspn(clde->d_name, "0123456789ABCDEF") == 8)
1476 TwoPhaseFileHeader *hdr;
1477 TransactionId *subxids;
1480 xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
1482 /* Reject XID if too new */
1483 if (TransactionIdFollowsOrEquals(xid, origNextXid))
1486 (errmsg("removing future two-phase state file \"%s\"",
1488 RemoveTwoPhaseFile(xid, true);
1493 * Note: we can't check if already processed because clog
1494 * subsystem isn't up yet.
1497 /* Read and validate file */
1498 buf = ReadTwoPhaseFile(xid);
1502 (errmsg("removing corrupt two-phase state file \"%s\"",
1504 RemoveTwoPhaseFile(xid, true);
1508 /* Deconstruct header */
1509 hdr = (TwoPhaseFileHeader *) buf;
1510 if (!TransactionIdEquals(hdr->xid, xid))
1513 (errmsg("removing corrupt two-phase state file \"%s\"",
1515 RemoveTwoPhaseFile(xid, true);
1521 * OK, we think this file is valid. Incorporate xid into the
1522 * running-minimum result.
1524 if (TransactionIdPrecedes(xid, result))
1528 * Examine subtransaction XIDs ... they should all follow main
1529 * XID, and they may force us to advance nextXid.
1531 subxids = (TransactionId *)
1532 (buf + MAXALIGN(sizeof(TwoPhaseFileHeader)));
1533 for (i = 0; i < hdr->nsubxacts; i++)
1535 TransactionId subxid = subxids[i];
1537 Assert(TransactionIdFollows(subxid, xid));
1538 if (TransactionIdFollowsOrEquals(subxid,
1539 ShmemVariableCache->nextXid))
1541 ShmemVariableCache->nextXid = subxid;
1542 TransactionIdAdvance(ShmemVariableCache->nextXid);
1555 * RecoverPreparedTransactions
1557 * Scan the pg_twophase directory and reload shared-memory state for each
1558 * prepared transaction (reacquire locks, etc). This is run during database
1562 RecoverPreparedTransactions(void)
1564 char dir[MAXPGPATH];
1566 struct dirent *clde;
1568 snprintf(dir, MAXPGPATH, "%s", TWOPHASE_DIR);
1570 cldir = AllocateDir(dir);
1571 while ((clde = ReadDir(cldir, dir)) != NULL)
1573 if (strlen(clde->d_name) == 8 &&
1574 strspn(clde->d_name, "0123456789ABCDEF") == 8)
1579 TwoPhaseFileHeader *hdr;
1580 TransactionId *subxids;
1581 GlobalTransaction gxact;
1584 xid = (TransactionId) strtoul(clde->d_name, NULL, 16);
1586 /* Already processed? */
1587 if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
1590 (errmsg("removing stale two-phase state file \"%s\"",
1592 RemoveTwoPhaseFile(xid, true);
1596 /* Read and validate file */
1597 buf = ReadTwoPhaseFile(xid);
1601 (errmsg("removing corrupt two-phase state file \"%s\"",
1603 RemoveTwoPhaseFile(xid, true);
1608 (errmsg("recovering prepared transaction %u", xid)));
1610 /* Deconstruct header */
1611 hdr = (TwoPhaseFileHeader *) buf;
1612 Assert(TransactionIdEquals(hdr->xid, xid));
1613 bufptr = buf + MAXALIGN(sizeof(TwoPhaseFileHeader));
1614 subxids = (TransactionId *) bufptr;
1615 bufptr += MAXALIGN(hdr->nsubxacts * sizeof(TransactionId));
1616 bufptr += MAXALIGN(hdr->ncommitrels * sizeof(RelFileNode));
1617 bufptr += MAXALIGN(hdr->nabortrels * sizeof(RelFileNode));
1620 * Reconstruct subtrans state for the transaction --- needed
1621 * because pg_subtrans is not preserved over a restart. Note that
1622 * we are linking all the subtransactions directly to the
1623 * top-level XID; there may originally have been a more complex
1624 * hierarchy, but there's no need to restore that exactly.
1626 for (i = 0; i < hdr->nsubxacts; i++)
1627 SubTransSetParent(subxids[i], xid);
1630 * Recreate its GXACT and dummy PGPROC
1632 * Note: since we don't have the PREPARE record's WAL location at
1633 * hand, we leave prepare_lsn zeroes. This means the GXACT will
1634 * be fsync'd on every future checkpoint. We assume this
1635 * situation is infrequent enough that the performance cost is
1636 * negligible (especially since we know the state file has already
1639 gxact = MarkAsPreparing(xid, hdr->gid,
1641 hdr->owner, hdr->database);
1642 GXactLoadSubxactData(gxact, hdr->nsubxacts, subxids);
1643 MarkAsPrepared(gxact);
1646 * Recover other state (notably locks) using resource managers
1648 ProcessRecords(bufptr, xid, twophase_recover_callbacks);
1657 * RecordTransactionCommitPrepared
1659 * This is basically the same as RecordTransactionCommit: in particular,
1660 * we must set the inCommit flag to avoid a race condition.
1662 * We know the transaction made at least one XLOG entry (its PREPARE),
1663 * so it is never possible to optimize out the commit record.
1666 RecordTransactionCommitPrepared(TransactionId xid,
1668 TransactionId *children,
1672 XLogRecData rdata[3];
1674 xl_xact_commit_prepared xlrec;
1677 START_CRIT_SECTION();
1679 /* See notes in RecordTransactionCommit */
1680 MyProc->inCommit = true;
1682 /* Emit the XLOG commit record */
1684 xlrec.crec.xact_time = GetCurrentTimestamp();
1685 xlrec.crec.nrels = nrels;
1686 xlrec.crec.nsubxacts = nchildren;
1687 rdata[0].data = (char *) (&xlrec);
1688 rdata[0].len = MinSizeOfXactCommitPrepared;
1689 rdata[0].buffer = InvalidBuffer;
1690 /* dump rels to delete */
1693 rdata[0].next = &(rdata[1]);
1694 rdata[1].data = (char *) rels;
1695 rdata[1].len = nrels * sizeof(RelFileNode);
1696 rdata[1].buffer = InvalidBuffer;
1699 /* dump committed child Xids */
1702 rdata[lastrdata].next = &(rdata[2]);
1703 rdata[2].data = (char *) children;
1704 rdata[2].len = nchildren * sizeof(TransactionId);
1705 rdata[2].buffer = InvalidBuffer;
1708 rdata[lastrdata].next = NULL;
1710 recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_PREPARED, rdata);
1713 * We don't currently try to sleep before flush here ... nor is there any
1714 * support for async commit of a prepared xact (the very idea is probably
1718 /* Flush XLOG to disk */
1721 /* Mark the transaction committed in pg_clog */
1722 TransactionIdCommit(xid);
1723 /* to avoid race conditions, the parent must commit first */
1724 TransactionIdCommitTree(nchildren, children);
1726 /* Checkpoint can proceed now */
1727 MyProc->inCommit = false;
1733 * RecordTransactionAbortPrepared
1735 * This is basically the same as RecordTransactionAbort.
1737 * We know the transaction made at least one XLOG entry (its PREPARE),
1738 * so it is never possible to optimize out the abort record.
1741 RecordTransactionAbortPrepared(TransactionId xid,
1743 TransactionId *children,
1747 XLogRecData rdata[3];
1749 xl_xact_abort_prepared xlrec;
1753 * Catch the scenario where we aborted partway through
1754 * RecordTransactionCommitPrepared ...
1756 if (TransactionIdDidCommit(xid))
1757 elog(PANIC, "cannot abort transaction %u, it was already committed",
1760 START_CRIT_SECTION();
1762 /* Emit the XLOG abort record */
1764 xlrec.arec.xact_time = GetCurrentTimestamp();
1765 xlrec.arec.nrels = nrels;
1766 xlrec.arec.nsubxacts = nchildren;
1767 rdata[0].data = (char *) (&xlrec);
1768 rdata[0].len = MinSizeOfXactAbortPrepared;
1769 rdata[0].buffer = InvalidBuffer;
1770 /* dump rels to delete */
1773 rdata[0].next = &(rdata[1]);
1774 rdata[1].data = (char *) rels;
1775 rdata[1].len = nrels * sizeof(RelFileNode);
1776 rdata[1].buffer = InvalidBuffer;
1779 /* dump committed child Xids */
1782 rdata[lastrdata].next = &(rdata[2]);
1783 rdata[2].data = (char *) children;
1784 rdata[2].len = nchildren * sizeof(TransactionId);
1785 rdata[2].buffer = InvalidBuffer;
1788 rdata[lastrdata].next = NULL;
1790 recptr = XLogInsert(RM_XACT_ID, XLOG_XACT_ABORT_PREPARED, rdata);
1792 /* Always flush, since we're about to remove the 2PC state file */
1796 * Mark the transaction aborted in clog. This is not absolutely necessary
1797 * but we may as well do it while we are here.
1799 TransactionIdAbort(xid);
1800 TransactionIdAbortTree(nchildren, children);