Skip to content

Commit f30b139

Browse files
Merge pull request #1752 from satya-bodapati/8.4
PXB-3768 [8.4]: Fix test failures on Jenkins
2 parents d6bb941 + 71f577b commit f30b139

6 files changed

Lines changed: 164 additions & 10 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#
2+
# PXB-3762: xtrabackup --backup --transition-key crashes when an undo
3+
# tablespace encryption key exists in redo only (newer than the on-disk
4+
# undo page).
5+
#
6+
# JIRA URL: https://perconadev.atlassian.net/browse/PXB-3762
7+
#
8+
# Strategy:
9+
# 1. Use release-safe server knobs that reduce page flushing pressure.
10+
# 2. Build enough undo/redo activity on an encrypted table.
11+
# 3. Rotate master key immediately before backup.
12+
# 4. Start backup with --transition-key right away.
13+
#
14+
# This widens the race window for "redo key exists and is newer than
15+
# undo-page LSN", which is required to enter Condition 1 in
16+
# srv_undo_tablespace_read_encryption().
17+
#
18+
require_server_version_higher_than 8.4.0
19+
20+
KEYRING_TYPE="component"
21+
. inc/keyring_common.sh
22+
. inc/keyring_file.sh
23+
24+
# Keep dirty pages in memory longer so on-disk undo pages are more likely
25+
# to lag behind redo-encryption records right after key rotation.
26+
MYSQLD_EXTRA_MY_CNF_OPTS="${MYSQLD_EXTRA_MY_CNF_OPTS}
27+
innodb_buffer_pool_size=512M
28+
innodb_log_file_size=256M
29+
innodb_io_capacity=100
30+
innodb_io_capacity_max=200
31+
innodb_max_dirty_pages_pct=95
32+
innodb_max_dirty_pages_pct_lwm=0
33+
"
34+
35+
configure_server_with_component
36+
37+
mysql -e "CREATE TABLE t (
38+
a BIGINT PRIMARY KEY AUTO_INCREMENT,
39+
b LONGBLOB
40+
) ENGINE=InnoDB ENCRYPTION='y'" test
41+
mysql -e "INSERT INTO t(b) VALUES (REPEAT(UUID(), 256))" test
42+
43+
for attempt in $(seq 1 5); do
44+
vlog "=== attempt ${attempt}/5: rotate + backup + prepare + restore ==="
45+
46+
backup_dir=$topdir/backup.$attempt
47+
mkdir -p "$backup_dir"
48+
49+
# Generate undo/redo churn right before rotation.
50+
for i in $(seq 1 200); do
51+
mysql -e "INSERT INTO t(b) VALUES (REPEAT(UUID(), 256))" test >/dev/null 2>&1
52+
mysql -e "DELETE FROM t WHERE a % 13 = 0 ORDER BY a LIMIT 2" test >/dev/null 2>&1
53+
done
54+
55+
# Rotate right before backup so redo key LSN can be newer than on-disk undo.
56+
mysql -e "ALTER INSTANCE ROTATE INNODB MASTER KEY" test
57+
58+
record_db_state test
59+
60+
xtrabackup --backup --transition-key=123 --target-dir="$backup_dir"
61+
xtrabackup --prepare --transition-key=123 --target-dir="$backup_dir"
62+
63+
stop_server
64+
rm -rf "$mysql_datadir"
65+
xtrabackup --copy-back --target-dir="$backup_dir"
66+
cp "${instance_local_manifest}" "$mysql_datadir"
67+
cp "${keyring_component_cnf}" "$mysql_datadir"
68+
start_server
69+
70+
verify_db_state test
71+
rm -rf "$backup_dir"
72+
done

storage/innobase/xtrabackup/test/t/PXB-2854_xbstream_memory_corruption.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
# PXB-2854 - Quicklz decompression memory corruption issue
2+
# xbstream still decompresses legacy .qp streams; skip cleanly when
3+
# the standalone qpress binary used to build the fixture is missing.
4+
5+
require_qpress
26

37
head -c 100000 </dev/urandom > $topdir/payload.bin
48
qpress $topdir/payload.bin $topdir/payload.qp

storage/innobase/xtrabackup/test/t/bug1600656.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,10 @@ xbstream -xv -C $topdir/backup < $topdir/backup/stream.xbs
2424
vlog "#########################################################################"
2525
vlog "Verifying that streamed and 'extra copy' of xtrabackup_info do not differ"
2626

27-
diff -q $topdir/backup/xtrabackup_info $topdir/lsndir/xtrabackup_info
27+
# The (uncompressed_)backup_size lines are sampled at different times
28+
# in the two copies, so they intentionally differ. Strip them before
29+
# diffing and verify everything else matches.
30+
diff <(sed -E '/^(uncompressed_)?backup_size = /d' \
31+
$topdir/backup/xtrabackup_info) \
32+
<(sed -E '/^(uncompressed_)?backup_size = /d' \
33+
$topdir/lsndir/xtrabackup_info)

