Linux异地备份数据

一、备份数据库

1、准备一份备份命令sh文件,比如将其存放在/opt/db_bak中,命名为bak_mysql.sh

#!/bin/bash
# MySQL备份配置
MYSQL_USER="root"
MYSQL_PASSWORD="root"
MYSQL_HOST="10.10.10.10"
MYSQL_PORT="3306"
BACKUP_DIR="/data/60_bak/sql"
LOG_FILE="/data/60_bak/backup.log"
DATE_SUFFIX=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7 # 文件保留天数

# 要备份的数据库列表(用空格分隔)
DATABASES=("abc" "aaa" "bbb" "ccc")

# 确保备份目录存在
mkdir -p $BACKUP_DIR

# 记录开始时间
echo "$(date +%Y-%m-%d\ %H:%M:%S) - 开始备份MySQL数据库" >> $LOG_FILE

# 检查磁盘空间(至少需要1GB空闲空间)
MIN_DISK_SPACE=1000000  # 1GB in KB
AVAILABLE_SPACE=$(df $BACKUP_DIR | awk 'NR==2 {print $4}')
if [ $AVAILABLE_SPACE -lt $MIN_DISK_SPACE ]; then
    echo "$(date +%Y-%m-%d\ %H:%M:%S) - 错误:磁盘空间不足,至少需要1GB空闲空间" >> $LOG_FILE
    exit 1
fi

# 备份状态标志
BACKUP_SUCCESS=true

# 循环备份每个数据库
for DB_NAME in "${DATABASES[@]}"
do
    echo "$(date +%Y-%m-%d\ %H:%M:%S) - 开始备份数据库: $DB_NAME" >> $LOG_FILE
    
    # 执行MySQL备份
    /opt/mysql-8.0.26/bin/mysqldump -h$MYSQL_HOST -P$MYSQL_PORT -u$MYSQL_USER -p$MYSQL_PASSWORD \
        --single-transaction \
        --routines \
        --triggers \
        --events \
        $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_${DATE_SUFFIX}.sql.gz 2>> $LOG_FILE

    # 检查备份是否成功
    if [ $? -eq 0 ]; then
        # 获取备份文件大小
        BACKUP_SIZE=$(du -h $BACKUP_DIR/${DB_NAME}_${DATE_SUFFIX}.sql.gz | cut -f1)
        echo "$(date +%Y-%m-%d\ %H:%M:%S) - 数据库 $DB_NAME 备份成功完成: ${DB_NAME}_${DATE_SUFFIX}.sql.gz (大小: $BACKUP_SIZE)" >> $LOG_FILE
    else
        echo "$(date +%Y-%m-%d\ %H:%M:%S) - 数据库 $DB_NAME 备份失败" >> $LOG_FILE
        BACKUP_SUCCESS=false
    fi
done

# 根据备份状态执行清理操作
if [ "$BACKUP_SUCCESS" = true ]; then
    # 清理旧备份
    find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -exec rm -f {} \; 2>> $LOG_FILE
    echo "$(date +%Y-%m-%d\ %H:%M:%S) - 清理$RETENTION_DAYS天前的旧备份完成" >> $LOG_FILE
else
    echo "$(date +%Y-%m-%d\ %H:%M:%S) - 部分数据库备份失败,跳过清理操作" >> $LOG_FILE
    exit 1
fi

2、给予bak_mysql执行权限

sudo chmod +x /opt/db_bak/bak_mysql.sh

 3、手动执行一遍确保没问题

cd /opt/db_bak
./bak_mysql.sh

4、编辑cron任务(cron在linux用于设置周期性执行任务的工具)

crontab -e
# 输入以下文本,如果你希望每天凌晨2点执行备份
0 2 * * * /opt/db_bak/db_mysql.sh
# 退出编辑,验证一下任务列表
crontab -l

 二、备份文件

1、比如10.10.251.58备份10.10.251.60服务器,首先在58和60服务器上都安装rysnc

yum install rsync -y

2、安装完,需要在60服务器上配置信息

vim /etc/rsyncd.conf
# 全局配置(用root权限运行,确保能访问root所属的备份目录)
uid = root
gid = root
use chroot = yes
# 监听端口
port = 873
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# 允许访问的客户机地址
hosts allow = 10.10.251.58/24

# 备份模块配置
[60_server_backup]
# 备份的目录
path = /data/test
# 只读模式,安全
read only = yes
# 指定虚拟用户(与密码文件中的用户名一致),这里用户名为:rsync_user
auth users = rsync_user
# 关联密码文件
secrets file = /etc/rsyncd.secrets
# 模块备注
comment = Virtual user backup (no system user)

3、配置虚拟用户信息,这里比如密码是123456

echo "rsync_user:123456" > /etc/rsyncd.secrets
# 设置可读权限
chmod 600 /etc/rsyncd.secrets

4、60服务器以守护进程模式启动rsync

rsync --daemon --config=/etc/rsyncd.conf

5、如果需要修改配置文件,手动重启rsync步骤如下:

# 杀死进程
kill -9 $(cat /var/run/rsyncd.pid)
# 删除残留pid文件
rm -f /var/run/rsyncd.pid
# 启动
rsync --daemon --config=/etc/rsyncd.conf

6、58服务器创建备份sh脚本,并命名为remote_backup.sh

#!/bin/bash
set -eo pipefail  # 启用严格错误检查

# 配置信息
REMOTE_USER="rsync_user"              # 远程rsync服务的用户名
REMOTE_HOST="10.10.251.60"         # 远程服务器IP
REMOTE_MODULE="backup_module"  # 远程rsync服务的模块名
LOCAL_DIR="/data/60_bak/file"         # 本地存储备份的目录
PASSWORD_FILE="/data/60_bak/rsync_pass.txt"   # rsync密码文件路径
LOG_DIR="/data/60_bak/file_bak_log"                  # 日志文件目录
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOG_FILE="${LOG_DIR}/rsync_data_${TIMESTAMP}.log"   # 带时间戳的日志文件

# 函数:记录错误信息并退出
error_exit() {
    echo "$1" >> "$LOG_FILE"
    echo "错误:$1(详情请查看日志:$LOG_FILE)" >&2
    exit 1
}

# 确保目录存在
mkdir -p "$LOCAL_DIR" "$LOG_DIR"

# 初始化日志文件
touch "$LOG_FILE" || { echo "无法创建日志文件 $LOG_FILE,请检查权限" >&2; exit 1; }
chmod 644 "$LOG_FILE"

# 记录备份开始信息(精简版)
echo "===== 备份任务启动于: $(date "+%Y-%m-%d %H:%M:%S") =====" > "$LOG_FILE"
echo "备份目标: ${REMOTE_HOST}::${REMOTE_MODULE} -> ${LOCAL_DIR}" >> "$LOG_FILE"

# 检查必要文件(仅记录结果,不记录过程)
[ -f "$PASSWORD_FILE" ] && [ -s "$PASSWORD_FILE" ] && [ -r "$PASSWORD_FILE" ] || {
    error_exit "密码文件 $PASSWORD_FILE 不存在、为空或无读取权限"
}

# 执行rsync备份(使用-q减少输出,只保留关键信息)
echo "开始执行备份..." >> "$LOG_FILE"
rsync -az --quiet --password-file="$PASSWORD_FILE" \
  "${REMOTE_USER}@${REMOTE_HOST}::${REMOTE_MODULE}/" \
  "$LOCAL_DIR/" >> "$LOG_FILE" 2>&1

# 检查备份结果
BACKUP_EXIT_CODE=$?
if [ $BACKUP_EXIT_CODE -eq 0 ]; then
  echo "备份成功完成于: $(date "+%Y-%m-%d %H:%M:%S")" >> "$LOG_FILE"
  echo "备份成功!日志已保存至: $LOG_FILE"
else
  echo "备份失败 (错误代码: $BACKUP_EXIT_CODE) 于: $(date "+%Y-%m-%d %H:%M:%S")" >> "$LOG_FILE"
  error_exit "备份失败,错误代码: $BACKUP_EXIT_CODE"
fi

# 日志清理(只记录清理结果,不列出具体文件)
OLD_LOG_COUNT=$(find "$LOG_DIR" -name "rsync_data_*.log" -type f -mtime +30 | wc -l)
if [ $OLD_LOG_COUNT -gt 0 ]; then
  find "$LOG_DIR" -name "rsync_data_*.log" -type f -mtime +30 -delete
  echo "已清理 $OLD_LOG_COUNT 个30天前的旧日志" >> "$LOG_FILE"
else
  echo "没有需要清理的旧日志" >> "$LOG_FILE"
fi

echo "===== 备份任务全部完成于: $(date "+%Y-%m-%d %H:%M:%S") =====" >> "$LOG_FILE"

7、在58服务器上创建密码本,这里直接写入123456

# 创建密码文件并写入远程rsync服务的密码(即rsyncd.secrets中rsync_user对应的密码)
echo "123456" > /data/60_bk/rsync_pass.txt
chmod 600 /data/60_bk/rsync_pass.txt

8、测试一下备份脚本,如果有问题,先看一下58服务器上的日志,再看一下60的日志(/var/log/rsyncd.log)

./remote_backup.sh

9、测试没问题加入定时任务

crontab -e
# 每天凌晨3点执行
0 3 * * * /data/60_bak/remote_backup.sh

 

posted @ 2025-09-16 16:59  维新派丁真  阅读(15)  评论(0)    收藏  举报