Hi

When we lazily assign XIDs, we gain another flag beside the existing
MyXactMadeTempRelUpdates, MyXactMadeXLogEntry, MyLastRecPtr and smgr's
pendingDeletes to tell what kind of actions a transaction performed. Adding
TransactionIsIsValid(GetCurrentTransactionIdIfAny()) on top of that
makes things quite impenetrable - at least for me. So I'm trying to
wrap my head around that logic, and simplify it a bit if possible.
(Nowadays, async commit even adds a bit more complexity)

Currently, we write out a COMMIT record if a transaction either created
any transaction-controlled XLOG entries (MyLastRecPtr.xrecoff != 0), or
scheduled the deletion of files on commit. Afterwards, the xlog is flushed
to the end last record created by the session (ProcLastRecEnd) if the
transaction created any xlog record at all. If we either made
transaction-controlled XLOG entries, or temporary relation updates, we
update the XID status in the CLOG.

An ABORT record is currently created if a transaction either created
transaction-controlled XLOG entries or scheduled the deletion of files
on abort. If we schedules file deletions, we flush the XLOG up to the
ABORT record. If we either made transaction-controlled XLOG entries,
updated temporary relations, or scheduled deletions we update the XID
status in the CLOG.

For subtransaction commit, a COMMIT record is emitted if we either made
transaction-controlled XLOG entries, or updated temporary relations.
No XLOG flush is performed.

Subtransaction ABORTS are handled the same way as regular transaction
aborts.

For toplevel transaction commits, we defer flushing the xlog if
synchronous_commit = off, and we didn't schedule any file deletions.

Now, with lazy XID assignment I believe the following holds true
.) If we didn't assign a valid XID, we cannot have made transaction-controlled
   XLOG entries (Can be checked by asserting that the current transaction id
   is valid if XLOG_NO_TRAN isn't set in XLogInsert).
.) We cannot have scheduled files for deletion (on either COMMIT or ABORT)
   if we don't have a valid XID, since any such deletion will happen together
   with a catalog update. Note that this is already assumed to be true for
   subtransactions, since they only call RecordSubTransaction{Commit|Abort}
   if they have an XID assigned.

I propose to do the following in my lazy XID assignment patch - can
anyone see a hole in that?

.) Get rid of MyLastRecPtr and MyXactMadeTempRelUpdates. Those are
   superseeded by TransactionIdIsValid(GetCurrentTransactionIdIfAny()).
.) Get rid of MyXactMadeXLogEntry. Instead, just reset ProcLast
.) Rename ProcLastRecEnd to XactLastRecEnd, and reset when starting
   a new toplevel transaction.

Transaction COMMIT:
  Write an COMMIT record if and only if we have a valid XID.
  Then, flush the XLOG to XactLastRecEnd if that is set, and
  synchronous_commit=on.
  Aferwards, update the CLOG if and only if we have a valid XID.

Transaction ABORT:
  Write an ABORT record if and only if we have a valid XID.
  Then, flush the XLOG to XactLastRecEnd if that is set, and
  we scheduled on-abort deletions.
  Update the CLOG if and only if we have a valid XID.

Subtransaction COMMIT:
  Update the CLOG if and only if we have a valid XID.

Subtransaction ABORT:
  Write an ABORT record if and only if we have a valid XID.
  Then, flush the XLOG to XactLastRecEnd if that is set, and
  we scheduled on-abort deletions.
  Update the CLOG if and only if we have a valid XID.

I think we might go even further, and *never* flush the XLOG on abort,
since if we crash just before the abort won't log anything either. But
if we leak the leftover files in such a case, that's probably a bad idea.

greetings, Florian Pflug


---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

              http://www.postgresql.org/docs/faq

Reply via email to