mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
Emit invalidations to standby for transactions without xid.
So far, when a transaction with pending invalidations, but without an assigned xid, committed, we simply ignored those invalidation messages. That's problematic, because those are actually sent for a reason. Known symptoms of this include that existing sessions on a hot-standby replica sometimes fail to notice new concurrently built indexes and visibility map updates. The solution is to WAL log such invalidations in transactions without an xid. We considered to alternatively force-assign an xid, but that'd be problematic for vacuum, which might be run in systems with few xids. Important: This adds a new WAL record, but as the patch has to be back-patched, we can't bump the WAL page magic. This means that standbys have to be updated before primaries; otherwise "PANIC: standby_redo: unknown op code 32" errors can be encountered. XXX: Reported-By: Васильев Дмитрий, Masahiko Sawada Discussion: CAB-SwXY6oH=9twBkXJtgR4UC1NqT-vpYAtxCseME62ADwyK5OA@mail.gmail.com CAD21AoDpZ6Xjg=gFrGPnSn4oTRRcwK1EBrWCq9OqOHuAcMMC=w@mail.gmail.com
This commit is contained in:
@ -1163,6 +1163,24 @@ RecordTransactionCommit(void)
|
||||
/* Can't have child XIDs either; AssignTransactionId enforces this */
|
||||
Assert(nchildren == 0);
|
||||
|
||||
/*
|
||||
* Transactions without an assigned xid can contain invalidation
|
||||
* messages (e.g. explicit relcache invalidations or catcache
|
||||
* invalidations for inplace updates); standbys need to process
|
||||
* those. We can't emit a commit record without an xid, and we don't
|
||||
* want to force assigning an xid, because that'd be problematic for
|
||||
* e.g. vacuum. Hence we emit a bespoke record for the
|
||||
* invalidations. We don't want to use that in case a commit record is
|
||||
* emitted, so they happen synchronously with commits (besides not
|
||||
* wanting to emit more WAL recoreds).
|
||||
*/
|
||||
if (nmsgs != 0)
|
||||
{
|
||||
LogStandbyInvalidations(nmsgs, invalMessages,
|
||||
RelcacheInitFileInval);
|
||||
wrote_xlog = true; /* not strictly necessary */
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't create XLOG entries, we're done here; otherwise we
|
||||
* should trigger flushing those entries the same as a commit record
|
||||
|
Reference in New Issue
Block a user