更新時間:2023-01-14 來源:黑馬程序員 瀏覽量:
支持讀取歷史版本數據, 引入了一個新的 system variable: tidb_snapshot ,這個變量是 Session 范圍有效,可以通過標準的 Set 語句修改其值。其值為文本,能夠存儲 TSO 和日期時間。TSO 即是全局授時的時間戳,是從 PD 端獲取的; 日期時間的格式可以為: “2020-10-08 16:45:26.999”,一般來說可以只寫到秒,比如”2020-10-08 16:45:26”。 當這個變量被設置時,TiDB 會用這個時間戳建立 Snapshot(沒有開銷,只是創(chuàng)建數據結構),隨后所有的 Select 操作都會在這個 Snapshot 上讀取數據。
注意:TiDB 的事務是通過 PD 進行全局授時,所以存儲的數據版本也是以 PD 所授時間戳作為版本號。在生成 Snapshot 時,是以 tidb_snapshot 變量的值作為版本號,如果 TiDB Server 所在機器和 PD Server 所在機器的本地時間相差較大,需要以 PD 的時間為準。
當讀取歷史版本操作結束后,可以結束當前 Session 或者是通過 Set 語句將 tidb_snapshot 變量的值設為 “",即可讀取最新版本的數據。
TiDB 使用 MVCC 管理版本,當更新/刪除數據時,不會做真正的數據刪除,只會添加一個新版本數據,所以可以保留歷史數據。歷史數據不會全部保留,超過一定時間的歷史數據會被徹底刪除,以減小空間占用以及避免歷史版本過多引入的性能開銷。
TiDB 使用周期性運行的 GC(Garbage Collection,垃圾回收)來進行清理,關于 GC 的詳細介紹參見 TiDB 垃圾回收 (GC)。
這里需要重點關注的是 tikv_gc_life_time 和 tikv_gc_safe_point 這條。tikv_gc_life_time
用于配置歷史版本保留時間,可以手動修改;tikv_gc_safe_point 記錄了當前的 safePoint,用戶可以安全地使用大于 safePoint
的時間戳創(chuàng)建 snapshot 讀取歷史版本。safePoint 在每次 GC 開始運行時自動更新。
1.初始化階段,創(chuàng)建一個表,并插入幾行數據:
create table t (c int); insert into t values (1), (2), (3);
2.查看表中的數據:
select * from t; +------+ | c | +------+ | 1 | | 2 | | 3 | +------+
3.查看當前時間:
select now(); +---------------------+ | now() | +---------------------+ | 2020-02-02 16:45:26 | +---------------------+
4.更新某一行數據:
update t set c=22 where c=2;
5.確認數據已經被更新:
select * from t; +------+ | c | +------+ | 1 | | 22 | | 3 | +------+
6.設置一個特殊的環(huán)境變量,這個是一個 session scope 的變量,其意義為讀取這個時間之前的最新的一個版本。
set @@tidb_snapshot="2020-02-02 16:45:26";
注意:這里的時間設置的是 update 語句之前的那個時間。在 tidb_snapshot 前須使用 @@ 而非 @,因為 @@ 表示系統(tǒng)變量,@ 表示用戶變量。
7.這里讀取到的內容即為 update 之前的內容,也就是歷史版本:
select * from t; +------+ | c | +------+ | 1 | | 2 | | 3 | +------+
8.清空這個變量后,即可讀取最新版本數據:
set @@tidb_snapshot=""; select * from t; +------+ | c | +------+ | 1 | | 22 | | 3 | +------+
注意:在 tidb_snapshot 前須使用 @@ 而非 @,因為 @@ 表示系統(tǒng)變量,@ 表示用戶變量。