本文为您介绍行存快照功能的特点以及如何使用行存快照查询历史数据。
版本限制
实例版本需为5.4.20-20240716_xcluster8.4.19-20240630及以上。且存储引擎为MySQL 8.0。
功能特点
行存快照功能可以让您查询到在快照保留时间内的历史数据。通过行存快照功能您可以:
恢复过去任意时间点的数据。
可以对关键时间点的数据进行备份。
可以对过去某一时间点的数据进行计算分析。
行存快照功能是基于Undo Log实现的。由于Undo Log所占额外存储空间是有限的,所以行存快照的保留时间不宜过长。
如果您需要保留更长时间的快照,推荐使用列存快照功能,它最多可保留一年内的快照。更多信息,请参见列存快照功能。
行存快照功能和列存快照功能可以同时使用。
费用
行存快照功能免费,但开启行存快照功能后,会产生额外的Undo Log占用存储空间,建议您提前做好存储空间规划。
注意事项
对开启快照功能的表执行DDL后,不支持查询该表执行DDL之前的行存快照。
不支持查询超过保留时间的快照点。
准备工作
在使用行存快照功能之前,您需要先调整数据库的一些配置参数:
在控制台上修改存储层参数
loose_opt_flashback_area
为true
。具体操作,请参见参数设置。说明该参数必须在使用行存快照的表创建之前修改。
如果在目标表创建完成后,再修改该参数为
true
,则需要对目标表进行重建(比如执行OPTIMIZE TABLE
),这样行存快照才能生效。
在控制台上修改存储层参数
loose_innodb_txn_retention
为预期数值,该参数为行存快照的保留时间(单位:秒)。说明该参数最大值为
4,294,967,295
秒,默认值为1,800
秒,建议您的保留时间设置不超过3天也就是259,200
秒。
获取快照点TSO值
行存快照支持任意时刻作为快照点,您可以通过如下代码,将一个时间戳转换为快照点TSO值:
SELECT TIME_TO_TSO("2024-07-24 10:00:00"); -- 转换2024-07-24 10:00:00为快照点TSO,时区会默认使用当前会话的时区
SELECT TIME_TO_TSO(NOW()); -- 转换当前时间为快照点TSO,时区会默认使用当前会话的时区
TIME_TO_TSO()
函数可以为任意时刻生成快照点TSO值,无论该时刻是否在保留时间范围内。
您也可以通过如下代码,手动指定转换函数使用的时区:
-- 第二个参数可以指定时区
SELECT TIME_TO_TSO("2024-07-24 10:00:00", "+8:00");
快照查询
快照查询通过在SELECT
语句中的目标表后追加AS OF TSO {TSO}
语句实现,示例如下:
SELECT * FROM tb1 AS OF TSO 7206138458723582016;
其中7206138458723582016
为获取快照点TSO值章节的TIME_TO_TSO()
函数所生成的快照点TSO值。
快照查询也支持INSERT/REPLACE SELECT
语法,也是在目标表后追加AS OF TSO {TSO}
语句实现,将某个版本的数据恢复到临时表。示例如下:
CREATE TABLE tmp (
-- 表结构保持和主表一致
);
INSERT INTO tmp SELECT * FROM tb1 AS OF TSO 7206138458723582016;
完整示例
根据准备工作,调整对应参数。
执行如下代码,创建
tb1
表:CREATE TABLE tb1 ( id INT PRIMARY KEY, a INT, gmt_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, gmt_modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) PARTITION BY KEY(id);
执行如下代码,插入一些实验数据,并生成快照点:
INSERT INTO tb1 (id, a) VALUES (0, 0); -- 等待 1 秒后执行 SELECT TIME_TO_TSO(NOW()); -- 记录该查询的返回结果快照点TSO值为 TSO1 INSERT INTO tb1 (id, a) VALUES (1, 1); -- 等待 1 秒后执行 SELECT TIME_TO_TSO(NOW()); -- 记录该查询的返回结果快照点TSO值为 TSO2 INSERT INTO tb1 (id, a) VALUES (2, 2);
查询行存快照示例:
SELECT * FROM tb1 AS OF TSO {TSO1} ORDER BY id; -- 预期出现 (0, 0) SELECT * FROM tb1 AS OF TSO {TSO2} ORDER BY id; -- 预期出现 (0, 0), (1, 1) SELECT * FROM tb1 ORDER BY id; -- 预期出现 (0, 0), (1, 1), (2, 2)
使用
INSERT SELECT AS OF TSO
恢复数据,示例如下:CREATE TABLE tb1_tmp ( id INT PRIMARY KEY, a INT, gmt_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, gmt_modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) PARTITION BY KEY(id); -- 使用行存快照恢复数据 INSERT INTO tb1_tmp SELECT * FROM tb1 AS OF TSO {TSO} FORCE INDEX(PRIMARY);