Skip to content

Commit 68e96e7

Browse files
keukoartificial-intelligence
authored andcommitted
Add way to backup from MariaDB replica server
ProxySQL reports its version to MySQL clients, causing the backup process to fail when ProxySQL is used. This patch adds a new script that handles backups from the replica server directly, without modifying the original backup script. The new script retrieves the server address via the load balancer and connects directly to the replica server to execute the backup. Moreover, this reduces the risk that the backup will be inconsistent or that it will block OpenStack MySQL clients, because they are connected to a different server, and no one is connected to the replica, or that it will overload the load balancer (such as ProxySQL or HAProxy) which listens on the VIP. Closes-Bug: #2080818 Change-Id: Ibf7e40e8b059d733e114963022df06180249c650 (cherry picked from commit ec4c431)
1 parent 648be98 commit 68e96e7

File tree

3 files changed

+144
-1
lines changed

3 files changed

+144
-1
lines changed

docker/mariadb/mariadb-server/Dockerfile.j2

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,12 @@ COPY mariadb_sudoers /etc/sudoers.d/kolla_mariadb_sudoers
3939
COPY extend_start.sh /usr/local/bin/kolla_extend_start
4040
COPY security_reset.expect /usr/local/bin/kolla_security_reset
4141
COPY backup.sh /usr/local/bin/kolla_mariadb_backup.sh
42+
COPY backup_replica.sh /usr/local/bin/kolla_mariadb_backup_replica.sh
4243

