WIUNIX ACADEMY
Install MariaDB primary-replica replication with GTID and TLS
Page 4 of 6. Review the earlier steps and prerequisites before continuing.
YOUR SYSTEM. YOUR STEPS.
Where are you working?
Choose your OS and version. The prerequisites, commands and troubleshooting follow your environment.
USE YOUR OWN VALUES
Configure this tutorial
Set the example values for your environment; related explanations and copy panels update together. Never enter passwords, private keys or tokens. Values stay in this tab and are not sent to the server or share links. Check actual DNS, certificates and network policy before running commands.
Different IP addresses, domains or ports? Open the settings below, change the values and select “Apply to tutorial”, then copy the updated commands.
Set values for my environment3 editable values
LET’S BUILD
Transfer both files over authenticated SSH
Primary Bash, logged in as the same dbadmin administrator. Each remote write refuses to overwrite an existing file. pipefail propagates local read and SSH failures. Passwordless sudo for these specific reads or a prior local sudo authentication is required; no secrets are echoed. Verify SSH host fingerprints by your existing trusted channel before this operation.
Primary shell as dbadmin
(
set -euo pipefail
sudo -v
sudo cat /root/academy-seed/seed.sql | ssh -l dbadmin 10.20.0.11 'umask 077; set -C; cat > "$HOME/academy-seed/seed.sql"'
sudo cat /root/academy-seed/SHA256SUMS | ssh -l dbadmin 10.20.0.11 'umask 077; set -C; cat > "$HOME/academy-seed/SHA256SUMS"'
)
Both SSH commands succeed; original protected primary seed is retained.
LET’S BUILD
Verify and restore only into the fresh replica
Replica Bash as dbadmin. This guard refuses any pre-existing academy_lab schema, any configured replication channel, any user table in other schemas or any applied GTID. It does not erase them. Verify checksum BEFORE import. Restore runs with session binary logging disabled so local seed writes do not create a competing domain 0 history; read_only stays ON because privileged bootstrap bypass is intentional here. Import errors stop immediately and leave the partial state for diagnosis; do not force or rerun on top of it.
Replica
(
set -euo pipefail
cd "$HOME/academy-seed"
sha256sum -c SHA256SUMS
test "$(sudo mariadb -NBe "SELECT COUNT(*) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='academy_lab';")" = 0
test "$(sudo mariadb -NBe "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys');")" = 0
channels=$(sudo mariadb -NBe 'SHOW SLAVE STATUS;')
test -z "$channels"
applied=$(sudo mariadb -NBe 'SELECT @@GLOBAL.gtid_slave_pos;')
test -z "$applied"
{ printf 'SET SESSION sql_log_bin=0;\n'; cat seed.sql; } | sudo mariadb
sudo mariadb -e 'SELECT @@read_only; SELECT * FROM academy_lab.replication_probe;'
)
Checksum OK; fresh-state checks pass; restored row1 consistent-seed and read_only1.
LET’S BUILD
Set only the GTID embedded in this seed
Replica Bash. Extract exactly one commented GTID line, reject a malformed/domain-mismatched position and send only that reviewed statement to the local administrator connection. It must be domain 0 with primary server_id101 and a positive sequence. Do not use current_pos, invent a GTID or copy the primary’s current position after the backup. This snapshot has only one GTID domain; multi-source histories need a different plan.
Replica
(
set -euo pipefail
cd "$HOME/academy-seed"
sha256sum -c SHA256SUMS
position=$(sed -n "s/^-- SET GLOBAL gtid_slave_pos='\(0-101-[1-9][0-9]*\)';$/\1/p" seed.sql)
if [[ ! "$position" =~ ^0-101-[1-9][0-9]*$ ]]; then
echo 'Missing, multiple or unexpected snapshot GTID; STOP' >&2; exit 1
fi
printf "SET GLOBAL gtid_slave_pos='%s';\n" "$position" | sudo mariadb
sudo mariadb -NBe 'SELECT @@GLOBAL.gtid_slave_pos;'
)
Replica gtid_slave_pos equals the single GTID from its verified seed.
LET’S BUILD
Open the replica SQL session securely
Replica terminal. Use the same history-free interactive method. Retrieve the SAME unique account password used on the primary. Do not place the CHANGE MASTER statement in a shell -e argument or publish its unredacted output/logs.
Replica terminal
sudo env MYSQL_HISTFILE=/dev/null mariadb
Local replica MariaDB administrator prompt is open with client history disabled.
LET’S BUILD
Attach with GTID and verified TLS
Inside replica SQL. MariaDB retains the historical CHANGE MASTER/SLAVE spelling for compatibility. The hostname must match the certificate SAN and private DNS. Replace the password safely before execution. slave_pos starts AFTER the restored snapshot. Verification remains explicitly ON across all supported versions; a TLS error is a stop condition, not permission to disable verification.
Replica SQL
CHANGE MASTER TO
MASTER_HOST='db-primary.example.internal',
MASTER_PORT=3306,
MASTER_USER='academy_repl',
MASTER_PASSWORD='REPLACE_WITH_THE_SAME_UNIQUE_SECRET',
MASTER_USE_GTID=slave_pos,
MASTER_SSL=1,
MASTER_SSL_CA='/etc/mariadb/tls/ca.pem',
MASTER_SSL_VERIFY_SERVER_CERT=1,
MASTER_CONNECT_RETRY=10;
START SLAVE;
SHOW SLAVE STATUS\G
EXIT;
Both receiver and applier run; GTID Slave_Pos, TLS allowed and server certificate verification enabled.
LET’S BUILD
Read receiver AND applier status
Replica Bash. Inspect both Yes flags, zero Last_IO_Errno/Last_SQL_Errno, empty corresponding errors, Using_Gtid Slave_Pos, correct Master_Server_Id101 and both TLS flags Yes. Seconds_Behind_Master0 alone is not proof: NULL can mean a stopped thread, and lag may not reflect queued or idle-source conditions. Protect status/log output because it contains internal topology.
Replica
sudo mariadb -e "SHOW SLAVE STATUS\G"
sudo mariadb -e "SELECT @@server_id,@@read_only,@@GLOBAL.gtid_slave_pos;"
Receiver Yes AND applier Yes, errors0/empty; correct source identity, GTID and verified TLS; read_only1.