MySQL 数据库是在 VPS 上运行的大多数应用程序的支柱 — 无论是 WordPress、Laravel、Node.js 还是电子商务平台。数据库内的数据是无法替代的,丢失数据可能意味着数小时甚至数天的停机时间和可能的永久数据丢失。了解如何可靠地备份和正确还原是任何 VPS 管理员最重要的技能之一。本指南将为您详细介绍所有内容:从使用 mysqldump 的简单手动备份到完全自动化的夜间 cron 任务,包含可立即使用的真实命令。

为什么 VPS 上的数据库备份很重要

与共享主机不同,共享主机上提供商通常处理服务器级别的快照,而 VPS 将责任完全推给您。您拥有完整的 root 访问权限,这意味着完整的责任。VPS 上数据丢失的最常见原因包括:

行业标准的 3-2-1 规则适用于此:保留 3 份数据副本,分别存储在 2 种不同的存储类型上,1 份副本存储在站点外。至少,您应该有本地每日备份和至少每周上传到云存储等远程位置。

MySQL 备份工具对比

MySQL 提供多个备份实用程序,每个都适合不同的场景。选择正确的工具取决于您的数据库大小、存储引擎以及您能容忍的停机时间。

工具 类型 表锁定 最佳用途
mysqldump 逻辑(SQL 文本) 无锁定(InnoDB + --single-transaction) DB < 5 GB,易于移植
mysqlpump 逻辑(并行) 无锁定(InnoDB) 多个数据库,> 1 GB,更快
Percona XtraBackup 物理(文件副本) 热备份,无锁定 大型生产数据库
mysqlhotcopy 物理(已弃用) 复制期间锁定表 不推荐(仅限旧版 MyISAM)

对于大多数 VPS 用户,mysqldump 是最好的起点。它预装在 MySQL 中,不需要任何额外的包,并生成可读的 SQL 文件,您可以在任何兼容的 MySQL 实例上检查、修改或还原。

使用 mysqldump 备份

mysqldump 将您的数据库结构和数据导出到包含 CREATE TABLE 和 INSERT 语句的 .sql 文件中。此文件可以在任何具有相同或更新版本的 MySQL 服务器上还原。

备份单个数据库

mysqldump -u root -p mydb > /backup/mydb_$(date +%Y%m%d).sql

为了节省磁盘空间,可以使用 gzip 实时压缩输出:

mysqldump -u root -p mydb | gzip > /backup/mydb_$(date +%Y%m%d).sql.gz

InnoDB 一致性备份(无表锁定)

--single-transaction 标志对于实时数据库至关重要。它告诉 mysqldump 在读取数据前开始一个一致的快照事务,这样应用程序可以在备份过程中继续写入,无需停机:

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  mydb | gzip > /backup/mydb_$(date +%Y%m%d_%H%M).sql.gz

--routines、--triggers 和 --events 标志确保存储过程、触发器和计划事件被包含在备份中 — 这对完整还原至关重要。

一次备份所有数据库

mysqldump -u root -p \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  | gzip > /backup/all_databases_$(date +%Y%m%d).sql.gz

仅模式备份(不含数据)

当你想要将表结构克隆到开发服务器而不复制生产数据时很有用:

mysqldump -u root -p --no-data mydb > /backup/mydb_schema_only.sql

还原 MySQL 数据库

还原必须小心执行。始终在实际紧急情况发生前在暂存环境中测试还原程序 — 从未测试过的备份不是真正的备份。

从纯 SQL 文件还原

# Step 1: Create the database if it doesn't exist
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

# Step 2: Restore
mysql -u root -p mydb < /backup/mydb_20260609.sql

从压缩文件还原 (.sql.gz)

gunzip -c /backup/mydb_20260609.sql.gz | mysql -u root -p mydb

另外,可以使用 zcat,它在某些系统上可能速度稍快:

zcat /backup/mydb_20260609.sql.gz | mysql -u root -p mydb

带进度跟踪的还原(大文件)

对于大型备份文件,安装 pv(管道查看器)来查看实时进度:

# Install pv if not already installed
apt install pv -y

# Restore with progress indicator
pv /backup/mydb_20260609.sql.gz | gunzip | mysql -u root -p mydb

仅还原特定表

当只有一个表损坏时,你可以仅转储和还原该表而不是整个数据库:

# Dump a specific table
mysqldump -u root -p mydb users > /backup/users_table.sql

# Restore just that table
mysql -u root -p mydb < /backup/users_table.sql

专业提示:将 MySQL 凭证安全地存储在 ~/.my.cnf 而不是在命令行上输入(这会在 shell 历史记录中记录):

[client]
user=root
password=YourPassword


立即设置严格权限:chmod 600 ~/.my.cnf — 然后可以运行 mysqldump 和 mysql 而无需 -p 标志。

使用 Cron 自动化备份

手动备份总比没有好,但自动化计划备份才是真正保护生产数据的方式。编写良好的 cron 作业每晚自动运行,无需人工干预。

创建备份脚本

创建文件 /usr/local/bin/mysql-backup.sh:

#!/bin/bash
# MySQL Automated Backup Script
# AsiaGB VPS Guide — 2026-06-09

BACKUP_DIR="/backup/mysql"
MYSQL_USER="root"
MYSQL_PASS="YourSecurePassword"
KEEP_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"

# Dump all databases with compression
mysqldump -u "$MYSQL_USER" -p"$MYSQL_PASS" \
  --all-databases \
  --single-transaction \
  --routines \
  --triggers \
  | gzip > "$BACKUP_DIR/all_db_${DATE}.sql.gz"

# Log result
if [ $? -eq 0 ]; then
    echo "[$(date)] SUCCESS: all_db_${DATE}.sql.gz" >> /var/log/mysql-backup.log
else
    echo "[$(date)] ERROR: Backup failed!" >> /var/log/mysql-backup.log
fi

# Remove backups older than KEEP_DAYS
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
echo "[$(date)] Cleaned up backups older than $KEEP_DAYS days" >> /var/log/mysql-backup.log

使脚本可执行:

chmod +x /usr/local/bin/mysql-backup.sh

添加 Cron 任务

crontab -e

添加以下这行,让备份每晚 02:00 自动执行:

# Nightly MySQL backup at 02:00
0 2 * * * /usr/local/bin/mysql-backup.sh

如需更高频率的备份(每 6 小时一次):

0 */6 * * * /usr/local/bin/mysql-backup.sh

验证 Cron 任务是否正常运行

# Check the backup log
tail -f /var/log/mysql-backup.log

# List backup files
ls -lh /backup/mysql/

# Test the script manually
/usr/local/bin/mysql-backup.sh

使用 mysqlpump 备份大型数据库

mysqlpump(带字母"p")在 MySQL 5.7 中引入,支持多线程并行导出,对大型数据库的速度远快于 mysqldump。

# Backup with mysqlpump using 4 parallel threads
mysqlpump -u root -p \
  --default-parallelism=4 \
  --compress-output=LZ4 \
  --all-databases \
  > /backup/all_db_pump_$(date +%Y%m%d).sql

# Backup selected databases only
mysqlpump -u root -p \
  --default-parallelism=4 \
  --include-databases=mydb,mydb2 \
  > /backup/selected_db_$(date +%Y%m%d).sql

mysqlpump 相比 mysqldump 的主要优势:

备份安全与文件管理

MySQL 备份文件包含整个数据库的 SQL 明文内容,保护这些文件与创建备份本身同等重要。

设置正确的文件权限

# Backup directory: readable only by root
chmod 700 /backup/mysql
chown root:root /backup/mysql

