mysqldump 是 MySQL 数据库的逻辑备份工具,用于将数据库结构和数据导出为 SQL 语句文件,便于备份、迁移和恢复。它是 MySQL 数据库管理中最常用的工具之一。
📖 基本语法
bash
mysqldump [选项] 数据库名 [表名...]
mysqldump [选项] --databases 数据库名...
mysqldump [选项] --all-databases
🎯 常用选项
| 选项 | 说明 |
|---|---|
-u, --user=用户名 |
连接数据库的用户名。 |
-p, --password[=密码] |
连接数据库的密码。 |
-h, --host=主机名 |
连接数据库的主机名。 |
-P, --port=端口号 |
连接数据库的端口号。 |
-S, --socket=套接字文件 |
用于连接的 Unix 套接字文件。 |
--protocol=协议 |
使用的连接协议(tcp, socket, pipe, memory)。 |
--databases |
备份多个数据库,指定此选项后,后面可以跟多个数据库名。 |
--all-databases |
备份所有数据库。 |
--tables |
覆盖 --databases 选项,指定要备份的表,后面先跟数据库名,然后跟表名。 |
--no-data |
只导出表结构,不导出数据。 |
--no-create-info |
只导出数据,不导出表结构。 |
--skip-triggers |
不导出触发器。 |
--add-drop-database |
在每个 CREATE DATABASE 语句前添加 DROP DATABASE 语句。 |
--add-drop-table |
在每个 CREATE TABLE 语句前添加 DROP TABLE 语句(默认开启)。 |
--skip-add-drop-table |
不在每个 CREATE TABLE 语句前添加 DROP TABLE 语句。 |
--compact |
压缩模式,产生更少的输出(去掉注释等)。 |
-c, --complete-insert |
使用完整的 INSERT 语句(包含列名)。 |
--extended-insert |
使用多行 INSERT 语法(默认开启)。 |
--skip-extended-insert |
每行数据使用一个 INSERT 语句。 |
--hex-blob |
以十六进制格式导出二进制字段(如 BLOB, BINARY, VARBINARY)。 |
--where='条件' |
只导出符合条件的数据。 |
--lock-all-tables |
备份期间锁定所有表(适用于 MyISAM)。 |
--single-transaction |
通过在一个事务中导出所有表来创建一致性快照(适用于 InnoDB)。 |
--master-data[=值] |
将二进制日志信息写入输出,值为 1(CHANGE MASTER 语句)或 2(注释的 CHANGE MASTER 语句)。 |
--flush-logs |
开始备份前刷新日志。 |
-r, --result-file=文件 |
将输出重定向到指定文件(在 Windows 上用于避免换行符转换)。 |
-t, --no-create-info |
同 --no-create-info。 |
-d, --no-data |
同 --no-data。 |
-B, --databases |
同 --databases。 |
-A, --all-databases |
同 --all-databases。 |
💡 核心用法示例
1. 备份单个数据库
bash
# 备份整个数据库(包含结构和数据)
mysqldump -u root -p database_name > backup.sql
# 备份数据库,并压缩
mysqldump -u root -p database_name | gzip > backup.sql.gz
# 备份到指定文件
mysqldump -u root -p database_name -r backup.sql
# 备份数据库,包含删除和创建数据库的语句
mysqldump -u root -p --add-drop-database database_name > backup.sql
2. 备份多个数据库
bash
# 备份多个数据库
mysqldump -u root -p --databases db1 db2 db3 > backup.sql
# 备份所有数据库
mysqldump -u root -p --all-databases > all_backup.sql
3. 备份特定表
bash
# 备份数据库中的特定表
mysqldump -u root -p database_name table1 table2 > tables_backup.sql
# 备份多个数据库的特定表(使用 --tables 选项,需要先指定数据库)
mysqldump -u root -p --tables database_name table1 table2 > tables_backup.sql
4. 只备份结构或只备份数据
bash
# 只备份表结构,不备份数据
mysqldump -u root -p -d database_name > structure.sql
# 只备份数据,不备份表结构
mysqldump -u root -p -t database_name > data.sql
# 同时排除触发器和事件
mysqldump -u root -p -d --skip-triggers --no-data --no-create-db database_name > structure.sql
5. 条件备份
bash
# 备份符合条件的数据
mysqldump -u root -p database_name table_name --where="id>100" > partial_backup.sql
# 备份最近 7 天的数据
mysqldump -u root -p database_name table_name --where="create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)" > recent_backup.sql
6. 生成压缩备份
bash
# 使用 gzip 压缩
mysqldump -u root -p database_name | gzip > backup.sql.gz
# 使用 bzip2 压缩(压缩率更高)
mysqldump -u root -p database_name | bzip2 > backup.sql.bz2
# 使用 xz 压缩
mysqldump -u root -p database_name | xz > backup.sql.xz
# 解压并恢复
gunzip < backup.sql.gz | mysql -u root -p database_name
🔧 高级用法
1. 用于主从复制
bash
# 备份并记录二进制日志位置(用于设置从库)
mysqldump -u root -p --master-data=2 --single-transaction --databases db1 db2 > backup.sql
# 备份所有数据库并记录二进制日志位置
mysqldump -u root -p --master-data=2 --single-transaction --all-databases > all_backup.sql
2. 分表备份
bash
# 备份每个表到单独的文件
for table in $(mysql -u root -p -N -e "SHOW TABLES FROM database_name"); do
mysqldump -u root -p database_name "$table" > "${table}.sql"
done
# 备份每个数据库到单独的文件
for db in $(mysql -u root -p -N -e "SHOW DATABASES"); do
mysqldump -u root -p --databases "$db" > "${db}.sql"
done
3. 远程备份
bash
# 从远程服务器备份
mysqldump -h remote_host -u remote_user -p remote_database > backup.sql
# 备份到远程服务器(通过 SSH)
mysqldump -u root -p local_database | ssh user@remote_host "cat > /backup/backup.sql"
# 从远程备份恢复到本地
ssh user@remote_host "mysqldump -u remote_user -p remote_database" | mysql -u local_user -p local_database
4. 备份加密
bash
# 使用 openssl 加密备份
mysqldump -u root -p database_name | openssl enc -aes-256-cbc -salt -out backup.sql.enc
# 解密并恢复
openssl enc -aes-256-cbc -d -in backup.sql.enc | mysql -u root -p database_name
⚠️ 重要注意事项
- 备份一致性 :对于 InnoDB 表,使用
--single-transaction选项可以确保备份的一致性。对于 MyISAM 表,可能需要使用--lock-all-tables。 - 备份期间性能:备份大型数据库可能会影响服务器性能,建议在低峰期进行。
- 备份文件安全:备份文件包含敏感数据,应妥善保管,避免未授权访问。
- 定期测试恢复:定期测试备份文件的恢复过程,确保备份有效。
📋 恢复数据库
bash
# 恢复整个数据库
mysql -u root -p database_name < backup.sql
# 恢复压缩的备份
gunzip < backup.sql.gz | mysql -u root -p database_name
# 恢复单个表(需要先创建数据库)
mysql -u root -p database_name < table_backup.sql
# 恢复所有数据库
mysql -u root -p < all_backup.sql
🔍 实用脚本示例
1. 自动备份脚本
bash
#!/bin/bash
# MySQL 自动备份脚本
DB_USER="root"
DB_PASS="password"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# 创建备份目录
mkdir -p "$BACKUP_DIR"
# 备份所有数据库
mysqldump -u "$DB_USER" -p"$DB_PASS" --all-databases --single-transaction --master-data=2 | gzip > "$BACKUP_DIR/all_databases_$DATE.sql.gz"
# 备份每个数据库到单独文件
for DB in $(mysql -u "$DB_USER" -p"$DB_PASS" -e "SHOW DATABASES;" | grep -v Database | grep -v information_schema | grep -v performance_schema | grep -v sys); do
mysqldump -u "$DB_USER" -p"$DB_PASS" --databases "$DB" --single-transaction | gzip > "$BACKUP_DIR/${DB}_$DATE.sql.gz"
done
# 删除旧备份
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "备份完成: $BACKUP_DIR"
2. 备份验证脚本
bash
#!/bin/bash
# 验证备份文件是否完整
BACKUP_FILE="$1"
if [[ -z "$BACKUP_FILE" ]]; then
echo "用法: $0 <备份文件>"
exit 1
fi
# 检查文件是否存在
if [[ ! -f "$BACKUP_FILE" ]]; then
echo "错误: 文件不存在"
exit 1
fi
# 检查文件是否包含有效的 SQL
if head -n 100 "$BACKUP_FILE" | grep -q "CREATE TABLE\|INSERT INTO\|DROP TABLE"; then
echo "备份文件看起来有效"
else
echo "警告: 备份文件可能损坏或不完整"
fi
# 如果是压缩文件,检查完整性
if [[ "$BACKUP_FILE" == *.gz ]]; then
if gzip -t "$BACKUP_FILE"; then
echo "压缩文件完整"
else
echo "压缩文件损坏"
fi
fi
📌 最佳实践
- 定期备份:根据数据变化频率制定备份策略(每日、每周等)。
- 异地备份:将备份文件存储在不同的物理位置。
- 监控备份:监控备份任务是否成功,并设置告警。
- 版本控制:对备份文件进行版本管理,保留多个时间点的备份。
- 加密敏感数据:对包含敏感数据的备份进行加密。
mysqldump 是 MySQL 数据库备份的经典工具,虽然对于非常大的数据库可能速度较慢,但它简单可靠,生成的 SQL 文件易于理解和修改。对于生产环境,建议结合物理备份工具(如 Percona XtraBackup)和逻辑备份(mysqldump)使用。