Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 428a260

Browse filesBrowse files
committed
Skip foreign tablespaces when running pg_checksums/pg_verify_checksums
Attempting to use pg_checksums (pg_verify_checksums in 11) on a data folder which includes tablespace paths used across multiple major versions would cause pg_checksums to scan all directories present in pg_tblspc, and not only marked with TABLESPACE_VERSION_DIRECTORY. This could lead to failures when for example running sanity checks on an upgraded instance with --check. Even worse, it was possible to rewrite on-disk pages with --enable for a cluster potentially online. This commit makes pg_checksums skip any directories not named TABLESPACE_VERSION_DIRECTORY, similarly to what is done for base backups. Reported-by: Michael Banck Author: Michael Banck, Bernd Helmle Discussion: https://postgr.es/m/62031974fd8e941dd8351fbc8c7eff60d59c5338.camel@credativ.de backpatch-through: 11
1 parent 05d8449 commit 428a260
Copy full SHA for 428a260

File tree

Expand file treeCollapse file tree

2 files changed

+54
-2
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+54
-2
lines changed
Open diff view settings
Collapse file

‎src/bin/pg_checksums/pg_checksums.c‎

Copy file name to clipboardExpand all lines: src/bin/pg_checksums/pg_checksums.c
+46-1Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,52 @@ scan_directory(const char *basedir, const char *subdir, bool sizeonly)
385385
#else
386386
else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn))
387387
#endif
388-
dirsize += scan_directory(path, de->d_name, sizeonly);
388+
{
389+
/*
390+
* If going through the entries of pg_tblspc, we assume to operate
391+
* on tablespace locations where only TABLESPACE_VERSION_DIRECTORY
392+
* is valid, resolving the linked locations and dive into them
393+
* directly.
394+
*/
395+
if (strncmp("pg_tblspc", subdir, strlen("pg_tblspc")) == 0)
396+
{
397+
char tblspc_path[MAXPGPATH];
398+
struct stat tblspc_st;
399+
400+
/*
401+
* Resolve tablespace location path and check whether
402+
* TABLESPACE_VERSION_DIRECTORY exists. Not finding a valid
403+
* location is unexpected, since there should be no orphaned
404+
* links and no links pointing to something else than a
405+
* directory.
406+
*/
407+
snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s/%s",
408+
path, de->d_name, TABLESPACE_VERSION_DIRECTORY);
409+
410+
if (lstat(tblspc_path, &tblspc_st) < 0)
411+
{
412+
pg_log_error("could not stat file \"%s\": %m",
413+
tblspc_path);
414+
exit(1);
415+
}
416+
417+
/*
418+
* Move backwards once as the scan needs to happen for the
419+
* contents of TABLESPACE_VERSION_DIRECTORY.
420+
*/
421+
snprintf(tblspc_path, sizeof(tblspc_path), "%s/%s",
422+
path, de->d_name);
423+
424+
/* Looks like a valid tablespace location */
425+
dirsize += scan_directory(tblspc_path,
426+
TABLESPACE_VERSION_DIRECTORY,
427+
sizeonly);
428+
}
429+
else
430+
{
431+
dirsize += scan_directory(path, de->d_name, sizeonly);
432+
}
433+
}
389434
}
390435
closedir(dir);
391436
return dirsize;
Collapse file

‎src/bin/pg_checksums/t/002_actions.pl‎

Copy file name to clipboardExpand all lines: src/bin/pg_checksums/t/002_actions.pl
+8-1Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use warnings;
66
use PostgresNode;
77
use TestLib;
8-
use Test::More tests => 62;
8+
use Test::More tests => 63;
99

1010

1111
# Utility routine to create and check a table with corrupted checksums
@@ -217,6 +217,13 @@ sub fail_corrupt
217217
# Stop instance for the follow-up checks.
218218
$node->stop;
219219

220+
# Create a fake tablespace location that should not be scanned
221+
# when verifying checksums.
222+
mkdir "$tablespace_dir/PG_99_999999991/";
223+
append_to_file "$tablespace_dir/PG_99_999999991/foo", "123";
224+
command_ok([ 'pg_checksums', '--check', '-D', $pgdata ],
225+
"succeeds with foreign tablespace");
226+
220227
# Authorized relation files filled with corrupted data cause the
221228
# checksum checks to fail. Make sure to use file names different
222229
# than the previous ones.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.