Skip to content

MySQL mysqldump 和 mysqlimport 使用与最佳实践

mysqldump 工具详解

工具简介

mysqldump 是 MySQL 提供的命令行工具,用于生成 MySQL 数据库的逻辑备份。它可以将数据库对象(表、视图、存储过程等)和数据导出为 SQL 格式的文件,便于备份、迁移和恢复。

基本语法

bash
mysqldump [options] [database [tables]] > dump.sql

常用参数

参数说明
-u, --user=name指定用户名
-p, --password[=password]指定密码
-h, --host=name指定主机名
-P, --port=port_num指定端口号
--databases指定多个数据库
--all-databases备份所有数据库
--single-transaction在单个事务中导出数据(适用于 InnoDB)
--lock-tables锁定表(适用于 MyISAM)
--routines导出存储过程和函数
--triggers导出触发器
--events导出事件
--no-data只导出结构,不导出数据
--no-create-info只导出数据,不导出结构
--compress压缩传输数据
--max_allowed_packet=bytes设置最大数据包大小

常见使用场景

备份单个数据库

bash
# 备份单个数据库到文件
mysqldump -u root -p mydatabase > mydatabase_backup.sql

# 备份单个数据库并压缩
mysqldump -u root -p mydatabase | gzip > mydatabase_backup.sql.gz

备份多个数据库

bash
# 备份多个数据库
mysqldump -u root -p --databases db1 db2 db3 > multiple_databases.sql

# 备份所有数据库
mysqldump -u root -p --all-databases > all_databases.sql

只备份表结构

bash
# 只备份表结构
mysqldump -u root -p --no-data mydatabase > mydatabase_schema.sql

只备份数据

bash
# 只备份数据
mysqldump -u root -p --no-create-info mydatabase > mydatabase_data.sql

备份特定表

bash
# 备份特定表
mysqldump -u root -p mydatabase table1 table2 > specific_tables.sql

备份带有存储过程和触发器

bash
# 备份带有存储过程和触发器
mysqldump -u root -p --routines --triggers --events mydatabase > mydatabase_full.sql

恢复数据

bash
# 恢复整个数据库
mysql -u root -p mydatabase < mydatabase_backup.sql

# 从压缩文件恢复
gunzip < mydatabase_backup.sql.gz | mysql -u root -p mydatabase

mysqlimport 工具详解

工具简介

mysqlimport 是 MySQL 提供的命令行工具,用于将文本文件中的数据导入到 MySQL 数据库表中。它是 LOAD DATA INFILE 语句的命令行接口,支持多种文件格式和导入选项。

基本语法

bash
mysqlimport [options] database textfile...

常用参数

参数说明
-u, --user=name指定用户名
-p, --password[=password]指定密码
-h, --host=name指定主机名
-P, --port=port_num指定端口号
-d, --delete导入前删除表中现有数据
-i, --ignore忽略重复行(基于主键或唯一索引)
-r, --replace替换重复行(基于主键或唯一索引)
-c, --columns=name,...指定导入的列顺序
-L, --local从本地文件导入,而非服务器端文件
-f, --force即使出现错误也继续执行
--fields-terminated-by=name指定字段分隔符
--fields-enclosed-by=name指定字段包围符
--fields-escaped-by=name指定转义字符
--lines-terminated-by=name指定行分隔符

常见使用场景

基本数据导入

bash
# 导入 CSV 文件
mysqlimport -u root -p --local --fields-terminated-by=',' --lines-terminated-by='\n' mydatabase users.csv

指定列顺序导入

bash
# 指定列顺序导入
mysqlimport -u root -p --local --columns=id,name,email --fields-terminated-by=',' mydatabase users.csv

导入前删除现有数据

bash
# 导入前删除现有数据
mysqlimport -u root -p --local --delete --fields-terminated-by=',' mydatabase users.csv

忽略重复行

bash
# 忽略重复行
mysqlimport -u root -p --local --ignore --fields-terminated-by=',' mydatabase users.csv

替换重复行

bash
# 替换重复行
mysqlimport -u root -p --local --replace --fields-terminated-by=',' mydatabase users.csv

