金仓数据库KingbaseES物理备份恢复最佳实践(特殊场景恢复实践案例)

上一章节介绍了通用的恢复场景,本章将举例说明恢复时可能遇到的问题,并解释特殊场景的恢复问题。

目录

8.1. 指定时间点恢复和指定备份集恢复的区别 ¶

8.2. 无法恢复到最新增量数据 ¶

8.3. 恢复后启动数据库报错 ¶

8.4. 恢复后发现查询卡住 ¶

8.4.1. 原因 ¶

8.4.2. 解决方法 ¶

8.4.3. 复现和定位问题步骤 ¶

8.5. 恢复后发现database被删除 ¶

8.6. 集群备库如何恢复 ¶


8.1. 指定时间点恢复和指定备份集恢复的区别 

指定时间点恢复和指定备份集恢复都可以将数据库恢复到同样的某个时刻,指定时间点恢复默认使用距离恢复点最近的备份集,因此二者使用的备份集可能不同。不同的备份集内的非表文件(比如kingbase.conf或sys_hba.conf等配置文件、日志文件)就会有差异,尤其是配置文件内参数的差异就会决定数据库恢复结束后的一些行为,比如最大连接数变了,某个IP段不允许访问数据库了。

8.2. 无法恢复到最新增量数据 

如下图所示,数据库在全量备份1之后创建了T1表, 位置1 为创建T1表之后的时刻,然后又创建了T2表, 位置2 为创建T2表之后的时刻,最后开始模拟恢复场景:

  1. 首先恢复到 位置1 ,并且执行了提升节点操作

  2. 然后又尝试恢复到 位置2 ,发现看不见T2表

原因是在步骤二恢复时,没有添加 --target-timeline 参数指定要恢复到时间线1上,因此默认恢复到了最新时间线2上,所以看不到T2表。

8.3. 恢复后启动数据库报错 

如下图所示,数据库在全量备份1之后又做了一次备份为全量备份2,然后开始模拟恢复场景:

  1. 首先恢复到 位置1 ,并且执行了提升节点操作

  2. 然后,通过时间点恢复尝试恢复到时间线1上的全量备份2之后的 位置2 ,启动数据库失败

原因是在步骤二的指定时间点恢复时没有指定时间线1,恢复过程是这样的:首先找到离 位置2 最近的备份集为 全量备份2 ,然后恢复备份集,启动数据库后开始从备份集开始的位置 0/4000028 重放WAL日志,默认又使用最新时间线2,发现时间线2在时间线1上的分歧点 0/310DE0 , 0/310DE0 到 0/4000028 这段的日志是不符合时间线2的预期的,因此数据库报错退出。

解决方式就是在步骤二指定时间点恢复时添加时间线1的设置。

8.4. 恢复后发现查询卡住 

如下图所示,指定了删除表t1之前的时间点做恢复,恢复后启动数据库查询t1表数据卡住,ksql没有任何查询输出,但执行 sys_wal_replay_resume() 函数之后,就可以正常查询t1表了,数据也是正常的。

8.4.1. 原因 

受限于KingbaseES PITR的机制,PITR选定的时间,一般都不是事务结束的时间,所以redo会继续往后走,将下一个事务的结束时间和设定的时间进行对比,如果设定时间小于,就停止了,就是目前数据库的状态:

  1. 这时候会有1个或多个事务处于未提交状态,这些未提交事务可能持有锁(例如drop table 持有排他锁,本示例中查询卡住就是因为拿不到t1的共享锁),此时执行 sys_wal_replay_resume() 函数将这些事务回滚就可以了,对恢复无影响

  2. 如果刚好卡在下一条事务是 drop database这种无法回滚的DDL操作,就会出现DDL语句被直接执行(kingbase不支持事务内执行drop database的操作,无法回滚,比如下一小节提到的问题)

8.4.2. 解决方法 

  1. 尝试更改指定时间点恢复的目标时刻,让恢复后的状态不卡在特殊SQL未提交前的状态。

  2. 改为指定事务ID恢复,事务ID是唯一标志,不会往下继续查时间大小,比如本示例改为xid=928。

8.4.3. 复现和定位问题步骤 

首先,创建测试表t1灌入一些数据,执行全量备份,随便更新一条t1表的数据,查询当前时间为 2022-05-20 17:47:06.674379+08 ,删掉t1表。

然后,停止数据库,重命名data目录,使用上一步中获得的时间执行指定时间点恢复。

/opt/Kingbase/ES/V8/Server/bin/sys_rman --config /home/kingbase/kbbr_repo/sys_rman.conf --stanza=kingbase restore --type=time --target='2022-05-20 17:47:06.674379+08'

再然后,启动数据库,查询t1表数据,发现卡住。

然后,获取查询语句对应的KingbaseES后台进程ID为 3809 ,使用pstack命令获取该进程的调用栈,发现是在等待锁。

其次,查看数据库日志,发现恢复停在 929 事务(结束时间为 2022-05-20 17:47:14.538044+08 )提交之前,最后使用了 000000010000000000000004 做的恢复。

