Skip to content

CI: run the pg_basebackup TAP tests - #2253

Open
tuhaihe wants to merge 10 commits into
apache:mainfrom
tuhaihe:ci-pg-basebackup
Open

tuhaihe wants to merge 10 commits into
apache:mainfrom
tuhaihe:ci-pg-basebackup

Conversation

@tuhaihe

@tuhaihe tuhaihe commented Nov 5, 2026

Copy link
Copy Markdown
Member

CI does not run the TAP tests in src/bin/pg_basebackup, so nobody sees when pg_basebackup breaks. gprecoverseg uses pg_basebackup for full recovery, and gpinitstandby uses it to create the standby coordinator.

Add an ic-pg-basebackup test job that runs them on Rocky 8, 9 and 10.

Assisted-by: Claude Code

Fixes #ISSUE_Number

What does this PR do?

Type of Change

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Breaking change (fix or feature with breaking changes)
  • Documentation update

Breaking Changes

Test Plan

  • Unit tests added/updated
  • Integration tests added/updated
  • Passed make installcheck
  • Passed make -C src/test installcheck-cbdb-parallel

Impact

Performance:

User-facing changes:

Dependencies:

Checklist

Additional Context

CI Skip Instructions


CI does not run the TAP tests in src/bin/pg_basebackup, so nobody sees
when pg_basebackup breaks.  gprecoverseg uses pg_basebackup for full
recovery, and gpinitstandby uses it to create the standby coordinator.

Add an ic-pg-basebackup test job that runs them on Rocky 8, 9 and 10.

Assisted-by: Claude Code
Since the REL_16_9 merge, pg_basebackup -Ft fails every time:

  pg_basebackup: error: could not create file "<dir>/base.tar/99":
  No such file or directory

The merge added the target dbid to the archive file name, so the
archive path became <dir>/<archive>/<dbid>.  It treats the archive name
as a directory that does not exist.  The same happens for base.tar,
for the <tablespace oid>.tar archives and for the .gz, .lz4 and .zst
names.  The dbid belongs in the tablespace directories of a plain
format backup, not in a tar file name.  Before the merge, the file was
written as <dir>/base.tar.

Write the archive to <dir>/<archive> again.  With this change, the
"tar format" and "backup tar was created" checks in 010_pg_basebackup
pass, and the plain and gzip tar backups of a demo cluster with a user
tablespace complete.

Assisted-by: Claude Code
In a plain format backup, the REL_16_9 merge lost the tablespace
mapping (-T) in two places:

- The data of a tablespace went to its location on the server, with
  the target dbid added.  The mapping was not applied.  So the backup
  wrote into the tablespace of the server when the target dbid was
  the same as the dbid of the server.
- The tar parser added the target dbid to each link target before the
  extractor applied the mapping.  "<location>/<dbid>" never matches
  the old directory of a mapping, so the link in pg_tblspc pointed to
  the tablespace of the server, not to the mapped directory.

The tar parser also added the dbid with sprintf() into its own input,
and did it for each member after the first link, because the link
target of a member is not cleared.  So the string got longer for each
file and could overflow.

Apply the mapping to the location first and then add the target dbid,
for both the data and the link, as before the merge.  Remove the
change from the tar parser, which is again the same as upstream.

Assisted-by: Claude Code
Many pg_basebackup commands that PostgreSQL 16 added to the TAP tests
do not pass --target-gp-dbid.  These are the compression option checks,
-X fetch, --target blackhole and server, the slot checks, the gzip
backups, the walsender kill check in 010, and the backup in
011_in_place_tablespace.

pg_basebackup checks for the option before most other options.  So
each command fails with "no target dbid specified".  The commands that
must succeed fail, and the checks for other errors fail because the
message is not the expected one.  Some checks that expect a failure
pass, but for the wrong reason.

Pass the option, as the other tests in these files do.

Assisted-by: Claude Code
Since the REL_16_9 merge, pg_basebackup writes internal.auto.conf
after it receives the archives, for each backup.  Before the merge, it
wrote the file only when it extracted the main tablespace of a plain
format backup.

So with --target, which has no output directory, the backup completes
on the server, and then pg_basebackup fails:

  pg_basebackup: error: could not create file "(null)/internal.auto.conf"

In tar format, pg_basebackup writes the file next to base.tar.  It is
not in the archive, so the backup does not contain it.

Write the file only for a plain format backup to a local directory,
as before the merge.

Assisted-by: Claude Code
A plain format backup of a server with an in-place tablespace does not
contain the data of that tablespace.  pg_tblspc/<oid> in the backup is
an empty directory.  There are two causes.

The REL_16_9 merge moved the Cloudberry code that removes an existing
directory into extract_directory(), but did not keep its condition.
Before the merge, pg_basebackup removed a directory only with
--force-overwrite, because only then can the target directory contain
an earlier data directory.  Now it removes each directory that exists.
The in-place tablespace is extracted into pg_tblspc/<oid> before the
main archive, and the pg_tblspc entry of the main archive then removes
it.

Also, pg_basebackup extracted an in-place tablespace into
pg_tblspc/<oid>/<dbid>.  But an in-place tablespace has no dbid
subdirectory: the server keeps its version directory directly in
pg_tblspc/<oid>.

Remove existing directories only with --force-overwrite again.  As the
version directory of a tablespace is created before the archives are
received, let it exist.  Extract an in-place tablespace into
pg_tblspc/<oid>.

Assisted-by: Claude Code
CREATE TABLESPACE creates the version directory GPDB_<version> with
mode 0700, also when the data directory allows group access.  Before
the REL_16_9 merge, and in PostgreSQL, the directory is created with
MakePGDirectory(), which uses the mode of the data directory.  The
merge changed this to pg_mkdir_p(..., S_IRWXU).  pg_mkdir_p() is
necessary, because it also creates pg_tblspc/<oid> for an in-place
tablespace, but S_IRWXU ignores the mode of the data directory.

So the version directory, and the same directory in a pg_basebackup of
the server, do not allow group access.  The "check backup dir
permissions" test in 010_pg_basebackup.pl fails because of this.

Use pg_dir_create_mode with pg_mkdir_p().

Assisted-by: Claude Code
- 010_pg_basebackup.pl calls done_testing() before the Cloudberry tests
  at the end of the file, so the test fails with "planned 188 tests but
  ran 208".  Call it at the end.
- The "tblspc directory copied" check looks for PG_* in an in-place
  tablespace, but the version directory in Cloudberry is GPDB_*.
- 030_pg_recvlogical.pl prepares a transaction to test the replay of a
  two-phase transaction.  Cloudberry does not support PREPARE
  TRANSACTION in utility mode, so skip that part.

Assisted-by: Claude Code
The REL_16_9 merge changed MAX_TARABLE_SYMLINK_PATH_LENGTH from 100 to
200.  This limit is Cloudberry code, not PostgreSQL code.  The tar
format still keeps only 100 bytes of a link target.

So a tablespace location of 100 to 199 characters does not cause the
"too long for TAR" warning in CREATE TABLESPACE.  A base backup of the
server then fails with the general "symbolic link target too long for
tar format" error and not with the Cloudberry message that tells why.
Two checks in 010_pg_basebackup.pl fail because of this.

Restore the limit to 100, as before the merge.

Assisted-by: Claude Code
@tuhaihe

tuhaihe commented Nov 6, 2026