最佳实践

mysqldump 最佳实践

1. 选择合适的锁定策略

  • InnoDB 表:使用 --single-transaction 参数,在单个事务中导出数据,避免表锁定
  • MyISAM 表:使用 --lock-tables 参数,锁定所有表以确保数据一致性
  • 混合存储引擎:结合使用 --single-transaction--lock-tables 参数
bash
# InnoDB 表备份
mysqldump -u root -p --single-transaction mydatabase > mydatabase_backup.sql

# MyISAM 表备份
mysqldump -u root -p --lock-tables mydatabase > mydatabase_backup.sql

2. 压缩备份文件

压缩备份文件可以节省存储空间和传输时间:

bash
# 压缩备份
mysqldump -u root -p --single-transaction mydatabase | gzip > mydatabase_backup.sql.gz

# 使用更高压缩比
mysqldump -u root -p --single-transaction mydatabase | xz > mydatabase_backup.sql.xz

3. 备份前检查数据库状态

在备份前检查数据库状态,确保数据库运行正常:

bash
# 检查数据库连接
mysqladmin -u root -p ping

# 检查数据库状态
mysqladmin -u root -p status

# 检查表状态
mysqlcheck -u root -p --check mydatabase

4. 定期备份并验证

  • 建立定期备份计划(每日、每周、每月)
  • 定期验证备份文件的完整性
  • 测试恢复流程,确保备份可用
bash
# 验证备份文件
gzip -t mydatabase_backup.sql.gz

# 测试恢复(在测试环境)
gunzip < mydatabase_backup.sql.gz | mysql -u root -p test_database

5. 控制备份大小

  • 对于大型数据库,考虑分表备份
  • 使用 --where 参数备份特定条件的数据
  • 考虑使用增量备份策略
bash
# 分表备份
for table in $(mysql -u root -p -N -e "SHOW TABLES FROM mydatabase;"); do
  mysqldump -u root -p mydatabase $table > ${table}_backup.sql
done

# 备份特定条件的数据
mysqldump -u root -p mydatabase users --where="created_at > '2023-01-01'" > recent_users.sql

mysqlimport 最佳实践

1. 优化导入性能

  • 使用 --local 参数从本地导入,减少网络开销
  • 禁用索引和约束,导入后再启用
  • 调整 max_allowed_packetinnodb_buffer_pool_size 等参数
bash
# 优化导入性能
mysqlimport -u root -p --local --fields-terminated-by=',' --lines-terminated-by='\n' --delete mydatabase users.csv

2. 确保数据一致性

  • 导入前验证文件格式和内容
  • 使用事务确保导入的原子性
  • 导入后验证数据完整性
bash
# 导入后验证数据
mysql -u root -p -e "SELECT COUNT(*) FROM mydatabase.users;"

3. 处理大文件导入

  • 对于大型文件,考虑分块导入
  • 使用 LOAD DATA INFILE 语句的 LOW_PRIORITYCONCURRENT 选项
  • 监控导入进度和系统资源使用

4. 选择合适的文件格式

  • 使用 CSV 格式,便于处理和验证
  • 确保文件编码与数据库编码一致
  • 正确设置字段分隔符和行分隔符

版本差异

MySQL 5.7 及之前版本

  • mysqldump

    • 支持基本的备份功能
    • 压缩支持有限
    • 并行备份功能较弱
    • 某些高级选项支持有限
  • mysqlimport

    • 支持基本的导入功能
    • 性能优化选项较少
    • 错误处理机制相对简单

MySQL 8.0

  • mysqldump

    • 增强了并行备份功能(--parallel 参数)
    • 支持更多压缩格式
    • 增强了安全性选项
    • 更好的性能和可靠性
  • mysqlimport

    • 增强了性能优化选项
    • 更好的错误处理和报告
    • 支持更多文件格式
    • 增强了安全性选项

主要版本差异示例

bash
# MySQL 8.0 并行备份示例
mysqldump -u root -p --single-transaction --parallel=4 mydatabase > mydatabase_backup.sql

