Re: standby recovery fails (tablespace related) (tentative patch and discussion)
Paul Guo <guopa@vmware.com>
From: Paul Guo <guopa@vmware.com>
To: Fujii Masao <masao.fujii@oss.nttdata.com>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>, Anastasia Lubennikova <a.lubennikova@postgrespro.ru>, "Asim Praveen (Pivotal)" <apraveen@pivotal.io>, "Lei Wang (Pivotal)" <leiwang@pivotal.io>, Thomas
Munro <thomas.munro@gmail.com>, Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>, PostgreSQL mailing lists <pgsql-hackers@postgresql.org>
Date: 2020-07-08T12:56:44Z
Lists: pgsql-hackers
Attachments
- v10-0001-Support-node-initialization-from-backup-with-tab.patch (application/octet-stream) patch v10-0001
- v10-0002-Tests-to-replay-create-database-operation-on-sta.patch (application/octet-stream) patch v10-0002
- v10-0003-Fix-replay-of-create-database-records-on-standby.patch (application/octet-stream) patch v10-0003
- v10-0004-Fix-database-create-drop-wal-description.patch (application/octet-stream) patch v10-0004
Looks like my previous reply was held for moderation (maybe due to my new email address).
I configured my pg account today using the new email address. I guess this email would be
held for moderation.
I’m now replying my previous reply email and attaching the new patch series.
On Jul 6, 2020, at 10:18 AM, Paul Guo <guopa@vmware.com<mailto:guopa@vmware.com>> wrote:
Thanks for the review. I’m now re-picking up the work. I modified the code following the comments.
Besides, I tweaked the test code a bit. There are several things I’m not 100% sure. Please see
my replies below.
On Jan 27, 2020, at 11:24 PM, Fujii Masao <masao.fujii@oss.nttdata.com<mailto:masao.fujii@oss.nttdata.com>> wrote:
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?
Yes looks like an issue. My understanding is the below scenario.
XLogLogMissingDir()
XLogFlush() in redo (e.g. in a commit redo). <- create a minimum recovery point (we call it LSN_A).
tblspc_redo()->XLogForgetMissingDir()
<- If we panic immediately after we remove the directory in tblspc_redo()
<- when we do replay during crash-recovery, we will check consistency at LSN_A and thus PANIC inXLogCheckMissingDirs()
commit
We should add a XLogFlush() in tblspc_redo(). This brings several other questions to my minds also.
1. Should we call XLogFlush() in dbase_redo() for XLOG_DBASE_DROP also?
It calls both XLogDropDatabase() and XLogForgetMissingDir, which seem to have this issue also?
2. xact_redo_abort() calls DropRelationFiles() also. Why do not we call XLogFlush() there?
- appendStringInfo(buf, "copy dir %u/%u to %u/%u",
- xlrec->src_tablespace_id, xlrec->src_db_id,
- xlrec->tablespace_id, xlrec->db_id);
+ dbpath1 = GetDatabasePath(xlrec->src_db_id, xlrec->src_tablespace_id);
+ dbpath2 = GetDatabasePath(xlrec->db_id, xlrec->tablespace_id);
+ appendStringInfo(buf, "copy dir %s to %s", dbpath1, dbpath2);
+ pfree(dbpath2);
+ pfree(dbpath1);
If the patch is for the bug fix and would be back-ported, the above change
would lead to change pg_waldump's output for CREATE/DROP DATABASE between
minor versions. IMO it's better to avoid such change and separate the above
as a separate patch only for master.
I know we do not want wal format between minor releases, but does wal description string change
between minor releases affect users? Anyone I’ll extract this part into a separate patch in the series
since this change is actually independent of the other changes..
- appendStringInfo(buf, " %u/%u",
- xlrec->tablespace_ids[i], xlrec->db_id);
+ {
+ dbpath1 = GetDatabasePath(xlrec->db_id, xlrec->tablespace_ids[i]);
+ appendStringInfo(buf, "%s", dbpath1);
+ pfree(dbpath1);
+ }
Same as above.
BTW, the above "%s" should be " %s", i.e., a space character needs to be
appended to the head of "%s”.
OK
+ get_parent_directory(parent_path);
+ if (!(stat(parent_path, &st) == 0 && S_ISDIR(st.st_mode)))
+ {
+ XLogLogMissingDir(xlrec->tablespace_id, InvalidOid, dst_path);
The third argument of XLogLogMissingDir() should be parent_path instead of
dst_path?
The argument is for debug message printing so both should be fine, but admittedly we are
logging for the tablespace directory so parent_path might be better.
+ if (hash_search(missing_dir_tab, &key, HASH_REMOVE, NULL) == NULL)
+ elog(DEBUG2, "dir %s tablespace %d database %d is not missing",
+ path, spcNode, dbNode);
I think that this elog() is useless and rather confusing.
OK. Modified.
+ XLogForgetMissingDir(xlrec->ts_id, InvalidOid, "");
The third argument should be set to the actual path instead of an empty
string. Otherwise XLogForgetMissingDir() may emit a confusing DEBUG2
message. Or the third argument of XLogForgetMissingDir() should be removed
and the path in the DEBUG2 message should be calculated from the spcNode
and dbNode in the hash entry in XLogForgetMissingDir().
I’m now removing the third argument. Use GetDatabasePath() to get the path if database did I snot InvalidOid.
+#include "common/file_perm.h"
This seems not necessary.
Right.
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