linux系统mysql每日备份方法

一般来说,实现公司的MySQL数据库每日备份是个很常见的需求。

在项目的初始阶段可能不太重视,当业务渐渐起来以及开发人员逐渐增多之后,数据库的每日备份就很重要了。

(一)编写shell文件

创建一个 .sh 脚本文件,实现 “备份 - 压缩 - 记录日志” 的完整流程。

下面我创建了个mysql_backup.sh文件。

#!/bin/bash
# MySQL备份脚本(按日期分文件夹管理)
# 功能:备份指定数据库,排除iplatform库的特定日志表,自动压缩并清理旧备份

#######################################
# 【配置参数区】-- 在此处修改以下参数
#######################################
DB_USER="root"                   # 数据库用户名
DB_PASS="123456"            # 数据库密码(在此处修改)
BACKUP_ROOT_DIR="/home/backup"   # 备份根目录(所有日期的备份放在这里)
DB_LIST=(                        # 需要备份的数据库列表(在此处增删)
  "user"
  "order"
)
EXCLUDE_TABLES=(                 # 需要排除的表(格式:库名.表名)
  "user.log"
  "order.log"
)
RETENTION_DAYS=30                # 备份保留天数(默认30天)
export PATH=$PATH:/usr/local/mysql/bin    # 设置环境变量
#######################################
# 【配置结束】-- 以下内容无需修改
#######################################

# 初始化变量(按日期创建子文件夹)
CURRENT_DATE=$(date +%Y%m%d)      # 当天日期(用于文件夹命名)
TIMESTAMP=$(date +%Y%m%d_%H%M%S)  # 完整时间戳(用于文件名)
BACKUP_DIR="$BACKUP_ROOT_DIR/$CURRENT_DATE"  # 当天备份的具体目录
LOG_FILE="$BACKUP_DIR/backup_$TIMESTAMP.log"

# 检查并创建备份目录(包括当天子文件夹)
if [ ! -d "$BACKUP_DIR" ]; then
  echo "备份目录 $BACKUP_DIR 不存在,尝试创建..."
  mkdir -p "$BACKUP_DIR"
  # 检查目录创建结果
  if [ $? -ne 0 ]; then
    echo "错误:无法创建备份目录 $BACKUP_DIR,请检查权限!"
    exit 1
  fi
  echo "备份目录创建成功"
fi

# 写入日志头部
echo "===== 备份开始于 $TIMESTAMP =====" >> "$LOG_FILE"
echo "备份数据库列表:${DB_LIST[*]}" >> "$LOG_FILE"
echo "排除表列表:${EXCLUDE_TABLES[*]}" >> "$LOG_FILE"
echo "备份文件存放目录:$BACKUP_DIR" >> "$LOG_FILE"

# 备份单个数据库的函数
backup_database() {
  local db_name=$1
  local exclude_params=""
  
  # 生成排除表参数(仅对iplatform库生效)
  if [ "$db_name" = "iplatform" ]; then
    for table in "${EXCLUDE_TABLES[@]}"; do
      exclude_params+=" --ignore-table=$table"
    done
  fi
  
  # 执行备份并压缩(文件存放在当天子文件夹中)
  echo "开始备份数据库:$db_name" >> "$LOG_FILE"
  mysqldump -u"$DB_USER" -p"$DB_PASS" --databases "$db_name" $exclude_params | gzip > "$BACKUP_DIR/${db_name}_$TIMESTAMP.sql.gz"
  
  # 检查备份结果
  if [ $? -eq 0 ]; then
    echo " 数据库 $db_name 备份成功:${db_name}_$TIMESTAMP.sql.gz" >> "$LOG_FILE"
    echo " 数据库 $db_name 备份成功"  # 同时输出到控制台
  else
    echo " 数据库 $db_name 备份失败!" >> "$LOG_FILE"
    echo " 数据库 $db_name 备份失败!"  # 同时输出到控制台
  fi
}

# 批量备份所有数据库
for db in "${DB_LIST[@]}"; do
  backup_database "$db"
done

# 清理过期备份(删除整个过期日期的文件夹)
echo "开始清理${RETENTION_DAYS}天前的备份文件夹..." >> "$LOG_FILE"
find "$BACKUP_ROOT_DIR" -maxdepth 1 -type d -name "20[0-9][0-9][0-1][0-9][0-3][0-9]" -mtime +"$RETENTION_DAYS" -exec rm -rf {} \;
echo "清理完成" >> "$LOG_FILE"

