On Tue, Nov 30, 2021 at 3:14 AM Andrew Dunstan <and...@dunslane.net> wrote: > choco install -y Carbon > Import-Module Carbon > Grant-CPrivilege -Identity myuser -Privilege SeCreateSymbolicLinkPrivilege
Interesting. Well, I found the problem with my last patch (to wit: junction points must be absolute, unlike real symlinks, which I'd considered already but I missed that tmp_check's DataDir had a stray internal \.\), and now I'm wondering whether these newer real symlinks could help. The constraints are pretty hard to work with... I thought about a couple of options: 1. We could try to use real symlinks, and fall back to junction points if that fails. That means that these new tests I'm proposing would fail unless you grant that privilege or run in developer mode as you were saying. It bothers me a bit that developers and the BF would be testing a different code path than production databases run... unless you're thinking we should switch to symlinks with no fallback, and require that privilege to be granted by end users to production servers at least if they want to use tablespaces, and also drop pre-Win10 support in the same release? That's bigger than I was thinking. 2. We could convert relative paths to absolute paths at junction point creation time, which I tried, and "check" now passes. Problems: (1) now you can't move pgdata around, (2) the is-the-path-too-long check performed on a primary is not sufficient to check if the transformed absolute path will be too long on a replica. The most conservative simple idea I have so far is: go with option 2, but make this whole thing an undocumented developer-only mode, and turn it on in the regression tests. Here's a patch set like that. Thoughts? Another option would be to stop using operating system symlinks, and build the target paths ourselves; I didn't investigate that as it seemed like a bigger change than this warrants. Next problem: The below is clearly not the right way to find the pg_regress binary and bindir, and doesn't work on Windows or VPATH. Any suggestions for how to do this? I feel like something like $node->installed_command() or similar logic is needed... # Run the regression tests against the primary. # XXX How should we find the pg_regress binary and bindir? system_or_bail("../regress/pg_regress", "--bindir=../../bin/psql", "--port=" . $node_primary->port, "--schedule=../regress/parallel_schedule", "--dlpath=../regress", "--inputdir=../regress"); BTW 0002 is one of those renaming patches from git that GNU patch doesn't seem to apply correctly, sorry cfbot...
From 1a442bfde9b44d28db7344df56e5c0069dbd2364 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Tue, 25 May 2021 20:42:17 +1200 Subject: [PATCH v7 1/5] Allow restricted relative tablespace paths. Traditionally, tablespace paths provided to LOCATION had to be absolute, because relative paths risked colliding with PostgreSQL-managed files and generally blurring the boundary between system-managed and user-managed data. This commit adds a very small exception: it allows relative paths to be used, but only under a new directory "pg_user_files", and only if the developer-only option allow_relative_tablespaces is enabled. This is intended to be used in automated testing. Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- src/backend/commands/tablespace.c | 55 +++++++++++++++++++++++++++---- src/backend/utils/misc/guc.c | 12 +++++++ src/bin/initdb/initdb.c | 1 + src/common/string.c | 9 +++++ src/include/commands/tablespace.h | 2 ++ src/include/common/string.h | 1 + src/port/dirmod.c | 4 +++ 7 files changed, 77 insertions(+), 7 deletions(-) diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 4b96eec9df..7e98ca5b76 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -70,6 +70,7 @@ #include "commands/tablecmds.h" #include "commands/tablespace.h" #include "common/file_perm.h" +#include "common/string.h" #include "miscadmin.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" @@ -87,6 +88,7 @@ /* GUC variables */ char *default_tablespace = NULL; char *temp_tablespaces = NULL; +bool allow_relative_tablespaces = false; static void create_tablespace_directories(const char *location, @@ -267,11 +269,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) errmsg("tablespace location cannot contain single quotes"))); /* - * Allowing relative paths seems risky + * Allowing relative paths seems risky in general, but we'll allow it under + * pg_user_files if a developer-mode option is enabled, for the purpose + * of testing. * * this also helps us ensure that location is not empty or whitespace */ - if (!is_absolute_path(location)) + if (!is_absolute_path(location) && + (!allow_relative_tablespaces || + !pg_str_startswith(location, "pg_user_files/"))) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("tablespace location must be an absolute path"))); @@ -587,6 +593,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) static void create_tablespace_directories(const char *location, const Oid tablespaceoid) { + char buffer[MAXPGPATH]; char *linkloc; char *location_with_version_dir; struct stat st; @@ -602,11 +609,27 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) if (chmod(location, pg_dir_create_mode) != 0) { if (errno == ENOENT) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FILE), - errmsg("directory \"%s\" does not exist", location), - InRecovery ? errhint("Create this directory for the tablespace before " - "restarting the server.") : 0)); + { + /* + * We're prepared to create directories under pg_user_files on the + * fly, for the benefit of regression tests. + */ + if (pg_str_startswith(location, "pg_user_files/")) + { + Assert(allow_relative_tablespaces || InRecovery); + if (mkdir(location, pg_dir_create_mode) != 0) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FILE), + errmsg("could not create directory \"%s\"", + location))); + } + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FILE), + errmsg("directory \"%s\" does not exist", location), + InRecovery ? errhint("Create this directory for the tablespace before " + "restarting the server.") : 0)); + } else ereport(ERROR, (errcode_for_file_access(), @@ -651,6 +674,24 @@ create_tablespace_directories(const char *location, const Oid tablespaceoid) if (InRecovery) remove_tablespace_symlink(linkloc); + if (!is_absolute_path(location)) + { +#ifdef WIN32 + /* + * Our Windows junction-based symlink() emulation can't handle relative + * paths, so convert "pg_user_files" to an absolute path. + */ + snprintf(buffer, sizeof(buffer), "%s/%s", DataDir, location); +#else + /* + * Add a ".." prefix so that we have a path relative to the symlink, + * rather than DataDir. + */ + snprintf(buffer, sizeof(buffer), "../%s", location); +#endif + location = buffer; + } + /* * Create the symlink under PGDATA */ diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ee6a838b3a..ab11bee118 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -46,6 +46,7 @@ #include "catalog/storage.h" #include "commands/async.h" #include "commands/prepare.h" +#include "commands/tablespace.h" #include "commands/trigger.h" #include "commands/user.h" #include "commands/vacuum.h" @@ -1963,6 +1964,17 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"allow_relative_tablespaces", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Allows the tablespaces located under pg_user_files."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &allow_relative_tablespaces, + false, + NULL, NULL, NULL + }, + { {"lo_compat_privileges", PGC_SUSET, COMPAT_OPTIONS_PREVIOUS, gettext_noop("Enables backward compatibility mode for privilege checks on large objects."), diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 403adb0ee7..7c4b3e9626 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -225,6 +225,7 @@ static const char *const subdirs[] = { "pg_tblspc", "pg_stat", "pg_stat_tmp", + "pg_user_files", "pg_xact", "pg_logical", "pg_logical/snapshots", diff --git a/src/common/string.c b/src/common/string.c index 3aa378c051..7e7e34f1f5 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -24,6 +24,15 @@ #include "common/string.h" +/* + * Returns whether the string `str' has the prefix `start'. + */ +bool +pg_str_startswith(const char *str, const char *start) +{ + return strncmp(str, start, strlen(start)) == 0; +} + /* * Returns whether the string `str' has the postfix `end'. */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index 49cfc8479a..d286ced1c8 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -19,6 +19,8 @@ #include "lib/stringinfo.h" #include "nodes/parsenodes.h" +extern bool allow_relative_tablespaces; + /* XLOG stuff */ #define XLOG_TBLSPC_CREATE 0x00 #define XLOG_TBLSPC_DROP 0x10 diff --git a/src/include/common/string.h b/src/include/common/string.h index 8eb5271ec8..ddd384f6f9 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -21,6 +21,7 @@ typedef struct PromptInterruptContext } PromptInterruptContext; /* functions in src/common/string.c */ +extern bool pg_str_startswith(const char *str, const char *start); extern bool pg_str_endswith(const char *str, const char *end); extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base); diff --git a/src/port/dirmod.c b/src/port/dirmod.c index 763bc5f915..8787912d03 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -182,6 +182,10 @@ pgsymlink(const char *oldpath, const char *newpath) while ((p = strchr(p, '/')) != NULL) *p++ = '\\'; + /* collapse useless instances of "\.\" to "\" */ + while ((p = strstr(nativeTarget, "\\.\\")) != NULL) + memmove(p, p + 2, strlen(p + 2) + 1); + len = strlen(nativeTarget) * sizeof(WCHAR); reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; reparseBuf->ReparseDataLength = len + 12; -- 2.33.1
From 9c4937895d969389157e7f9df9d031ecd1cbc8f4 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Wed, 4 Aug 2021 22:17:54 +1200 Subject: [PATCH v7 2/5] Use relative paths for tablespace regression test. Remove the machinery from pg_regress that manages the testtablespace directory. Instead, use a relative path. Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- src/test/regress/GNUmakefile | 3 +- .../tablespace.out} | 18 +++++++-- src/test/regress/pg_regress.c | 40 ------------------- .../tablespace.source => sql/tablespace.sql} | 19 +++++++-- src/tools/msvc/vcregress.pl | 2 - 5 files changed, 32 insertions(+), 50 deletions(-) rename src/test/regress/{output/tablespace.source => expected/tablespace.out} (97%) rename src/test/regress/{input/tablespace.source => sql/tablespace.sql} (95%) diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile index fe6e0c98aa..d014b4a35d 100644 --- a/src/test/regress/GNUmakefile +++ b/src/test/regress/GNUmakefile @@ -119,7 +119,7 @@ submake-contrib-spi: | submake-libpgport submake-generated-headers ## Run tests ## -REGRESS_OPTS = --dlpath=. --max-concurrent-tests=20 --make-testtablespace-dir \ +REGRESS_OPTS = --dlpath=. --max-concurrent-tests=20 \ $(EXTRA_REGRESS_OPTS) check: all @@ -163,5 +163,4 @@ clean distclean maintainer-clean: clean-lib rm -f pg_regress_main.o pg_regress.o pg_regress$(X) # things created by various check targets rm -f $(output_files) $(input_files) - rm -rf testtablespace rm -rf $(pg_regress_clean_files) diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/expected/tablespace.out similarity index 97% rename from src/test/regress/output/tablespace.source rename to src/test/regress/expected/tablespace.out index e7629d470e..7386693e05 100644 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/expected/tablespace.out @@ -1,7 +1,19 @@ +-- Note: this test uses relative paths and expects the server to create the +-- directory on the fly, so that a streaming replica on the same system can +-- replay it. Normally we require absolute paths to directories that already +-- exist. +-- create a tablespace under a relative path +SET allow_relative_tablespaces = off; +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace'; -- fail +ERROR: tablespace location must be an absolute path +-- enable developer option allowing relative paths, with unacceptable prefix +SET allow_relative_tablespaces = on; +CREATE TABLESPACE regress_tblspacewith LOCATION 'xyz/testtablespace'; -- fail +ERROR: tablespace location must be an absolute path -- create a tablespace using WITH clause -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (some_nonexistent_parameter = true); -- fail ERROR: unrecognized parameter "some_nonexistent_parameter" -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (random_page_cost = 3.0); -- ok -- check to see the parameter was used SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; spcoptions @@ -12,7 +24,7 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; -- drop the tablespace so we can re-use the location DROP TABLESPACE regress_tblspacewith; -- create a tablespace we can use -CREATE TABLESPACE regress_tblspace LOCATION '@testtablespace@'; +CREATE TABLESPACE regress_tblspace LOCATION 'pg_user_files/testtablespace'; -- try setting and resetting some properties for the new tablespace ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true); -- fail diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index 2c8a600bad..7c1404dac1 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -477,7 +477,6 @@ replace_string(StringInfo string, const char *replace, const char *replacement) static void convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const char *dest_subdir, const char *suffix) { - char testtablespace[MAXPGPATH]; char indir[MAXPGPATH]; char outdir_sub[MAXPGPATH]; char **name; @@ -506,9 +505,6 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch if (!directory_exists(outdir_sub)) make_directory(outdir_sub); - /* We might need to replace @testtablespace@ */ - snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", outputdir); - /* finally loop on each file and do the replacement */ for (name = names; *name; name++) { @@ -554,7 +550,6 @@ convert_sourcefiles_in(const char *source_subdir, const char *dest_dir, const ch { replace_string(&line, "@abs_srcdir@", inputdir); replace_string(&line, "@abs_builddir@", outputdir); - replace_string(&line, "@testtablespace@", testtablespace); replace_string(&line, "@libdir@", dlpath); replace_string(&line, "@DLSUFFIX@", DLSUFFIX); fputs(line.data, outfile); @@ -587,32 +582,6 @@ convert_sourcefiles(void) convert_sourcefiles_in("output", outputdir, "expected", "out"); } -/* - * Clean out the test tablespace dir, or create it if it doesn't exist. - * - * On Windows, doing this cleanup here makes it possible to run the - * regression tests under a Windows administrative user account with the - * restricted token obtained when starting pg_regress. - */ -static void -prepare_testtablespace_dir(void) -{ - char testtablespace[MAXPGPATH]; - - snprintf(testtablespace, MAXPGPATH, "%s/testtablespace", outputdir); - - if (directory_exists(testtablespace)) - { - if (!rmtree(testtablespace, true)) - { - fprintf(stderr, _("\n%s: could not remove test tablespace \"%s\"\n"), - progname, testtablespace); - exit(2); - } - } - make_directory(testtablespace); -} - /* * Scan resultmap file to find which platform-specific expected files to use. * @@ -2152,7 +2121,6 @@ help(void) printf(_(" --launcher=CMD use CMD as launcher of psql\n")); printf(_(" --load-extension=EXT load the named extension before running the\n")); printf(_(" tests; can appear multiple times\n")); - printf(_(" --make-testtablespace-dir create testtablespace directory\n")); printf(_(" --max-connections=N maximum number of concurrent connections\n")); printf(_(" (default is 0, meaning unlimited)\n")); printf(_(" --max-concurrent-tests=N maximum number of concurrent tests in schedule\n")); @@ -2211,12 +2179,10 @@ regression_main(int argc, char *argv[], {"load-extension", required_argument, NULL, 22}, {"config-auth", required_argument, NULL, 24}, {"max-concurrent-tests", required_argument, NULL, 25}, - {"make-testtablespace-dir", no_argument, NULL, 26}, {NULL, 0, NULL, 0} }; bool use_unix_sockets; - bool make_testtablespace_dir = false; _stringlist *sl; int c; int i; @@ -2342,9 +2308,6 @@ regression_main(int argc, char *argv[], case 25: max_concurrent_tests = atoi(optarg); break; - case 26: - make_testtablespace_dir = true; - break; default: /* getopt_long already emitted a complaint */ fprintf(stderr, _("\nTry \"%s -h\" for more information.\n"), @@ -2397,9 +2360,6 @@ regression_main(int argc, char *argv[], unlimit_core_size(); #endif - if (make_testtablespace_dir) - prepare_testtablespace_dir(); - if (temp_instance) { FILE *pg_conf; diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/sql/tablespace.sql similarity index 95% rename from src/test/regress/input/tablespace.source rename to src/test/regress/sql/tablespace.sql index cb9774ecc8..6c79eb0333 100644 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/sql/tablespace.sql @@ -1,6 +1,19 @@ +-- Note: this test uses relative paths and expects the server to create the +-- directory on the fly, so that a streaming replica on the same system can +-- replay it. Normally we require absolute paths to directories that already +-- exist. + +-- create a tablespace under a relative path +SET allow_relative_tablespaces = off; +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace'; -- fail + +-- enable developer option allowing relative paths, with unacceptable prefix +SET allow_relative_tablespaces = on; +CREATE TABLESPACE regress_tblspacewith LOCATION 'xyz/testtablespace'; -- fail + -- create a tablespace using WITH clause -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (some_nonexistent_parameter = true); -- fail -CREATE TABLESPACE regress_tblspacewith LOCATION '@testtablespace@' WITH (random_page_cost = 3.0); -- ok +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (some_nonexistent_parameter = true); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION 'pg_user_files/testtablespace' WITH (random_page_cost = 3.0); -- ok -- check to see the parameter was used SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; @@ -9,7 +22,7 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; DROP TABLESPACE regress_tblspacewith; -- create a tablespace we can use -CREATE TABLESPACE regress_tblspace LOCATION '@testtablespace@'; +CREATE TABLESPACE regress_tblspace LOCATION 'pg_user_files/testtablespace'; -- try setting and resetting some properties for the new tablespace ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl index f3357b3292..92debf9b0f 100644 --- a/src/tools/msvc/vcregress.pl +++ b/src/tools/msvc/vcregress.pl @@ -118,7 +118,6 @@ sub installcheck_internal "--bindir=../../../$Config/psql", "--schedule=${schedule}_schedule", "--max-concurrent-tests=20", - "--make-testtablespace-dir", "--encoding=SQL_ASCII", "--no-locale"); push(@args, $maxconn) if $maxconn; @@ -153,7 +152,6 @@ sub check "--bindir=", "--schedule=${schedule}_schedule", "--max-concurrent-tests=20", - "--make-testtablespace-dir", "--encoding=SQL_ASCII", "--no-locale", "--temp-instance=./tmp_check"); -- 2.33.1
From 5ad0e41cdad1539221f61d2a47a6f3486310fad8 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Tue, 5 Oct 2021 21:01:02 +1300 Subject: [PATCH v7 3/5] Test replay of regression tests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new TAP test under src/test/recovery to run the standard regression tests while a streaming replica replays the WAL. This provides a basic workout for WAL decoding and redo code, and compares the replicated result. Optionally, enable (expensive) wal_consistency_checking if listed in the env variable PG_TEST_EXTRA. Reviewed-by: 綱川 貴之 (Takayuki Tsunakawa) <tsunakawa.ta...@fujitsu.com> Reviewed-by: Andres Freund <and...@anarazel.de> Reviewed-by: Andrew Dunstan <and...@dunslane.net> Reviewed-by: Tom Lane <t...@sss.pgh.pa.us> Reviewed-by: Anastasia Lubennikova <lubennikov...@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGKpRWQ9SxdxxDmTBCJoR0YnFpMBe7kyzY8SUQk%2BHeskxg%40mail.gmail.com --- doc/src/sgml/regress.sgml | 11 ++++ src/test/perl/PostgreSQL/Test/Cluster.pm | 2 +- src/test/recovery/t/027_stream_regress.pl | 69 +++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/test/recovery/t/027_stream_regress.pl diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index 724ef566e7..64fc81776d 100644 --- a/doc/src/sgml/regress.sgml +++ b/doc/src/sgml/regress.sgml @@ -289,6 +289,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl' </para> </listitem> </varlistentry> + + <varlistentry> + <term><literal>wal_consistency_checking</literal></term> + <listitem> + <para> + Uses <literal>wal_consistency_checking=all</literal> while running + some of the tests under <filename>src/test/recovery</filename>. Not + enabled by default because it is resource intensive. + </para> + </listitem> + </varlistentry> </variablelist> Tests for features that are not supported by the current build diff --git a/src/test/perl/PostgreSQL/Test/Cluster.pm b/src/test/perl/PostgreSQL/Test/Cluster.pm index 9467a199c8..5cfa137cde 100644 --- a/src/test/perl/PostgreSQL/Test/Cluster.pm +++ b/src/test/perl/PostgreSQL/Test/Cluster.pm @@ -460,7 +460,7 @@ sub init print $conf "hot_standby = on\n"; # conservative settings to ensure we can run multiple postmasters: print $conf "shared_buffers = 1MB\n"; - print $conf "max_connections = 10\n"; + print $conf "max_connections = 25\n"; # limit disk space consumption, too: print $conf "max_wal_size = 128MB\n"; } diff --git a/src/test/recovery/t/027_stream_regress.pl b/src/test/recovery/t/027_stream_regress.pl new file mode 100644 index 0000000000..a9eead02cf --- /dev/null +++ b/src/test/recovery/t/027_stream_regress.pl @@ -0,0 +1,69 @@ +# Run the standard regression tests with streaming replication +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More tests => 4; + +# Initialize primary node +my $node_primary = PostgreSQL::Test::Cluster->new('primary'); +$node_primary->init(allows_streaming => 1); + +# WAL consistency checking is resource intensive so require opt-in with the +# PG_TEST_EXTRA environment variable. +if ($ENV{PG_TEST_EXTRA} && + $ENV{PG_TEST_EXTRA} =~ m/\bwal_consistency_checking\b/) { + $node_primary->append_conf('postgresql.conf', + 'wal_consistency_checking = all'); +} + +$node_primary->start; +is( $node_primary->psql( + 'postgres', + qq[SELECT pg_create_physical_replication_slot('standby_1');]), + 0, + 'physical slot created on primary'); +my $backup_name = 'my_backup'; + +# Take backup +$node_primary->backup($backup_name); + +# Create streaming standby linking to primary +my $node_standby_1 = PostgreSQL::Test::Cluster->new('standby_1'); +$node_standby_1->init_from_backup($node_primary, $backup_name, + has_streaming => 1); +$node_standby_1->append_conf('postgresql.conf', + "primary_slot_name = standby_1"); +$node_standby_1->start; + +# Run the regression tests against the primary. +# XXX How should we find the pg_regress binary and bindir? +system_or_bail("../regress/pg_regress", + "--bindir=../../bin/psql", + "--port=" . $node_primary->port, + "--schedule=../regress/parallel_schedule", + "--dlpath=../regress", + "--inputdir=../regress"); + +# Clobber all sequences with their next value, so that we don't have +# differences between nodes due to caching. +$node_primary->psql('regression', + "select setval(seqrelid, nextval(seqrelid)) from pg_sequence"); + +# Wait for standby to catch up +$node_primary->wait_for_catchup($node_standby_1, 'replay', + $node_primary->lsn('insert')); + +# Perform a logical dump of primary and standby, and check that they match +command_ok( + [ "pg_dump", '-f', 'primary.dump', '--no-sync', '-p', $node_primary->port, 'regression' ], + "dump primary server"); +command_ok( + [ "pg_dump", '-f', 'standby.dump', '--no-sync', '-p', $node_standby_1->port, 'regression' ], + "dump standby server"); +command_ok( + [ "diff", 'primary.dump', 'standby.dump' ], + "compare primary and standby dumps"); + +$node_standby_1->stop; +$node_primary->stop; -- 2.33.1