Skip to content

Commit bccd394

Browse files
author
Mohit Joshi
committed
Added new testcase for PG-1932
1 parent f4102dc commit bccd394

File tree

2 files changed

+184
-1
lines changed

2 files changed

+184
-1
lines changed

postgresql/bugs/PG-1932.sh

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#!/bin/bash
2+
3+
# CONFIGURATION
4+
INSTALL_DIR="$HOME/postgresql/bld_18.1.1/install"
5+
PGDATA="$INSTALL_DIR/data"
6+
LOGFILE=$PGDATA/server.log
7+
ARCHIVE_DIR="$INSTALL_DIR/wal_archive"
8+
BACKUP_DIR="$INSTALL_DIR/base_backup"
9+
PORT=5432
10+
11+
# Cleanup from previous runs
12+
PID=$(lsof -ti :$PORT)
13+
if [ -n "$PID" ]; then
14+
kill -9 $PID
15+
fi
16+
rm -rf "$PGDATA" "$ARCHIVE_DIR" "$BACKUP_DIR" "${PGDATA}_bk" "/tmp/keyring.per"
17+
rm -rf /dev/shm/*
18+
mkdir -p "$ARCHIVE_DIR"
19+
20+
echo "=== Step 1: Initialize primary server ==="
21+
"$INSTALL_DIR/bin/initdb" -D "$PGDATA"
22+
23+
# Configure archive settings
24+
echo "shared_preload_libraries = 'pg_tde'" >> "$PGDATA/postgresql.conf"
25+
echo "io_method = 'sync'" >> "$PGDATA/postgresql.conf"
26+
echo "archive_mode = on" >> "$PGDATA/postgresql.conf"
27+
echo "archive_command = '$INSTALL_DIR/bin/pg_tde_archive_decrypt %f %p \"cp %%p $ARCHIVE_DIR/%%f\"'" >> "$PGDATA/postgresql.conf"
28+
echo "wal_level = replica" >> "$PGDATA/postgresql.conf"
29+
echo "wal_compression = on" >> "$PGDATA/postgresql.conf"
30+
echo "listen_addresses = '*'" >> "$PGDATA/postgresql.conf"
31+
echo "port = $PORT" >> "$PGDATA/postgresql.conf"
32+
echo "logging_collector = on" >> "$PGDATA/postgresql.conf"
33+
echo "log_directory = '$PGDATA'" >> "$PGDATA/postgresql.conf"
34+
echo "log_filename = 'server.log'" >> "$PGDATA/postgresql.conf"
35+
echo "log_statement = 'all'" >> "$PGDATA/postgresql.conf"
36+
37+
echo "=== Step 2: Start PostgreSQL server ==="
38+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w start
39+
sleep 2
40+
41+
echo "=== Step 3: Create extension, keys, and table ==="
42+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "CREATE EXTENSION pg_tde;"
43+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_tde_add_global_key_provider_file('global_provider', '/tmp/keyring.per');"
44+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_tde_create_key_using_global_key_provider('wal_key', 'global_provider');"
45+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_tde_create_key_using_global_key_provider('database_key', 'global_provider');"
46+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_tde_set_server_key_using_global_key_provider('wal_key', 'global_provider');"
47+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_tde_set_key_using_global_key_provider('database_key', 'global_provider');"
48+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "ALTER SYSTEM SET pg_tde.wal_encrypt=ON;"
49+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "CREATE TABLE mohit(id SERIAL PRIMARY KEY, name TEXT) USING tde_heap;"
50+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "INSERT INTO mohit(name) VALUES('before backup 1'), ('before backup 2');"
51+
52+
echo "=== Step 4: Restart server to enable WAL encryption ==="
53+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w restart
54+
sleep 2
55+
56+
echo "=== Step 5: Take a base backup ==="
57+
mkdir $BACKUP_DIR
58+
chmod 700 $BACKUP_DIR
59+
cp -R $PGDATA/pg_tde $BACKUP_DIR/
60+
"$INSTALL_DIR/bin/pg_tde_basebackup" -D "$BACKUP_DIR" -F plain -X stream -E -p $PORT
61+
62+
echo "=== Step 5.1: Insert and capture 5 recovery target times ==="
63+
declare -A RECOVERY_TARGET_TIMES
64+
for i in {1..5}; do
65+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "INSERT INTO mohit(name) VALUES('after backup $i');"
66+
sleep 2
67+
RECOVERY_TARGET_TIMES[$i]=$("$INSTALL_DIR/bin/psql" -d postgres -p $PORT -Atc "SELECT now();")
68+
echo "Captured recovery target time $i: ${RECOVERY_TARGET_TIMES[$i]}"
69+
done
70+
71+
# Switch WAL & force archive
72+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_switch_wal();"
73+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w restart
74+
75+
############################################################
76+
### === TEST A: No temp files after successful archive ===
77+
############################################################
78+
echo "=== TEST A: Checking that no temp files remain after success ==="
79+
if ls /dev/shm | grep -q pg_tde; then
80+
echo "ERROR: Temp files leaked on success"
81+
exit 1
82+
else
83+
echo "OK: No temp files on success"
84+
fi
85+
86+
###############################################################
87+
### === TEST B: Cleanup on failure of wrapped archive cmd ===
88+
###############################################################
89+
echo "=== TEST B: Cleanup on failure of archive command ==="
90+
91+
sed -i "s|cp %%p $ARCHIVE_DIR/%%f|false|" $PGDATA/postgresql.conf
92+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w restart
93+
94+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT pg_switch_wal();"
95+
sleep 2
96+
97+
if ls /dev/shm | grep -q pg_tde; then
98+
echo "ERROR: Temp files leaked on wrapped-command failure"
99+
exit 1
100+
else
101+
echo "OK: Cleanup successful on failure"
102+
fi
103+
104+
# Restore original archive_command
105+
sed -i "s|false|cp %%p $ARCHIVE_DIR/%%f|" $PGDATA/postgresql.conf
106+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w restart
107+
108+
###############################################################
109+
### === TEST C: ENOSPC behavior (/dev/shm full) ===
110+
###############################################################
111+
echo "=== TEST C: Insufficient tmpfs capacity (ENOSPC test) ==="
112+
rm -rf /tmp/fake_wal
113+
touch /tmp/fake_wal
114+
dd if=/dev/urandom of=/tmp/fake_wal bs=1M count=1
115+
116+
# Fill /dev/shm until ENOSPC
117+
echo "Filling /dev/shm..."
118+
counter=0
119+
while :; do
120+
dd if=/dev/urandom of=/dev/shm/fill_$counter bs=1M count=50 2>/dev/null || break
121+
counter=$((counter+1))
122+
done
123+
echo "/dev/shm filled, running pg_tde_archive_decrypt..."
124+
125+
set +e
126+
$INSTALL_DIR/bin/pg_tde_archive_decrypt /tmp/fake_wal /tmp/fake_out "cp %f %p"
127+
RET=$?
128+
set -e
129+
130+
if [ $RET -eq 0 ]; then
131+
echo "pg_tde_archive_decrypt command is successful"
132+
else
133+
echo "ERROR: Not successful"
134+
exit 1
135+
fi
136+
137+
# Cleaning up tmpfs
138+
rm -f /dev/shm/fill_*
139+
140+
###############################################################
141+
### === TEST D: Multiple retries do NOT leak ===
142+
###############################################################
143+
echo "=== TEST D: Multiple retry stress test ==="
144+
145+
for i in {1..8}; do
146+
set +e
147+
$INSTALL_DIR/bin/pg_tde_archive_decrypt /tmp/fake_wal /tmp/fake_out "false"
148+
set -e
149+
150+
if ls /dev/shm | grep -q pg_tde; then
151+
echo "ERROR: Leak on retry $i!"
152+
exit 1
153+
fi
154+
done
155+
156+
echo "OK: No leaks after repeated failures"
157+
158+
echo "=== Printing WAL content from $ARCHIVE_DIR using strings utility ==="
159+
strings $ARCHIVE_DIR/000000010000000000000001 | grep 'before backup'
160+
161+
echo "=== Perform recovery ==="
162+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w stop
163+
164+
rm -rf "$PGDATA"
165+
cp -r "$BACKUP_DIR" "$PGDATA"
166+
167+
sed -i '/restore_command/d' "$PGDATA/postgresql.conf"
168+
sed -i '/recovery_target_time/d' "$PGDATA/postgresql.conf"
169+
170+
echo "restore_command = '$INSTALL_DIR/bin/pg_tde_restore_encrypt %f %p \"cp $ARCHIVE_DIR/%%f %%p\"'" >> "$PGDATA/postgresql.conf"
171+
echo "recovery_target_time = '${RECOVERY_TARGET_TIMES[4]}'" >> "$PGDATA/postgresql.conf"
172+
touch "$PGDATA/recovery.signal"
173+
174+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" -o "-p $PORT" -w start
175+
sleep 5
176+
177+
echo "=== Promote the server ==="
178+
"$INSTALL_DIR/bin/pg_ctl" -D "$PGDATA" promote
179+
sleep 3
180+
181+
echo "=== Verify post-promotion data ==="
182+
"$INSTALL_DIR/bin/psql" -d postgres -p $PORT -c "SELECT * FROM mohit;"
183+

postgresql/tests/run_tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
DIR="."
55

66
# List of files to exclude (space-separated)
7-
EXCLUDE_LIST=("server_upgrade_17.5_17.6.sh" "import_vault_keys_cli_tool.sh" "import_vault_keys.sh" "read_encrypted_wal_using_pg_waldump.sh" "pg_tde_upgrade_test.sh" "change_pg_tde_key_provider.sh" "run_tests.sh")
7+
EXCLUDE_LIST=("server_upgrade_17.5_17.6.sh" "import_vault_keys_cli_tool.sh" "import_vault_keys.sh" "read_encrypted_wal_using_pg_waldump.sh" "pg_tde_upgrade_test.sh" "run_tests.sh")
88

99
# Loop through all .sh files
1010
for file in "$DIR"/*.sh; do

0 commit comments

Comments
 (0)