4344
RUN chmod 644 /usr/local/bin/kolla_extend_start \
44-
&& chmod 755 /usr/local/bin/kolla_security_reset /usr/local/bin/kolla_mariadb_backup.sh \
45+
&& chmod 755 /usr/local/bin/kolla_security_reset \
46+
/usr/local/bin/kolla_mariadb_backup.sh \
47+
/usr/local/bin/kolla_mariadb_backup_replica.sh \
4548
&& chmod 750 /etc/sudoers.d \
4649
&& chmod 440 /etc/sudoers.d/kolla_mariadb_sudoers \
4750
&& rm -rf /var/lib/mysql/*
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/usr/bin/env bash
2+
3+
set -eu
4+
set -o pipefail
5+
6+
BACKUP_DIR=/backup/
7+
DEFAULT_MY_CNF="/etc/mysql/my.cnf"
8+
REPLICA_MY_CNF="$(mktemp)"
9+
RETRY_INTERVAL=5 # Interval between retries (in seconds)
10+
MAX_RETRIES=12 # Max retries (12 retries * 5 seconds = 60 seconds)
11+
12+
# Cleanup function to remove the REPLICA_MY_CNF file
13+
cleanup() {
14+
rm -f "${REPLICA_MY_CNF}"
15+
}
16+
17+
# Set trap to ensure cleanup occurs on exit or error
18+
trap cleanup EXIT
19+
20+
cd "${BACKUP_DIR}"
21+
22+
# Execute a full backup
23+
backup_full() {
24+
echo "Taking a full backup"
25+
LAST_FULL_DATE=$(date +%d-%m-%Y-%s)
26+
mariabackup \
27+
--defaults-file="${REPLICA_MY_CNF}" \
28+
--backup \
29+
--stream=mbstream \
30+
--history="${LAST_FULL_DATE}" | gzip > \
31+
"${BACKUP_DIR}/mysqlbackup-${LAST_FULL_DATE}.qp.mbc.mbs.gz" && \
32+
echo "${LAST_FULL_DATE}" > "${BACKUP_DIR}/last_full_date"
33+
}
34+
35+
# Execute an incremental backup
36+
backup_incremental() {
37+
if [ -r "${BACKUP_DIR}/last_full_date" ]; then
38+
LAST_FULL_DATE=$(cat "${BACKUP_DIR}/last_full_date")
39+
else
40+
LAST_FULL_DATE=""
41+
fi
42+
if [ ! -z "${LAST_FULL_DATE}" ]; then
43+
echo "Taking an incremental backup"
44+
mariabackup \
45+
--defaults-file="${REPLICA_MY_CNF}" \
46+
--backup \
47+
--stream=mbstream \
48+
--incremental-history-name="${LAST_FULL_DATE}" \
49+
--history="${LAST_FULL_DATE}" | gzip > \
50+
"${BACKUP_DIR}/incremental-$(date +%H)-mysqlbackup-${LAST_FULL_DATE}.qp.mbc.mbs.gz"
51+
else
52+
echo "Error: Full backup don't exist."
53+
exit 1
54+
fi
55+
}
56+
57+
# Retry logic for database queries
58+
retry_mysql_query() {
59+
local query="$1"
60+
local result=""
61+
local attempt=1
62+
63+
while [ ${attempt} -le ${MAX_RETRIES} ]; do
64+
result=$(mysql -h "${HOST}" -u "${USER}" -p"${PASS}" -s -N -e "${query}" 2>/dev/null || true)
65+
if [ -n "${result}" ]; then
66+
echo "${result}"
67+
return 0
68+
fi
69+
echo "Attempt ${attempt}/${MAX_RETRIES} failed. Retrying in ${RETRY_INTERVAL} seconds..."
70+
sleep "${RETRY_INTERVAL}"
71+
attempt=$((attempt + 1))
72+
done
73+
74+
echo "Error: Failed to execute the query after ${MAX_RETRIES} attempts."
75+
return 1
76+
}
77+
78+
get_and_set_replica_server() {
79+
HOST="$(grep '^host' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)"
80+
USER="$(grep '^user' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)"
81+
PASS="$(grep '^password' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)"
82+
83+
ALL_HOSTS_SELECT="SELECT REGEXP_REPLACE(VARIABLE_VALUE, ':[0-9]*','') FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';"
84+
ALL_HOSTS=$(retry_mysql_query "${ALL_HOSTS_SELECT}")
85+
if [ -z "${ALL_HOSTS}" ]; then
86+
echo "Backup failed due to inability to fetch a list of servers."
87+
exit 1
88+
fi
89+
90+
ACTIVE_HOST_SELECT='SELECT @@hostname;'
91+
ACTIVE_HOST=$(retry_mysql_query "${ACTIVE_HOST_SELECT}" | xargs getent hosts | awk '{print $1}')
92+
if [ -z "${ACTIVE_HOST}" ]; then
93+
echo "Backup failed due to inability to fetch active host."
94+
exit 1
95+
fi
96+
97+
# Multinode
98+
if echo "${ALL_HOSTS}" | grep -q ','; then
99+
for server in $(echo "${ALL_HOSTS}" | tr ',' '\n'); do
100+
if [[ "${server}" != "${ACTIVE_HOST}" ]]; then
101+
REPLICA_HOST="${server}"
102+
break
103+
fi
104+
done
105+
# Single node
106+
else
107+
REPLICA_HOST="${ALL_HOSTS}"
108+
fi
109+
if [ -z "${REPLICA_HOST}" ]; then
110+
echo "Backup failed due to inability to determine replica host."
111+
exit 1
112+
fi
113+
114+
cp "${DEFAULT_MY_CNF}" "${REPLICA_MY_CNF}"
115+
sed -i "s/${HOST}/${REPLICA_HOST}/g" "${REPLICA_MY_CNF}"
116+
}
117+
118+
if [ -n "${BACKUP_TYPE}" ]; then
119+
get_and_set_replica_server
120+
case "${BACKUP_TYPE}" in
121+
"full")
122+
backup_full
123+
;;
124+
"incremental")
125+
backup_incremental
126+
;;
127+
*)
128+
echo "Only full or incremental options are supported."
129+
exit 1
130+
;;
131+
esac
132+
else
133+
echo "You need to specify either full or incremental backup options."
134+
exit 1
135+
fi
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
fixes:
3+
- |
4+
Fixes MariaDB backup failure when ProxySQL is used
5+
`LP#2080818 <https://launchpad.net/bugs/2080818>`__

0 commit comments

Comments
 (0)