storage/innobase/xtrabackup/test/t/estimate_memory.sh

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,26 @@ redo_memory=$(grep 'redo_memory' ${backupdir}/xtrabackup_checkpoints | awk '{pri
9292
redo_frames=$(grep 'redo_frames' ${backupdir}/xtrabackup_checkpoints | awk '{print $3}') #pages
9393
total_memory=$((redo_memory + (redo_frames * 16384))) #bytes
9494

95-
free_memory=$(cat /proc/meminfo | grep 'MemAvailable' | awk '{print $2}') #kb
96-
free_memory_bytes=$((free_memory * 1024)) #bytes
95+
# Use MemAvailable to mirror what xtrabackup's host_free_memory() returns on
96+
# Linux (libprocps kb_main_available). PXB-3770 tracks the libproc2 build
97+
# returning 0 here; on those boxes the test will still fail until the binary
98+
# fix lands. Log MemFree too so any failure shows the full kernel view.
99+
mem_avail_kb=$(awk '/^MemAvailable:/ {print $2}' /proc/meminfo)
100+
mem_free_kb=$(awk '/^MemFree:/ {print $2}' /proc/meminfo)
101+
free_memory_bytes=$((mem_avail_kb * 1024)) #bytes
97102
free_memory_1_pct=$((free_memory_bytes * 1 / 100)) #bytes
98103
free_memory_99_pct=$((free_memory_bytes * 99 / 100)) #bytes
104+
vlog "gate inputs: mem_avail_kb=${mem_avail_kb}, mem_free_kb=${mem_free_kb},"
105+
vlog " free_memory_99_pct=${free_memory_99_pct}, total_memory=${total_memory}"
99106

100107
if [[ "${free_memory_99_pct}" -lt "${total_memory}" ]];
101108
then
102109
vlog "Skipping full memory workload test as 99% of free memory is lower than required by pxb"
103110
else
111+
vlog "OS view just before --prepare:" \
112+
"$(awk '/^MemFree:|^MemAvailable:/ {print $1, $2, $3}' /proc/meminfo | tr '\n' ' ')"
104113
vlog "Preparing backup with --use-free-memory-pct=99"
105-
xtrabackup --prepare --use-free-memory-pct=99 --target-dir=${backupdir} 2> ${logfile}
114+
xtrabackup --prepare --use-free-memory-pct=99 --target-dir=${backupdir} 2> >(tee "${logfile}" >&2)
106115

107116
if grep -q "Required memory will exceed free memory configuration" ${logfile}
108117
then
@@ -128,7 +137,7 @@ then
128137
fi
129138

130139
vlog "Preparing backup with --use-free-memory-pct=1"
131-
xtrabackup --prepare --use-free-memory-pct=1 --target-dir=${backupdir2} 2> ${logfile2}
140+
xtrabackup --prepare --use-free-memory-pct=1 --target-dir=${backupdir2} 2> >(tee "${logfile2}" >&2)
132141

133142
if ! grep -q "Required memory will exceed Free memory configuration" ${logfile2}
134143
then

storage/innobase/xtrabackup/test/t/pxb-3003-redo-log-purge-race.sh

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,14 @@
1111
require_server_version_higher_than 8.0.29
1212
require_debug_pxb_version
1313

14+
# Start at 16M capacity so we can later shrink to 8M. The shrink sets
15+
# target_capacity < current_capacity, the one log_files governor case
16+
# that reliably fires here and forces reclamation behind the registered
17+
# PXB consumer. Without it, none of the other governor cases trigger on
18+
# a release build merely because PXB has crossed the oldest file's
19+
# end_lsn, and MIN_FILEID would never advance.
1420
MYSQLD_EXTRA_MY_CNF_OPTS="
15-
innodb_redo_log_capacity=8M
21+
innodb_redo_log_capacity=16M
1622
"
1723
start_server
1824

@@ -28,8 +34,15 @@ $MYSQL $MYSQL_ARGS -Ns -e "CREATE TABLE redo_log_consumer (
2834
str BLOB
2935
);" test
3036

37+
# Ensure at least 2 redo files exist before xtrabackup starts. The
38+
# PFS loop makes this deterministic regardless of bootstrap redo.
3139
$MYSQL $MYSQL_ARGS -Ns -e "INSERT INTO test.redo_log_consumer VALUES (NULL, REPEAT('a', 63 * 1024))"
3240
$MYSQL $MYSQL_ARGS -Ns -e "INSERT INTO test.redo_log_consumer VALUES (NULL, REPEAT('a', 63 * 1024))"
41+
NUM_REDO_FILES=`$MYSQL $MYSQL_ARGS -Ns -e "SELECT COUNT(*) FROM performance_schema.innodb_redo_log_files"`
42+
while [ "${NUM_REDO_FILES}" -lt 2 ]; do
43+
$MYSQL $MYSQL_ARGS -Ns -e "INSERT INTO test.redo_log_consumer VALUES (NULL, REPEAT('a', 63 * 1024))"
44+
NUM_REDO_FILES=`$MYSQL $MYSQL_ARGS -Ns -e "SELECT COUNT(*) FROM performance_schema.innodb_redo_log_files"`
45+
done
3346

