首頁(yè)教研故事正文

TiDB-讀取歷史數(shù)據(jù)的操作流程

更新時(shí)間:2022-08-16 來(lái)源:黑馬程序員 瀏覽量:

接下來(lái)介紹 TiDB 如何讀取歷史版本數(shù)據(jù),包括具體的操作流程以及歷史數(shù)據(jù)的保存策略。

1. 功能說(shuō)明

TiDB 實(shí)現(xiàn)了通過(guò)標(biāo)準(zhǔn) SQL 接口讀取歷史數(shù)據(jù)功能,無(wú)需特殊的 client 或者 driver。當(dāng)數(shù)據(jù)被更新、刪除后,依然可以通過(guò) SQL 接口將更新/刪除前的數(shù)據(jù)讀取出來(lái)。

另外即使在更新數(shù)據(jù)之后,表結(jié)構(gòu)發(fā)生了變化,TiDB 依舊能用舊的表結(jié)構(gòu)將數(shù)據(jù)讀取出來(lái)。

2. 操作流程

為支持讀取歷史版本數(shù)據(jù), 引入了一個(gè)新的 system variable: tidb_snapshot ,這個(gè)變量是 Session 范圍有效,可以通過(guò)標(biāo)準(zhǔn)的 Set 語(yǔ)句修改其值。其值為文本,能夠存儲(chǔ) TSO 和日期時(shí)間。TSO 即是全局授時(shí)的時(shí)間戳,是從 PD 端獲取的; 日期時(shí)間的格式可以為: “2020-10-08 16:45:26.999”,一般來(lái)說(shuō)可以只寫到秒,比如”2020-10-08 16:45:26”。 當(dāng)這個(gè)變量被設(shè)置時(shí),TiDB 會(huì)用這個(gè)時(shí)間戳建立 Snapshot(沒(méi)有開(kāi)銷,只是創(chuàng)建數(shù)據(jù)結(jié)構(gòu)),隨后所有的 Select 操作都會(huì)在這個(gè) Snapshot 上讀取數(shù)據(jù)。

注意:

TiDB 的事務(wù)是通過(guò) PD 進(jìn)行全局授時(shí),所以存儲(chǔ)的數(shù)據(jù)版本也是以 PD 所授時(shí)間戳作為版本號(hào)。在生成 Snapshot 時(shí),是以 tidb_snapshot 變量的值作為版本號(hào),如果 TiDB Server 所在機(jī)器和 PD Server 所在機(jī)器的本地時(shí)間相差較大,需要以 PD 的時(shí)間為準(zhǔn)。

當(dāng)讀取歷史版本操作結(jié)束后,可以結(jié)束當(dāng)前 Session 或者是通過(guò) Set 語(yǔ)句將 tidb_snapshot 變量的值設(shè)為 “",即可讀取最新版本的數(shù)據(jù)。

3. 歷史數(shù)據(jù)保留策略

TiDB 使用 MVCC 管理版本,當(dāng)更新/刪除數(shù)據(jù)時(shí),不會(huì)做真正的數(shù)據(jù)刪除,只會(huì)添加一個(gè)新版本數(shù)據(jù),所以可以保留歷史數(shù)據(jù)。歷史數(shù)據(jù)不會(huì)全部保留,超過(guò)一定時(shí)間的歷史數(shù)據(jù)會(huì)被徹底刪除,以減小空間占用以及避免歷史版本過(guò)多引入的性能開(kāi)銷。

TiDB 使用周期性運(yùn)行的 GC(Garbage Collection,垃圾回收)來(lái)進(jìn)行清理,關(guān)于 GC 的詳細(xì)介紹參見(jiàn) TiDB 垃圾回收 (GC)。

這里需要重點(diǎn)關(guān)注的是 tikv_gc_life_time 和 tikv_gc_safe_point 這條。tikv_gc_life_time 用于配置歷史版本保留時(shí)間,可以手動(dòng)修改;tikv_gc_safe_point 記錄了當(dāng)前的 safePoint,用戶可以安全地使用大于 safePoint 的時(shí)間戳創(chuàng)建 snapshot 讀取歷史版本。safePoint 在每次 GC 開(kāi)始運(yùn)行時(shí)自動(dòng)更新。

操作示例:

①初始化階段,創(chuàng)建一個(gè)表,并插入幾行數(shù)據(jù):

create table t (c int);
insert into t values (1), (2), (3);

②查看表中的數(shù)據(jù):

select * from t;
+------+
| c    |
+------+
|    1 |
|    2 |
|    3 |
+------+

③查看當(dāng)前時(shí)間:

select now();
+---------------------+
| now()               |
+---------------------+
| 2020-02-02 16:45:26 |
+---------------------+

④更新某一行數(shù)據(jù):

update t set c=22 where c=2;

⑤確認(rèn)數(shù)據(jù)已經(jīng)被更新:

select * from t;
+------+
| c    |
+------+
|    1 |
|   22 |
|    3 |
+------+

⑥設(shè)置一個(gè)特殊的環(huán)境變量,這個(gè)是一個(gè) session scope 的變量,其意義為讀取這個(gè)時(shí)間之前的最新的一個(gè)版本。

set @@tidb_snapshot="2020-02-02 16:45:26";

注意:

這里的時(shí)間設(shè)置的是 update 語(yǔ)句之前的那個(gè)時(shí)間。

在 tidb_snapshot 前須使用 @@ 而非 @,因?yàn)?@@ 表示系統(tǒng)變量,@ 表示用戶變量。

⑦這里讀取到的內(nèi)容即為 update 之前的內(nèi)容,也就是歷史版本:

select * from t;
+------+
| c    |
+------+
|    1 |
|    2 |
|    3 |
+------+

⑧清空這個(gè)變量后,即可讀取最新版本數(shù)據(jù):

set @@tidb_snapshot="";
select * from t;
+------+
| c    |
+------+
|    1 |
|   22 |
|    3 |
+------+

注意:

在 tidb_snapshot 前須使用 @@ 而非 @,因?yàn)?@@ 表示系統(tǒng)變量,@ 表示用戶變量。


分享到:

Java培訓(xùn)班課程javaee

Python培訓(xùn)機(jī)構(gòu)python大數(shù)據(jù)

web前端培訓(xùn)課程升級(jí)V8.5web

AI+設(shè)計(jì)培訓(xùn)課程ui

大數(shù)據(jù)培訓(xùn)課程cloud

軟件測(cè)試培訓(xùn)課程test

c

新媒體運(yùn)營(yíng)培訓(xùn)netmarket

產(chǎn)品經(jīng)理培訓(xùn)課程pm

linux培訓(xùn)Linux

movies

智能機(jī)器人培訓(xùn)robot

電商視覺(jué)設(shè)計(jì)課程uids

AI

集成電路應(yīng)用開(kāi)發(fā)(嵌入式)培訓(xùn)課程jdbc

選擇校區(qū)
北京校區(qū)