一、数据库全量备份
bash
复制代码
#!/bin/bash
# 配置参数
DB_HOST="数据库IP地址"
DB_USER="数据库用户名"
DB_PASS="数据库密码"
BACKUP_DIR="/usr/local/mysqldump"
DATE=$(date +"%Y%m%d_%H%M%S")
LOG_FILE="$BACKUP_DIR/backup_$DATE.log"
# 创建备份目录
mkdir -p $BACKUP_DIR/$DATE
# 开始日志
echo "$(date): 开始MySQL全库备份" | tee -a $LOG_FILE
# 获取数据库列表(排除系统库)
echo "$(date): 获取数据库列表..." | tee -a $LOG_FILE
DATABASES=$(mysql -h $DB_HOST -u $DB_USER -p$DB_PASS -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "(Database|information_schema|performance_schema|sys)")
if [ $? -ne 0 ]; then
echo "$(date): 错误:无法连接MySQL服务器" | tee -a $LOG_FILE
exit 1
fi
echo "找到数据库: $DATABASES" | tee -a $LOG_FILE
# 备份每个数据库
for DB in $DATABASES; do
echo "$(date): 备份数据库: $DB" | tee -a $LOG_FILE
# 备份命令
mysqldump -h $DB_HOST -u $DB_USER -p$DB_PASS \
--single-transaction \
--routines \
--events \
--triggers \
--add-drop-database \
$DB 2>> $LOG_FILE | gzip > $BACKUP_DIR/$DATE/${DB}_${DATE}.sql.gz
# 检查备份是否成功
if [ ${PIPESTATUS[0]} -eq 0 ]; then
echo "$(date): ✓ 成功备份: $DB" | tee -a $LOG_FILE
else
echo "$(date): ✗ 备份失败: $DB" | tee -a $LOG_FILE
fi
done
echo "$(date): 备份完成!文件保存在: $BACKUP_DIR/$DATE/" | tee -a $LOG_FILE
# 显示备份文件信息
echo "备份文件列表:" | tee -a $LOG_FILE
ls -lh $BACKUP_DIR/$DATE/ | tee -a $LOG_FILE
二、数据库备份恢复
bash
复制代码
#!/bin/bash
# 配置参数
NEW_DB_HOST="数据库IP地址"
NEW_DB_USER="数据库用户名"
NEW_DB_PASS="数据库密码"
# 数据库端口,默认3306
NEW_DB_PORT="3306"
BACKUP_DIR="数据库备份地址"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志文件
LOG_FILE="$BACKUP_DIR/import_$(date +%Y%m%d_%H%M%S).log"
# 显示带颜色的消息
log_info() { echo -e "${GREEN}[INFO]${NC} $(date): $1" | tee -a $LOG_FILE; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $(date): $1" | tee -a $LOG_FILE; }
log_error() { echo -e "${RED}[ERROR]${NC} $(date): $1" | tee -a $LOG_FILE; }
# 测试数据库连接
test_db_connection() {
log_info "测试数据库连接..."
mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS -e "SELECT 1;" > /dev/null 2>&1
if [ $? -ne 0 ]; then
log_error "无法连接到目标MySQL服务器"
exit 1
fi
log_info "数据库连接测试成功"
}
# 获取备份文件列表
get_backup_files() {
find $BACKUP_DIR -name "*.sql.gz" -type f | sort
}
# 从文件名提取数据库名
extract_db_name() {
local filename=$(basename "$1")
# 使用sed去掉日期时间部分和扩展名
echo "$filename" | sed 's/_[0-9]\{8\}_[0-9]\{6\}\.sql\.gz$//'
#echo $filename | cut -d'_' -f1
}
# 创建数据库
create_database() {
local db_name=$1
log_info "创建数据库: $db_name"
mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS \
-e "CREATE DATABASE IF NOT EXISTS \`$db_name\`
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>> $LOG_FILE
if [ $? -eq 0 ]; then
log_info "✓ 数据库创建成功: $db_name"
return 0
else
log_error "创建数据库失败: $db_name"
return 1
fi
}
# 导入数据库
import_database() {
local db_name=$1
local backup_file=$2
log_info "开始导入: $db_name"
# 显示进度(估算)
total_size=$(gunzip -c "$backup_file" | wc -c 2>/dev/null)
if [ -n "$total_size" ]; then
log_info "预计导入数据量: $(($total_size/1024/1024)) MB"
fi
# 导入数据
start_time=$(date +%s)
gunzip -c "$backup_file" | mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS $db_name 2>> $LOG_FILE
local import_status=$?
end_time=$(date +%s)
duration=$((end_time - start_time))
if [ $import_status -eq 0 ]; then
log_info "✓ 导入成功: $db_name (耗时: ${duration}秒)"
return 0
else
log_error "导入失败: $db_name"
return 1
fi
}
# 主函数
main() {
log_info "开始数据库导入过程"
# 测试连接
test_db_connection
# 获取备份文件列表
backup_files=$(get_backup_files)
total_files=$(echo "$backup_files" | wc -l)
current_file=0
log_info "找到 $total_files 个备份文件需要导入"
# 导入每个数据库
success_count=0
fail_count=0
for backup_file in $backup_files; do
current_file=$((current_file + 1))
db_name=$(extract_db_name "$backup_file")
log_info "处理文件 [$current_file/$total_files]: $db_name"
# 创建数据库
if create_database "$db_name"; then
# 导入数据
if import_database "$db_name" "$backup_file"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
else
fail_count=$((fail_count + 1))
fi
echo "----------------------------------------" | tee -a $LOG_FILE
done
# 显示总结
log_info "导入完成!"
log_info "成功: $success_count 个数据库"
if [ $fail_count -gt 0 ]; then
log_warn "失败: $fail_count 个数据库"
fi
# 显示所有导入的数据库
log_info "新服务器上的数据库列表:"
mysql -h $NEW_DB_HOST -P $NEW_DB_PORT -u $NEW_DB_USER -p$NEW_DB_PASS -e "SHOW DATABASES;" | tee -a $LOG_FILE
}
# 执行主函数
main
三、按表备份
bash
复制代码
#!/bin/bash
# 远程MySQL数据库同步(导出+导入)
# 源数据库(要导出的数据库)
SRC_HOST="源数据库ip地址"
SRC_USER="源数据库用户名"
SRC_PASS="源数据库密码"
SRC_DB="源数据库表名称"
# 目标数据库(要导入的数据库)
DST_HOST="目标数据库ip地址"
DST_USER="目标数据库用户名"
DST_PASS="目标数据库密码"
DST_DB="目标数据库表名称"
# 临时目录
TEMP_DIR="./temp_backup_$(date +%Y%m%d_%H%M%S)"
mkdir -p $TEMP_DIR
echo "=== 开始数据库同步 ==="
echo "从: $SRC_HOST.$SRC_DB"
echo "到: $DST_HOST.$DST_DB"
# 从源数据库导出
echo "正在从源数据库导出..."
TABLES=$(mysql -h $SRC_HOST -u $SRC_USER -p$SRC_PASS $SRC_DB -N -e "SHOW TABLES;")
for TABLE in $TABLES; do
echo "导出: $TABLE"
mysqldump -h $SRC_HOST -u $SRC_USER -p$SRC_PASS $SRC_DB $TABLE > $TEMP_DIR/$TABLE.sql
done
# 导入到目标数据库
echo "正在导入到目标数据库..."
for SQL_FILE in $TEMP_DIR/*.sql; do
TABLE_NAME=$(basename $SQL_FILE .sql)
echo "导入: $TABLE_NAME"
mysql -h $DST_HOST -u $DST_USER -p$DST_PASS $DST_DB < $SQL_FILE
done
# 清理临时文件
rm -rf $TEMP_DIR
echo "同步完成! 共处理 $(echo "$TABLES" | wc -l) 个表"
四、大SQL按表拆分为小SQL文件
bash
复制代码
#!/bin/bash
# SQL文件拆分脚本 - 按表拆分
# 用法: ./split_sql.sh <sql文件> [输出目录]
split_sql_by_tables() {
local sql_file="$1"
local output_dir="${2:-split_tables}"
local current_table=""
local output_file=""
# 检查文件是否存在
if [[ ! -f "$sql_file" ]]; then
echo "错误: 文件 $sql_file 不存在"
return 1
fi
# 创建输出目录
mkdir -p "$output_dir"
echo "开始拆分SQL文件: $sql_file"
echo "输出目录: $output_dir"
# 计数器
local table_count=0
# 逐行读取SQL文件
while IFS= read -r line; do
# 检测表创建语句
if [[ "$line" =~ ^CREATE\ TABLE\ \`([^\`]+)\` ]]; then
current_table="${BASH_REMATCH[1]}"
output_file="$output_dir/${current_table}.sql"
echo "创建表文件: ${current_table}.sql"
table_count=$((table_count + 1))
# 如果文件已存在,先删除(避免重复内容)
if [[ -f "$output_file" ]]; then
rm "$output_file"
fi
fi
# 写入到当前表文件
if [[ -n "$output_file" && -n "$current_table" ]]; then
echo "$line" >> "$output_file"
fi
done < "$sql_file"
echo "拆分完成!共处理 $table_count 个表"
echo "文件保存在: $output_dir"
}
# 显示帮助信息
show_help() {
echo "用法: $0 <SQL文件> [输出目录]"
echo ""
echo "示例:"
echo " $0 database.sql # 输出到 split_tables 目录"
echo " $0 database.sql table_files # 输出到 table_files 目录"
echo ""
echo "功能: 将MySQL导出的SQL文件按表拆分成多个文件"
}
# 主程序
main() {
# 检查参数
if [[ $# -eq 0 ]] || [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
show_help
exit 0
fi
local sql_file="$1"
local output_dir="$2"
# 执行拆分
split_sql_by_tables "$sql_file" "$output_dir"
}
# 运行主程序
main "$@"