Skip to content

Commit 1c52918

Browse files
committed
Proceed with major upgrade when data directory lacks checksums
This can happen when a data directory is imported from an external system. Issue: PGO-619
1 parent 380eb6c commit 1c52918

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

internal/controller/pgupgrade/jobs.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,28 @@ func upgradeCommand(spec *v1beta1.PGUpgradeSettings, fetchKeyCommand string) []s
117117
// steps used and command flag specifics can be found in the documentation:
118118
// - https://www.postgresql.org/docs/current/pgupgrade.html
119119

120+
// Examine the old data directory.
121+
`control=$(LC_ALL=C PGDATA="${old_data}" "${old_bin}/pg_controldata")`,
122+
`read -r checksums <<< "${control##*page checksum version:}"`,
123+
124+
// Data checksums on the old and new data directories must match.
125+
// Configuring these checksums depends on the version of initdb:
126+
//
127+
// - PostgreSQL v17 and earlier: disabled by default, enable with "--data-checksums"
128+
// - PostgreSQL v18: enabled by default, enable with "--data-checksums", disable with "--no-data-checksums"
129+
//
130+
// https://www.postgresql.org/docs/release/18#RELEASE-18-MIGRATION
131+
//
132+
// Data page checksum version zero means checksums are disabled.
133+
// Produce an initdb argument that enables or disables data checksums.
134+
//
135+
// https://git.postgresql.org/gitweb/?p=postgresql.git;hb=refs/tags/REL_11_0;f=src/bin/pg_verify_checksums/pg_verify_checksums.c#l303
136+
// https://git.postgresql.org/gitweb/?p=postgresql.git;hb=refs/tags/REL_12_0;f=src/bin/pg_checksums/pg_checksums.c#l523
137+
// https://git.postgresql.org/gitweb/?p=postgresql.git;hb=refs/tags/REL_18_0;f=src/bin/pg_checksums/pg_checksums.c#l571
138+
`checksums=$(if [[ "${checksums}" -gt 0 ]]; then echo '--data-checksums'; elif [[ "${new_version}" -ge 18 ]]; then echo '--no-data-checksums'; fi)`,
139+
120140
`section 'Step 3 of 7: Initializing new data directory...'`,
121-
`PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access --data-checksums` + argEncryptionKeyCommand,
141+
`PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access ${checksums}` + argEncryptionKeyCommand,
122142

123143
// Read the configured value then quote it; every single-quote U+0027 is replaced by two.
124144
//

internal/controller/pgupgrade/jobs_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,11 @@ spec:
222222
(set -x && [[ "$("${old_bin}/postgres" --version)" =~ ") ${old_version}"($|[^0-9]) ]])
223223
(set -x && [[ "$("${new_bin}/initdb" --version)" =~ ") ${new_version}"($|[^0-9]) ]])
224224
cd "${data_volume}"
225+
control=$(LC_ALL=C PGDATA="${old_data}" "${old_bin}/pg_controldata")
226+
read -r checksums <<< "${control##*page checksum version:}"
227+
checksums=$(if [[ "${checksums}" -gt 0 ]]; then echo '--data-checksums'; elif [[ "${new_version}" -ge 18 ]]; then echo '--no-data-checksums'; fi)
225228
section 'Step 3 of 7: Initializing new data directory...'
226-
PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access --data-checksums
229+
PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access ${checksums}
227230
section 'Step 4 of 7: Copying shared_preload_libraries parameter...'
228231
value=$(LC_ALL=C PGDATA="${old_data}" "${old_bin}/postgres" -C shared_preload_libraries)
229232
echo >> "${new_data}/postgresql.conf" "shared_preload_libraries = '${value//$'\''/$'\'\''}'"
@@ -272,7 +275,7 @@ status: {}
272275

273276
tdeJob := reconciler.generateUpgradeJob(ctx, upgrade, startup, "echo testKey")
274277
assert.Assert(t, cmp.MarshalContains(tdeJob,
275-
`PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access --data-checksums --encryption-key-command='echo testKey'`))
278+
`PGDATA="${new_data}" "${new_bin}/initdb" --allow-group-access ${checksums} --encryption-key-command='echo testKey'`))
276279
}
277280

278281
func TestGenerateRemoveDataJob(t *testing.T) {

0 commit comments

Comments
 (0)