作者:玉璁,OceanBase 生态产品技术专家。
孙夕恩,花名玉璁,工作十余年,一直在基础架构与中间件领域从事研发工作。现任职于 OceanBase 生态产品团队,负责离线导数产品工具的研发工作,致力于为 OceanBase 建设一套完善的生态工具体系。玉璁在Java、分布式、基础架构、中间件领域有着较为丰富的研发实战经验。
认识备份恢复
在数据库日常运维过程中,备份是一项非常关键的动作。企业为了数据安全,DBA会定期为数据库进行不同程度的备份。数据库按备份形式来分,主要分为逻辑备份和物理备份。物理备份是把数据库中的物理文件(例如:数据文件、日志文件等)转储到另外的设备上。一旦数据库发生故障,可以利用这些物理备份文件进行还原。逻辑备份是利用导出工具将数据库中的对象(例如:模式、数据等)在逻辑上以特定的格式导出到存储设备上,我们可以利用导入工具把逻辑备份出来的文件导入到数据库。从备份时数据库的运行状态来看,备份恢复主要分为冷备、温备和热备。冷备时数据库不提供在线的读写服务,用户将机器上的数据库软件所包括的控制文件、配置文件以及数据/日志文件进行归档迁移到目标机器上并重新启动即可。温备时数据库仅提供在线读服务,用户仅需要考虑冷备操作对于在线读业务的影响。热备时数据库提供在线读写服务,用户不仅要考虑数据的一致性问题,还要考虑备份工作对于在线业务的影响。
obdumper/obloader 是 OceanBase 官方提供的导入导出使用工具,它也可以用来实现轻量级的逻辑备份恢复,适用于快速搭建测试环境和小规模生产数据库。下面我们来简单介绍一下逻辑备份恢复的核心原理之一——全局数据一致性。
全局数据一致性
我们在网络博客上或者客户的交流中发现,经常会有人提出这样的问题:如何保证导出(或者备份)的数据具有全局一致性?下面我们将通过数据库不同的技术方案来讲解OceanBase 如何实现全局的数据一致性,以及我们的工具是如何解决一致性的问题。
方式一:锁表
FLUSH TABLES WITH READ LOCK;
MySQL 逻辑备份工具(例如:mysqldump, mydumper)对于 MySQL MyISAM 存储引擎是采用锁表的方式来保证全局数据的一致性。锁表可以阻止业务的DML语句执行所带来的一致性问题。当然,锁表会影响“热备”。思考:为什么 MySQL InnoDB 存储引擎不使用“锁表”的方式来实现数据一致性?
方式二:多版本控制
MySQL InnoDB 存储引擎实现了MVCC机制,大多数逻辑备份工具利用事务来解决一致性问题。下面我们先简单介绍 MySQL InnoDB 存储引擎是如何利用事务来实现数据一致性。
START TRANSACTION WITH CONSISTENT SNAPSHOT;
上述语句中 WITH CONSISTENT SNAPSHOT 子句是为了开启一致性读的能力,该子句仅适用于InnoDB存储引擎,并且在可重复读(REPEATABLE READ)的事务隔离级别下才会生效,同时它不会改变当前数据库的事务隔离级别。在其它所有的事务隔离级别中执行上述语句时,MySQL会忽略 WITH CONSTRIATED SNAPSHOT 子句并且会产生一个警告,如下所示:
[mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read uncommitted;
Query OK, 0 rows affected (0.00 sec)
mysql> start transaction with consistent snapshot;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-------------------------------------------------------------------------------------------------------------------------+
| Warning | 138 | InnoDB: WITH CONSISTENT SNAPSHOT was ignored because this phrase can only be used with REPEATABLE READ isolation level. |
+---------+------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
InnoDB 存储引擎中的读取操作是使用基于任意时间点的快照信息来查询数据的,而不用考虑其它事务正在执行的修改操作。如果查询的数据已被其它事务修改,InnoDB 存储引擎会根据 UNDO 日志中的内容来重新构建历史版本中的数据。这种技术(即MVCC)避免了使用加锁的方式强制当前或者其它事务进入等待状态从而降低了并发性。对于 REPEATABLE READ 隔离级别,基于第一次发起读取操作的时间建立快照点。对于 READ COMMITTED 隔离级别,基于每次发起一致性读操作的时间建立快照点。一致性读是指 InnoDB 存储引擎使用了多版本机制(即MVCC)来查询数据库处于某一个时间点的数据。该操作可以查询到T1时间点以前提交的事务数据,无法查询到T1时间点以后提交的事务数据或者未提交的事务数据(例外是在当前的事务内可以查询到早期未提交的事务数据)。如果当前的事务隔离级别是 REPEATABLE READ(默认的隔离级别),同一事务中所有的一致读操作是根据该事务中第一个发起的读操作建立快照点。您可以通过提交当前事务后再发起新的一致性读操作查询到更新的快照数据。设置 READ COMMITTED 隔离级别时,事务中的每一个一致性读操作都会为自己设置一个最新的快照点并读取最新的快照数据。一致性读是 InnoDB 存储引擎在 READ COMMITTED 和 REPEATABLE READ 隔离级别下处理SELECT语句的默认行为。一致性读操作不会对表加任何锁,所以其它会话可以同时对表进行更新操作。假设数据库设置的是 REPEATABLE READ 隔离级别,当您发起一致读操作(即普通的SELECT查询)时,InnoDB 存储引擎会为当前的事务创建一个时间点T2(或者叫快照点),以上查询操作会根据T2时间点查询数据库。如果另一个事务删除了一行数据并在T2时间点之后提交,则在T2时间点内一致性读取到的数据仍然是删除前的状态。插入和更新操作同理。
方式三:闪回技术
闪回技术(Flashback)是Oracle实现逻辑备份恢复功能的关键特性。在数据库发生逻辑错误时,闪回技术能提供快速且最小损失的恢复。闪回技术主要用于快速恢复逻辑错误,对于物理损坏或是存储介质丢失的错误则无法进行恢复。Oracle 闪回功能使用自动撤消管理(AUM)系统来获取事务的元数据和历史数据。它们依赖于撤销数据,即单个事务所影响的记录。例如,如果用户执行UPDATE语句将薪资从1000更改为1100,则Oracle数据库将值1000存储在撤消数据中。撤消数据是持久性的,在数据库关闭后仍然有效。它将在UNDO_RETENTION指定的时间内保留,或在自动撤消管理(AUM)存在的情况下保留到优化的UNDO_RETENTION。通过使用闪回功能,您可以使用撤消数据来查询过去的数据或从逻辑损坏中恢复。除了在闪回功能中使用它之外,Oracle数据库还使用撤消数据执行以下操作:
- 回滚活动的事务
- 使用数据库或者进程恢复机制恢复终止的事务
- 为SQL查询提供一致性读取
在 OceanBase Oracle 模式下,我们仅利用到数据库的闪回查询(Flashback Query)功能来解决数据逻辑备份的一致性问题。我们在使用闪回查询功能时,首先需要给 UNDO_RETENTION 参数设定一个合理的值。其次要慎重考虑磁盘的空间是否足够。
闪回事务查询,基于SCN的闪回查询语句
SELECT * FROM OWNER.TABLE AS OF SCN <SCN_NUMBER>;
闪回版本查询,基于时间点的闪回查询语句
SELECT * FROM OWNER.TABLE AS OF TIMESTAMP TO_TIMESTAMP('2021-01-01 12:00:00','yyyy-mm-dd hh24:mi:ss');
小提示:
- scn_timestamp 是任意的日历时间;但是要确保undo还保留该时间窗口内的事务数据。
- scn_number 是全局事务序列号;使用sys租户从v$ob_timestamp_service 视图查询。
方式四:冻结版本
简单介绍一下转储的原理和过程:“当 MemTable 的内存使用达到一定阈值时,数据库需要将 MemTable 中的数据存储到磁盘上以释放内存空间,这个过程称之为转储。在转储之前,首先数据库需要保证被转储的 MemTable 不再接受新的数据写入,这个过程称之为冻结(Minor Freeze)。每次冻结都会阻止当前活跃的 MemTable 再有新的写入,同时生成一个冻结版本号,并且生成新的活跃 MemTable。” 我们使用这里提到的冻结版本来解决 OceanBase 数据库的读取一致性的问题。
基于冻结版本的查询语句
SELECT /*+frozen_version(number)*/ * FROM OWNER.TABLE;
小提示:frozen_version 是合并时的冻结版本号;使用sys租户从 oceanbase.__all_zone 系统表查询。
以上四种方式都可以用来解决逻辑备份所面临的全局数据一致性的问题。其中,锁表和多版本控制是MySQL备份工具主流的实现方案。obdumper 主要利用 OceanBase 存储机制中的冻结版本来解决全局一致性的问题。该方案的优势是可以规避事务隔离级别的影响支持多线程并行备份。但是,使用冻结版本的前提是集群至少主动或者被动发生过一次转储。同时,obdumper 也利用了闪回查询的方式,闪回查询的优势是不需要用户主动或者被动的方式触发集群转储的操作,但是仅限于OceanBase Oracle模式下使用。具体的用法可以查阅 obloader/obdumper 的官方用户手册。
MySQL 备份恢复工具
mysqldump 是 MySQL 官方的逻辑备份恢复工具。mydumper 是一款开源的 MySQL 备份恢复工具(GPLv3)。mydumper 内部支持多线程,比官方的 mysqldump 拥有更高的性能。这两款工具都支持库级和表级的逻辑备份和恢复的功能。在 OceanBase MySQL 模式下,也是可以直接使用 mysqldump/mydumper 工具的。但是从用户的业务场景和使用体验来看,可能与自研的工具存在一些差异。例如:高性能恢复、运行监控、稳定性等方面。
Oracle 备份恢复工具
exp/imp 是 Oracle 官方提供的客户端备份恢复工具,它既可以在客户端使用也可以在服务端使用。Oracle 10g 后续的版本主要使用 expdp/impdp 服务端备份恢复工具,仅可以在服务端运行。使用 exp 工具导出的数据只能使用 imp 导入,expdp 也是有同样的限制。在 OceanBase Oracle 模式下,用户只能使用 OceanBase 自研的数据库逻辑备份工具 obloader/obdumper。
OceanBase 备份恢复工具
obloader/obdumper 是 OceanBase 官方使用Java语言开发的一种逻辑备份恢复工具。 obloader 可以兼容 mysqldump/mydumper 备份出来的逻辑数据格式。obloader/obdumper 3.0 版本产品新增了许多功能,即将正式对外发布。这里我们将会以两大功能为例进行介绍。
功能一:obdumper支持从备副本(Follower)进行逻辑备份,不影响主副本(Leader)的业务处理。
功能二:obdumper可以对备份出来的数据进行预处理,例如:数据转换、清洗等。
此外,obloader/obdumper 3.0版本中逻辑备份恢复还完成了许多性能优化工作。我们计划在obloader/obdumper 3.0发版期间会发布一项OceanBase逻辑备份恢复的基准性能测试报告。
最后,OceanBase还提供了功能强大的物理备份恢复功能,支持企业内大规模生产系统使用。该功能通过OCP对用户提供了易用的管理操作。备份恢复TB级以上的数据,用户可以使用OCP产品中提供的物理备份恢复功能。
相关文章参考
一、《准备好您的数据了吗?》 用户在处理逻辑备份恢复的时候,最容易在数据格式的辨识和使用上出现错误,这篇文章主要介绍数据格式以及如何使用好这些数据格式。
二、《学会使用导数工具了吗?》obloader/obdumper是 OceanBase 自研的客户端逻辑备份恢复工具。用户对于它的使用比较陌生,这篇文章教大家如何快速上手使用该工具。
欢迎加入OceanBase,探索数据库的乐趣,一起做最先进的分布式数据库!