Skip to content

Commit 17937f4

Browse files
authored
Merge pull request #689 from MariaDB/next
MariaDB Server Releases Maintenance 2026 Q1 - 20260204 - merge into master
2 parents fff6ab3 + cfc6a06 commit 17937f4

49 files changed

Lines changed: 1567 additions & 1121 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ name: GitHub CI
22

33
on:
44
pull_request:
5-
branches-ignore:
6-
- next
75
paths-ignore:
86
- examples
97
- Dockerfile.template
@@ -13,8 +11,6 @@ on:
1311
- Containerfile.debug
1412
- Containerfile.debug-ubi
1513
push:
16-
branches-ignore:
17-
- next
1814
paths-ignore:
1915
- examples
2016
- Dockerfile.template

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.test/*.xml

.test/lib.sh

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
#!/bin/bash
2+
# Shared test utilities for MariaDB Docker image tests
3+
# Sourced by run.sh — do not execute directly
4+
5+
set -eo pipefail
6+
7+
# Variables set by run.sh (image/dir before sourcing, architecture after)
8+
: "${image:?}" "${dir:?}"
9+
declare -g image dir architecture
10+
11+
# Global state
12+
cid=""
13+
cname=""
14+
master_host=""
15+
netid=""
16+
tmpvol=""
17+
mariadb=mariadb
18+
19+
# Cleanup helpers
20+
21+
killoff() {
22+
if [ -n "$cid" ]; then
23+
docker kill "$cid" > /dev/null || true
24+
fi
25+
sleep 2
26+
if [ -n "$cid" ]; then
27+
docker rm -v -f "$cid" > /dev/null || true
28+
fi
29+
cid=""
30+
if [ -n "$master_host" ]; then
31+
cid=$master_host
32+
master_host=""
33+
killoff
34+
fi
35+
if [ -n "$netid" ]; then
36+
docker network rm "$netid"
37+
netid=
38+
fi
39+
}
40+
41+
die() {
42+
[ -n "$cid" ] && docker logs "$cid"
43+
[ -n "$tmpvol" ] && docker rm "$tmpvol"
44+
[ -n "$master_host" ] && docker logs "$master_host"
45+
killoff
46+
echo "$@" >&2
47+
exit 1
48+
}
49+
50+
# Container lifecycle
51+
52+
runandwait() {
53+
local port_int
54+
if [ -z "$cname" ]; then
55+
cname="mariadbcontainer$RANDOM"
56+
fi
57+
if [ -z "$port" ]; then
58+
cid="$(
59+
docker run -d \
60+
--name "$cname" --rm --publish 3306 "$@"
61+
)"
62+
port_int=3306
63+
else
64+
cid="$(
65+
docker run -d \
66+
--name "$cname" --rm "$@"
67+
)"
68+
port_int=$port
69+
fi
70+
waiting=${DOCKER_LIBRARY_START_TIMEOUT:-15}
71+
echo "waiting to start..."
72+
set +e +o pipefail
73+
while [ "$waiting" -gt 0 ]; do
74+
(( waiting-- ))
75+
sleep 1
76+
if ! docker exec -i "$cid" "$mariadb" -h localhost --protocol tcp -P "$port_int" -e 'select 1' 2>&1 | grep -F "Can't connect" > /dev/null; then
77+
break
78+
fi
79+
done
80+
set -eo pipefail
81+
if [ "$waiting" -eq 0 ]; then
82+
die 'timeout'
83+
fi
84+
}
85+
86+
# Client wrappers
87+
88+
mariadbclient_tcp() {
89+
docker exec -i \
90+
"$cname" \
91+
$mariadb \
92+
--host 127.0.0.1 \
93+
--protocol tcp \
94+
--silent \
95+
"$@"
96+
}
97+
98+
mariadbclient() {
99+
docker exec -i \
100+
"$cname" \
101+
$mariadb \
102+
--silent \
103+
"$@"
104+
}
105+
106+
# Assertions / checks
107+
108+
checkUserExistInMariaDB() {
109+
if [ -z "$1" ]; then
110+
return 1
111+
fi
112+
113+
local user
114+
user=$(mariadbclient --user root ${2:+--password=$2} -e "SELECT User FROM mysql.global_priv where User='$1';")
115+
if [ -z "$user" ]; then
116+
return 1
117+
fi
118+
119+
return 0
120+
}
121+
122+
# Reusable test building blocks
123+
124+
checkReplication() {
125+
mariadb_replication_user='foo'
126+
local pass_str=
127+
local pass=
128+
if [ "$1" = 'MARIADB_REPLICATION_PASSWORD_HASH' ]; then
129+
pass_str=MARIADB_REPLICATION_PASSWORD_HASH='*0FD9A3F0F816D076CF239580A68A1147C250EB7B'
130+
pass='jane'
131+
else
132+
pass_str='MARIADB_REPLICATION_PASSWORD=foo123'
133+
pass='foo123'
134+
fi
135+
136+
netid="mariadbnetwork$RANDOM"
137+
docker network create "$netid"
138+
139+
rootpass=consistent_and_checkcheckable
140+
runandwait \
141+
--network "$netid" \
142+
-e MARIADB_REPLICATION_USER="$mariadb_replication_user" \
143+
-e "$pass_str" \
144+
-e MARIADB_DATABASE=replcheck \
145+
-e MARIADB_ROOT_PASSWORD="${rootpass}" \
146+
"$image" --server-id=3000 --log-bin --log-basename=my-mariadb
147+
148+
if checkUserExistInMariaDB $mariadb_replication_user "${rootpass}"; then
149+
grants=$(mariadbclient_tcp -u $mariadb_replication_user -p$pass -e "SHOW GRANTS")
150+
# shellcheck disable=SC2076
151+
[[ "${grants/SLAVE/REPLICA}" =~ "GRANT REPLICATION REPLICA ON *.* TO \`$mariadb_replication_user\`@\`%\`" ]] || die "I wasn't created how I was expected: got $grants"
152+
153+
mariadbclient_tcp -u root --password="$rootpass" --batch --skip-column-names -e 'create table t1(i int)' replcheck
154+
readarray -t vals < <(mariadbclient_tcp --password="$rootpass" -u root --batch --skip-column-names -e 'show master status\G' replcheck)
155+
lastfile="${vals[1]}"
156+
pos="${vals[2]}"
157+
[[ "$lastfile" = my-mariadb-bin.00000[12] ]] || die "too many binlog files"
158+
[ "$pos" -lt 500 ] || die 'binary log too big'
159+
docker exec "$cid" ls -la /var/lib/mysql/my-mariadb-bin.000001
160+
docker exec "$cid" sh -c '[ $(wc -c < /var/lib/mysql/my-mariadb-bin.000001 ) -gt 2500 ]' && die 'binary log 1 too big'
161+
docker exec "$cid" sh -c "[ \$(wc -c < /var/lib/mysql/$lastfile ) -gt $pos ]" && die 'binary log 2 too big'
162+
163+
master_host=$cname
164+
unset cname
165+
master_ip=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$master_host")
166+
port=3307
167+
runandwait \
168+
--network "$netid" \
169+
-e MARIADB_MASTER_HOST="$master_ip" \
170+
-e MARIADB_ROOT_PASSWORD="${rootpass}" \
171+
-e MARIADB_REPLICATION_USER="$mariadb_replication_user" \
172+
-e MARIADB_REPLICATION_PASSWORD="$pass" \
173+
-e MARIADB_HEALTHCHECK_GRANTS="REPLICA MONITOR" \
174+
--health-cmd='healthcheck.sh --connect --innodb-initialized --replication_io --replication_sql --replication_seconds_behind_master=0 --replication' \
175+
--health-interval=3s \
176+
"$image" --server-id=3001 --port "${port}"
177+
unset port
178+
179+
c="${DOCKER_LIBRARY_START_TIMEOUT:-10}"
180+
until docker exec "$cid" healthcheck.sh --connect --replication_io --replication_sql --replication_seconds_behind_master=0 --replication || [ "$c" -eq 0 ]; do
181+
sleep 1
182+
c=$(( c - 1 ))
183+
done
184+
185+
docker exec --user mysql -i \
186+
"$cname" \
187+
$mariadb --defaults-file=/var/lib/mysql/.my-healthcheck.cnf \
188+
-e 'SHOW SLAVE STATUS\G' || die 'error examining replica status'
189+
190+
mariadbclient -u root --password="$rootpass" --batch --skip-column-names replcheck -e 'show create table t1;' || die 'sample table not replicated'
191+
192+
killoff
193+
else
194+
die "User $mariadb_replication_user did not get created for replication mode master"
195+
fi
196+
}
197+
198+
galera_sst() {
199+
if [ "$architecture" != amd64 ]; then
200+
echo test is too slow if not run natively
201+
return 0
202+
fi
203+
sst=$1
204+
205+
netid="mariadbnetwork$RANDOM"
206+
docker network create "$netid"
207+
208+
cname="mariadbcontainer_donor$RANDOM"
209+
runandwait \
210+
--network "$netid" \
211+
--env MARIADB_ROOT_PASSWORD=secret --env MARIADB_DATABASE=test --env MARIADB_USER=test --env MARIADB_PASSWORD=test \
212+
"${image}" \
213+
--wsrep-new-cluster --wsrep-provider=/usr/lib/libgalera_smm.so --wsrep_cluster_address=gcomm://"$cname" --binlog_format=ROW --innodb_autoinc_lock_mode=2 --wsrep_on=ON --wsrep_sst_method="$sst" --wsrep_sst_auth=root:secret
214+
master_host=$cid
215+
unset cname
216+
ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$cid")
217+
DOCKER_LIBRARY_START_TIMEOUT=$(( ${DOCKER_LIBRARY_START_TIMEOUT:-10} * 7 )) runandwait \
218+
--network "$netid" \
219+
--env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 \
220+
"${image}" \
221+
--wsrep-provider=/usr/lib/libgalera_smm.so --wsrep_cluster_address=gcomm://"$ip" --binlog_format=ROW --innodb_autoinc_lock_mode=2 --wsrep_on=ON --wsrep_sst_method="$sst" --wsrep_sst_auth=root:secret
222+
223+
v=$(mariadbclient -u root -psecret -e 'select VARIABLE_VALUE from information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME="WSREP_LOCAL_STATE"' || :)
224+
225+
waiting=${DOCKER_LIBRARY_START_TIMEOUT:-10}
226+
set +e +o pipefail
227+
while [ "$waiting" -gt 0 ] && [ "$v" != 4 ]; do
228+
(( waiting-- ))
229+
sleep 1
230+
v=$(mariadbclient -u root -psecret -e 'select VARIABLE_VALUE from information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME="WSREP_LOCAL_STATE"' || :)
231+
done
232+
set -eo pipefail
233+
if [ "$v" != 4 ]; then
234+
die 'timeout'
235+
fi
236+
237+
killoff
238+
}
239+
240+
# initdb helpers
241+
242+
prepare_initdb() {
243+
local initdb
244+
initdb=$(mktemp -d)
245+
chmod go+rx "${initdb}"
246+
cp -a "$dir"/initdb.d/* "${initdb}"
247+
chmod -R go+rX "${initdb}"
248+
gzip "${initdb}"/*gz*
249+
xz "${initdb}"/*xz*
250+
zstd "${initdb}"/*zst*
251+
echo "$initdb"
252+
}

0 commit comments

Comments
 (0)