MyDumper 是一个高性能的 MySQL 备份工具,由 MySQL 社区开发。它旨在克服 mysqldump 的一些性能限制,特别是对于大规模数据备份和恢复,MyDumper 通过多线程操作大幅提高了备份和恢复的速度。
适用场景
- 大规模数据备份:MyDumper 适用于备份包含大量数据的大型数据库。
- 高效恢复:MyDumper 提供了高效的数据恢复工具 myloader,可以快速将数据导入数据库。
- 增量备份需求:对于需要频繁备份的系统,MyDumper 的增量备份功能非常实用。
- 最小化停机时间:MyDumper 支持最小化表锁,可以减少备份过程中对数据库操作的影响。
优缺点
优点
- 多线程备份:显著提高备份速度。
- 增量备份:仅备份数据变化部分,节省时间和存储空间。
- 高效恢复:配合 myloader 实现快速数据恢复。
- 最小化表锁:减少对生产环境的影响。
- 压缩输出:生成的备份文件更小,节省存储空间。
缺点
- 复杂性:相对于 mysqldump,MyDumper 的配置和使用更复杂。
- 第三方工具:需要额外安装和配置,不像 mysqldump 那样默认集成在 MySQL 中。
- 依赖性:对一些系统库和环境有依赖,需要确保兼容性。
MyDumper 的主要工作步骤
- 施加全局只读锁(FLUSH TABLES WITH READ LOCK) MyDumper 在备份开始时会执行 FLUSH TABLES WITH READ LOCK 命令,这会对所有表施加一个全局只读锁,阻止 DML语句对表进行写操作,以确保备份过程中数据的一致性。
- 记录二进制日志文件名和位置 在备份开始时,MyDumper 会记录当前二进制日志文件的名称和写入位置,这些信息会保存在 metadata 文件中。这些信息可以用于执行基于日志文件的恢复操作,保证备份的一致性和完整性。
- 开启读一致性事务(START TRANSACTION WITH CONSISTENT SNAPSHOT) MyDumper 在备份过程中会启动一个读一致性的事务。这个步骤确保在整个备份过程中,数据库看到的数据是一致的,不会受到正在进行的写操作的影响。
- 导出表和表结构 MyDumper 根据指定的线程数(默认为 4)启动多个线程,并行导出数据库中的表和表结构。这一步是备份的核心过程,用于将数据库的数据导出到备份文件中。
- 备份非事务类型的表 MyDumper 首先备份非事务类型的表。这些表不会在事务内导出,而是直接导出表数据。这种方式可以提高备份的效率,因为不需要额外的事务处理。
- 释放全局只读锁(UNLOCK TABLES) 备份非事务类型的表完成后,MyDumper 会释放之前施加的全局只读锁,允许数据库恢复正常的写操作。
- 导出 InnoDB 表(基于事务) 接着,MyDumper 会对 InnoDB 表执行基于事务的备份操作。这一步确保了事务的一致性,并允许 MyDumper 在事务的基础上导出数据。
- 事务结束 当所有的事务和非事务类型的表备份完成后,MyDumper 结束当前的事务,释放事务锁,并完成备份过程。
安装
代码语言:javascript复制yum install -y cmake gcc gcc-c git make
release=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/mydumper/mydumper/releases/latest | cut -d'/' -f8)
yum install https://github.com/mydumper/mydumper/releases/download/${release}/mydumper-${release:1}.el7.x86_64.rpm
yum install https://github.com/mydumper/mydumper/releases/download/${release}/mydumper-${release:1}.el8.x86_64.rpm
导出示例
代码语言:javascript复制全库备份8线程包含列名的完整 INSERT 语句
mydumper -u root -p 123456 -P 3306 -t 8 --trx-consistency-only --less-locking --kill-long-queries --complete-insert -o /jesong/test/
全库备份设置备份文件大小
mydumper -u root -p 123456 -P 3306 -t 8 --trx-consistency-only --less-locking --kill-long-queries -F 64 --complete-insert -o /jesong/test/
全库压缩备份
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --kill-long-queries -c --complete-insert -o /jesong/test/
备份指定库
mydumper -u root -p 123456 -P 3306 -B edumsdb --trx-consistency-only --less-locking --kill-long-queries -o /jesong/test/
备份执行表
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -T edumsdb.el_edums_attendance_user,edumsdb.el_edums_attendance -v 3 -o /jesong/test/
备份在特定时间段内更新过的表
mydumper -u root -p 123456 -P 3306 -B externaldb --trx-consistency-only --less-locking --kill-long-queries -U 7 -o /jesong/test/
指定每个 INSERT 语句中的行数
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -t 8 -B crmdb -r 1000000 --kill-long-queries -o /jesong/test/
只导表结构
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -B edumsdb --kill-long-queries -d -o /jesong/test/
只导数据
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -B edumsdb --kill-long-queries -m -o /jesong/test/
导出为 CSV 文件
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -t 8 -B crmdb -r 100000 --csv -o /jesong/test/
根据指定条件导出数据
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking -T edumsdb.el_edums_attendance --where="id > 380" -v 3 -o /jesong/test/
流式备份
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --stream -B edumsdb -v 3 -t 6 | myloader -h 192.168.1.10 -u archery -p '123456' -P 3366 --stream -e
流式备份恢复到指定db
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --stream -B edumsdb -v 3 -t 6 | myloader -h 192.168.1.10 -u archery -p '123456' -P 3366 --stream -e -t 6 --database=yang
正则导出示例
代码语言:javascript复制正则表达式:
不转储 mysql、sys 和 test 数据库
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --regex '^(?!(mysql.|sys.|test.))' -o /jesong/test/
仅转储 mysql 和 test 数据库
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --regex '^(mysql.|test.)' -o /jesong/test/
不转储以 test 开头的所有数据库
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --regex '^(?!(test))' -o /jesong/test/
转储不同数据库中的特定表
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --regex '^(edumsdb.el_edums_data_push_config$|externaldb.authorization_token_info$)' -o /jesong/test/
转储几个数据库,但要丢弃一些表
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --regex '^(?=(?:(edumsdb.|externaldb.)))(?!(?:(edumsdb.el_edums_data_push_config$|externaldb.authorization_token_info$)))' -o /jesong/test/
导入示例
代码语言:javascript复制导入示例
指定目录恢复
myloader -u root -p 123456 -h localhost -P 3306 -e -t 6 -d /jesong/test
指定目标库恢复
myloader -u root -p 123456 -h localhost -P 3306 -e -t 6 -d /jesong/test --database zzdb
仅加载部分表(database 目标新库名称。-T 源库、表名)
myloader -h 192.168.1.10 -u archery -p '123456' -P 3366 e -t 6 -d /jesong/test --database wushouyang -T crmdb.el_app_banner
流式恢复
mydumper -u root -p 123456 -P 3306 --trx-consistency-only --less-locking --stream -B edumsdb -v 3 -t 6 | myloader -h 192.168.1.10 -u archery -p '123456' -P 3366 --stream -e
Mydumper参数详解
代码语言:javascript复制### Connection Options
-h, --host 要连接的主机
-u, --user 拥有必要权限的用户名
-p, --password 用户密码
-a, --ask-password 提示输入用户密码
-P, --port 要连接的 TCP/IP 端口
-S, --socket 用于连接的 UNIX 域套接字文件
--protocol 用于连接的协议 (tcp, socket)
-C, --compress-protocol 使用压缩的 MySQL 连接
--ssl 使用 SSL 连接
--ssl-mode 与服务器连接的安全状态:DISABLED, PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY
--key 密钥文件的路径
--cert 证书文件的路径
--ca 证书颁发机构文件的路径
--capath 包含受信任 SSL CA 证书的 PEM 格式目录的路径
--cipher 用于 SSL 加密的允许密码列表
--tls-version 服务器允许的加密连接协议
### Filter Options
-x, --regex 'db.table' 匹配的正则表达式
-B, --database 逗号分隔的数据库列表
-i, --ignore-engines 逗号分隔的存储引擎列表
--where 仅导出选定的记录
-U, --updated-since 使用 Update_time 仅导出过去 U 天内更新的表
--partition-regex 按分区名称过滤的正则表达式
-O, --omit-from-file 包含要跳过的 database.table 条目的文件(逐行跳过)
-T, --tables-list 要导出的逗号分隔的表列表(不排除正则表达式选项)。表名必须包含数据库名。例如:test.t1,test.t2
### Lock Options
-z, --tidb-snapshot 用于 TiDB 的快照
-k, --no-locks 不执行临时共享读取锁。警告:这将导致备份不一致
--use-savepoints 使用保存点以减少元数据锁定问题,需要 SUPER 权限
--no-backup-locks 不使用 Percona 备份锁
--lock-all-tables 使用 LOCK TABLE 而不是 FTWRL
--less-locking 最小化 InnoDB 表的锁定时间
--trx-consistency-only 仅事务一致性
--skip-ddl-locks 尽可能不发送 DDL 锁
### PMM Options
--pmm-path 默认值为 /usr/local/percona/pmm2/collectors/textfile-collector/high-resolution
--pmm-resolution 默认值为 high
### Exec Options
--exec-threads 使用 --exec 时的线程数
--exec 使用文件作为参数执行的命令
--exec-per-thread 设置将通过 STDIN 接收并写入 STDOUT 到输出文件的命令
--exec-per-thread-extension 使用 --exec-per-thread 时 STDOUT 文件的扩展名
### If long query running found
--long-query-retries 重试检查长查询,默认 0(不重试)
--long-query-retry-interval 重试长查询检查前的等待时间(秒),默认 60
-l, --long-query-guard 设置长查询计时器(秒),默认 60
-K, --kill-long-queries 终止长时间运行的查询
### Job Options
--max-threads-per-table 每个表使用的最大线程数
--char-deep 定义当主键为字符串时使用的字符数
--char-chunk 定义表应分割成多少部分。默认情况下,我们使用线程数
-r, --rows 将表拆分为这么多行的块。可以是 MIN:START_AT:MAX。MAX 可以是 0,这意味着没有限制。如果查询耗时少于 1 秒,将增加块大小,如果超过 2 秒,将减半
--split-partitions 将分区导出到单独的文件。此选项覆盖分区表的 --rows 选项
### Checksum Options
-M, --checksum-all 导出所有元素的校验和
--data-checksums 导出包含数据的表的校验和
--schema-checksums 导出架构表和视图创建校验和
--routine-checksums 导出触发器、函数和例程的校验和
### Objects Options
-m, --no-schemas 不导出包含数据和触发器的表架构
-Y, --all-tablespaces 导出所有表空间
-d, --no-data 不导出表数据
-G, --triggers 导出触发器。默认情况下,不导出触发器
-E, --events 导出事件。默认情况下,不导出事件
-R, --routines 导出存储过程和函数。默认情况下,不导出存储过程和函数
--skip-constraints 从 CREATE TABLE 语句中删除约束。默认情况下,不修改语句
--skip-indexes 从 CREATE TABLE 语句中删除索引。默认情况下,不修改语句
--views-as-tables 将视图导出为表
-W, --no-views 不导出视图
### Statement Options
--load-data 创建 LOAD DATA 语句和 .dat 文件,而不是 INSERT INTO 语句
--csv 自动启用 --load-data 并设置变量以 CSV 格式导出
--include-header 当使用 --load-data 或 --csv 时,包括列名的头
--fields-terminated-by 定义字段之间写入的字符
--fields-enclosed-by 定义用于括字段的字符。默认:"
--fields-escaped-by LOAD DATA 语句中用于转义字符的单字符,默认:''
--lines-starting-by 在每行开头添加字符串。当使用 --load-data 时,会添加到 LOAD DATA 语句中。当使用 INSERT INTO 语句时,也会影响
--lines-terminated-by 在每行末尾添加字符串。当使用 --load-data 时,会添加到 LOAD DATA 语句中。当使用 INSERT INTO 语句时,也会影响
--statement-terminated-by 除非你知道你在做什么,否则不要使用
-N, --insert-ignore 使用 INSERT IGNORE 导出行
--replace 使用 REPLACE 导出行
--complete-insert 使用包含列名的完整 INSERT 语句
--hex-blob 使用十六进制表示法导出二进制列
--skip-definer 从 CREATE 语句中删除 DEFINER。默认情况下,不修改语句
-s, --statement-size 尝试的 INSERT 语句大小(字节),默认 1000000
--tz-utc 在备份文件顶部设置 SET TIME_ZONE=' 00:00',以允许在服务器有不同时间区域的数据或在不同时间区域之间移动数据时备份 TIMESTAMP 数据,默认启用,使用 --skip-tz-utc 禁用
--skip-tz-utc 不在备份文件中添加 SET TIMEZONE
--set-names 设置名称,自行承担风险,默认 binary
### Extra Options
-F, --chunk-filesize 将数据文件拆分为此大小的块(MB)。对于 myloader 多线程很有用
--exit-if-broken-table-found 如果发现损坏的表,则退出
--success-on-1146 如果表不存在,不增加错误计数,并将警告改为重要
-e, --build-empty-files 即使表中没有数据,也要生成空文件
--no-check-generated-fields 不执行与生成字段相关的查询。如果你有生成的列,这将导致恢复问题
--order-by-primary 按主键或唯一键排序数据,如果不存在主键
--compact 输出更简洁。禁用页眉/页脚结构
-c, --compress 使用:/usr/bin/gzip 和 /usr/bin/zstd 压缩输出文件。选项:GZIP 和 ZSTD。默认:GZIP
--use-defer 使用延迟整数分片,直到处理所有非整数 PK 表(节省巨大表数量的 RSS)
--check-row-count 运行 SELECT COUNT(*),如果导出的行数不同,则 mydumper 失败
### Daemon Options
-D, --daemon 启用守护模式
-I, --snapshot-interval 转储快照之间的间隔(分钟),需要 --daemon,默认 60
-X, --snapshot-count 快照数量,默认 2
### Application Options
-?, --help 显示帮助选项
-o, --outputdir 输出文件的目录
--clear 在转储前清理输出目录
--dirty 覆盖输出目录而不清理(注意遗留块)
--stream 一旦文件写入完成,它将通过 STDOUT 流式传输。从 v0.12.7-1 开始,接受 NO_DELETE、NO_STREAM_AND_NO_DELETE 和 TRADITIONAL,其中 TRADITIONAL 是默认值,如果没有给出参数,则使用此值
-L, --logfile 使用的日志文件名,默认使用 stdout
--disk-limits 设置限制以在确定没有足够磁盘空间时暂停和恢复。接受类似的值:':<
-t, --threads 使用的线程数,0 表示使用 CPU 的数量。默认值:4
-V, --version 显示程序版本并退出
-v, --verbose 输出的详细程度,0 = 静默,1 = 错误,2 = 警告,3 = 信息,默认值:2
--debug 打开调试输出(自动将详细程度设置为 3)
--defaults-file 使用特定的默认文件。默认值:/etc/mydumper.cnf
--defaults-extra-file 使用额外的默认文件。在 --defaults-file 之后加载,替换之前定义的值
--fifodir 创建 FIFO 文件的目录(如果需要)。默认值:与备份相同
Myloader参数详解
代码语言:javascript复制Connection Options
-h, --host 要连接的主机
-u, --user 拥有必要权限的用户名
-p, --password 用户密码
-a, --ask-password 提示输入用户密码
-P, --port 要连接的 TCP/IP 端口
-S, --socket 用于连接的 UNIX 域套接字文件
--protocol 用于连接的协议 (tcp, socket)
-C, --compress-protocol 使用压缩的 MySQL 连接
--ssl 使用 SSL 连接
--ssl-mode 与服务器连接的安全状态:DISABLED, PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY
--key 密钥文件的路径
--cert 证书文件的路径
--ca 证书颁发机构文件的路径
--capath 包含受信任 SSL CA 证书的 PEM 格式目录的路径
--cipher 用于 SSL 加密的允许密码列表
--tls-version 服务器允许的加密连接协议
Filter Options
-x, --regex 'db.table' 匹配的正则表达式
-s, --source-db 要恢复的数据库
--skip-triggers 不导入触发器。默认情况下导入触发器
--skip-post 不导入事件、存储过程和函数。默认情况下导入
--skip-constraints 不导入约束。默认情况下导入约束
--skip-indexes 不导入 InnoDB 表上的二级索引。默认情况下导入索引
--no-data 不转储或导入表数据
-O, --omit-from-file 包含要跳过的 database.table 条目的文件,每行一个(在应用正则表达式选项之前跳过)
-T, --tables-list 要转储的逗号分隔的表列表(不排除正则表达式选项)。表名必须包含数据库名。例如:test.t1,test.t2
PMM Options
--pmm-path 默认值为 /usr/local/percona/pmm2/collectors/textfile-collector/high-resolution
--pmm-resolution 默认值为 high
Execution Options
-e, --enable-binlog 启用恢复数据的二进制日志记录
--innodb-optimize-keys 在表创建时不包含索引,并在最后添加它们。选项:AFTER_IMPORT_PER_TABLE 和 AFTER_IMPORT_ALL_TABLES。默认:AFTER_IMPORT_PER_TABLE
--no-schema 不导入表架构和触发器
--purge-mode 指定清除模式,可以是:FAIL, NONE, DROP, TRUNCATE 和 DELETE。默认:FAIL
--disable-redo-log 禁用 REDO_LOG 并在之后启用,不检查初始状态
--checksum 校验处理方式:skip, fail (默认), warn
-o, --overwrite-tables 如果表已存在则删除
--overwrite-unsafe 同 --overwrite-tables,但尽快开始数据加载。可能导致外键的 InnoDB 死锁
--retry-count 超时重试次数,默认 10(当前仅适用于 DROP TABLE)
--serialized-table-creation 表重新创建将按序执行,一个线程一次。意味着 --max-threads-for-schema-creation=1。此选项将在未来版本中删除
--stream 从 STDIN 接收流并在磁盘上创建文件,然后开始处理。从 v0.12.7-1 开始,接受 NO_DELETE, NO_STREAM_AND_NO_DELETE 和 TRADITIONAL,其中 TRADITIONAL 是默认值,如果没有给出参数,则使用此值
--metadata-refresh-interval 每处理此数量的表后刷新内部元数据。如果元数据文件中的表数量很大,应增加此值。默认:100
--ignore-errors 在发生逗号分隔的错误编号列表中的任何错误时,不增加错误计数并改为警告
Threads Options
--max-threads-per-table 每个表使用的最大线程数,默认为 --threads
--max-threads-for-index-creation 创建索引的最大线程数,默认 4
--max-threads-for-post-actions 后期操作的最大线程数,如约束、过程、视图和触发器,默认 1
--max-threads-for-schema-creation 创建架构的最大线程数。设置为 1 时,与 --serialized-table-creation 相同,默认 4
--exec-per-thread 设置命令,该命令将通过 STDIN 从输入文件接收并写入 STDOUT
--exec-per-thread-extension 使用 --exec-per-thread 时设置输入文件扩展名。否则将被忽略
Statement Options
-r, --rows 将 INSERT 语句拆分为这么多行
-q, --queries-per-transaction 每个事务的查询数量,默认 1000
--append-if-not-exist 将 IF NOT EXISTS 添加到 CREATE TABLE 语句。这将在 https://bugs.mysql.com/bug.php?id=103791 实现时删除
--set-names 设置名称,自行承担风险,默认 binary
--skip-definer 从 CREATE 语句中删除 DEFINER。默认情况下不修改语句
Application Options
-?, --help 显示帮助选项
-d, --directory 要导入的转储目录
-L, --logfile 使用的日志文件名,默认使用 stdout
-B, --database 要恢复到的备用数据库
-Q, --quote-character INSERT 语句中使用的标识符引号字符。可能的值是:BACKTICK, bt, ` 表示反引号,和 DOUBLE_QUOTE, dt, " 表示双引号。默认:如果可能,从转储中检测,否则使用 BACKTICK
--show-warnings 如果启用,则在 INSERT IGNORE 期间打印警告
--resume 期望在备份目录中找到恢复文件并只处理这些文件
-k, --kill-at-once 按下 Ctrl c 时立即终止进程
-t, --threads 要使用的线程数,0 表示使用 CPU 数量。默认:4
-V, --version 显示程序版本并退出
-v, --verbose 输出的详细程度,0 = 静默,1 = 错误,2 = 警告,3 = 信息,默认 2
--debug 打开调试输出(自动将详细程度设置为 3)
--defaults-file 使用特定的默认文件。默认:/etc/mydumper.cnf
--defaults-extra-file 使用附加的默认文件。这是在 --defaults-file 之后加载,替换之前定义的值
--fifodir 创建 FIFO 文件时所需的目录。默认:与备份相同
总结
MyDumper 是一个功能强大且高效的 MySQL 备份工具,特别适用于大规模数据备份和恢复。它的多线程特性、增量备份功能以及高效的数据恢复工具使其成为大型数据库管理中的重要工具。尽管其配置和使用较 mysqldump 更复杂,但其带来的性能提升和功能优势使得它在大数据场景下更具吸引力。选择 MyDumper 可以显著减少备份时间和存储成本,同时减少对生产环境的影响。