然后从sys_rman归档目录中拿到数据库恢复的最后一个wal日志文件 000000010000000000000004 ,并使用sys_waldump输出该文件记录的wal record,发现了事务ID为 929 的事务是DROP表操作(已经做了排他锁表操作,因此查表时无法拿到该表的共享锁)。

最后,执行 sys_wal_replay_resume() 函数, 929 事务回滚,排他锁释放,查询t1表正常了。

8.5. 恢复后发现database被删除 

将上一节中的drop table操作改为drop database后,指定drop database操作之前的时刻做恢复,会发现该database异常,无法正常切换到该database做任何操作。因为drop database这种操作无法回滚,所以该database异常,具体复现和分析步骤不再赘述,可参考上一小节自行做验证。

8.6. 集群备库如何恢复 

恢复好主库,主库启动后查询数据符合预期,执行 sys_wal_replay_resume() 提升节点,清空 kingbase.auto.conf 内的PITR参数设定,再通过 repmgr 重做备机,具体可参考《KingbaseES集群使用手册》。

<think>好的,我现在需要帮助用户解决如何通过日志实现数据回滚与恢复的问题,并且按照最佳实践来回答。首先,我需要回忆一下数据库系统中日志和恢复的相关知识。 用户提到了引用[1]和引用[2],这两个引用分别来自MySQL的全量/增量备份金仓数据库物理备份恢复案例。这说明用户可能在使用不同的数据库系统,但问题集中在日志回滚和数据恢复的方法上。我需要结合这两个例子,同时给出通用的方法。 首先,数据恢复通常需要备份和日志的结合。全量备份可以恢复到一个时间点,而增量备份或者日志可以用于恢复到更近的状态。引用[1]中提到了使用mysqldump进行全量备份,以及二进制日志进行增量备份。而引用[2]中的金仓数据库案例显示,他们使用物理备份和日志恢复到特定的事务点。 接下来,我需要整理步骤。一般流程包括:定期全量备份,结合日志记录所有事务操作。当需要恢复时,先还原全量备份,再应用日志中的操作到故障前的状态。如果要回滚到某个时间点或事务,可能需要逆向操作或者停止在某个点。 需要注意的是不同的数据库系统可能有不同的日志机制,比如MySQL的二进制日志,而其他数据库可能有WAL(Write Ahead Logging)或者redo/undo日志。但用户的问题更关注方法而不是具体实现,所以应该保持通用,但可以举MySQL的例子作为参考。 另外,用户提到“日志回滚”,这可能涉及事务的回滚,即撤销未提交的事务或者有错误的事务。这通常通过undo日志实现,但如果是灾难恢复,可能需要使用备份和redo日志来前滚。 需要确保回答结构清晰,分步骤说明,并且结合用户提供的引用内容。例如,定期演练恢复是引用[1]中的建议,而查看日志确定恢复点是引用[2]中的案例。 可能的问题点包括:如何确定恢复的时间点或事务点,如何处理增量日志的应用,以及如何测试恢复的有效性。这些都需要在回答中覆盖。 最后,生成相关问题,需要围绕数据恢复和日志回滚的方法、工具、最佳实践以及不同数据库的实现来提问。</think>### 通过日志实现数据回滚与恢复的步骤 #### 1. **备份与日志结合的核心原理** 数据库通过**全量备份+日志文件(如事务日志、二进制日志)**实现数据恢复。全量备份保存某一时刻的完整数据状态,日志记录后续所有数据变更操作。恢复时先还原全量备份,再通过日志“重放”事务,使数据恢复到指定时间点或事务点[^1][^2]。 #### 2. **具体操作流程** **步骤1:定期全量备份** 例如,MySQL使用`mysqldump`生成全量备份: ```bash mysqldump -u root -p --all-databases > alldb_backup.sql ``` **步骤2:启用并管理增量日志** - MySQL通过**二进制日志(Binary Log)**记录增量操作: ```bash mysqladmin -u root -p flush-logs # 刷新日志,生成新日志文件 ``` - 其他数据库(如KingbaseES)可能使用WAL(预写日志)或归档日志。 **步骤3:恢复数据到指定时间点** - **场景1:完全恢复** 还原全量备份后,应用所有日志到故障前的最新状态: ```bash mysql -u root -p < alldb_backup.sql # 恢复全量备份 mysqlbinlog binlog.000001 | mysql -u root -p # 应用二进制日志 ``` - **场景2:回滚到特定事务/时间点** 若需撤销部分操作(如误删除),需定位日志中目标事务的位置(如金仓案例中的`000000010000000000000004`),仅重放该事务前的日志[^2]。 #### 3. **关键注意事项** - **日志完整性**:确保日志文件与备份版本匹配,避免缺失或损坏。 - **恢复演练**:定期模拟恢复流程(如引用[1]所述),验证备份和日志的有效性。 - **监控日志状态**:通过数据库日志(如`error.log`)确认恢复终点,如金仓案例中通过日志定位到事务提交前的状态[^2]。 #### 4. **工具与自动化** - MySQL:`mysqlbinlog`解析二进制日志,`xtrabackup`支持增量备份。 - KingbaseES:提供`sys_rman`工具管理物理备份与日志归档。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值