MySQL数据库的自动复制脚本
前言
我们可能在某些情况下,总要复制mysql数据库。比如,从A服务器,复制到B服务器去。这种复制操作可能是为了迁移数据库,也可能是为了建立主从,又或者单纯只是为了备份。在复制MySQL数据库的过程中,经常需要手工操作数据库,例如登录数据库进行数据的导入导出。当数据库很大的时候,又得在每一步操作之间各种传输等待。这些操作不仅繁琐,还容易出错。尤其是在操作生产环境数据库时,总得小心翼翼,怕误操作导致数据丢失或损坏。
为了方便以及更可靠,我写了一个脚本来简化数据库的复制流程。使用脚本,只要简单输入数据库信息,便可自动复制。它的好处主要有以下几点:
- 便捷高效:脚本可以自动执行预设的操作步骤,大大减少手工操作的次数和时间。
- 减少误操作:通过预定义的脚本流程,减少了人为操作的风险。
- 易于复用:脚本可以多次使用,便于日后的数据库迁移工作。
- 性能不错:该脚本利用mysqldump进行数据导入导出,支持逐表进行管道传输,理论上可以处理较大的数据库。
下面是详细步骤:
创建迁移脚本
首先,我们需要创建一个新的脚本文件 vi sync_db.sh ,并在文件中填入以下内容:
#!/bin/bash
# 捕获退出信号,确保删除临时文件
cleanup() {
rm -f "$mysqldump_config" "$mysql_config"
}
trap cleanup EXIT
# 检查是否安装了 mysqldump
if ! command -v mysqldump &> /dev/null; then
echo "mysqldump 命令不存在。请安装 MySQL 客户端或在安装了 MySQL 的服务器上运行此脚本。"
exit 1
fi
# 提示用户输入数据库参数的函数
prompt_db_parameters() {
local db_type=$1
local host_var=$2
local port_var=$3
local user_var=$4
local pass_var=$5
local name_var=$6
read -p "请输入${db_type}数据库主机地址 (默认: 127.0.0.1): " input
eval $host_var="${input:-127.0.0.1}"
read -p "请输入${db_type}数据库端口号 (默认: 3306): " input
eval $port_var="${input:-3306}"
read -p "请输入${db_type}数据库用户名 (默认: root): " input
eval $user_var="${input:-root}"
read -sp "请输入${db_type}数据库密码: " input
echo
eval $pass_var="$input"
read -p "请输入${db_type}数据库名称: " input
eval $name_var="$input"
}
# 提示用户输入源数据库的参数
prompt_db_parameters "源" src_host src_port src_user src_pass src_db
# 提示用户输入目标数据库的参数
prompt_db_parameters "目标" dest_host dest_port dest_user dest_pass dest_db
# 显示输入信息供用户确认
echo "请确认以下信息是否正确:"
echo "源数据库主机地址: $src_host"
echo "源数据库端口号: $src_port"
echo "源数据库用户名: $src_user"
echo "源数据库名称: $src_db"
echo "目标数据库主机地址: $dest_host"
echo "目标数据库端口号: $dest_port"
echo "目标数据库用户名: $dest_user"
echo "目标数据库名称: $dest_db"
read -p "以上信息是否正确?按y会开始同步数据 (y/n): " confirm
if [ "$confirm" != "y" ]; then
echo "操作取消。"
exit 1
fi
# 使用临时的 MySQL 配置文件传递密码
mysqldump_config=$(mktemp)
cat <<EOF > "$mysqldump_config"
[client]
user=$src_user
password=$src_pass
host=$src_host
port=$src_port
EOF
mysql_config=$(mktemp)
cat <<EOF > "$mysql_config"
[client]
user=$dest_user
password=$dest_pass
host=$dest_host
port=$dest_port
EOF
# 检查目标数据库是否存在,如果不存在则尝试创建
db_exists=$(mysql --defaults-file="$mysql_config" -e "SHOW DATABASES LIKE '$dest_db';" | tail -n +2)
if [ -z "$db_exists" ]; then
mysql --defaults-file="$mysql_config" -e "CREATE DATABASE $dest_db;"
if [ $? -ne 0 ]; then
echo "无法创建目标数据库,可能是权限不足。"
exit 1
fi
echo "目标数据库已创建:$dest_db"
else
# 检查目标数据库是否存在数据
table_count=$(mysql --defaults-file="$mysql_config" -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='$dest_db';" | tail -n 1)
if [ "$table_count" -gt 0 ]; then
read -p "目标数据库存在数据,是否清空目标数据库后覆盖? (y/n): " clear_confirm
if [ "$clear_confirm" != "y" ]; then
echo "操作取消。"
exit 1
else
mysql --defaults-file="$mysql_config" -e "DROP DATABASE IF EXISTS \`$dest_db\`; CREATE DATABASE \`$dest_db\`;"
fi
fi
fi
# 尝试锁定源数据库
mysql --defaults-file="$mysqldump_config" -e "FLUSH TABLES WITH READ LOCK;" "$src_db"
lock_result=$?
if [ $lock_result -ne 0 ]; then
echo "没有锁定数据库权限,请自行确保关闭应用程序、不再往数据库写入新数据。"
read -p "是否继续操作?按y会继续 (y/n): " continue_confirm
if [ "$continue_confirm" != "y" ]; then
echo "操作取消。"
exit 1
fi
else
# 如果成功锁定,则设置一个标记以便在操作完成后解锁
locked=1
fi
# 获取所有表名
tables=$(mysql --defaults-file="$mysqldump_config" -e "SHOW TABLES;" "$src_db" | tail -n +2)
# 尝试逐个表进行同步
for table in $tables; do
echo "同步表:$table"
mysqldump --defaults-file="$mysqldump_config" --single-transaction --quick --compress --net_buffer_length=16384 --max_allowed_packet=512M "$src_db" "$table" | mysql --defaults-file="$mysql_config" "$dest_db"
sync_result=$?
if [ $sync_result -ne 0 ]; then
echo "同步表 $table 失败,请检查相关参数或网络连接。"
exit 1
fi
done
# 如果数据库成功被锁定,则解锁源数据库
if [ "${locked:-0}" -eq 1 ]; then
mysql --defaults-file="$mysqldump_config" -e "UNLOCK TABLES;" "$src_db"
fi
echo "数据库同步成功!"
使用脚本
1 保存上述代码到文件 sync_db.sh 中。
2 运行脚本:
sh sync_db.sh
脚本会提示你输入源数据库和目标数据库的连接信息,然后按照提示执行数据库复制操作。
注意事项
- 权限问题:确保使用root或具有足够权限的用户进行操作,避免因为权限不足导致的迁移失败。
- 锁定数据库:脚本会尝试锁定源数据库以防止数据在迁移过程中被修改,如果无法锁定,请确保停应用程序在迁移过程中不进行数据写入操作。
如无特殊说明,本站皆为原创。转载请注明来自第七星尘的独立博客的《MySQL数据库的自动复制脚本》
2024-07-05
编程技术
评论