Re: Race condition in recovery?
Dilip Kumar <dilipbalaut@gmail.com>
From: Dilip Kumar <dilipbalaut@gmail.com>
To: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Cc: Robert Haas <robertmhaas@gmail.com>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2021-05-07T05:34:53Z
Lists: pgsql-hackers
On Fri, May 7, 2021 at 8:23 AM Kyotaro Horiguchi
<horikyota.ntt@gmail.com> wrote:
>
> At Tue, 4 May 2021 17:41:06 +0530, Dilip Kumar <dilipbalaut@gmail.com> wrote in
> Could you please fix the test script so that it causes your issue
> correctly? And/or elaborate a bit more?
>
> The attached first file is the debugging aid logging. The second is
> the test script, to be placed in src/test/recovery/t.
I will look into your test case and try to see whether we can
reproduce the issue. But let me summarise what is the exact issue.
Basically, the issue is that first in validateRecoveryParameters if
the recovery target is the latest then we fetch the latest history
file and set the recoveryTargetTLI timeline to the latest available
timeline assume it's 2 but we delay updating the expectedTLEs (as per
commit ee994272ca50f70b53074f0febaec97e28f83c4e). Now, while reading
the checkpoint record if we don't get the required WAL from the
archive then we try to get from primary, and while getting checkpoint
from primary we use "ControlFile->checkPointCopy.ThisTimeLineID"
suppose that is older timeline 1. Now after reading the checkpoint we
will set the expectedTLEs based on the timeline from which we got the
checkpoint record.
See below Logic in WaitForWalToBecomeAvailable
if (readFile < 0)
{
if (!expectedTLEs)
expectedTLEs = readTimeLineHistory(receiveTLI);
Now, the first problem is we are breaking the sanity of expectedTLEs
because as per the definition it should already start with
recoveryTargetTLI but it is starting with the older TLI. Now, in
rescanLatestTimeLine we are trying to fetch the latest TLI which is
still 2, so this logic returns without reinitializing the expectedTLEs
because it assumes that if recoveryTargetTLI is pointing to 2 then
expectedTLEs must be correct and need not be changed.
See below logic:
rescanLatestTimeLine(void)
{
....
newtarget = findNewestTimeLine(recoveryTargetTLI);
if (newtarget == recoveryTargetTLI)
{
/* No new timelines found */
return false;
}
...
newExpectedTLEs = readTimeLineHistory(newtarget);
...
expectedTLEs = newExpectedTLEs;
Solution:
1. Find better way to fix the problem of commit
(ee994272ca50f70b53074f0febaec97e28f83c4e) which is breaking the
sanity of expectedTLEs.
2. Assume, we have to live with fix 1 and we have to initialize
expectedTLEs with an older timeline for validating the checkpoint in
absence of tl.hostory file (as this commit claims). Then as soon as
we read and validate the checkpoint, fix the expectedTLEs and set it
based on the history file of recoveryTargetTLI.
Does this explanation make sense? If not please let me know what part
is not clear in the explanation so I can point to that code.
--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com
Commits
-
Further refinement of stuck_on_old_timeline recovery test
- e46f6a078c1a 9.6.23 landed
- 1dc53c914fe8 10.18 landed
- c0a7587807dd 11.13 landed
- fb3d6b0e1aa4 12.8 landed
- d906d106f854 13.4 landed
- 54a5ed220169 14.0 landed
-
Adjust new test case to set wal_keep_segments.
- 6cd0e55f9ffb 9.6.23 landed
- 1c2c6a9a299c 10.18 landed
- 534b9be805b4 11.13 landed
- 2208d71a0099 12.8 landed
-
Adjust new test case to set wal_keep_size.
- 3465328aa19e 13.4 landed
- 4dcb1d087aeb 14.0 landed
-
Fix corner case failure of new standby to follow new primary.
- 6eb5b9ae3917 9.6.23 landed
- 31bda6a22ad1 10.18 landed
- ca158c168ea3 11.13 landed
- 5d950c721d38 12.8 landed
- 082656429215 13.4 landed
- caba8f0d43fb 14.0 landed
-
Back-port a few PostgresNode.pm methods.
- 75212a854f99 9.6.23 landed
-
Allow PostgresNode.pm's backup method to accept backup_options.
- 9778a191a4c0 10.18 landed
- 38982b8b7bd9 11.13 landed
- 6fc2febc28ae 12.8 landed
- 99a0a2ada8c5 13.4 landed
-
Add end-to-end testing of pg_basebackup's tar-format output.
- 081876d75ea1 14.0 cited
-
Allow PostgresNode.pm tests to wait for catchup
- fb093e4cb36f 10.0 cited
-
Delay reading timeline history file until it's fetched from master.
- ee994272ca50 9.3.0 cited