# 写入日志尾部
echo "===== 备份结束于 $(date +%Y%m%d_%H%M%S) =====" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

echo "所有备份操作已完成,详细日志:$LOG_FILE"

上述shell脚本的实现有如下注意点:

1.脚本实现了备份多个数据库的功能,另外因为日志表通常较大,可以将较大的数据库表排除掉,以免每日备份的文件过大。

2.选择 .sql.gz 而非 .sql,核心是通过压缩解决纯 SQL 文件体积过大的问题,同时几乎不增加使用成本。纯 .sql 文件是明文文本格式,包含大量重复字符(如 SQL 关键字、表结构定义),压缩率极高。通常数据库备份的压缩率可达 70%-90%,即 10GB 的 .sql 文件压缩后仅需 1-3GB,能显著减少硬盘占用,尤其适合需要长期保留备份的场景。

3.脚本里需要设置环境变量,因为定时任务不认/etc/profile里加的环境变量。

(二)其它处理

1.更改文件权限

.sh文件变更为可执行文件。

chmod +x mysql_backup.sh

2.换行符替换

可能脚本运行会报错 ./mysql_backup.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录,这是由于脚本文件的换行符格式不兼容导致的,通常是因为在 Windows 系统中编辑了脚本,然后传到 Linux 系统时保留了 Windows 的换行符(\r\n),而 Linux 期望的是 Unix 风格的换行符(\n)。

sed -i 's/\r$//' mysql_backup.sh

3.环境变量

执行脚本文件前,检查下环境变量是否有配置。

比如,可能mysqldump命令执行不了,因为mysql安装后没加入环境变量。下面添加下环境变量:

# 使用find命令搜索mysql安装位置
sudo find / -name "mysql" -type f 2>/dev/null | grep bin

编辑用户主目录下的 /etc/profile文件。

vi /etc/profile

添加环境变量

# MySQL PATH
export PATH=$PATH:/usr/local/mysql/bin
# 如果还需要库路径,可以添加
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/mysql/lib

让配置立即生效:

source /etc/profile

注意:定时任务crontab不会去加载/etc/profile等用户环境的变量,只包含/bin:/usr/bin的环境变量,所以需要在脚本中加入环境变量,或者在/bin:/usr/bin的目录加入软链接。

可能环境变量加了之后,还是连不上ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/usr/local/mysql/mysql.sock' 。这时候需要可以配置下软链接。

# 假设找到的实际socket文件在 /var/lib/mysql/mysql.sock
# 而客户端期望在 /usr/local/mysql/mysql.sock
sudo ln -s /var/lib/mysql/mysql.sock /usr/local/mysql/mysql.sock

4.解压缩与还原数据库

可以先手动执行,查看脚本是否能成功运行得到.sql.gz的文件。

后续可以通过以下命令解压缩.sql.gz的文件,得到.sql文件。

# 解压不保留.gz文件
gzip -d backupfile.sql.gz
# 解压但保留原.gz文件
gzip -dc backup_file.sql.gz > backup_file.sql

查看或使用SQL文件

# 查看SQL文件内容
cat backup_file.sql
# 或者
less backup_file.sql

后续可以测试下备份的文件是否能成功还原。

# 导入到MySQL数据库
mysql -u username -p database_name < backup_file.sql

或者,一步到位直接解压并导入MySQL

# 直接解压并导入到MySQL
gzip -dc backup_file.sql.gz | mysql -u username -p database_name

还原过程中,若数据库不存在,则会重建。若数据库中还有很多有数据的表,则会删除表并重新建表来插入备份的数据。

(三)设置定时任务(Cron)

1.打开 Cron 编辑界面:

crontab -e

2.添加定时任务(例如每天凌晨 2 点执行):

# 每天02:00执行备份脚本,并将错误输出到日志
0 2 * * * /path/to/mysql_backup.sh >> /path/to/backup/error.log 2>&1

3.保存退出wq,Cron 会自动生效。

# 可以查看当前用户的crontab:
crontab -l
# 查看最近的cron执行记录
tail -f /var/log/cron
# 查看生成.gz文件
zcat backup.sql.gz | head -100  # 查看前100行

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值