2023-04-16 21:38:32 +08:00

219 lines
6.8 KiB
Bash
Executable File

#!/bin/bash
##################################################
# EVN #
# - SERVER_ID #
# - GROUP_REPLICATION #
# - GROUP_REPLICATION_LOCAL_ADDRESS #
# - GROUP_REPLICATION_GROUP_SEEDS #
# - EXTRA_SCRIPTS #
# Mount file #
# - /etc/my.cnf #
# Mount dir #
# - LOG_DIR #
# - DATA_DIR #
# - BINLOG_DIR #
##################################################
set -euo pipefail
export LANG=en_US.UTF-8
trap Quit EXIT
PIDS=
GOT_SIGTERM=
LOG_DIR='/var/log/mysql'
DATA_DIR='/var/lib/mysql'
BINLOG_DIR='/var/lib/mysql-bin'
SOCK_FILE='/run/mysqld/mysqld.sock'
PID_FILE='/run/mysqld/mysqld.pid'
INIT_FLAG=
GROUP_REPLICATION="${GROUP_REPLICATION:+1}"
EXTRA_SCRIPTS="${EXTRA_SCRIPTS:+1}"
if [ -n "$GROUP_REPLICATION" ]; then
SERVER_ID=${SERVER_ID:?}
GROUP_REPILCATION_GROUP_NAME="${GROUP_REPILCATION_GROUP_NAME:-aaaabbbb-7777-8888-9999-ccccddddeeee}"
GROUP_REPLICATION_LOCAL_ADDRESS="${GROUP_REPLICATION_LOCAL_ADDRESS}"
GROUP_REPLICATION_GROUP_SEEDS="${GROUP_REPLICATION_GROUP_SEEDS}"
BOOTSTRAP_GROUP=1
fi
function Print {
local file=/dev/null
[ '-f' = "$1" ] && file=$2 && shift && shift
date +"[%F %T] $*" | tee -a $file
}
function Quit {
Print killing mysqld ...
mysqladmin shutdown || true
while :; do
pkill -f mysqld && Print killing mysqld ... || break
sleep 1
done
Print Container stopped.
test -n "$GOT_SIGTERM"
}
function ProbeSeeds {
local all_seeds=" ${GROUP_REPLICATION_GROUP_SEEDS//,/ } "
local other_seeds="${all_seeds/ $GROUP_REPLICATION_LOCAL_ADDRESS / }"
local seed= seed_return=0
[ "$all_seeds" = "$other_seeds" ] \
&& Print Not found local_address in group_seeds! \
&& exit 1
Print Probing connection to other seeds ...
for seed in $other_seeds; do
echo -n "Connecting $seed ... "
curl -s --connect-timeout 8 ftp://$seed || seed_return=$?
[ 6 = "$seed_return" ] && echo failed to resolve host:"${seed%:*}"! && exit 1
[ 7 = "$seed_return" ] && echo offline. && continue
echo online.
BOOTSTRAP_GROUP=
break
done
}
function Init {
rm -f ${SOCK_FILE}* ${PID_FILE}
chown -R mysql:mysql $LOG_DIR $BINLOG_DIR $DATA_DIR
if [ ! -d "$DATA_DIR/mysql" ]; then
Print Writing essential server config to /etc/mysql/my.cnf ...
Print Initing mysql db files ...
mysqld_pre_systemd
INIT_FLAG=1
fi
}
function InitGroupReplication {
if ! grep -i '^group[-_]replication' /etc/my.cnf; then
Print Writing advisable group replication config to /etc/my.cnf ...
grep -i '^binlog[-_]expire[-_]logs[-_]seconds' /etc/my.cnf \
|| echo 'binlog-expire-logs-seconds = 172800' >> /etc/my.cnf
echo 'group-replication-consistency = BEFORE_ON_PRIMARY_FAILOVER
group-replication-member-expel-timeout = 2
group-replication-unreachable-majority-timeout = 2
group-replication-autorejoin-tries = 0
group-replication-exit-state-action = OFFLINE_MODE
' >> /etc/my.cnf
fi
if ! grep -i '^group[-_]replication' /etc/mysql/my.cnf; then
Print Writing essential group replication config to /etc/mysql/my.cnf ...
cat >> /etc/mysql/my.cnf <<-EOF
server-id = $SERVER_ID
gtid-mode = ON
enforce-gtid-consistency = TRUE
binlog-format = ROW
binlog-checksum = NONE
log-bin = /var/lib/mysql-bin/master
relay-log = /var/lib/mysql-bin/slave
log-slave-updates = TRUE
relay-log-recovery = TRUE
slave-parallel-type = LOGICAL_CLOCK
slave-preserve-commit-order = ON
disabled-storage-engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
plugin-load-add = "group_replication.so;mysql_clone.so"
group-replication-group-name = "$GROUP_REPILCATION_GROUP_NAME"
group-replication-local-address = "$GROUP_REPLICATION_LOCAL_ADDRESS"
group-replication-group-seeds = "$GROUP_REPLICATION_GROUP_SEEDS"
group-replication-bootstrap-group = OFF
group-replication-start-on-boot = OFF
EOF
fi
}
function ImportInitSql {
local sql_file= sql_files=
mysql -e "CREATE USER docker@localhost IDENTIFIED BY 'China_19\$(10)!'"
mysql -e "GRANT SHUTDOWN ON *.* TO docker@localhost"
if sql_files="$(ls $LOG_DIR/init_sql/*.sql 2>/dev/null)"; then
Print Importing the sql files ...
for sql_file in $sql_files; do
Print Importing $sql_file ...
mysql < $sql_file
done
Print Imported all sql files successfully.
fi
}
function StartGroupReplication {
if [ -n "$BOOTSTRAP_GROUP" ]; then
Print Bootstraping new group replication ...
mysql -e "
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
"
else
Print Joining a running group replication ...
mysql -e "START GROUP_REPLICATION;"
fi
}
function CreateGroupReplicationChannel {
Print Creating user and channel of group replication ...
mysql -e "SET SQL_LOG_BIN=0;
CREATE USER rpl@'%' IDENTIFIED BY 'Rpl_1234';
GRANT REPLICATION SLAVE ON *.* TO rpl@'%';
GRANT BACKUP_ADMIN ON *.* TO rpl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
CHANGE MASTER TO
MASTER_USER='rpl',
MASTER_PASSWORD='Rpl_1234'
FOR CHANNEL 'group_replication_recovery';
"
}
function StartExtraScripts {
Print Starting extra scripts ...
while sleep 2; do
for script in $(find $LOG_DIR/extra_scripts/ -type f -executable \
2>/dev/null || true); do
$script &
done
done &
}
function StartProc {
Print Starting mysql ...
mysqld -u mysql &
PIDS="$PIDS $!"
while sleep 1; do
[ -e $SOCK_FILE ] && break || echo -n .
[ ! -e /proc/$! ] && echo && Print unexpected error! && exit
done
echo
if [ -n "$INIT_FLAG" ]; then
ImportInitSql
if [ -n "$GROUP_REPLICATION" ]; then
CreateGroupReplicationChannel
fi
fi
if [ -n "$GROUP_REPLICATION" ]; then
StartGroupReplication
fi
if [ -n "$EXTRA_SCRIPTS" ]; then
StartExtraScripts
fi
Print MySQL is ready for connections.
}
function Main {
local pid=
[ -n "$GROUP_REPLICATION" ] && ProbeSeeds
Init
[ -n "$GROUP_REPLICATION" ] && InitGroupReplication
StartProc
trap "GOT_SIGTERM=1; Print Got SIGTERM ..." SIGTERM
while [ -z "$GOT_SIGTERM" ] && sleep 1; do
for pid in $PIDS; do
[ ! -e /proc/$pid ] && Print Unexpected error! && exit
done
done
}
# Start here
Main