Re: standby recovery fails (tablespace related) (tentative patch and discussion)
Kyotaro Horiguchi <horikyota.ntt@gmail.com>
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
To: guopa@vmware.com
Cc: masao.fujii@oss.nttdata.com, alvherre@2ndquadrant.com,
a.lubennikova@postgrespro.ru, apraveen@pivotal.io, leiwang@pivotal.io,
thomas.munro@gmail.com, horiguchi.kyotaro@lab.ntt.co.jp,
pgsql-hackers@postgresql.org
Date: 2021-01-05T01:07:24Z
Lists: pgsql-hackers
At Wed, 8 Jul 2020 12:56:44 +0000, Paul Guo <guopa@vmware.com> wrote in
> On 2020/01/15 19:18, Paul Guo wrote:
> I further fixed the last test failure (due to a small bug in the test, not in code). Attached are the new patch series. Let's see the CI pipeline result.
>
> Thanks for updating the patches!
>
> I started reading the 0003 patch.
>
> The approach that the 0003 patch uses is not the perfect solution.
> If the standby crashes after tblspc_redo() removes the directory and before
> its subsequent COMMIT record is replayed, PANIC error would occur since
> there can be some unresolved missing directory entries when we reach the
> consistent state. The problem would very rarely happen, though...
> Just idea; calling XLogFlush() to update the minimum recovery point just
> before tblspc_redo() performs destroy_tablespace_directories() may be
> safe and helpful for the problem?
It seems to me that what the current patch does is too complex. What
we need to do here is to remember every invalid operation then forget
it when the prerequisite object is dropped.
When a table space is dropped before consistency is established, we
don't need to care what has been performed inside the tablespace. In
this perspective, it is enough to remember tablespace ids when failed
to do something inside it due to the absence of the tablespace and
then forget it when we remove it. We could remember individual
database id to show them in error messages, but I'm not sure it's
useful. The reason log_invalid_page records block numbers is to allow
the machinery handle partial table truncations, but this is not the
case since dropping tablespace cannot leave some of containing
databases.
As the result, we won't see an unresolved invalid operations in a
dropped tablespace.
Am I missing something?
dbase_redo:
+ if (!(stat(parent_path, &st) == 0 && S_ISDIR(st.st_mode)))
+ {
+ XLogRecordMissingDir(xlrec->tablespace_id, InvalidOid, parent_path);
This means "record the belonging table space directory if it is not
found OR it is not a directory". The former can be valid but the
latter is unconditionally can not (I don't think we bother considering
symlinks there).
+ /*
+ * Source directory may be missing. E.g. the template database used
+ * for creating this database may have been dropped, due to reasons
+ * noted above. Moving a database from one tablespace may also be a
+ * partner in the crime.
+ */
+ if (!(stat(src_path, &st) == 0 && S_ISDIR(st.st_mode)))
+ {
+ XLogLogMissingDir(xlrec->src_tablespace_id, xlrec->src_db_id, src_path);
This is a part of *creation* of the target directory. Lack of the
source directory cannot be valid even if the source directory is
dropped afterwards in the WAL stream and we can allow that if the
*target* tablespace is dropped afterwards. As the result, as I
mentioned above, we don't need to record about the database directory.
By the way the name XLogLogMiss.. is somewhat confusing. How about
XLogReportMissingDir (named after report_invalid_page).
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center
Commits
-
Improve recently-added test reliability
- ad0e08394746 10.22 landed
- 9d5c96d9be64 14.5 landed
- 8c5d9ccca967 13.8 landed
- 782e5631e5dd 12.12 landed
- 772e6383d1da 11.17 landed
- 6c1c9f88ad54 16.0 landed
- 6390bc740f90 15.0 landed
-
Fix new recovery test for log_error_verbosity=verbose case
- b998196bb59a 16.0 cited
-
Fix test instability
- fcd72cf295c3 11.17 landed
- 7cfe688dee86 13.8 landed
- 798d64488ca9 15.0 landed
- 6ffaf75a8001 10.22 landed
- 658e5d53459f 12.12 landed
- 59be1c942a47 16.0 landed
- 4d8d85740c02 14.5 landed
-
Fix replay of create database records on standby
- 9e4f914b5eba 16.0 landed
- a3aacb7cbfc7 14.5 landed
- 9a7e26b9c2ac 13.8 landed
- 8348413dbded 15.0 landed
- 6d20f8c5a46a 12.12 landed
- 5a10c262fc60 11.17 landed
- 084318c33a1f 10.22 landed
- ffd28516e699 14.3 landed
- 50e3ed8e9172 13.7 landed
- 49d9cfc68bf4 15.0 landed
-
Allow "in place" tablespaces.
- 961cab0a5a90 14.5 landed
- 16e7a8fd8e97 13.8 landed
- ca347f5433ed 12.12 landed
- 7bdbbb87340f 10.22 landed
- 258c896418bf 11.17 landed
-
Fix get_dirent_type() for Windows junction points.
- fee0165fc1cf 14.5 landed
- 6d306ab73168 15.0 landed
- 9d3444dcce4d 16.0 landed
-
Revert "Fix replay of create database records on standby"
- bf902c13930c 15.0 landed
- adc943b4e1fe 14.3 landed
- a54ed2de80ec 13.7 landed
-
Add end-to-end testing of pg_basebackup's tar-format output.
- 081876d75ea1 14.0 cited
-
Make DROP DATABASE command generate less WAL records.
- e6d8069522c8 13.0 cited
-
Consolidate methods for translating a Perl path to a Windows path.
- 660a2b19038b 12.0 cited