fix(db-tool): postgres-init: createdb on reuse when target DB missing
Previously when PG_REUSE=1 and PG_VERSION existed but the target database had never been successfully created (e.g. devshell exited mid-init in a prior run), postgres-init skipped createdb and the subsequent psql connection failed with 'database "<db>" does not exist'. Now on reuse path we probe pg_database and create the target DB if missing, making postgres-init fully idempotent across stale-state recovery. Adds postgres-init-reuse-missing-db test.
This commit is contained in:
@@ -39,7 +39,13 @@ postgres_init_main() {
|
|||||||
pg_ctl -D "$data" -o "-F" -w start || return 2
|
pg_ctl -D "$data" -o "-F" -w start || return 2
|
||||||
|
|
||||||
user="$(id -un)" || return 1
|
user="$(id -un)" || return 1
|
||||||
if [ "$PG_REUSE" -eq 0 ]; then createdb -h "$sockdir" -U "$user" "$db" || return 1; fi
|
if [ "$PG_REUSE" -eq 0 ]; then
|
||||||
|
createdb -h "$sockdir" -U "$user" "$db" || return 1
|
||||||
|
else
|
||||||
|
if ! psql -h "$sockdir" -p "$PG_PORT" -U "$user" -d postgres -tAc "select 1 from pg_database where datname = '$db'" 2>/dev/null | grep -q '^1$'; then
|
||||||
|
createdb -h "$sockdir" -U "$user" "$db" || return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
psql -h "$sockdir" -p "$PG_PORT" -d "$db" -v ON_ERROR_STOP=1 -c 'select 1;' || return 1
|
psql -h "$sockdir" -p "$PG_PORT" -d "$db" -v ON_ERROR_STOP=1 -c 'select 1;' || return 1
|
||||||
|
|
||||||
export POSTGRESQL_HOST="$sockdir" POSTGRESQL_PORT="$PG_PORT" POSTGRESQL_USER="$user" POSTGRESQL_DATABASE="$db"
|
export POSTGRESQL_HOST="$sockdir" POSTGRESQL_PORT="$PG_PORT" POSTGRESQL_USER="$user" POSTGRESQL_DATABASE="$db"
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# shellcheck shell=dash
|
||||||
|
|
||||||
|
HECTIC_NAMESPACE=test-db-tool-postgres-init-reuse-missing-db
|
||||||
|
|
||||||
|
PG_WORKING_DIR=$(mktemp -d)
|
||||||
|
export PG_WORKING_DIR PG_DATABASE=testdb PG_PORT=5432 PG_SHARED_PRELOAD_LIBRARIES=''
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
postgres-cleanup >/dev/null 2>&1 || :
|
||||||
|
rm -rf "$PG_WORKING_DIR"
|
||||||
|
}
|
||||||
|
trap 'cleanup' EXIT INT TERM
|
||||||
|
|
||||||
|
log notice "step 1: fresh init creates testdb"
|
||||||
|
if ! postgres-init; then
|
||||||
|
log error "initial postgres-init failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log notice "step 2: drop testdb to simulate stale-state cluster"
|
||||||
|
sockdir="$PG_WORKING_DIR/sock"
|
||||||
|
if ! dropdb -h "$sockdir" -p "$PG_PORT" -U "$(id -un)" testdb; then
|
||||||
|
log error "dropdb failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log notice "step 3: stop cluster (simulate prior devshell exit)"
|
||||||
|
postgres-cleanup >/dev/null 2>&1 || :
|
||||||
|
|
||||||
|
log notice "step 4: re-init with PG_REUSE=1 must recreate missing testdb"
|
||||||
|
export PG_REUSE=1
|
||||||
|
if ! postgres-init; then
|
||||||
|
log error "postgres-init with PG_REUSE=1 and missing DB failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
unset PG_REUSE
|
||||||
|
|
||||||
|
log notice "step 5: verify testdb is reachable"
|
||||||
|
pgurl="postgresql://$(id -un)@/testdb?host=${sockdir}&port=5432"
|
||||||
|
if ! psql "$pgurl" -c 'SELECT 1;' >/dev/null 2>&1; then
|
||||||
|
log error "testdb not reachable after reuse-create"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
log notice "test passed"
|
||||||
Reference in New Issue
Block a user