本文為您介紹行存快照功能的特點以及如何使用行存快照查詢歷史數據。
版本限制
實例版本需為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);