需求概述
-
目标:在 Debian 云服务器上安装并配置 MySQL,建立安全、稳定、可维护的数据库服务;实现“每周自动备份指定数据库”并同步到网盘。
-
场景:中小型业务生产/测试环境;需要具备灾备能力和可验证的恢复流程。
技术背景知识
-
MySQL vs MariaDB
-
MySQL:Oracle 维护,企业生态成熟;Debian 12 默认仓库为 MariaDB,如需“原生 MySQL 8.0/8.4 LTS”需额外添加 APT 源。
-
MariaDB:MySQL 的分支,Debian 12 默认提供 10.11 LTS,兼容性较好,部署更快。
-
-
备份类型
-
逻辑备份(mysqldump):导出 SQL 文本,通用易迁移,适合中小库;恢复较慢,体积较大。
-
物理备份(XtraBackup):拷贝数据文件,快、可做增量;更复杂,依赖引擎/版本。
-
-
定时调度
-
cron:配置简单、广泛可用。
-
systemd timer:与系统日志集成更好,便于管理与观察状态。
-
-
网盘对接
-
rclone:统一适配多种网盘/对象存储;可选透明加密(crypt)、生命周期与同步策略。
-
restic:自带加密与去重,支持通过 rclone 对接远端,提供保留策略(forget/prune)。
-
实现方案对比
-
方案 A:mysqldump + rclone + cron(上手快)
-
优点:依赖少,学习成本低,易调试;适合中小数据量和迁移。
-
缺点:导出/恢复速度慢;备份体积大;去重与加密需额外配置。
-
适用:首次上线、日常周备份、数据量≤数 GB。
-
-
方案 B(推荐生产):mysqldump + restic + rclone + systemd timer
-
优点:内置强加密与去重;保留策略完善;兼容多云存储。
-
缺点:组件更多;初次学习成本略高。
-
适用:生产/长期运行、对安全与存储成本更敏感。
-
-
方案 C:Percona XtraBackup(物理备份)
-
优点:速度快、可做增量与热备;适合大库。
-
缺点:复杂度高;与存储引擎/版本耦合。
-
适用:大数据量、高恢复时效要求场景。
-
下面给出完整落地步骤,默认采用“方案 A”作为主线;并在后文提供“方案 B”的替代实现。
实现步骤详解
一、安装数据库(两种可选)
-
选项 1:安装 MySQL Community(8.4 LTS)
-
下载并添加 MySQL APT 源(访问
https://dev.mysql.com/downloads/repo/apt/获取最新版包名)wget https://dev.mysql.com/get/mysql-apt-config_0.8.34-1_all.deb sudo dpkg -i mysql-apt-config_0.8.34-1_all.deb # 选择 MySQL Server 版本(我选择的是 8.4 LTS) sudo apt update -
安装并启动
sudo apt install -y mysql-server # 会有图形界面提示设置 root 密码 sudo systemctl enable --now mysql # 这个命令会同时完成两件事: # - 设置开机自启:将 MySQL 服务添加到系统启动项 # - 立即启动服务:不重启系统就让 MySQL 开始运行 -
安全向导
该命令会交互式地引导你完成以下安全设置:
-
设置 root 密码(如果尚未设置)
-
移除匿名用户(默认安装可能存在的无密码账户)
-
禁止 root 远程登录(只允许本地登录)
-
移除测试数据库(默认存在的
test数据库) -
立即重载权限表(使更改生效)
sudo mysql_secure_installation -
-
-
选项 2:安装 MariaDB(更快更简)
sudo apt update sudo apt install -y mariadb-server sudo systemctl enable --now mariadb sudo mysql_secure_installation
注意:若需远程访问,谨慎调整 bind-address,并配合防火墙/安全组。建议默认仅本机访问。
二、基础配置与加固
-
字符集与连接数(示例)
-
编辑
'/etc/mysql/mysql.conf.d/mysqld.cnf'(MySQL)或'/etc/mysql/mariadb.conf.d/50-server.cnf'(MariaDB),增加:[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci max_connections = 200 innodb_flush_log_at_trx_commit = 1 -
重启服务:
sudo systemctl restart mysql # 或 mariadb
-
-
创建备份专用用户(最小权限)
-
登录:
sudo mysql -u root -p -
示例(调整库名或授予全库只读):
-- 创建一个名为'backup'的本地用户, CREATE USER 'backup'@'localhost' IDENTIFIED BY '强密码'; -- 授予其对所有数据库的备份相关权限(查询、查看视图、重载、锁表、查看进程) GRANT SELECT, SHOW VIEW, RELOAD, LOCK TABLES, PROCESS ON *.* TO 'backup'@'localhost'; -- 重新加载权限表,使最近对用户权限的更改立即生效(无需重启数据库服务) FLUSH PRIVILEGES;
-
-
本地安全凭据文件(避免明文密码出现在脚本)
-
创建
'/root/.my.cnf':[client] user=backup password=你的强密码 -
权限:
sudo chown root:root /root/.my.cnf sudo chmod 600 /root/.my.cnf
-
三、网盘对接(rclone)
-
安装 rclone
curl -fsSL https://rclone.org/install.sh | sudo bash-
我用上述命令安装速度很慢,没有进展,换成下面的方式安装
wget https://downloads.rclone.org/rclone-current-linux-amd64.zip unzip rclone-*.zip sudo cp rclone-*/rclone /usr/bin/ sudo chmod +x /usr/bin/rclone -
-
创建远端(以
cloud:命名,类型根据你的网盘选择)rclone config # 按向导创建 remote,名称如 cloud,配置完成可用:rclone ls cloud:- 坚果云的配置可以参考:🔗
-
可选:透明加密远端
rclone config # 新建类型选择 crypt,Remote 指向 cloud:db-backups(或你的目录),配置密码 # 最终使用名称如 cloud-crypt:
四、方案 A:每周自动备份(mysqldump + rclone + cron)
-
备份范围与目录
-
本地目录:
'/var/backups/mysql' -
远端目录:
cloud:db-backups/(或cloud-crypt:db-backups/如启用加密)
-
-
导出示例(单库)
mysqldump --single-transaction --quick --routines --triggers --events \ --databases 你的数据库名 \ | gzip -c > /var/backups/mysql/yourdb_$(date +%F).sql.gz- 说明:
--single-transaction适合 InnoDB 热备;--routines/--triggers/--events保留对象;压缩节省空间。
- 说明:
-
多库/全库导出(二选一)
-
指定多库:
mysqldump --single-transaction --quick --routines --triggers --events \ --databases db1 db2 db3 \ | gzip -c > /var/backups/mysql/multi_$(date +%F).sql.gz -
全库(含系统库会变大,通常不建议):
mysqldump --single-transaction --quick --routines --triggers --events --all-databases \ | gzip -c > /var/backups/mysql/all_$(date +%F).sql.gz
-
-
同步到网盘(rclone)
rclone copy /var/backups/mysql cloud:db-backups --transfers=4 --checkers=8 --fast-list-
可配合删除本地过期文件(仅保留 30 天):
find /var/backups/mysql -type f -mtime +30 -name '*.gz' -delete
-
-
集成为每周定时任务(周日 03:00)
sudo mkdir -p /var/backups/mysql sudo crontab -e # 添加一行(示例:备份两个库并同步) 0 3 * * 0 mysqldump --single-transaction --quick --routines --triggers --events --databases db1 db2 | gzip -c > /var/backups/mysql/weekly_$(date +\%F).sql.gz && rclone copy /var/backups/mysql cloud:db-backups --transfers=4 --checkers=8 --fast-list && find /var/backups/mysql -type f -mtime +30 -name '*.gz' -delete- 建议:将命令拆为脚本以便维护与日志统一;cron 中仅调用脚本路径。
-
恢复演练(示例)
-
从网盘取回最新备份:
rclone ls cloud:db-backups rclone copy cloud:db-backups/weekly_2025-01-05.sql.gz /tmp -
导入恢复(目标库需先创建或使用
--databases自动创建)gzip -dc /tmp/weekly_2025-01-05.sql.gz | mysql
-
五、方案 B(推荐生产):restic + rclone + systemd timer
-
安装 restic
sudo apt install -y restic -
初始化远端仓库(通过 rclone 远端对接)
export RESTIC_REPOSITORY="rclone:cloud:db-backups-restic" export RESTIC_PASSWORD_FILE="/root/.restic-pass" # 文件内容为强密码,权限 600 restic init -
备份流程
-
本地导出到
'/var/backups/mysql/dumps'mkdir -p /var/backups/mysql/dumps mysqldump --single-transaction --quick --routines --triggers --events --databases db1 db2 \ | gzip -c > /var/backups/mysql/dumps/weekly_$(date +%F).sql.gz -
使用 restic 备份并设置保留策略
restic backup /var/backups/mysql/dumps restic forget --keep-weekly 8 --keep-monthly 12 --prune
-
-
定时器(更可观测)
-
创建
'/etc/systemd/system/db-backup.service'(简化示例):[Unit] Description=Weekly MySQL dump and restic backup [Service] Type=oneshot Environment=RESTIC_REPOSITORY=rclone:cloud:db-backups-restic Environment=RESTIC_PASSWORD_FILE=/root/.restic-pass ExecStart=/bin/bash -c 'mysqldump --single-transaction --quick --routines --triggers --events --databases db1 db2 | gzip -c > /var/backups/mysql/dumps/weekly_$(date +%%F).sql.gz' ExecStart=/usr/bin/restic backup /var/backups/mysql/dumps ExecStart=/usr/bin/restic forget --keep-weekly 8 --keep-monthly 12 --prune -
创建
'/etc/systemd/system/db-backup.timer':[Unit] Description=Run db-backup weekly [Timer] OnCalendar=Sun *-*-* 03:00:00 Persistent=true [Install] WantedBy=timers.target -
启用:
sudo systemctl daemon-reload sudo systemctl enable --now db-backup.timer systemctl list-timers | grep db-backup
-
-
恢复要点
restic snapshots restic restore latest --target /restore # 找到 .sql.gz 文件后:gzip -dc 恢复到 mysql
写在最后
可先用方案 A 快速上线,随后平滑切换到方案 B 以获得更好的加密、去重与保留策略。