Copy link
Copy Markdown
Member Author
make[1]: Leaving directory '/__w/cloudberry/cloudberry/src/backend'
echo "# +++ tap install-check in src/bin/pg_basebackup +++" && rm -rf '/__w/cloudberry/cloudberry/src/bin/pg_basebackup'/tmp_check && /usr/bin/mkdir -p '/__w/cloudberry/cloudberry/src/bin/pg_basebackup'/tmp_check && cd . && TESTLOGDIR='/__w/cloudberry/cloudberry/src/bin/pg_basebackup/tmp_check/log' TESTDATADIR='/__w/cloudberry/cloudberry/src/bin/pg_basebackup/tmp_check' PATH="/usr/local/cloudberry-db/bin:/__w/cloudberry/cloudberry/src/bin/pg_basebackup:$PATH" PGPORT='65432' top_builddir='/__w/cloudberry/cloudberry/src/bin/pg_basebackup/../../..' PG_REGRESS='/__w/cloudberry/cloudberry/src/bin/pg_basebackup/../../../src/test/regress/pg_regress' /usr/bin/prove -I ../../../src/test/perl/ -I .  t/*.pl
# +++ tap install-check in src/bin/pg_basebackup +++
"my" variable @tempRelationFiles masks earlier declaration in same scope at t/010_pg_basebackup.pl line 457.

#   Failed test 'failure if method "none" specified with compression level: matches'
#   at t/010_pg_basebackup.pl line 42.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:compression\ algorithm\ \"none\"\ does\ not\ accept\ a\ compression\ level)'

#   Failed test 'failure on incorrect separator to define compression level: matches'
#   at t/010_pg_basebackup.pl line 46.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:unrecognized\ compression\ algorithm\:\ \"none\+\")'

#   Failed test 'client failure on invalid compression algorithm: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ unrecognized\ compression\ algorithm\:\ \"extrasquishy\")'

#   Failed test 'server failure on invalid compression algorithm: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ unrecognized\ compression\ algorithm\:\ \"extrasquishy\")'

#   Failed test 'client failure on empty compression options list: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ found\ empty\ string\ where\ a\ compression\ option\ was\ expected)'

#   Failed test 'server failure on empty compression options list: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ found\ empty\ string\ where\ a\ compression\ option\ was\ expected)'

#   Failed test 'client failure on unknown compression option: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ unrecognized\ compression\ option\:\ \"thunk\")'

#   Failed test 'server failure on unknown compression option: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ unrecognized\ compression\ option\:\ \"thunk\")'

#   Failed test 'client failure on missing compression level: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ compression\ option\ \"level\"\ requires\ a\ value)'

#   Failed test 'server failure on missing compression level: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ compression\ option\ \"level\"\ requires\ a\ value)'

#   Failed test 'client failure on empty compression level: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ value\ for\ compression\ option\ \"level\"\ must\ be\ an\ integer)'

#   Failed test 'server failure on empty compression level: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ value\ for\ compression\ option\ \"level\"\ must\ be\ an\ integer)'

#   Failed test 'client failure on non-numeric compression level: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ value\ for\ compression\ option\ \"level\"\ must\ be\ an\ integer)'

#   Failed test 'server failure on non-numeric compression level: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ value\ for\ compression\ option\ \"level\"\ must\ be\ an\ integer)'

#   Failed test 'client failure on out-of-range compression level: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ expects\ a\ compression\ level\ between\ 1\ and\ 9)'

#   Failed test 'server failure on out-of-range compression level: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ expects\ a\ compression\ level\ between\ 1\ and\ 9)'

#   Failed test 'client failure on extra, empty compression option: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ found\ empty\ string\ where\ a\ compression\ option\ was\ expected)'

#   Failed test 'server failure on extra, empty compression option: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ found\ empty\ string\ where\ a\ compression\ option\ was\ expected)'

#   Failed test 'client failure on worker count for gzip: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ does\ not\ accept\ a\ worker\ count)'

#   Failed test 'server failure on worker count for gzip: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ does\ not\ accept\ a\ worker\ count)'

#   Failed test 'client failure on long mode for gzip: matches'
#   at t/010_pg_basebackup.pl line 157.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ does\ not\ support\ long\-distance\ mode)'

#   Failed test 'server failure on long mode for gzip: matches'
#   at t/010_pg_basebackup.pl line 165.
#                   'pg_basebackup: error: no target dbid specified, --target-gp-dbid is required
# Try "pg_basebackup --help" for more information.
# '
#     doesn't match '(?^:pg_basebackup\:\ error\:\ could\ not\ initiate\ base\ backup\:\ ERROR\:\ \ invalid\ compression\ specification\:\ compression\ algorithm\ \"gzip\"\ does\ not\ support\ long\-distance\ mode)'

#   Failed test 'tar format'
#   at t/010_pg_basebackup.pl line 308.

#   Failed test 'backup tar was created'
#   at t/010_pg_basebackup.pl line 310.
Bailout called.  Further testing stopped:  command "pg_basebackup -D /__w/cloudberry/cloudberry/src/bin/pg_basebackup/tmp_check/t_010_pg_basebackup_main_data/backup/tarbackup2 -h /tmp/0KzhWKLxuS -p 22712 --checkpoint fast --no-sync --target-gp-dbid 99 -Ft" exited with value 1
FAILED--Further testing stopped: command "pg_basebackup -D /__w/cloudberry/cloudberry/src/bin/pg_basebackup/tmp_check/t_010_pg_basebackup_main_data/backup/tarbackup2 -h /tmp/0KzhWKLxuS -p 22712 --checkpoint fast --no-sync --target-gp-dbid 99 -Ft" exited with value 1
make: *** [Makefile:84: installcheck] Error 255
make: Leaving directory '/__w/cloudberry/cloudberry/src/bin/pg_basebackup'
Warning: Test execution failed for configuration 1: make -C src/bin/pg_basebackup installcheck

CREATE TABLESPACE gives a "too long for TAR" warning when the location
is longer than MAX_TARABLE_SYMLINK_PATH_LENGTH allows.  The PAX tests
gp_tablespace, temp_tablespaces and default_tablespace put their
tablespaces below contrib/pax_storage/src/test/regress.  In CI, this
path is long enough to cause the warning.

Before the REL_16_9 merge, these tests ignored the warning and its
DETAIL line.  The merge moved them from input/*.source to sql/*.sql
and removed the ignore rules, or replaced them with rules for a
message that does not exist.  The limit was 200 after the merge, so
no test failed.  Now that the limit is 100 again, the three tests
fail in CI.

Restore the ignore rules as they were before the merge.

Assisted-by: Claude Code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant