TiDB 事務(wù)限制詳解

在2.1及之前的 TiDB 版本中浇冰,對于事務(wù)的限制是和其他關(guān)系型數(shù)據(jù)庫而言比較特殊的地方贬媒,很多用戶在使用過程中總是會感覺比較困惑,本文針對事務(wù)限制做一些詳細(xì)的說明肘习,希望能夠幫助大家理解际乘。

官方定義

由于 TiDB 分布式兩階段提交的要求,修改數(shù)據(jù)的大事務(wù)可能會出現(xiàn)一些問題漂佩。因此脖含,TiDB 特意對事務(wù)大小設(shè)置了一些限制以減少這種影響:

每個鍵值對不超過 6MB

鍵值對的總數(shù)不超過 300,000

鍵值對的總大小不超過 100MB

詳見PingCAP 官方文檔罪塔,https://pingcap.com/docs-cn/sql/mysql-compatibility/


相信鍵值對應(yīng)該比較容易理解,畢竟 TiDB 底層存儲選用的是 rocksdb 引擎养葵,一種基于 key-value 的存儲結(jié)構(gòu)征堪。而每個鍵值對的大小和總大小限制分別是6MB 和100MB,這個應(yīng)該也比較容易理解关拒。關(guān)鍵在于每個事物包含鍵值對的總數(shù)不超過30W 這個經(jīng)常會引起一些誤解佃蚜,下面做一些詳細(xì)說明。

如何理解30W

很多人第一眼看上去着绊,以為是一個事務(wù)涉及的行數(shù)不能超過30W谐算,但其實不是這樣的,首先需要了解 TiKV 對于結(jié)構(gòu)化數(shù)據(jù)是如何轉(zhuǎn)化為 key-value 結(jié)構(gòu)存儲的归露。

對于 key-value 結(jié)構(gòu)的數(shù)據(jù)洲脂,可以認(rèn)為結(jié)構(gòu)如下

當(dāng)插入一條數(shù)據(jù)時,tikv 是如何記錄這條數(shù)據(jù)呢剧包,包含以下幾個步驟:

1恐锦、插入數(shù)據(jù)本身

2、插入唯一索引

3疆液、插入普通索引

綜上踩蔚,當(dāng)執(zhí)行 insert 事務(wù)時,30W 限制需要除以所有索引的數(shù)量(包含主鍵和唯一索引)枚粘。


下面考慮當(dāng)刪除一條數(shù)據(jù)時馅闽,tikv 是如何處理的。首先需要明確馍迄,rocksdb 引擎所有的操作都是新增福也,所以刪除也是插入,只是插入了一條 flag = del 的記錄攀圈,具體情況如下:

1暴凑、插入數(shù)據(jù)本身的刪除標(biāo)記

2、插入唯一索引的刪除標(biāo)記

3赘来、插入普通索引的刪除標(biāo)記

綜上现喳,當(dāng)執(zhí)行delete 事務(wù)時,30W 限制需要除以所有索引的數(shù)量(包含主鍵和唯一索引)犬辰。


更新比較復(fù)雜嗦篱,放到最后來說明。首先來看幌缝,更新的是非主鍵且無索引字段的情況灸促。

這種情況,只需要修改記錄本身的內(nèi)容即可,也就是下面一步:

1浴栽、插入數(shù)據(jù)本身即可

綜上荒叼,非主鍵且無索引字段更新,30W 限制就是30W典鸡。


其次被廓,來看更新的是非主鍵,但包含索引的字段情況萝玷。

1伊者、數(shù)據(jù)本身

2、如果更新字段上有唯一索引

3间护、如果更新字段上有普通索引

綜上亦渗,非主鍵但索引相關(guān)字段的更新,30W 限制需要除以(1 + 字段涉及索引數(shù)量 * 2)汁尺。


最后來看當(dāng)更新的是主鍵字段的情況法精。從上面插入的描述中可以看出,無論是數(shù)據(jù)本身痴突,還是索引搂蜓,都包含了 pk,所以主鍵更新會觸發(fā)所有的key 更新辽装,具體如下:

1帮碰、數(shù)據(jù)本身

2、所有的唯一索引

3拾积、所有的普通索引

綜上殉挽,主鍵字段的更新,30W 限制需要除以(所有索引的數(shù)量 * 2)拓巧。

30W 鍵值對的轉(zhuǎn)換

總結(jié)如下:

具體案例:

CREATE TABLE `t1` (

? `id` int(11) NOT NULL AUTO_INCREMENT,

? `name` char(10) CHARSET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,

? `age` int(11) DEFAULT NULL,

? PRIMARY KEY (`id`),

? KEY `idx_name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

以上面的簡單表結(jié)構(gòu)為例斯碌,該表有自增主鍵,外加1個普通索引肛度,那么上面的事務(wù)限制對應(yīng)的記錄數(shù)為


事務(wù)的其他限制

除了上面 rocksdb 層的限制意外傻唾,tidb 中對于事務(wù)還有另外一個限制

1、參數(shù) stmt-count-limit承耿,默認(rèn)值是5000冠骄。

StmtCountLimit limits the max count of statement inside a transaction.

也就是一個事務(wù)里面,默認(rèn)最多包含5000條 SQL statement加袋,在不超過上面 rocksdb 層的幾個限制的前提下凛辣,這個參數(shù)可以修改 tidb 的配置文件進(jìn)行調(diào)整。


2锁荔、另外在某些場景下蟀给,例如執(zhí)行insert into? select 的時候蝙砌,可能會遇到下面的報錯

ERROR 1105 (HY000): BatchInsert failed with error: [try again later]: con:3877 txn takes too much time, start: 405023027269206017, commit: 405023312534306817????

這個主要是有一個隱藏參數(shù)阳堕,max-txn-time-use跋理,默認(rèn)值是 gc_life_time - 10s,也就是590

具體參考 PingCAP GitHub 上的文檔:https://github.com/pingcap/tidb/blob/master/config/config.toml.example#L240

# The max time a Txn may use (in seconds) from its startTS to commitTS.# We use it to guarantee GC worker will not influence any active txn. Please make sure that this# value is less than gc_life_time - 10s.

所以我們要盡量保證一個事務(wù)在這個gc_life_time - 10s 的時間內(nèi)完成恬总,也可以通過調(diào)整 gc 時間 + 修改這個參數(shù)來避免這個問題前普,可能 tidb 的配置文件中沒有放出這個參數(shù),可以手動編輯壹堰,加入這個值拭卿。當(dāng)然了,更好的辦法應(yīng)該是開啟 tidb_batch_insert 參數(shù)來規(guī)避單個事務(wù)過大的問題贱纠。

如何繞開大事務(wù)的限制

官方提供內(nèi)部 batch 的方法峻厚,來繞過大事務(wù)的限制,分別由三個參數(shù)來控制:

tidb_batch_insert

作用域: SESSION默認(rèn)值: 0這個變量用來設(shè)置是否自動切分插入數(shù)據(jù)谆焊。僅在 autocommit 開啟時有效惠桃。 當(dāng)插入大量數(shù)據(jù)時,可以將其設(shè)置為 true辖试,這樣插入數(shù)據(jù)會被自動切分為多個 batch辜王,每個 batch 使用一個單獨的事務(wù)進(jìn)行插入。

tidb_batch_delete

作用域: SESSION默認(rèn)值: 0這個變量用來設(shè)置是否自動切分待刪除的數(shù)據(jù)罐孝。僅在 autocommit 開啟時有效呐馆。 當(dāng)刪除大量數(shù)據(jù)時,可以將其設(shè)置為 true莲兢,這樣待刪除數(shù)據(jù)會被自動切分為多個 batch汹来,每個 batch 使用一個單獨的事務(wù)進(jìn)行刪除。

tidb_dml_batch_size

作用域: SESSION默認(rèn)值: 20000這個變量用來設(shè)置自動切分插入/待刪除數(shù)據(jù)的的 batch 大小改艇。僅在 tidb_batch_insert 或 tidb_batch_delete 開啟時有效俗慈。 需要注意的是,當(dāng)單行總數(shù)據(jù)大小很大時遣耍,20k 行總數(shù)據(jù)量數(shù)據(jù)會超過單個事務(wù)大小限制闺阱。因此在這種情況下,用戶應(yīng)當(dāng)將其設(shè)置為一個較小的值舵变。

針對 update 場景酣溃,官方還是建議通過 limit 的方式來循環(huán)操作,目前并未提供內(nèi)部 batch update 的參數(shù)開關(guān)纪隙。

需要注意的是赊豌,開啟了 batch 功能之后,大事務(wù)的完整性就沒法保證了绵咱,只能保證每個批次的事務(wù)完整性碘饼。當(dāng)然,數(shù)據(jù)庫的最佳實踐依然是由程序或 DBA 來控制事務(wù)的大小,尤其是針對分布式數(shù)據(jù)庫艾恼,建議每個batch 控制在100條左右住涉,高并發(fā)的寫入,同時避免熱點現(xiàn)象钠绍,才能發(fā)揮TiDB? 分布式的優(yōu)勢舆声。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市柳爽,隨后出現(xiàn)的幾起案子媳握,更是在濱河造成了極大的恐慌,老刑警劉巖磷脯,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛾找,死亡現(xiàn)場離奇詭異,居然都是意外死亡赵誓,警方通過查閱死者的電腦和手機打毛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來架曹,“玉大人隘冲,你說我怎么就攤上這事“笮郏” “怎么了展辞?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長万牺。 經(jīng)常有香客問我罗珍,道長,這世上最難降的妖魔是什么脚粟? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任覆旱,我火速辦了婚禮,結(jié)果婚禮上核无,老公的妹妹穿的比我還像新娘扣唱。我一直安慰自己,他們只是感情好团南,可當(dāng)我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布噪沙。 她就那樣靜靜地躺著,像睡著了一般吐根。 火紅的嫁衣襯著肌膚如雪正歼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天拷橘,我揣著相機與錄音局义,去河邊找鬼喜爷。 笑死,一個胖子當(dāng)著我的面吹牛萄唇,可吹牛的內(nèi)容都是我干的檩帐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼穷绵,長吁一口氣:“原來是場噩夢啊……” “哼轿塔!你這毒婦竟也來了特愿?” 一聲冷哼從身側(cè)響起仲墨,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎揍障,沒想到半個月后目养,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡毒嫡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年癌蚁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兜畸。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡努释,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咬摇,到底是詐尸還是另有隱情伐蒂,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布肛鹏,位于F島的核電站逸邦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏在扰。R本人自食惡果不足惜缕减,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芒珠。 院中可真熱鬧桥狡,春花似錦、人聲如沸皱卓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽好爬。三九已至局雄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間存炮,已是汗流浹背炬搭。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工蜈漓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人宫盔。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓融虽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灼芭。 傳聞我的和親對象是個殘疾皇子有额,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容