Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
12.3.3
-
None
-
None
-
Linux x86_64; Docker; official image
`mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979`;
server and `mariadb-backup` report `12.3.3-MariaDB-ubu2404`, source revision
`83e909fc2a0dbc394b4b683fb3fa2d7dcf26cc5e`
Description
MariaDB accepts a multi-source connection name containing an apostrophe when
the SQL literal escapes it as `source''one`. `mariadb-backup --slave-info`
serializes that name into `mariadb_backup_slave_info` without escaping the
apostrophe. Feeding the generated file back to the same server version fails
with SQL error 1064.
Steps to reproduce
#!/usr/bin/env bash
|
set -euo pipefail
|
IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
|
C="mdev-mcf2s09-$$"; OWNER="mdev-mcf2s09-$$"
|
cleanup() {
|
if docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
|
"$C" 2>/dev/null | grep -Fqx "$OWNER"; then
|
docker rm -f "$C" >/dev/null 2>&1 || true
|
fi
|
}
|
trap cleanup EXIT
|
|
|
docker run -d --name "$C" --label "io.encryptiondbfuzz.owner=$OWNER" \
|
--network none --read-only --cap-drop ALL \
|
--security-opt no-new-privileges=true --pids-limit 160 --memory 1100m \
|
--cpus 1 --user 999:999 \
|
--tmpfs /var/lib/mysql:rw,nosuid,nodev,size=512m,uid=999,gid=999 \
|
--tmpfs /run/mysqld:rw,nosuid,nodev,size=16m,uid=999,gid=999 \
|
--tmpfs /tmp:rw,nosuid,nodev,size=512m,uid=999,gid=999 \
|
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 "$IMAGE" \
|
--server-id=2 --log-bin=mariadb-bin --bind-address=127.0.0.1 >/dev/null
|
|
|
READY=0
|
for I in $(seq 1 90); do
|
if docker exec --user 999:999 "$C" mariadb --protocol=socket \
|
--socket=/run/mysqld/mysqld.sock -uroot -NBe 'SELECT VERSION()' 2>/dev/null; then READY=1; break; fi
|
sleep 1
|
done
|
test "$READY" -eq 1
|
SQL=(docker exec --user 999:999 "$C" mariadb --protocol=socket --socket=/run/mysqld/mysqld.sock -uroot --batch --skip-column-names)
|
"${SQL[@]}" -e "CHANGE MASTER 'source''one' TO MASTER_HOST='127.0.0.1',MASTER_PORT=1,MASTER_USER='u',MASTER_PASSWORD='p',MASTER_LOG_FILE='mariadb-bin.000001',MASTER_LOG_POS=4; SHOW ALL SLAVES STATUS"
|
docker exec --user 999:999 "$C" timeout 150 mariadb-backup --backup \
|
--slave-info --protocol=socket --socket=/run/mysqld/mysqld.sock \
|
--user=root --target-dir=/tmp/backup 2>&1 | grep -E 'slave binlog position|completed OK'
|
INFO=/tmp/backup/mariadb_backup_slave_info
|
echo 'generated file:'
|
docker exec --user 999:999 "$C" cat "$INFO"
|
echo 'replay result:'
|
set +e
|
docker exec --user 999:999 "$C" cat "$INFO" | docker exec --user 999:999 -i "$C" \
|
mariadb --protocol=socket --socket=/run/mysqld/mysqld.sock -uroot --batch --skip-column-names
|
RC=$?
|
set -e
|
echo "replay_rc=$RC"
|
test "$RC" -ne 0
|
"${SQL[@]}" -e "SELECT CONCAT('server_health=',1)"
|
Actual result
`mariadb-backup` succeeds, but the generated file contains an unterminated
connection-name literal:
[00] ... MySQL slave binlog position: master 'source'one' filename 'mariadb-bin.000001' position '4'
|
[00] ... completed OK!
|
generated file:
|
CHANGE MASTER 'source'one' TO MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=4;
|
replay result:
|
ERROR 1064 (42000) at line 1: ... near 'one' TO MASTER_LOG_FILE=...
|
replay_rc=1
|
server_health=1
|
The server remains running; no crash was observed.
Expected result
The backup should escape SQL string delimiters in the connection name, for
example by emitting `CHANGE MASTER 'source''one' ...`, so its own recovery SQL
can be parsed by the same MariaDB version.