3447
mkdir -p $topdir/backup/
3548

@@ -43,8 +56,17 @@ xb_pid=`cat $pid_file`
4356

4457
vlog "backup pid is $job_pid"
4558

59+
# Snapshot redo log file layout at suspend time for diagnosability.
60+
vlog "performance_schema.innodb_redo_log_files at suspend:"
61+
$MYSQL $MYSQL_ARGS -t -e \
62+
"SELECT file_id, start_lsn, end_lsn, is_full FROM performance_schema.innodb_redo_log_files ORDER BY file_id" >&2
63+
4664
INITIAL_MIN_FILEID=`$MYSQL $MYSQL_ARGS -Ns -e "SELECT MIN(file_id) FROM performance_schema.innodb_redo_log_files"`
4765

66+
# Force file reclamation by shrinking redo capacity (see top of file).
67+
vlog "Shrinking innodb_redo_log_capacity to 8M to force file reclamation"
68+
$MYSQL $MYSQL_ARGS -Ns -e "SET GLOBAL innodb_redo_log_capacity = 8 * 1024 * 1024"
69+
4870
run_inserts &
4971
insert_pid=$!
5072
CURRENT_MIN_FILEID=`$MYSQL $MYSQL_ARGS -Ns -e "SELECT MIN(file_id) FROM performance_schema.innodb_redo_log_files"`

storage/innobase/xtrabackup/test/t/redo_log_consumer.sh

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,59 @@ xb_pid=`cat $pid_file`
5959
echo "backup pid is $job_pid"
6060

6161
run_inserts &
62-
63-
# ER_IB_MSG_LOG_WRITER_WAIT_ON_CONSUMER
64-
while ! grep -q "Redo log writer is waiting for" ${MYSQLD_ERRFILE} ; do
62+
inserts_pid=$!
63+
64+
# Wait for backpressure: with 8M capacity and the registered PXB/MEB
65+
# consumer pinned at the catch-up LSN, the server cannot reclaim redo
66+
# files. Exit on the first of: a consumer-lagging warning anchored on
67+
# the consumer name (avoids false matches from the prior backup's
68+
# log_checkpointer warnings), or PFS reporting >= 3 redo files (proof
69+
# we're past 8M with the consumer holding it back). Bound the wait so
70+
# MTR fails with diagnostics instead of Jenkins killing the job.
71+
max_wait_s=60
72+
for ((i=1; i<=max_wait_s; i++)) ; do
73+
if grep -qE "(Redo log writer is waiting for (PXB|MEB) redo log consumer|'(PXB|MEB)' consumer still lagging behind)" \
74+
${MYSQLD_ERRFILE} ; then
75+
vlog "consumer-lagging warning observed in mysql error file"
76+
break
77+
fi
78+
79+
n_files=$($MYSQL $MYSQL_ARGS -Ns -e \
80+
"SELECT COUNT(*) FROM performance_schema.innodb_redo_log_files" \
81+
2>/dev/null || echo 0)
82+
if [ "${n_files:-0}" -ge 3 ] ; then
83+
vlog "redo log accumulated ${n_files} files;" \
84+
"consumer is holding the server back as expected"
85+
break
86+
fi
87+
88+
vlog "waiting for redo log backpressure" \
89+
"(#files=${n_files:-?}, ${i}/${max_wait_s}s)"
6590
sleep 1
66-
vlog "waiting for redo log writer message in mysql error file"
6791
done
6892

93+
if [ ${i} -gt ${max_wait_s} ] ; then
94+
vlog "ERROR: timed out waiting for redo log backpressure"
95+
vlog "performance_schema.innodb_redo_log_files at timeout:"
96+
$MYSQL $MYSQL_ARGS -t -e \
97+
"SELECT file_id, start_lsn, end_lsn, is_full FROM performance_schema.innodb_redo_log_files ORDER BY file_id" \
98+
>&2 || true
99+
vlog "tail of mysqld error file ${MYSQLD_ERRFILE}:"
100+
tail -100 ${MYSQLD_ERRFILE} >&2 || true
101+
kill ${inserts_pid} 2>/dev/null || true
102+
kill -SIGCONT ${xb_pid} 2>/dev/null || true
103+
die "redo_log_consumer: timeout waiting for backpressure"
104+
fi
105+
69106
# Resume the xtrabackup process
70107
vlog "Resuming xtrabackup"
71108
kill -SIGCONT $xb_pid
72109
run_cmd wait $job_pid
73110

111+
# Stop background inserts before stop_server to avoid ERROR 2002 spam.
112+
kill ${inserts_pid} 2>/dev/null || true
113+
wait ${inserts_pid} 2>/dev/null || true
114+
74115
xtrabackup --prepare --target-dir=$topdir/backup
75116

76117
# PXB-3147 - register redo log consumer fails with ANSI_QUOTES

0 commit comments

Comments
 (0)