一、数据库全量备份
#!/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 ]; thenecho "$(date): 错误:无法连接MySQL服务器" | tee -a $LOG_FILEexit 1
fiecho "找到数据库: $DATABASES" | tee -a $LOG_FILE
for DB in $DATABASES; doecho "$(date): 备份数据库: $DB" | tee -a $LOG_FILEmysqldump -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.gzif [ ${PIPESTATUS[0]} -eq 0 ]; thenecho "$(date): ✓ 成功备份: $DB" | tee -a $LOG_FILEelseecho "$(date): ✗ 备份失败: $DB" | tee -a $LOG_FILEfi
doneecho "$(date): 备份完成!文件保存在: $BACKUP_DIR/$DATE/" | tee -a $LOG_FILE
echo "备份文件列表:" | tee -a $LOG_FILE
ls -lh $BACKUP_DIR/$DATE/ | tee -a $LOG_FILE
二、数据库备份恢复
#!/bin/bash
NEW_DB_HOST="数据库IP地址"
NEW_DB_USER="数据库用户名"
NEW_DB_PASS="数据库密码"
NEW_DB_PORT="3306"
BACKUP_DIR="数据库备份地址"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
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>&1if [ $? -ne 0 ]; thenlog_error "无法连接到目标MySQL服务器"exit 1filog_info "数据库连接测试成功"
}
get_backup_files() {find $BACKUP_DIR -name "*.sql.gz" -type f | sort
}
extract_db_name() {local filename=$(basename "$1") echo "$filename" | sed 's/_[0-9]\{8\}_[0-9]\{6\}\.sql\.gz$//'
}
create_database() {local db_name=$1log_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_FILEif [ $? -eq 0 ]; thenlog_info "✓ 数据库创建成功: $db_name"return 0elselog_error "创建数据库失败: $db_name"return 1fi
}
import_database() {local db_name=$1local backup_file=$2log_info "开始导入: $db_name"total_size=$(gunzip -c "$backup_file" | wc -c 2>/dev/null)if [ -n "$total_size" ]; thenlog_info "预计导入数据量: $(($total_size/1024/1024)) MB"fistart_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_FILElocal import_status=$?end_time=$(date +%s)duration=$((end_time - start_time))if [ $import_status -eq 0 ]; thenlog_info "✓ 导入成功: $db_name (耗时: ${duration}秒)"return 0elselog_error "导入失败: $db_name"return 1fi
}
main() {log_info "开始数据库导入过程"test_db_connectionbackup_files=$(get_backup_files)total_files=$(echo "$backup_files" | wc -l)current_file=0log_info "找到 $total_files 个备份文件需要导入"success_count=0fail_count=0for backup_file in $backup_files; docurrent_file=$((current_file + 1))db_name=$(extract_db_name "$backup_file")log_info "处理文件 [$current_file/$total_files]: $db_name"if create_database "$db_name"; thenif import_database "$db_name" "$backup_file"; thensuccess_count=$((success_count + 1))elsefail_count=$((fail_count + 1))fielsefail_count=$((fail_count + 1))fiecho "----------------------------------------" | tee -a $LOG_FILEdonelog_info "导入完成!"log_info "成功: $success_count 个数据库"if [ $fail_count -gt 0 ]; thenlog_warn "失败: $fail_count 个数据库"filog_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
三、按表备份
#!/bin/bash
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_DIRecho "=== 开始数据库同步 ==="
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; doecho "导出: $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; doTABLE_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_DIRecho "同步完成! 共处理 $(echo "$TABLES" | wc -l) 个表"
四、大SQL按表拆分为小SQL文件
#!/bin/bash
split_sql_by_tables() {local sql_file="$1"local output_dir="${2:-split_tables}"local current_table=""local output_file=""if [[ ! -f "$sql_file" ]]; thenecho "错误: 文件 $sql_file 不存在"return 1fimkdir -p "$output_dir"echo "开始拆分SQL文件: $sql_file"echo "输出目录: $output_dir"local table_count=0while IFS= read -r line; doif [[ "$line" =~ ^CREATE\ TABLE\ \`([^\`]+)\` ]]; thencurrent_table="${BASH_REMATCH[1]}"output_file="$output_dir/${current_table}.sql"echo "创建表文件: ${current_table}.sql"table_count=$((table_count + 1))if [[ -f "$output_file" ]]; thenrm "$output_file"fifiif [[ -n "$output_file" && -n "$current_table" ]]; thenecho "$line" >> "$output_file"fidone < "$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" ]]; thenshow_helpexit 0filocal sql_file="$1"local output_dir="$2"split_sql_by_tables "$sql_file" "$output_dir"
}
main "$@"