RE: pg_logical_slot_get_changes waits continously for a partial WAL record spanning across 2 pages
Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com>
From: "Hayato Kuroda (Fujitsu)" <kuroda.hayato@fujitsu.com>
To: 'Michael Paquier' <michael@paquier.xyz>, vignesh C <vignesh21@gmail.com>
Cc: PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>, Alexander
Korotkov <aekorotkov@gmail.com>, Tom Lane <tgl@sss.pgh.pa.us>, Amit Kapila <amit.kapila16@gmail.com>, Melanie Plageman <melanieplageman@gmail.com>
Date: 2025-06-26T02:20:05Z
Lists: pgsql-hackers
Dear Michael, Vignesh, > On Wed, Jun 25, 2025 at 10:19:55PM +0530, vignesh C wrote: > > Currently, the logic attempts to read the complete WAL record based on > > the size obtained before the crash—even though only a partial record > > was written. It then checks the page header to determine whether the > > XLP_FIRST_IS_OVERWRITE_CONTRECORD flag is set only after reading the > > complete WAL record at XLogDecodeNextRecord function, but since that > > much WAL data was not available in the system we never get a chance to > > check the header after this.. To address this issue, a more robust > > approach would be to first read the page header, check if the > > XLP_FIRST_IS_OVERWRITE_CONTRECORD flag is set, and only then proceed > > to read the WAL record size if the record is not marked as a partial > > overwrite. This would prevent the system from waiting for WAL data > > that will never arrive. Attached partial_wal_record_fix.patch patch > > for this. > > So you are suggesting the addition of an extra ReadPageInternal() that > forces a read of only the read, perform the checks on the header, then > read the rest. After reading SizeOfXLogShortPHD worth of data, > shouldn't the checks on xlp_rem_len be done a bit earlier than what > you are proposing in this patch? I have a concern for the performance perspective. This approach must read the page twice in any cases, right? The workaround is needed only for the corner case but affects for all the passes. Or, is it actually negligible? > Another reliable approach would be to make the > code wait before reading the record in the internal loop of > ReadPageInternal() with an injection point when we know that we have a > contrecord, but I'm not really excited about this prospect in > xlogreader.c which can be also used in the frontend. Per my understanding an injection point must be added while flushing a WAL record, to emulate the incomplete WAL record issue. To confirm, how can it be used in ReadPageInternal()? Best regards, Hayato Kuroda FUJITSU LIMITED
Commits
-
Fix infinite wait when reading a partially written WAL record
- c9f4e7520603 17.6 landed
- 762f352ca4a6 13.22 landed
- bedfdb85b0a3 14.19 landed
- 9f270f48f3fe 15.14 landed
- b485e1c89a6d 16.10 landed
- d3917d8f13e7 19 (unreleased) landed
- 5449d5b7ae9c 18.0 landed
-
Improve the stability of the recovery test 047_checkpoint_physical_slot
- fd39c3cf2839 17.6 landed
- c71c702f067b 18.0 landed
- ccd945159361 19 (unreleased) landed
-
Improve recovery test 046_checkpoint_logical_slot
- 6aefde2a2db8 17.6 landed