AI Agent 越来越多地被用来做数据库运维、数据分析和自动化测试,一个麻烦也跟着来了:它会反复“试错”,反复改数据。某次探索性的 UPDATE 可能把整张配置表改坏,某次误判可能执行了错误的 DELETE,甚至 DROP 掉对象。

传统做法往往是在旁边复制一份整库作为实验场,或者定期做快照。但整库复制会带来存储、同步和时间成本;而一旦没用实验库,误操作发生后只能依靠备份恢复,回滚粒度又太粗。

KingbaseES 的闪回(Flashback)走的是另一条路:数据库本身通过 MVCC 保留了历史版本,闪回相当于直接向数据库要“某个时间点的数据版本”,而不是再复制一份整库。
在这里插入图片描述
图1:时间轴上只有一个时间点被改坏,闪回是把读取位置拨回那个点之前,不复制数据

我用一个 AI Agent 误操作的场景,把闪回查询、闪回表、闪回版本查询和回收站串起来演示一遍。


一、场景:Agent 一次试错,把整表改坏

假设有一个配置表 t1,AI Agent 本来要修改其中一行,但因为生成条件错误,执行了整表 UPDATE,导致所有行都被改坏。

先准备测试数据:

-- 1. 创建测试表
CREATE TABLE t1 (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    status VARCHAR(20)
);

-- 2. 写入初始数据
INSERT INTO t1 VALUES 
(1, 'alice', 'active'),
(2, 'bob', 'active'),
(3, 'carol', 'active');

随后 Agent 执行了误操作:

-- 3. 误操作:整表更新
UPDATE t1 SET status = 'unknown';

这时如果直接查表,看到的是错误结果:

SELECT * FROM t1;

如果事先没有实验库,又没有行级变更记录,这种“整表误更新”就会比较棘手。


二、闪回查询:先找回历史版本

KingbaseES 支持在 SELECT 的 FROM 子句中使用 AS OF 指定历史点,直接读取历史版本。历史点可以用时间戳(TIMESTAMP)、提交顺序号(CSN)或 SCN 指定。

在这里插入图片描述

图2:AS OF 挂在整个查询后面,只改变“看哪个时刻”,不改变查哪张表

假设误操作前的时间点是 2022-08-05 14:22:30,可以先通过闪回查询找回当时的数据:

-- 按时间戳闪回查询
SELECT * FROM t1 AS OF TIMESTAMP TO_TIMESTAMP('2022-08-05 14:22:30', 'yyyy-mm-dd hh24:mi:ss');

这样就能看到误操作前的 status 值,确认数据确实存在历史版本中。

如果拿到了误操作前的提交顺序号,也可以按 CSN 查询:

-- 按 CSN 闪回查询
SELECT * FROM t1 AS OF CSN 65536000011;

CSN 是 commit sequence number,即提交顺序号,适合在应用侧或监控侧已经记录了误操作前提交点的情况下使用。


三、闪回表:整表恢复到历史点

确认历史版本存在后,可以直接把整张表恢复到指定历史点,而不需要手工把查询结果重新写回。

按时间戳恢复:

-- 按时间戳闪回表
FLASHBACK TABLE t1 TO TIMESTAMP TO_TIMESTAMP('2022-08-05 14:22:30', 'yyyy-mm-dd hh24:mi:ss');

按 CSN 恢复:

-- 按 CSN 闪回表
FLASHBACK TABLE t1 TO CSN 65536000011;

恢复后再次查询,数据应回到误操作前的状态。对 AI Agent 试错这种场景,直接整表回滚比手工一行行改回来省事,也比复制整库做实验场轻。


四、闪回版本查询:看数据是怎么变化的

如果需要分析 Agent 到底改了哪些行、版本如何变化,可以使用闪回版本查询。

SELECT versions_startscn, versions_endcsn, * 
FROM t1 VERSIONS BETWEEN CSN MINVALUE AND MAXVALUE;

