脚本源码
#!/bin/bash
# 数据库迁移脚本 - 导出mysql数据库并导入到新机器
# 支持可配置的数据库列表和目标服务器ip地址
# 默认配置
source_host="127.0.0.1"
source_user="user"
source_pass="password"
target_host="127.0.0.1"
target_user="user"
target_pass="password"
db_list=("net" "event" "scd" "stgy" "web")
backup_dir="/tmp/mysql_backup_$(date +%y%m%d_%h%m%s)"
compress=true
# 帮助信息
show_help() {
echo "用法: $0 [选项]"
echo "选项:"
echo " -s, --source-host 源数据库主机地址 (默认: $source_host)"
echo " -u, --source-user 源数据库用户名 (默认: $source_user)"
echo " -p, --source-pass 源数据库密码"
echo " -t, --target-host 目标数据库主机地址 (默认: $target_host)"
echo " -u, --target-user 目标数据库用户名 (默认: $target_user)"
echo " -p, --target-pass 目标数据库密码"
echo " -d, --databases 要迁移的数据库列表,用逗号分隔 (默认: net,event,scd,stgyweb)"
echo " -o, --output-dir 备份目录 (默认: /tmp/mysql_backup_时间戳)"
echo " -c, --compress 是否压缩备份文件 (true/false,默认: true)"
echo " -h, --help 显示此帮助信息"
echo " --export-only 仅导出数据库,不导入"
echo " --import-only 仅导入数据库(需指定备份目录)"
echo ""
echo "示例:"
echo " # 使用默认配置导出导入所有数据库到本地"
echo " $0"
echo ""
echo " # 导出到指定ip的服务器"
echo " $0 --target-host 192.168.1.100 --target-user admin --target-pass password"
echo ""
echo " # 仅导出特定数据库"
echo " $0 --databases net,event --export-only"
echo ""
echo " # 仅导入特定备份目录"
echo " $0 --import-only --output-dir /tmp/mysql_backup_20230101_120000"
}
# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
-s|--source-host)
source_host="$2"
shift 2
;;
-u|--source-user)
source_user="$2"
shift 2
;;
-p|--source-pass)
source_pass="$2"
shift 2
;;
-t|--target-host)
target_host="$2"
shift 2
;;
-u|--target-user)
target_user="$2"
shift 2
;;
-p|--target-pass)
target_pass="$2"
shift 2
;;
-d|--databases)
ifs=',' read -r -a db_list <<< "$2"
shift 2
;;
-o|--output-dir)
backup_dir="$2"
shift 2
;;
-c|--compress)
compress="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
--export-only)
export_only=true
shift
;;
--import-only)
import_only=true
shift
;;
*)
echo "未知选项: $1"
show_help
exit 1
;;
esac
done
# 检查必要的工具
check_requirements() {
if ! command -v mysqldump &> /dev/null; then
echo "错误: 未找到 mysqldump 命令,请安装 mysql 客户端工具。"
exit 1
fi
if ! command -v mysql &> /dev/null; then
echo "错误: 未找到 mysql 命令,请安装 mysql 客户端工具。"
exit 1
fi
if [ "$compress" = true ] && ! command -v gzip &> /dev/null; then
echo "警告: 未找到 gzip 命令,将不压缩备份文件。"
compress=false
fi
}
# 导出数据库
export_databases() {
echo "开始导出数据库..."
echo "源数据库主机: $source_host"
echo "数据库列表: ${db_list[*]}"
echo "备份目录: $backup_dir"
# 创建备份目录
mkdir -p "$backup_dir"
# 导出每个数据库
for db in "${db_list[@]}"; do
echo "正在导出数据库: $db"
# 构建导出命令
export_cmd="mysqldump -h $source_host -u $source_user"
if [ -n "$source_pass" ]; then
export_cmd="$export_cmd -p$source_pass"
fi
# 添加--databases选项来包含创建数据库的语句
export_cmd="$export_cmd --databases $db"
# 添加一些常用的选项
export_cmd="$export_cmd --single-transaction --routines --triggers --events"
# 根据是否压缩构建完整命令
if [ "$compress" = true ]; then
export_cmd="$export_cmd | gzip > $backup_dir/${db}.sql.gz"
echo "执行: $export_cmd"
eval "$export_cmd"
else
export_cmd="$export_cmd > $backup_dir/${db}.sql"
echo "执行: $export_cmd"
eval "$export_cmd"
fi
# 检查导出是否成功
if [ $? -eq 0 ]; then
echo "数据库 $db 导出成功。"
else
echo "错误: 数据库 $db 导出失败!"
export_errors=true
fi
done
# 生成配置文件记录导出信息
cat > "$backup_dir/backup_info.txt" << eof
备份时间: $(date '+%y-%m-%d %h:%m:%s')
源数据库主机: $source_host
源数据库用户名: $source_user
数据库列表: ${db_list[*]}
是否压缩: $compress
eof
if [ -n "$export_errors" ]; then
echo "警告: 部分数据库导出失败!"
return 1
else
echo "所有数据库导出成功!"
return 0
fi
}
# 导入数据库
import_databases() {
echo "开始导入数据库..."
echo "目标数据库主机: $target_host"
echo "备份目录: $backup_dir"
# 检查备份目录是否存在
if [ ! -d "$backup_dir" ]; then
echo "错误: 备份目录 '$backup_dir' 不存在!"
exit 1
fi
# 检查备份信息文件
if [ -f "$backup_dir/backup_info.txt" ]; then
echo "备份信息:"
cat "$backup_dir/backup_info.txt"
else
echo "警告: 未找到备份信息文件。"
fi
# 确定要导入的文件列表
if [ ${#db_list[@]} -eq 0 ]; then
# 如果没有指定数据库列表,尝试从备份目录中读取
if [ "$compress" = true ] || ls "$backup_dir"/*.sql.gz 1> /dev/null 2>&1; then
backup_files=("$backup_dir"/*.sql.gz)
else
backup_files=("$backup_dir"/*.sql)
fi
else
# 如果指定了数据库列表,使用指定的列表
backup_files=()
for db in "${db_list[@]}"; do
if [ -f "$backup_dir/${db}.sql.gz" ]; then
backup_files+=("$backup_dir/${db}.sql.gz")
compress=true
elif [ -f "$backup_dir/${db}.sql" ]; then
backup_files+=("$backup_dir/${db}.sql")
else
echo "警告: 未找到数据库 $db 的备份文件!"
fi
done
fi
# 导入每个数据库文件
import_errors=false
for file in "${backup_files[@]}"; do
# 提取数据库名
db_name=$(basename "$file")
db_name=${db_name%.sql.gz}
db_name=${db_name%.sql}
echo "正在导入数据库: $db_name"
# 构建导入命令
import_cmd="mysql -h $target_host -u $target_user"
if [ -n "$target_pass" ]; then
import_cmd="$import_cmd -p$target_pass"
fi
# 根据文件类型构建完整命令
if [[ "$file" == *.gz ]]; then
import_cmd="gzip -dc $file | $import_cmd"
echo "执行: $import_cmd"
eval "$import_cmd"
else
import_cmd="$import_cmd < $file"
echo "执行: $import_cmd"
eval "$import_cmd"
fi
# 检查导入是否成功
if [ $? -eq 0 ]; then
echo "数据库 $db_name 导入成功。"
else
echo "错误: 数据库 $db_name 导入失败!"
import_errors=true
fi
done
if [ -n "$import_errors" ]; then
echo "警告: 部分数据库导入失败!"
return 1
else
echo "所有数据库导入成功!"
return 0
fi
}
# 主函数
main() {
echo "========================================"
echo "mysql数据库迁移工具"
echo "========================================"
# 检查必要的工具
check_requirements
# 根据参数执行导出或导入
if [ "$import_only" != true ]; then
export_databases
export_result=$?
fi
if [ "$export_only" != true ] && [ "$import_only" != true ]; then
# 如果不是仅导出或仅导入,则在导出后进行导入
if [ $export_result -eq 0 ]; then
import_databases
else
echo "由于导出失败,跳过导入步骤。"
exit 1
fi
elif [ "$import_only" == true ]; then
# 如果是仅导入,则直接执行导入
import_databases
fi
echo "========================================"
echo "迁移完成!"
echo "========================================"
}
# 执行主函数
main
脚本概述
这是一个功能完整的mysql数据库迁移工具,支持将多个数据库从源服务器导出并导入到目标服务器。脚本使用mysqldump进行逻辑备份,确保数据迁移的兼容性和可靠性。
主要特性:
- 支持批量迁移多个数据库
- 可配置的源和目标服务器连接参数
- 可选择压缩备份以节省磁盘空间
- 支持导出/导入分离操作
- 完整的错误检查和日志记录
快速开始
基本用法
# 使用默认配置迁移所有数据库到本地 ./mysql_migration.sh # 迁移到远程服务器 ./mysql_migration.sh --target-host 192.168.1.100 --target-user admin --target-pass password # 仅迁移特定数据库 ./mysql_migration.sh --databases net,event
常见用法
1.从本机迁移数据库到指定主机
将所有数据库迁移到指定主机
./db_migrate.sh --source-host 127.0.0.1 --target-host 10.10.110.46
仅迁移某个数据库到指定主机
./db_migrate.sh --source-host 127.0.0.1 --target-host 10.10.110.46 -d scd
2.将其他主机数据库迁移到指定主机
将所有数据库迁移到指定主机
./db_migrate.sh --source-host 10.10.112.3 --target-host 10.10.110.46
仅迁移某个数据库到指定主机
./db_migrate.sh --source-host 10.10.112.3 --target-host 10.10.110.46 -d web
参数详解
连接参数
| 参数 | 简写 | 默认值 | 说明 |
|---|---|---|---|
| --source-host | -s | 127.0.0.1 | 源数据库主机地址 |
| --source-user | -u | username | 源数据库用户名 |
| --source-pass | -p | password | 源数据库密码 |
| --target-host | -t | 127.0.0.1 | 目标数据库主机地址 |
| --target-user | -u | username | 目标数据库用户名 |
| --target-pass | -p | password | 目标数据库密码 |
功能参数
| 参数 | 简写 | 默认值 | 说明 |
|---|---|---|---|
| --databases | -d | net,event,scd,stgy,web | 要迁移的数据库列表(逗号分隔) |
| --output-dir | -o | 自动生成 | 备份文件存储目录 |
| --compress | -c | true | 是否压缩备份文件 |
| --export-only | 无 | false | 仅执行导出操作 |
| --import-only | 无 | false | 仅执行导入操作(需指定备份目录) |
使用示例
完整迁移到远程服务器
./mysql_migration.sh \ --source-host 192.168.1.50 \ --source-user dbadmin \ --source-pass src_password \ --target-host 192.168.1.100 \ --target-user dbadmin \ --target-pass tgt_password \ --databases net,event,scd
分步执行
# 第一步:仅导出数据库 ./mysql_migration.sh \ --source-host 192.168.1.50 \ --export-only \ --output-dir /backup/mysql_20231213 # 第二步:将备份文件传输到目标服务器 scp -r /backup/mysql_20231213 user@target-server:/tmp/ # 第三步:在目标服务器上导入 ./mysql_migration.sh \ --target-host 192.168.1.100 \ --import-only \ --output-dir /tmp/mysql_20231213
大型数据库优化
对于大型数据库,建议添加性能优化参数:
# 在脚本中的export_cmd变量添加以下参数: export_cmd="$export_cmd --single-transaction --quick --skip-lock-tables"
迁移技术细节
导出参数说明
脚本使用的关键mysqldump参数:
--single-transaction:在事务中执行导出,确保数据一致性--routines:导出存储过程和函数--triggers:导出触发器--events:导出事件调度器--databases:包含创建数据库语句
备份文件结构
/tmp/mysql_backup_20231213_143022/
├── net.sql.gz # 压缩的数据库备份
├── event.sql.gz
├── scd.sql.gz
├── stgy.sql.gz
├── web.sql.gz
└── backup_info.txt # 备份元数据信息
最佳实践建议
1. 迁移前准备
权限检查:确保数据库用户有足够权限
-- 源数据库用户需要select、lock tables权限 grant select, lock tables on source_db.* to 'username'@'localhost'; -- 目标数据库用户需要create、insert等权限 grant create, insert, update on target_db.* to 'username'@'localhost';
版本兼容性:检查mysql版本兼容性,特别是5.7到8.0的迁移
2. 大数据量迁移优化
分批次迁移:对于特大表可以考虑分批次导出
# 按条件分批导出大数据表 mysqldump --where="id between 1 and 1000000" large_table > part1.sql
网络优化:使用压缩传输减少网络带宽占用
# 管道直接传输(避免中间文件) mysqldump -h source_host -u user -p db | gzip | ssh user@target_host "gunzip | mysql -u user -p db"
3. 数据一致性验证
迁移完成后建议进行数据验证:
# 记录数对比 source_count=$(mysql -h source_host -u user -p -n -s -e "select count(*) from table") target_count=$(mysql -h target_host -u user -p -n -s -e "select count(*) from table") echo "source: $source_count | target: $target_count"
故障排除
常见问题解决
连接失败
- 检查防火墙设置和端口访问(默认3306)
- 验证用户名和密码是否正确
- 确认mysql服务是否正常运行
权限错误
- 确保用户有导出/导入权限
- 检查数据库名是否正确
字符集问题
- 添加字符集参数:
--default-character-set=utf8mb4 - 统一源和目标数据库的字符集设置
大数据量导出超时
- 调整超时参数:
set global ob_query_timeout=1000000000; - 使用
--quick参数优化大表导出
注意事项
- 业务影响:迁移期间建议停止使用源数据库的应用程序
- 存储空间:确保备份目录有足够磁盘空间
- 网络稳定性:跨网络迁移需要稳定的网络连接
- 回滚方案:重要数据迁移前建议做好备份
- 触发器处理:注意触发器的导出和导入设置
扩展功能
如需更高级的数据库版本控制,可以考虑集成flyway或liquibase等专业工具,它们提供更好的版本管理和回滚能力。
此脚本提供了mysql数据库迁移的基础功能,适用于大多数迁移场景。根据具体需求可以进一步定制和优化参数设置。
到此这篇关于使用脚本迁移mysql数据库的完整代码及使用说明的文章就介绍到这了,更多相关mysql数据库迁移脚本内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论