# MySQL 5.7 不支持 --parallel 参数
mysqldump -u root -p --single-transaction mydatabase > mydatabase_backup.sql

常见问题与解决方案

问题:mysqldump 导出大数据库时内存不足

解决方案

  • 使用 --quick 参数,逐行导出数据,减少内存占用
  • 分表备份,避免单次备份过大
  • 调整 max_allowed_packet 参数
bash
# 使用 --quick 参数
mysqldump -u root -p --single-transaction --quick mydatabase > mydatabase_backup.sql

问题:mysqlimport 导入时出现字符集错误

解决方案

  • 确保文件编码与数据库编码一致
  • 使用 --default-character-set 参数指定字符集
  • 预处理文件,转换为正确的编码
bash
# 指定字符集导入
mysqlimport -u root -p --local --default-character-set=utf8mb4 --fields-terminated-by=',' mydatabase users.csv

问题:mysqldump 备份时出现锁等待超时

解决方案

  • 调整 innodb_lock_wait_timeout 参数
  • 使用 --single-transaction 参数(针对 InnoDB 表)
  • 在低峰期执行备份
bash
# 调整锁等待超时
mysqldump -u root -p --single-transaction --lock-wait-timeout=600 mydatabase > mydatabase_backup.sql

问题:mysqlimport 导入速度慢

解决方案

  • 禁用表索引,导入后再重建
  • 增加 innodb_buffer_pool_size 参数
  • 使用 LOAD DATA INFILE 语句替代 mysqlimport
  • 调整 bulk_insert_buffer_size 参数
sql
-- 使用 LOAD DATA INFILE 优化导入
ALTER TABLE users DISABLE KEYS;
LOAD DATA LOCAL INFILE 'users.csv' INTO TABLE users FIELDS TERMINATED BY ',';
ALTER TABLE users ENABLE KEYS;

常见问题(FAQ)

Q1: mysqldump 和 mysqlpump 有什么区别?

A1: mysqlpump 是 MySQL 5.7 引入的新工具,与 mysqldump 相比:

  • 支持并行备份,速度更快
  • 支持更好的压缩选项
  • 支持更灵活的备份策略
  • 但在某些复杂场景下,mysqldump 可能更稳定

Q2: 如何使用 mysqldump 进行增量备份?

A2: mysqldump 本身不支持直接的增量备份,但可以结合二进制日志实现:

  1. 定期使用 mysqldump 进行全量备份
  2. 启用二进制日志
  3. 增量备份时,备份指定时间段的二进制日志
  4. 恢复时,先恢复全量备份,再应用二进制日志

Q3: mysqlimport 和 LOAD DATA INFILE 有什么区别?

A3: mysqlimport 是 LOAD DATA INFILE 语句的命令行接口,主要区别:

  • mysqlimport 更适合命令行脚本和自动化
  • LOAD DATA INFILE 更适合在 SQL 语句中使用
  • LOAD DATA INFILE 提供更多的选项和灵活性

Q4: 如何确保 mysqldump 备份的完整性?

A4: 可以采取以下措施确保备份完整性:

  • 使用 --checksum 参数生成校验和
  • 备份后验证文件完整性
  • 定期测试恢复流程
  • 监控备份过程中的错误信息

Q5: 如何优化 mysqldump 备份大型数据库的性能?

A5: 可以采取以下措施优化备份性能:

  • 使用 --single-transaction 参数(InnoDB 表)
  • 使用 --quick 参数减少内存占用
  • 使用 --parallel 参数(MySQL 8.0+)
  • 压缩备份文件,减少 I/O 开销
  • 在低峰期执行备份

Q6: 如何使用 mysqlimport 导入不同格式的文件?

A6: mysqlimport 支持多种文件格式,主要通过以下参数控制:

  • --fields-terminated-by:指定字段分隔符
  • --fields-enclosed-by:指定字段包围符
  • --fields-escaped-by:指定转义字符
  • --lines-terminated-by:指定行分隔符

例如,导入 TSV 文件:

bash
mysqlimport -u root -p --local --fields-terminated-by='\t' --lines-terminated-by='\n' mydatabase users.tsv