这条 SQL 会返回行的版本变化历史,其中 versions_startscn 和 versions_endcsn 是伪列,用来表示某个版本对应的提交顺序号范围。通过它,可以大致判断一行数据在什么时候被谁改过、改之前是什么样。

适合在排障时使用:比如 Agent 说“我刚改过一次”,但你不确定改动范围,可以先看版本历史,再决定回滚到哪个点。


五、MVCC:为什么数据库能直接读历史版本?

闪回查询之所以能直接拿到历史数据,并不是数据库额外保存了一份全量快照,而是因为 KingbaseES 的 MVCC(多版本并发控制)机制。

简单理解:

  • UPDATE / DELETE 不会立即物理覆盖或删除旧行;
  • 数据库通过事务号(xid)与标记,控制旧版本对后续事务的可见性;
  • 读不阻塞写,写也不阻塞读;
  • 每个 SQL 看到的是“一小段时间之前的数据快照”;
  • 不再被需要的旧版本(dead tuple)由 VACUUM 负责回收。

因此,在旧版本尚未被回收之前,AS OF 查询就能通过可见性规则找到那个时间点的数据版本。闪回表本质上也是利用这些历史版本,将表的当前数据恢复到指定的历史状态。

所以闪回不用“复制整库”,它直接借数据库已有的历史版本。


六、误删表:用回收站找回

AI Agent 还可能误删整张表。对于这种误操作,可以打开 KingbaseES 的闪回回收站。

开启参数:

SET kdb_flashback.db_recyclebin = on;

默认情况下该参数关闭。开启后,执行 DROP TABLE 且未指定 PURGE 时,表不会立即被物理销毁,而是进入 SYS_RECYCLEBIN。

例如:

-- 误删表
DROP TABLE t1;

-- 查看回收站
SELECT * FROM RECYCLEBIN;

-- 从回收站恢复
FLASHBACK TABLE t1 TO BEFORE DROP;

如果希望恢复到新表名,可以使用:

FLASHBACK TABLE t1 TO BEFORE DROP RENAME TO t1_backup;

回收站适合处理“删除对象”这种误操作,和前面的闪回查询/闪回表互补:一个解决数据改坏,一个解决对象删错。


七、限制与注意事项

闪回并不是万能的,有几类边界需要特别清楚:

在这里插入图片描述

图3:VACUUM / TRUNCATE / REWRITE 之后旧版本被回收,历史点就落在空处

  1. 依赖历史数据仍然存在。
    如果误操作后数据库执行了 VACUUM,或者对表执行了 TRUNCATE、REWRITE 等操作,旧版本可能已经被回收。此时 AS OF 查询可能拿不到目标数据,闪回表也会失败。

  2. 回收站也要依赖参数开启。
    kdb_flashback.db_recyclebin 默认关闭。如果误删表之前没有开启,表可能直接进入物理删除流程,无法通过回收站恢复。

  3. 闪回更适合短时间、误操作后的快速找回。
    对于关键业务,不能把闪回当作唯一保障。如果历史版本已被清理,或者需要跨非常长的时间窗口恢复,应结合时间点恢复(PITR)等更重的兜底方案。


小结

在 AI Agent 试错场景下,KingbaseES 的闪回能力可以明显降低误操作恢复成本:

  • 闪回查询:用 AS OF 直接读历史版本,先确认数据还能找回;
  • 闪回表:整表恢复到指定时间点或 CSN,适合误改后快速回滚;
  • 闪回版本查询:查看行级版本变化,帮助定位变更范围;
  • 闪回回收站:配合 kdb_flashback.db_recyclebin,找回误删的表。

它不需要复制整库,而是利用 MVCC 已经保留的历史版本,直接向数据库要“过去的版本”。但同时也必须清楚:一旦历史版本被 VACUUM、TRUNCATE、REWRITE 等操作回收,闪回就会失效,重要场景仍需 PITR 兜底。

Logo

更多推荐