Skip to content

Commit 722e61f

Browse files
author
Mohit Joshi
committed
Added tests for PG WAL encryption and pg_createsubscriber
1 parent faac82a commit 722e61f

File tree

3 files changed

+406
-0
lines changed

3 files changed

+406
-0
lines changed
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
#!/bin/bash
2+
3+
# Set variable
4+
INSTALL_DIR=/home/mohit.joshi/postgresql/bld_tde/install
5+
PRIMARY_DATA=$INSTALL_DIR/primary_data
6+
REPLICA_DATA=$INSTALL_DIR/replica_data
7+
PRIMARY_LOGFILE=$PRIMARY_DATA/server.log
8+
REPLICA_LOGFILE=$REPLICA_DATA/server.log
9+
TABLES=1000
10+
11+
# initate the database
12+
initialize_server() {
13+
PG_PIDS=$(lsof -ti :5433 -ti :5434 2>/dev/null) || true
14+
if [[ -n "$PG_PIDS" ]]; then
15+
echo "Killing PostgreSQL processes: $PG_PIDS"
16+
kill -9 $PG_PIDS
17+
fi
18+
rm -rf $PRIMARY_DATA $REPLICA_DATA
19+
$INSTALL_DIR/bin/initdb -D $PRIMARY_DATA > /dev/null 2>&1
20+
cat > "$PRIMARY_DATA/postgresql.conf" <<SQL
21+
port=5433
22+
listen_addresses='*'
23+
shared_preload_libraries = 'pg_tde'
24+
logging_collector = on
25+
log_directory = '$PRIMARY_DATA'
26+
log_filename = 'server.log'
27+
log_statement = 'all'
28+
wal_level = 'logical'
29+
default_table_access_method = 'tde_heap'
30+
SQL
31+
32+
cat >> "$PRIMARY_DATA/pg_hba.conf" <<SQL
33+
# Allow replication connections
34+
host replication repuser 127.0.0.1/32 trust
35+
SQL
36+
}
37+
38+
start_primary() {
39+
$INSTALL_DIR/bin/pg_ctl -D $PRIMARY_DATA start -l $PRIMARY_LOGFILE > $PRIMARY_LOGFILE 2>&1
40+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"CREATE USER repuser replication;"
41+
}
42+
43+
stop_server() {
44+
datadir=$1
45+
$INSTALL_DIR/bin/pg_ctl -D $datadir stop
46+
}
47+
48+
start_server() {
49+
datadir=$1
50+
$INSTALL_DIR/bin/pg_ctl -D $datadir start
51+
}
52+
53+
start_replica() {
54+
$INSTALL_DIR/bin/pg_basebackup -h localhost -U repuser --checkpoint=fast -D $REPLICA_DATA -R --slot=somename -C --port=5433
55+
sleep 5
56+
cat >> "$REPLICA_DATA/postgresql.conf" <<SQL
57+
port=5434
58+
logging_collector = on
59+
log_directory = '$REPLICA_DATA'
60+
log_filename = 'server.log'
61+
log_statement = 'all'
62+
SQL
63+
$INSTALL_DIR/bin/pg_ctl -D $REPLICA_DATA -l $REPLICA_LOGFILE start
64+
65+
}
66+
67+
disable_wal_encryption() {
68+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"ALTER SYSTEM SET pg_tde.wal_encrypt=OFF"
69+
stop_server $PRIMARY_DATA
70+
start_server $PRIMARY_DATA
71+
}
72+
73+
enable_wal_encryption() {
74+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"ALTER SYSTEM SET pg_tde.wal_encrypt=ON"
75+
stop_server $PRIMARY_DATA
76+
start_server $PRIMARY_DATA
77+
}
78+
79+
enable_tde_and_create_load() {
80+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"CREATE EXTENSION pg_tde;"
81+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_add_database_key_provider_file('local_key_provider','$PRIMARY_DATA/keyring.file');"
82+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_create_key_using_database_key_provider('local_key','local_key_provider');"
83+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_set_key_using_database_key_provider('local_key','local_key_provider');"
84+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_add_global_key_provider_file('global_key_provider','$PRIMARY_DATA/keyring.file');"
85+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_create_key_using_global_key_provider('global_key','global_key_provider');"
86+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c"SELECT pg_tde_set_server_key_using_global_key_provider('global_key','global_key_provider');"
87+
88+
echo "Create some tables on Primary Node"
89+
sysbench /usr/share/sysbench/oltp_insert.lua --pgsql-user=`whoami` --pgsql-db=postgres --db-driver=pgsql --pgsql-port=5433 --threads=5 --tables=$TABLES --table-size=3000 prepare
90+
}
91+
92+
rotate_server_key() {
93+
echo "Rotating server keys for 30 seconds..."
94+
95+
local start_time=$(date +%s)
96+
local duration=30
97+
98+
while [[ $(($(date +%s) - start_time)) -lt $duration ]]; do
99+
RAND=$RANDOM
100+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c "SELECT pg_tde_create_key_using_global_key_provider('global_key$RAND','global_key_provider');" >/dev/null
101+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c "SELECT pg_tde_set_server_key_using_global_key_provider('global_key$RAND','global_key_provider');" >/dev/null
102+
sleep 2 # optional: adjust to control key rotation rate
103+
done
104+
}
105+
106+
verify_streaming_replication() {
107+
echo "Creating verification table on primary..."
108+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c "CREATE TABLE verify_replication(id INT PRIMARY KEY, val TEXT);" || exit 1
109+
$INSTALL_DIR/bin/psql -d postgres -p 5433 -c "INSERT INTO verify_replication VALUES (1, 'streaming_test');" || exit 1
110+
111+
echo "Waiting for replication to apply..."
112+
sleep 5
113+
114+
echo "Checking data on replica..."
115+
result=$($INSTALL_DIR/bin/psql -d postgres -p 5434 -Atc "SELECT val FROM verify_replication WHERE id=1;" 2>/dev/null)
116+
117+
if [[ "$result" == "streaming_test" ]]; then
118+
echo "Streaming replication is working correctly"
119+
else
120+
echo "Streaming replication failed or is delayed"
121+
exit 1
122+
fi
123+
}
124+
125+
verify_logical_replication() {
126+
echo "Verifying logical replication of sysbench tables..."
127+
128+
local retries=5
129+
local delay=5
130+
local all_tables_replicated=true
131+
132+
for ((i=1; i<=TABLES; i++)); do
133+
table_name="sbtest$i"
134+
echo "Checking table: $table_name"
135+
136+
attempt=1
137+
while (( attempt <= retries )); do
138+
primary_count=$($INSTALL_DIR/bin/psql -d postgres -p 5433 -Atc "SELECT count(*) FROM $table_name;" 2>/dev/null)
139+
replica_count=$($INSTALL_DIR/bin/psql -d postgres -p 5434 -Atc "SELECT count(*) FROM $table_name;" 2>/dev/null)
140+
141+
if [[ "$primary_count" == "$replica_count" ]]; then
142+
echo "Table $table_name replicated successfully with $replica_count rows"
143+
break
144+
else
145+
echo "Mismatch (Attempt $attempt): Primary=$primary_count, Replica=$replica_count"
146+
((attempt++))
147+
sleep $delay
148+
fi
149+
done
150+
151+
if (( attempt > retries )); then
152+
echo "Table $table_name replication failed after $retries attempts"
153+
all_tables_replicated=false
154+
fi
155+
done
156+
157+
if $all_tables_replicated; then
158+
echo "All sysbench tables successfully replicated via logical replication"
159+
else
160+
echo "One or more sysbench tables failed to replicate correctly"
161+
exit 1
162+
fi
163+
}
164+
165+
run_workload_during_conversion() {
166+
echo "Running workload on primary during pg_createsubscriber execution..."
167+
168+
sysbench /usr/share/sysbench/oltp_write_only.lua \
169+
--pgsql-user=$(whoami) \
170+
--pgsql-db=postgres \
171+
--db-driver=pgsql \
172+
--pgsql-port=5433 \
173+
--threads=10 \
174+
--tables=$TABLES \
175+
--table-size=3000 \
176+
--time=60 \
177+
run > /tmp/workload.log 2>&1 &
178+
WORKLOAD_PID=$!
179+
}
180+
181+
run_pg_createsubscriber() {
182+
echo "Running pg_createsubscriber..."
183+
184+
stop_server $REPLICA_DATA
185+
sleep 20
186+
187+
$INSTALL_DIR/bin/pg_createsubscriber \
188+
-d postgres \
189+
-D $REPLICA_DATA \
190+
--subscriber-port=5434 \
191+
--subscriber-username=$(whoami) \
192+
--publisher-server="host=127.0.0.1 port=5433 dbname=postgres user=$(whoami)" \
193+
--publication=mypub \
194+
--subscription=mysub \
195+
--verbose
196+
197+
start_server $REPLICA_DATA
198+
}
199+
200+
# Actual test starts here...
201+
202+
echo "1=>Create Data Directory"
203+
initialize_server
204+
205+
echo "2=>Start Primary Server"
206+
start_primary
207+
208+
echo "3=>Start Replica Server"
209+
start_replica
210+
211+
echo "4=>Enable pg_tde on Primary Server"
212+
enable_tde_and_create_load
213+
214+
echo "5=>Verifying Streaming Replication"
215+
verify_streaming_replication
216+
217+
echo "6=>Run workload in parallel on Primary Server"
218+
run_workload_during_conversion
219+
sleep 15
220+
enable_wal_encryption
221+
run_workload_during_conversion
222+
rotate_server_key &
223+
224+
echo "7=>Convert physical replica into logical replica"
225+
run_pg_createsubscriber
226+
227+
echo "8=>Verifying Logical Replication"
228+
verify_logical_replication
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/bin/bash
2+
3+
INSTALL_DIR="$HOME/postgresql/bld_tde/install"
4+
DATA_DIR_BASE="$INSTALL_DIR/data"
5+
KEYFILE="/tmp/keyfile.per"
6+
PG_PORT=5432
7+
8+
WAL_BUFFER_SIZES=("4MB" "16MB" "32MB")
9+
10+
# Check for pg_tde keyfile
11+
if [[ -f $KEYFILE ]]; then
12+
rm -rf $KEYFILE
13+
fi
14+
15+
run_test() {
16+
local wal_buffer=$1
17+
local data_dir="${DATA_DIR_BASE}_${wal_buffer}"
18+
echo "============================="
19+
echo "Testing with wal_buffers = $wal_buffer"
20+
echo "Data dir: $data_dir"
21+
echo "============================="
22+
23+
pkill -9 postgres
24+
rm -rf "$data_dir"
25+
"$INSTALL_DIR/bin/initdb" -D "$data_dir"
26+
27+
echo "shared_preload_libraries = 'pg_tde'" >> "$data_dir/postgresql.conf"
28+
echo "port = $PG_PORT" >> "$data_dir/postgresql.conf"
29+
echo "wal_buffers = '$wal_buffer'" >> "$data_dir/postgresql.conf"
30+
echo "logging_collector = on" >> "$data_dir/postgresql.conf"
31+
echo "log_directory = 'log'" >> "$data_dir/postgresql.conf"
32+
echo "log_filename = 'postgresql.log'" >> "$data_dir/postgresql.conf"
33+
34+
"$INSTALL_DIR/bin/pg_ctl" -D "$data_dir" -l "$data_dir/server.log" start
35+
sleep 2
36+
37+
# Setup pg_tde
38+
"$INSTALL_DIR/bin/psql" -p $PG_PORT -d postgres -c "CREATE EXTENSION pg_tde;"
39+
"$INSTALL_DIR/bin/psql" -p $PG_PORT -d postgres -c "SELECT pg_tde_add_global_key_provider_file('global_provider', '$KEYFILE');"
40+
"$INSTALL_DIR/bin/psql" -p $PG_PORT -d postgres -c "SELECT pg_tde_create_key_using_global_key_provider('server_key1', 'global_provider');"
41+
"$INSTALL_DIR/bin/psql" -p $PG_PORT -d postgres -c "SELECT pg_tde_set_server_key_using_global_key_provider('server_key1', 'global_provider');"
42+
"$INSTALL_DIR/bin/psql" -p $PG_PORT -d postgres -c "ALTER SYSTEM SET pg_tde.wal_encrypt='ON';"
43+
44+
"$INSTALL_DIR/bin/pg_ctl" -D "$data_dir" restart
45+
sleep 2
46+
47+
# Create test DB and run workload
48+
"$INSTALL_DIR/bin/createdb" -p $PG_PORT testdb
49+
"$INSTALL_DIR/bin/pgbench" -p $PG_PORT -i testdb
50+
"$INSTALL_DIR/bin/pgbench" -p $PG_PORT -c 4 -j 2 -T 30 testdb
51+
52+
# Verify WAL files
53+
echo "Sample hexdump from WAL file:"
54+
WAL_FILE=$(find "$data_dir/pg_wal" -type f | head -n 1)
55+
if [[ -f "$WAL_FILE" ]]; then
56+
hexdump -C "$WAL_FILE" | head -n 10
57+
else
58+
echo "No WAL file found!"
59+
fi
60+
61+
"$INSTALL_DIR/bin/pg_ctl" -D "$data_dir" stop
62+
echo "Test complete for wal_buffers = $wal_buffer"
63+
echo
64+
}
65+
66+
for size in "${WAL_BUFFER_SIZES[@]}"; do
67+
run_test "$size"
68+
done
69+
70+
echo "✅ All tests complete."
71+

0 commit comments

Comments
 (0)