测试环境: CentOS 7.9 / MySQL 8.0
适用人群: 后端开发、运维新手、中小企业技术负责人
阅读建议: 建议先在测试机完整操作一遍,确认备份可恢复后再应用到生产环境。


一、为什么我要写这篇备份指南

三年前,我负责的一个项目发生过一次「虚惊」。

凌晨 2 点,运维误操作删错了表。好在有定时备份,但恢复时发现备份文件是空的—— cron 任务早就挂了,没人发现。那次虽然最终通过 binlog 找回了数据,但整个过程让我后背发凉。

备份的核心不是「有没有做」,而是「能不能恢复」。

很多教程只讲 mysqldump 命令,不讲验证,不讲自动化,不讲坑。这篇文章我把安装、配置、备份、恢复、自动化脚本全部串起来,确保你照着做,真能保住数据。


二、MySQL 安装(避坑版)

官方文档很全,但新手容易踩几个坑:密码策略太严、字符集不对、服务起不来。以下是我总结的「最小可用」安装流程。

2.1 安装前检查

确保系统没有残留的 MySQL 或 MariaDB。

# 检查是否已安装
rpm -qa | grep mysql
rpm -qa | grep mariadb

# 如果有,卸载干净
yum remove -y mysql mariadb


2.2 安装 MySQL 8.0

Step 1:下载并安装 YUM 源

wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo yum localinstall -y mysql80-community-release-el7-3.noarch.rpm

Step 2:安装服务器

# 如果报错需要GPG密钥验证,可以执行这个命令yum -y install mysql-community-server --nogpgcheck
sudo yum install -y mysql-community-server

Step 3:启动服务

sudo systemctl start mysqld
sudo systemctl enable mysqld
sudo systemctl status mysqld

2.3 获取初始密码并修改

MySQL 8.0 首次安装会生成一个随机密码,藏在日志里。

# 获取临时密码
sudo grep 'temporary password' /var/log/mysqld.log

Step 4:登录并修改密码

mysql -u root -p
# 输入临时密码登录后执行
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123098';

⚠️ 坑点说明:
MySQL 8.0 默认密码策略很严(需要大小写、数字、特殊字符)。如果设置简单密码会报错。测试环境想改简单点,可以执行:

SET GLOBAL validate_password.policy=0;
SET GLOBAL validate_password.length=6;

2.4 关键配置(my.cnf)

编辑 /etc/my.cnf,确保以下配置正确(防止中文乱码和便于排查问题):

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
log_bin=mysql-bin
server-id=1

说明:utf8mb4 支持 emoji 表情,log_bin 开启二进制日志用于增量恢复。

修改后重启服务:

sudo systemctl restart mysqld

三、备份策略:只有一种备份是不够的

3.1 逻辑备份(mysqldump)

最常用,适合中小数据库(<50GB),方便迁移和查看。

备份单个数据库:

mysqldump -u root -p demo_01 > demo_01_$(date +%F).sql

备份所有数据库:

mysqldump -u root -p --all-databases > all_databases_$(date +%F).sql

压缩备份(节省空间):

mysqldump -u root -p demo_01 | gzip > demo_01$(date +%F).sql.gz


3.2 物理备份(xtrabackup)

如果数据库很大(>100GB)或要求停机时间短,建议用 Percona XtraBackup。
注:本文重点讲 mysqldump,xtrabackup 配置较复杂,后续单独写文章。

3.3 自动化备份脚本(生产必备)

手动备份一定会忘。写个脚本,配合 cron 定时任务。

脚本内容(/usr/local/bin/mysql_backup.sh):

#!/bin/bash

# 配置项
BACKUP_DIR="/data/backup/mysql"
DB_USER="root"
DB_PASS="password"
DATE=$(date +%F_%H%M)
KEEP_DAYS=7

# 创建目录
mkdir -p $BACKUP_DIR

# 执行备份
mysqldump -u$DB_USER -p$DB_PASS --all-databases | gzip > $BACKUP_DIR/all_$DATE.sql.gz

# 删除 7 天前的备份
find $BACKUP_DIR -name "all_*.sql.gz" -mtime +$KEEP_DAYS -delete

# 记录日志
echo "Backup completed at $DATE" >> $BACKUP_DIR/backup.log

赋予执行权限:

chmod +x /usr/local/bin/mysql_backup.sh

配置 Cron 任务(每天凌晨 2 点):

crontab -e
# 添加以下内容
0 2 * * * /usr/local/bin/mysql_backup.sh

使用脚本备份成功:


四、恢复验证:备份不验证等于零

这是 most 人忽略的一步。没有经过恢复测试的备份都是假备份。

4.1 模拟数据丢失

为了测试,我们先故意删个库。

CREATE DATABASE test_backup;
USE test_backup;
CREATE TABLE users (id INT);
DROP DATABASE test_backup;

4.2 执行恢复

# 解压(如果是压缩文件)
gunzip < /data/backup/mysql/all_2024-05-01_0200.sql.gz | mysql -u root -p

# 或者直接导入
mysql -u root -p < /data/backup/mysql/backup.sql

4.3 验证结果

登录 MySQL 检查数据是否回来。

SHOW DATABASES;
USE test_backup;
SELECT * FROM users;

五、常见坑与解决方案

5.1 备份时锁表导致业务卡顿

问题: mysqldump 默认会锁表,大表备份时业务会只读。
解决: 使用 --single-transaction 参数(仅适用于 InnoDB 引擎)。

mysqldump -u root -p --single-transaction --all-databases > backup.sql

5.2 备份文件过大

问题: 每天备份,磁盘很快满。
解决:

  1. 开启压缩(| gzip)。
  2. 设置保留天数(脚本中的 find -mtime +7)。
  3. 分离大表,只备份核心库。

5.3 权限不足

问题: 脚本手动执行成功,cron 执行失败。
原因: 环境变量问题。
解决: 在脚本中使用绝对路径(如 /usr/bin/mysqldump),并在 cron 中配置 PATH。


六、自查清单(发布前必对)

每次配置完备份,对照此表检查:

  • 备份文件是否生成?(检查文件大小不为 0)
  • 备份文件是否可读取?(尝试解压或查看头部)
  • 是否做过恢复测试?(至少在测试环境验证过)
  • 备份文件是否异地存储?(不要只放在本机)
  • 定时任务是否在运行?(检查 systemctl status crond)
  • 磁盘空间是否充足?(检查 df -h)
  • 敏感信息是否保护?(备份脚本权限 chmod 700)

七、写在最后

备份是技术人的底线。

我见过太多人平时不重视,出事才后悔。建议每季度做一次「灾难恢复演练」,随机找一个备份文件,尝试在空白机器上恢复,记录恢复耗时。

技术栈可以换,数据不能丢。


免责声明: 本文所有操作建议在测试环境验证后再应用于生产环境。误操作导致的数据丢失责任自负。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