docker环境脚本一键安装mysql8.0和进行数据库备份
·
文章目录
前言
提示:在docker环境脚本一键按照mysql8.0数据库,方便快捷省事省时,包括如何定时备份和恢复 我的安装目录是/software/mysql下,如果需要修改自行修改脚本,我的默认密码是123456

一、安装MySql8.0版本
1.1 安装脚本 (install_mysql.sh)
提示:创建my-network,否则删除 --network my-network \
新建文件 install_mysql.sh*,内容如下:
#!/bin/bash
# 设置变量
MYSQL_ROOT_PASSWORD="123456"
MYSQL_VERSION="8.0.26"
MYSQL_PORT="3306"
MYSQL_BASE_DIR="/software/mysql"
TEMP_CONTAINER_NAME="mysql_temp_$(date +%s)" # 使用时间戳避免冲突
echo "开始安装MySQL..."
# 检查端口是否被占用
if netstat -tuln | grep ":${MYSQL_PORT} " > /dev/null; then
echo "错误:端口 ${MYSQL_PORT} 已被占用!"
exit 1
fi
# 清理可能存在的旧临时容器
docker rm -f mysql_temp 2>/dev/null || true
docker rm -f ${TEMP_CONTAINER_NAME} 2>/dev/null || true
# 创建必要的目录(如果不存在)
sudo mkdir -p ${MYSQL_BASE_DIR}/data
sudo mkdir -p ${MYSQL_BASE_DIR}/config
sudo mkdir -p ${MYSQL_BASE_DIR}/logs
# 只有第一次才复制默认配置
if [ ! -f "${MYSQL_BASE_DIR}/config/my.cnf" ]; then
echo "正在启动临时MySQL容器以获取默认配置..."
# 运行临时容器
docker run \
-d \
-p ${MYSQL_PORT}:3306 \
--name ${TEMP_CONTAINER_NAME} \
-e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
mysql:${MYSQL_VERSION}
# 等待MySQL启动完成
echo "等待MySQL启动..."
# 更好的等待方式
for i in {1..60}; do
if docker exec ${TEMP_CONTAINER_NAME} mysqladmin ping -h localhost --silent; then
echo "MySQL已启动"
break
fi
echo "等待MySQL启动... ($i/60)"
sleep 2
done
# 复制配置文件
echo "复制配置文件..."
docker cp ${TEMP_CONTAINER_NAME}:/etc/mysql/. ${MYSQL_BASE_DIR}/config
# 停止并删除临时容器
echo "清理临时容器..."
docker stop ${TEMP_CONTAINER_NAME}
docker rm ${TEMP_CONTAINER_NAME}
# 修改配置文件,忽略表名大小写
if ! grep -q "lower_case_table_names" ${MYSQL_BASE_DIR}/config/my.cnf; then
echo "lower_case_table_names=1" | sudo tee -a ${MYSQL_BASE_DIR}/config/my.cnf
fi
else
echo "配置文件已存在,跳过配置生成步骤..."
fi
# 设置正确的目录权限(仅在需要时)
if [ -d "${MYSQL_BASE_DIR}/data" ]; then
sudo chown -R 999:999 ${MYSQL_BASE_DIR}/data 2>/dev/null || true
fi
if [ -d "${MYSQL_BASE_DIR}/logs" ]; then
sudo chown -R 999:999 ${MYSQL_BASE_DIR}/logs 2>/dev/null || true
fi
echo "MySQL安装完成!"
echo "数据目录: ${MYSQL_BASE_DIR}/data"
echo "配置目录: ${MYSQL_BASE_DIR}/config"
echo "日志目录: ${MYSQL_BASE_DIR}/logs"
1.2 启动脚本 (start_mysql.sh)
#!/bin/bash
# 设置变量
MYSQL_ROOT_PASSWORD="123456"
MYSQL_VERSION="8.0.26"
MYSQL_PORT="3306"
MYSQL_BASE_DIR="/software/mysql"
echo "正在启动MySQL容器..."
# 检查端口是否被占用
if netstat -tuln | grep ":${MYSQL_PORT} " > /dev/null; then
echo "错误:端口 ${MYSQL_PORT} 已被占用!"
exit 1
fi
# 检查网络是否存在
if ! docker network ls | grep -q my-network; then
echo "警告:网络 'my-network' 不存在,创建中..."
docker network create my-network
fi
# 检查是否已存在同名容器
CONTAINER_EXISTS=$(docker ps -a --filter "name=mysql" --format "{{.Names}}")
if [ ! -z "$CONTAINER_EXISTS" ]; then
echo "发现已存在的MySQL容器,正在停止并删除..."
docker stop mysql >/dev/null 2>&1
docker rm mysql >/dev/null 2>&1
echo "旧容器已清理"
fi
# 检查数据目录是否存在且非空
if [ -d "${MYSQL_BASE_DIR}/data" ] && [ "$(ls -A ${MYSQL_BASE_DIR}/data)" ]; then
echo "警告:数据目录非空,将使用现有数据启动"
echo " 如果MySQL版本不同,可能导致启动失败"
fi
# 检查配置文件
if [ ! -f "${MYSQL_BASE_DIR}/config/my.cnf" ]; then
echo "警告:配置文件不存在,将使用默认配置"
mkdir -p ${MYSQL_BASE_DIR}/config
fi
# 设置正确的权限(可选)
if [ -d "${MYSQL_BASE_DIR}/data" ]; then
sudo chown -R 999:999 ${MYSQL_BASE_DIR}/data 2>/dev/null || true
fi
# 启动最终的MySQL容器
echo "启动MySQL容器..."
docker run \
-d \
-p ${MYSQL_PORT}:3306 \
--name mysql \
--restart unless-stopped \
--privileged \
--network my-network \
--log-opt max-size=50m \
--log-opt max-file=3 \
-v /etc/localtime:/etc/localtime:ro \
-v ${MYSQL_BASE_DIR}/data:/var/lib/mysql \
-v ${MYSQL_BASE_DIR}/config:/etc/mysql \
-v ${MYSQL_BASE_DIR}/logs:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} \
-e TZ=Asia/Shanghai \
mysql:${MYSQL_VERSION}
if [ $? -ne 0 ]; then
echo "✗ 容器启动失败!"
exit 1
fi
# 等待容器启动(更智能的等待)
echo "等待MySQL服务启动..."
for i in {1..30}; do
if docker exec mysql mysqladmin ping -h localhost --silent 2>/dev/null; then
echo "✓ MySQL服务已就绪"
break
fi
echo "等待中... ($i/30)"
sleep 2
done
# 检查容器状态
echo "检查MySQL容器状态..."
if docker ps | grep -q mysql; then
echo "✓ MySQL容器运行正常"
# 验证数据库连接
if docker exec mysql mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SELECT 1" 2>/dev/null; then
echo "✓ MySQL数据库连接成功"
else
echo "⚠ 容器运行但数据库连接失败"
fi
else
echo "✗ MySQL容器未运行!"
echo "查看容器日志:docker logs mysql"
exit 1
fi
echo ""
echo "MySQL启动完成!"
echo "连接信息:"
echo "端口: ${MYSQL_PORT}"
echo "用户名: root"
echo "密码: ${MYSQL_ROOT_PASSWORD}"
echo "数据目录: ${MYSQL_BASE_DIR}/data"
echo "配置目录: ${MYSQL_BASE_DIR}/config"
echo ""
echo "常用命令:"
echo "查看日志: docker logs mysql"
echo "进入容器: docker exec -it mysql bash"
echo "停止服务: docker stop mysql"
1.3 停止脚本 (stop_mysql.sh)
#!/bin/bash
echo "正在停止MySQL容器..."
if docker ps | grep -q mysql; then
docker stop mysql
echo "MySQL容器已停止"
else
echo "MySQL容器未在运行"
fi
1.4 重启脚本 (restart_mysql.sh)
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo "正在重启MySQL容器..."
# 停止MySQL
if docker ps | grep -q mysql; then
docker stop mysql
echo "MySQL容器已停止"
fi
# 启动MySQL
bash ${SCRIPT_DIR}/start_mysql.sh
1.5 添加权限
chmod +x install_mysql.sh start_mysql.sh stop_mysql.sh restart_mysql.sh
二、备份
提示:检查脚本密码和原来数据库密码是否一致,如果不一致设置脚本内的密码,否则恢复后会重置密码!
1.进行数据备份
在backup文件夹下新建mysql_backup.sh 文件,内容如下
#!/bin/bash
# 备份配置
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
MYSQL_USER="root"
MYSQL_PASSWORD="123456"
BACKUP_BASE_DIR="/software/mysql/backup"
BACKUP_DIR="${BACKUP_BASE_DIR}/backups"
RESTORE_DIR="${BACKUP_BASE_DIR}/restores"
LOG_FILE="${BACKUP_BASE_DIR}/backup.log"
RETENTION_DAYS=7
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="mysql_backup_${DATE}"
# 创建备份目录
mkdir -p ${BACKUP_DIR}
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> ${LOG_FILE}
echo "$1"
}
log "=== 开始MySQL备份 ==="
# 检查MySQL连接
if ! docker exec mysql mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SELECT 1;" &>/dev/null; then
log "错误: 无法连接到MySQL"
exit 1
fi
# 创建临时备份目录
TEMP_DIR="${BACKUP_DIR}/${BACKUP_NAME}"
mkdir -p ${TEMP_DIR}
# 1. 全量数据库备份(重定向错误输出,避免警告混入)
log "执行全量数据库备份..."
docker exec mysql bash -c "mysqldump -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD} \
--all-databases \
--single-transaction \
--routines \
--events \
--triggers \
--no-tablespaces \
2>/dev/null" > ${TEMP_DIR}/databases.sql
if [ $? -eq 0 ] && [ -s ${TEMP_DIR}/databases.sql ]; then
log "全量备份完成,文件大小: $(du -h ${TEMP_DIR}/databases.sql | cut -f1)"
else
log "错误: 全量备份失败或文件为空"
exit 1
fi
# 2. 备份二进制日志位置(可选)
log "备份二进制日志信息..."
docker exec mysql mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SHOW MASTER STATUS\G" > ${TEMP_DIR}/binlog_info.txt 2>/dev/null
# 3. 创建备份信息文件
cat > ${TEMP_DIR}/backup_info.txt << INFO
备份时间: $(date)
备份名称: ${BACKUP_NAME}
MySQL版本: $(docker exec mysql mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -s -N -e "SELECT VERSION();" 2>/dev/null)
数据库列表: $(docker exec mysql mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -s -N -e "SHOW DATABASES;" 2>/dev/null | tr '\n' ' ')
INFO
# 4. 压缩备份文件
log "压缩备份文件..."
cd ${BACKUP_DIR}
tar -czf ${BACKUP_NAME}.tar.gz ${BACKUP_NAME}
rm -rf ${TEMP_DIR}
# 5. 清理旧备份(保留7天)
log "清理过期备份..."
find ${BACKUP_DIR} -name "mysql_backup_*.tar.gz" -mtime +${RETENTION_DAYS} -delete
find ${BACKUP_BASE_DIR} -name "*.log" -mtime +${RETENTION_DAYS} -delete
# 6. 记录备份结果
BACKUP_SIZE=$(du -h ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz | cut -f1)
log "备份完成: ${BACKUP_NAME}.tar.gz (${BACKUP_SIZE})"
log "=== 备份结束 ===\n"
2.修改文件权限
修改文件权限,命令如下:
chmod +x /software/mysql/backup/mysql_backup.sh*
3. 设置定时任务
#1. 编辑root的crontab
sudo crontab -e
# 2.添加以下内容(每天凌晨2点备份):
0 2 * * * /software/mysql/backup/mysql_backup.sh >> /software/mysql/backup/backup.log 2>&1
# 3.ctrl+o 保存
# 4.Enter 回车确认
# 5.ctrl+X 退出
三、恢复数
提示:检查脚本密码和原来数据库密码是否一致,如果不一致设置脚本内的密码,否则恢复后会重置密码!
1.恢复数据备份脚本
在backup文件夹下新建safe_restore.sh* 文件,内容如下:
#!/bin/bash
echo "=== 安全恢复脚本(修复版) ==="
if [ $# -eq 0 ]; then
echo "请指定备份文件:"
ls -lt /software/mysql/backup/backups/*.tar.gz | head -10
exit 1
fi
BACKUP_FILE=$1
RESTORE_DIR="/tmp/restore_$(date +%s)"
echo "使用备份文件: $BACKUP_FILE"
echo "临时目录: $RESTORE_DIR"
# 解压备份文件
mkdir -p $RESTORE_DIR
tar -xzf "$BACKUP_FILE" -C $RESTORE_DIR
# 查找SQL文件
SQL_FILE=$(find $RESTORE_DIR -name "databases.sql" | head -1)
if [ -z "$SQL_FILE" ]; then
echo "错误: 未找到databases.sql文件"
exit 1
fi
echo "找到SQL文件: $SQL_FILE ($(ls -lh $SQL_FILE | awk '{print $5}'))"
# 清理备份文件中的警告信息
echo "清理备份文件中的警告信息..."
CLEANED_SQL="/tmp/cleaned_backup_$(date +%s).sql"
grep -v "WARNING:" "$SQL_FILE" | grep -v "Using a password" > "$CLEANED_SQL"
echo "清理后文件大小: $(ls -lh $CLEANED_SQL | awk '{print $5}')"
# 备份当前数据
echo "创建恢复前备份..."
CURRENT_BACKUP="/software/mysql/backup/restores/restore_$(date +%Y%m%d_%H%M%S).sql"
docker exec mysql mysqldump -uroot -p123456 --all-databases --single-transaction --no-tablespaces > "$CURRENT_BACKUP" 2>/dev/null
echo "当前数据备份: $CURRENT_BACKUP"
# 执行恢复
echo "开始恢复数据..."
if docker exec -i mysql mysql -uroot -p123456 < "$CLEANED_SQL"; then
echo "✅ 数据恢复成功"
else
echo "❌ 数据恢复失败"
echo "尝试从当前备份恢复..."
docker exec -i mysql mysql -uroot -p123456 < "$CURRENT_BACKUP"
echo "已恢复原始数据"
# 清理临时文件
rm -f "$CLEANED_SQL"
rm -rf "$RESTORE_DIR"
exit 1
fi
# 验证恢复
echo "验证恢复..."
docker exec mysql mysql -uroot -p123456 -e "
SHOW DATABASES;
SELECT '恢复完成,密码未改变' as status;
"
# 清理临时文件
rm -f "$CLEANED_SQL"
rm -rf "$RESTORE_DIR"
echo "=== 恢复完成 ==="
2.修改文件权限
修改文件权限,命令如下:
chmod +x /software/mysql/backup/safe_restore.sh*
3.使用恢复文件脚本
1、cd /software/mysql/backup
2、./safe_restore.sh +文件名
例如相对路径的恢复文件:./safe_restore.sh ./mysql_backup_20241202_020001.tar.gz
总结
如果安装完成数据库,进行验证数据库备份恢复,不慎设置密码与原来不一样或者恢复后不知道密码多少时,最简单暴力的方法就是将/software/mysql文件夹下除了安装脚本install_mysql.sh*,其他全部删除,再次进行安装
更多推荐

所有评论(0)