# Individual backup files: readable only by root
chmod 600 /backup/mysql/*.sql.gz

验证备份完整性

每次备份完成后,验证文件未损坏且转储已成功完成:

# Test that the gz file is not corrupted
gunzip -t /backup/mysql/all_db_20260609.sql.gz && echo "File OK"

# Check the last few lines of the dump for "Dump completed"
gunzip -c /backup/mysql/all_db_20260609.sql.gz | tail -5

使用 rclone 进行异地备份

要实现真正的灾难恢复,至少每周将备份发送到云存储等异地位置。使用 rclone 可以轻松对接任何 S3 兼容存储、Google Drive 或 Backblaze B2:

# Example: sync backup folder to S3
rclone copy /backup/mysql/ s3:mybucket/mysql-backup/ --min-age 1h

# Add to cron to run 30 minutes after the local backup
30 2 * * * rclone copy /backup/mysql/ s3:mybucket/mysql-backup/ --min-age 1h

常见问题排查

即使命令看似简单,备份和还原操作也可能以可预见的方式失败。以下是最常见的问题及解决方法。

错误:用户 'root'@'localhost' 访问被拒绝

这通常是凭证错误或用户权限不足导致的。建议创建专用备份用户以提高安全性:

CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'StrongPassword';
GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER, EVENT ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;

还原大型数据库时速度极慢

可以通过在 /etc/mysql/my.cnf 中添加以下设置临时调优 MySQL,加快导入速度:

[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0

同时,在还原会话中禁用外键检查可进一步加速:

mysql -u root -p mydb <<EOF
SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
SOURCE /backup/mydb_20260609.sql;
SET FOREIGN_KEY_CHECKS=1;
SET UNIQUE_CHECKS=1;
EOF

生产环境 MySQL 备份最佳实践

健全的备份策略不仅仅是每天跑一个 cron 任务。以下是生产部署中值得额外考量的做法:

常见问题解答(FAQ)

mysqldump 和 mysqlpump 有什么区别?

mysqldump 是传统的单线程工具,以纯文本形式导出 SQL,适合中小型数据库。mysqlpump 是较新的工具,支持多个数据库同时并行导出,内置进度指示器,且能原生压缩输出内容。对于超过 1 GB 的数据库,或需要同时备份多个数据库的场景,推荐使用 mysqlpump。

还原 MySQL 数据库后,部分数据丢失,应该检查哪些方面?

还原后数据丢失,请检查三个主要方面:第一,字符集不匹配 — 转储文件可能使用 utf8mb4,而目标数据库为 utf8,请检查 .sql 文件中的 CHARACTER SET 声明。第二,外键约束导致事务回滚 — 在导入前添加 SET FOREIGN_KEY_CHECKS=0,导入后重新启用。第三,转储不完整 — 检查 .sql 文件最后几行是否包含"Dump completed on"字样来验证备份是否完整。

如何使用 cron 设置自动夜间 MySQL 备份?

使用 crontab -e 打开 crontab 并添加:0 2 * * * /usr/bin/mysqldump -u root -p'YOURPASSWORD' --all-databases | gzip > /backup/db_$(date +\%Y\%m\%d).sql.gz — 这会在每晚 02:00 运行并使用 gzip 压缩输出。将备份文件存放在网站根目录之外,并使用 find /backup -name '*.sql.gz' -mtime +30 -delete 自动清除超过 30 天的旧文件。

如何加快大型 MySQL 数据库的备份速度?

以下几种方法可以提升大型数据库的备份速度:第一,使用 mysqlpump 替代 mysqldump,并设置 --default-parallelism=4 启用多线程并行导出。第二,对 InnoDB 使用 Percona XtraBackup,作为无需表锁的热备份方案。第三,在 mysqldump 中添加 --single-transaction,实现一致的 InnoDB 备份而不锁表。第四,通过管道将输出压缩为 gzip 或 zstd 格式以减少 I/O 时间。第五,按数据库或表分别备份,而非一次性转储所有内容。

AsiaGB 高性能 KVM VPS

AsiaGB VPS 提供完整 root 权限,支持 Docker、MySQL、Python、Node.js,月费低至 399 泰铢。

查看 VPS 套餐

查看泰国VPS主机全部套餐 →