本文约 3869字,预计阅读需要 15分钟。
前言:鉴于最近的滴滴、阿里云的互联网大事件,验证了搞基础运维的那句话:高可用、数据备份、数据容灾、备份验真、切换演练、一致性保障、应急预案等,真真一个都不能少。建议后面把保障系统稳定性纳入OKR。
数据库备份工具通常有物理备份工具和逻辑备份工具两大类。常用物理备份工具有Percona XtraBackup、MySQL Enterprise Backup;常用逻辑备份工具有mysqldump、mydumper、mysqlshell等实现。
鉴于数据库备份和恢复时长、及易操作性的综合考量。一般来说,100GB内的数据库通常考虑使用轻巧灵活的逻辑备份方式,可每天定时进行全量备份,备份时间在业务低峰期发起,保留最近两周的备份恢复窗口。100GB以上的数据库通常考虑使用备份恢复速度快的物理备份方式,一般选择一周一个全备,其余每天进行增量备份,备份时间建议在业务低峰期发起,建议至少保留最近两周的备份恢复窗口。
逻辑备份的另一种场景是帮助业务用户、DBA方便、简洁的迁移小量数据(通常认为在5GB内),尤其是在跨操作系统、跨数据库版本的背景下,相比物理备份, 逻辑备份更为灵活方便和易操作。本文将讲述3种常用的MySQL数据库逻辑备份工具(mysqldump、mydumper、mysqlshell),结合对表级、库级和实例级对象进行备份和恢复来帮助读者学习和理解。
三种常用MySQL逻辑备份工具有:
1. mysqldump,单线程工具,MySQL官方备份工具,特点是备份速度慢,命令和操作简单。
2. mydumper,多线程工具,开源备份工具,特点是可手动指定备份线程数,备份速度较之mysqldump快,命令和操作稍显复杂。
3. mysqlshell,多线程工具,MySQL官方推荐的一款快速备份恢复工具,工具中集成了备份函数,该工具需单独部署才可使用。特点是备份速度较之mydumper又有提升,命令和操作简洁,推荐在MySQL8.0环境中使用。
(1)mysqldump逻辑备份工具讲解
先来看如下这条常用的mysqldump逻辑备份示例命令,此条逻辑备份命令是对整库数据发起的逻辑备份,包含备份数据库的触发器、事件、存储过程和函数;且在备份期间该条备份session使用RR(REPEATABLE READ)的隔离机制,不影响其他session会话对数据库的读写操作。具体来看如下命令:
# mysqldump -uroot -proot -h127.0.0.1 --single-transaction --master-data=2 --routines --events --triggers --all-databases | gzip > `date +%Y%m%d`.sql.gz
参数介绍:
--single-transaction :
1. 备份开始时事务隔离级别设置成session级 repeatable read可重复读;
2. 然后启动一个事务(执行begin),备份结束时提交备份事务(执行commit)。
--master-data=2:
备份过程中记录主库的binlog和pos点,在备份文件中注释掉这一行。
--routines:导出数据库中的存储过程和函数
--events:导出数据库中的事件
--triggers:导出数据库中的触发器
表1 mysqldump逻辑备份执行步骤
序号 |
执行命令 |
说明 |
1 |
FLUSH TABLES |
刷新表,关闭实例上所有的打开表,为第二步做准备。目的是防止长查询或者大事务导致关闭表无法完成,导致长期持有全局读锁,造成FLUSH TABLES WITH READ LOCK操作迟迟得不到锁,同时阻塞了其它session对表操作。 |
2 |
调用FWRL(flush tables with read lock) |
加全局读锁,获取数据库一致性状态。 --master-data=2参数作用,这时需要flush tables with read lock锁住全库,记录此时master_log_file和master_log_pos。 |
3 |
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ |
设置事务的隔离级别为可重复读 --single-transaction参数的作用,设置事务的隔离级别为可重复读(REPEATABLE READ),保证在接下来的备份事务中所有相同查询能读取到不变的数据。 |
4 |
START TRANSACTION WITH CONSISTENT SNAPSHOT |
开启备份事务 --single-transaction参数的作用,开启一个备份事务进行快照读(仅仅对innodb起作用)。需要注意的是,WITH CONSISTENT SNAPSHOT只在RR隔离级别下有效。 |
5 |
SHOW MASTER STATUS |
获取gtid和binlog、pos信息 --master-data=2参数的作用,记录了开始备份时,binlog的状态信息,包括MASTER_LOG_FILE和MASTER_LOG_POS。 --master-data=2表示在dump过程中记录主库的binlog和pos点,并在dump文件中注释掉这一行;--master-data=1表示在dump过程中记录主库的binlog和pos点,并在dump文件中不注释掉这一行,即恢复时会执行。 |
6 |
备份非innodb表数据(*.frm,*.myi,*.myd等) |
备份数据字典等信息,数据字典数据量不大,此阶段备份执行速度会很快。 |
7 |
UNLOCK TABLES |
非innodb表备份完毕之后,释放FTWRL锁。 |
8 |
设置回滚点逐一备份innodb数据表 |
期间因MVCC机制,并不会影响阻塞session的读写;此段为备份数据阶段,执行时长视数据量而定。 |
9 |
commit |
提交备份事务,备份备份完成。 |
接下来通过命令讲解如何使用mysqldump逻辑备份工具对表级、库级和实例级对象进行备份和恢复演练。
1.mysqldump备份表级tables
# mysqldump -uroot -proot -h127.0.0.1 -P3306 --single-transaction --master-data=2 --routines --events --triggers --tables table1,table2 | gzip > `date +%Y%m%d`.sql.gz
2.mysqldump备份库级schemas
# mysqldump -uroot -proot -h127.0.0.1 -P3306 --single-transaction --master-data=2 --routines --events --triggers --databases schema1,schema2 | gzip > `date +%Y%m%d`.sql.gz
3.mysqldump备份实例级instance
# mysqldump -uroot -proot -h127.0.0.1 -P3306 --single-transaction --master-data=2 --routines --events --triggers --all-databases | gzip > `date +%Y%m%d`.sql.gz
4.mysqldump恢复数据
因备份出来的是SQL执行语句,表级、库级和实例级对象的逻辑备份恢复数据命令是一致的,示例命令如下:
# mysql -uroot -proot -h127.0.0.1 -P3306 < 20231118.sql
(2)mydumper 逻辑备份工具讲解
mydumper 是一款社区开源的逻辑备份工具。该工具主要由C语言编写,由MySQL、Facebook等公司人员开发维护。mysqldump是单线程逻辑备份方式,备份速度较慢,为提升逻辑备份的速度,mydumper应运而生。mydumper常被用于MySQL跨平台迁移,字符集转换重导库,大版本升级,误操作大表误删除恢复等场景。
mydumper主要有以下几点特性:
1.C语言编写,使用glibc库;
2.执行速度比mysqldump快约10倍;
3.支持事务性表和非事务性表一致的快照;
4.支持快速文件压缩,支持到备份文件切块;
5.多线程备份(因是多线程逻辑备份,备份后会产生多个备份文件);
6.多线程恢复(适用于0.2.1以上版本);
7.备份时对Myisam表加FTWRL(flush tables with read lock);
8.以守护进程的方式工作,支持定时快照;
9.基于GNU GPLv3协议开源。
还是先来看一条常用的mydumper 逻辑备份示例命令,此条备份命令是备份除指定库(mysql|sys|information_schema|performance_schema)外的数据备份。
mydumper -uroot -proot -h127.0.0.1 -P3306 --regex '^(?!(mysql|sys|information_schema|performance_schema))' -c -e -G -E -R --use-savepoints -t 8 -L data/backup/mydumper.log -o data/backup/
参数介绍:
--regex '^(?!(mysql|sys|information_schema|performance_schema|test))':使用正则表达式排除特定的数据库(mysql、sys、information_schema、performance_schema、test)。
-c:启用压缩模式,以减小备份文件的大小
-e:备份事件(Events)
-G:备份存储过程(Stored Procedures)
-E:备份事件调度器(Event Scheduler)
-R:备份表结构和数据
--use-savepoints:使用保存点进行事务处理,以提高备份的一致性
-t 8:指定使用的线程数,这里设置为8个线程并行备份
-L 日志推荐输出到文件,方便后续验证结果和排错
-o:/data/backup/:指定备份文件的输出目录
mydumper进行数据备份时的主逻辑由一个主线程和多个备份子线程共同完成,默认情况下为4个子线程(可以手动设置)。
mydumper主要工作步骤:
表2 mydumper 主线程执行步骤
序号 |
执行命令 |
说明 |
1 |
主线程调用FWRL(flush tables with read lock) |
将脏页刷新到磁盘,加全局读锁,获取数据库一致性状态。 |
2 |
START TRANSACTION !40108 WITH CONSISTENT SNAPSHOT |
开启备份事务 WITH CONSISTENT SNAPSHOT只在RR隔离级别下有效。 |
3 |
SHOW MASTER STATUS |
读取当前时间点的二进制日志文件名和日志写入的位置并记录在metadata文件中,以供恢复时使用。 |
4 |
主线程创建N个(线程数可以指定,默认是4) |
备份子线程导出表和表结构 |
5 |
主线程为子线程分配任务并push 到队列queue中 |
|
6 |
在各子线程处理完所有非 InnoDB 表之后,将事件通知给主线程,主线程UNLOCK TABLES |
备份完成非事务类型的表之后,释放全局只读锁 |
7 |
thread.join()等待子线程结束。 |
等待各备份子线程结束 |
表3 mydumper 子进程执行步骤
序号 |
执行命令 |
说明 |
1 |
连接数据库
|
|
将 session 的隔离级别设置为 Repeatable Read |
设置session级隔离级别为可重复读 |
|
2 |
START TRANSACTION /!40108 WITH CONSISTENT SNAPSHOT / |
开启事务并获取一致性快照 WITH CONSISTENT SNAPSHOT只在RR隔离级别下有效。 |
3 |
从主线程队列中 pop 任务并执行
|
从主线程队列queue中获取主线程分配的任务,获取需要备份的表信息,在备份文件中创建对应的表结构文件,并记录表相关的元数据信息。 |
4 |
备份非 InnoDB 表 |
非InnoDB执行完成后,将事件通知给主线程, |
5 |
备份InnoDB tables |
当前子线程备份基于事务导出InnoDB表 |
备份主线程和备份子线程的协作使得mydumper能够并发备份数据库,提高备份速度和效率。值得注意的是,虽然mydumper支持表级别的并行操作,且在导出的时候会对大的表数据进行分块chunk导出,同一个表的chunks是在同一个线程中处理的,并非多线程并行的。
接下来通过命令讲解如何使用mydumper逻辑备份工具对表级、库级和实例级对象进行备份和恢复演练。
1.mydumper备份表级tables(备份一个库的两个表)
mydumper -uroot -proot -h127.0.0.1 -P3306 -B schema1 -T table1,table2 -t 4 -r 100000 -c --less-locking -v 3 -D -L /data/backup/mydumper.log -o /data/backup/
2.mydumper备份库级schemas
mydumper -uroot -proot -h127.0.0.1 -P3306 -B schema1 -t 4 -r 100000 -c --less-locking -v 3 -D -L /data/backup/mydumper.log -o /data/backup/
3.mydumper备份库级instance
mydumper -uroot -proot -h127.0.0.1 -P3306 --regex '^(?!(mysql|sys|information_schema|performance_schema))' -c -t 8 -L /data/backup/mydumper.log -o /data/backup/
参数介绍:
--regex '^(?!(mysql|sys|information_schema|performance_schema|test))':使用正则表达式排除特定的数据库(mysql、sys、information_schema、performance_schema、test)。
-r, --rows 尝试将表的数据按多少行分隔为块,当使用--chunk-filesize 时
-c, --compress 压缩输出文件
--less-locking 在 InnoDB 表使用最小的锁表时间
-v, --verbose 输出信息的等级 0 = silent, 1 = errors, 2 = warnings, 3 = info 默认为 2
--daemon参数用于将mydumper进程以守护进程(daemon)的形式运行。当使用--daemon参数启动mydumper时,它将在后台运行并不会占用终端窗口。
mydumper和myloader是相对应的一组可执行程序,myloader用于恢复mydumper备份文件,myloader从备份文件中恢复数据不需要先创建数据库。myloader支持恢复到指定时间点的备份文件,可支持指定要恢复的数据表和数据行。
4.myloader 恢复源库数据表级tables和schemas(同一条语句)
因备份出来的是SQL执行语句,表级、库级和实例级对象的逻辑备份恢复数据命令是一致的,示例命令如下:
myloader -uroot -proot -h127.0.0.1 -P3306 -B schema1 -e -t 4 -d /data/backup/ --overwrite-tables -v 3
参数介绍:
-o, --overwrite-tables 若表存在则删除
-C, --compress-protocol 在 mysql 连接的时候使用压缩协议
-v, --verbose 输出日志的等级, 0 = silent, 1 = errors, 2 = warnings, 3 = info, 默认为 2
-t, --threads 恢复使用的线程数,默认是 4
-d, --directory 数据恢复的目录
-B, --database 需要恢复的数据库
-e, --enable-binlog 恢复数据的时候开启 binlog
(3)逻辑备份工具mysqlshell讲解
mysql shell是MySQL官方的一款逻辑备份工具,该工具中集成了备份函数。2020年7月,MySQL官方在mysqlshell 8.0.21中集成了实例和库级别的备份函数;2020年10月,8.0.22版本又发布了表级备份函数。至此8.0.22版本后的mysql shell能够实现对表、库和实例级别的备份函逻辑备份。MySQL数据库版本在5.7以上,推荐使用mysqlshell 8.0工具进行运维管理。
mysqlshell包含多种实用程序集(工具集),可使用mysqlsh -- util --help命令查看其工具集。mysqlshell主要使用三个备份工具(备份表dump-tables、备份库dump-schemas、备份进程dump-instance),以及恢复工具load-dump(恢复dump-tables/dump-schemas/dump-instance备份的数据)。
接下来通过命令讲解如何使用mysqlshell逻辑备份工具对表级、库级和实例级对象进行备份和恢复演练。
1.mysqlshell备份表级tables
mysqlsh root@127.0.0.1:3306 -- util dump-tables schema1 'table1,table2' --output-url='/data/backup/' --threads=4 --consistent=false --dryRun=true
2.mysqlshell备份schemas
mysqlsh root@127.0.0.1:3306 -- util dump-schemas 'schema1,schema2' --output-url='/data/backup/' --threads=4 --consistent=false --dryRun=true
3.mysqlshell备份instance
mysqlsh root@127.0.0.1:3306 -- util dump-instance '/data/backup/' --threads=4 --consistent=false --dryRun=true
参数介绍:
--util dump-tables:使用MySQL Shell的util工具,并选择dump-tables子命令来导出数据表。
--output-url='/data/backup/':指定导出文件的输出路径和前缀。
--threads=4:指定使用的线程数。
--consistent=false:禁用一致性读取,即在导出期间不使用事务。
--dryRun=true:模拟导出操作,而不实际执行。
--consistent: [ true | false ] 是否开启一执性快照备份,默认true。开启时,通过flush tables with read lock获取全局读锁,每个备份线程设置会话隔离级别RR,开启一致性快照事务。当所有线程开启事务后,获取实例级备份锁(lock intance for backup),释放全局读锁。
4.mysqlshell 恢复表级tables
备份schema1库table1/table2的数据,恢复至schema2库。
mysqlsh root@127.0.0.1:3306 -- util load-dump '/data/backup/' --analyzeTables=on --skipBinlog=true --updateGtidSet=off --schema=schema2 --dryRun=false
5.恢复dump-schemas/dump-instance备份数据
mysqlsh root@127.0.0.1:3306 -- util load-dump '/data/backup/' --analyzeTables=on --skipBinlog=true --updateGtidSet=off --dryRun=true
参数介绍:
--dryRun=true:模拟导出操作,而不实际执行
--analyzeTables=on:在加载数据后对表进行分析
--skipBinlog=true:跳过写入二进制日志。
--updateGtidSet=off:禁用更新GTID。
文章至此。
以下是个人微信公众号,欢迎关注: