Files
agent-skills/skills/g3fo-docs/references/middleware/mysql/backup-sync.sh
T
ken.li 3808192fd8 feat(mysql): 添加MySQL全量备份与还原脚本及文档
新增备份脚本backup-sync.sh和还原脚本restore-sync.sh,用于处理严重复制冲突场景
更新故障分析文档,补充全量备份还原的操作流程和注意事项
添加测试流程模板文件_TEST_FLOW_TEMPLATE.md
更新SKILL.md文档,增加测试流程分析相关内容
2026-02-02 14:40:46 +08:00

132 lines
4.0 KiB
Bash

#!/bin/bash
TAG=""
while getopts "t:" opt; do
case $opt in
t) TAG="$OPTARG" ;;
*) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
esac
done
shift $((OPTIND-1))
cd /data/backup/mysql || exit 1
if [ -n "$TAG" ]; then
BACKUP_DIR="./$(date +%Y%m%d%H%M%S)_${TAG}"
else
BACKUP_DIR="./$(date +%Y%m%d%H%M%S)"
fi
mkdir -p "$BACKUP_DIR"
MYSQL_USER="root"
MYSQL_PASSWORD="ENC(VN13kACOdhyl7xYqbgDMTMP0fK4dwoCkFe0AQW0VEt7/tpwx96GzRVY6eIpwlASM)"
MYSQL_HOST="127.0.0.1"
if [[ "$MYSQL_PASSWORD" =~ ^ENC\(.*\)$ ]]; then
encrypted_pwd="${MYSQL_PASSWORD:4:-1}"
if ! MYSQL_PASSWORD=$(java -cp /data/secure/jasypt-agent.jar com.jasypt.agent.DecryptionCLI $encrypted_pwd \
2>&1); then
echo -e "\033[31m[Fatal Error] Password decryption failed. Reason:"
echo "$MYSQL_PASSWORD" | grep -iE "error|exception"
exit 1
fi
fi
# Function to execute MySQL command
mysql_exec() {
docker exec -i mysql mysql -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" -N -e "$1" 2>/dev/null
}
# Function to restore MySQL state (called on exit)
restore_mysql_state() {
if [ "$READ_ONLY_SET" = "true" ]; then
echo "Restoring MySQL state..."
mysql_exec "SET GLOBAL read_only = OFF;" || echo "[Warning] Failed to set read_only = OFF"
echo "MySQL state restored"
fi
}
# Set trap to ensure MySQL state is restored even on error
trap restore_mysql_state EXIT ERR
# Pre-backup: Set read-only and stop slave
echo "Setting MySQL to read-only mode..."
if ! mysql_exec "SET GLOBAL read_only = ON;"; then
echo "[Critical Error] Failed to set read_only = ON"
exit 1
fi
READ_ONLY_SET="true"
echo "Stopping slave replication..."
if ! mysql_exec "STOP REPLICA;"; then
echo "[Warning] Failed to stop replica (may not be a slave server or already stopped)"
fi
# Get GTID position using SELECT @@global.gtid_executed;
echo "Getting GTID position..."
GTID_EXECUTED=$(mysql_exec "SELECT @@global.gtid_executed;")
if [ -n "$GTID_EXECUTED" ]; then
# Remove newlines and literal \n strings
GTID_EXECUTED=$(echo "$GTID_EXECUTED" | tr -d '\n' | sed 's/\\n//g' | tr -s ' ')
echo "GTID Executed: $GTID_EXECUTED"
# Write GTID to file for restore use
echo "$GTID_EXECUTED" > "$BACKUP_DIR/gtid_executed.txt"
else
echo "[Warning] Failed to get GTID executed information"
fi
# Get database list for backup
if [ $# -eq 0 ]; then
# When no arguments, get all non-system databases
databases=$(mysql_exec "SHOW DATABASES;" | grep -Ev "(Database|information_schema|performance_schema|mysql|skywalking|sys)")
# Convert to array and check empty values
readarray -t db_list <<< "$databases" || {
echo "ERROR: No valid databases found or failed to retrieve database list"
restore_mysql_state
exit 1
}
else
# Use arguments as database list when provided
db_list=("$@")
fi
# Check if database list is empty
if [ ${#db_list[@]} -eq 0 ]; then
echo "ERROR: No databases to backup"
restore_mysql_state
exit 1
fi
backup_list_str="$BACKUP_DIR.7z"
# Perform backup
for db in "${db_list[@]}"; do
echo "Backing up database: $db"
backup_list_str="$backup_list_str $db"
if ! docker exec -i mysql mysqldump -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -h "$MYSQL_HOST" --set-gtid-purged=OFF --single-transaction --databases "$db" > "$BACKUP_DIR/$db.sql"; then
echo "[Critical Error] Failed to backup database $db, aborting"
restore_mysql_state
exit 1
fi
done
# Post-backup: Restore MySQL state (before compression)
echo "Restoring MySQL to read-write mode..."
mysql_exec "SET GLOBAL read_only = OFF;" || echo "[Warning] Failed to set read_only = OFF"
# Clear the trap since we've successfully restored
READ_ONLY_SET="false"
trap - EXIT ERR
# Compress backup files
if ! 7zz a "$BACKUP_DIR.7z" "$BACKUP_DIR" >/dev/null; then
echo "Compression failed. Please check disk space or 7z installation"
exit 1
fi
# Cleanup temporary files
rm -rf "$BACKUP_DIR"
echo "Backup completed: $BACKUP_DIR.7z"
echo $backup_list_str >> backup_list.txt
echo "Backup process completed successfully"