當(dāng)發(fā)生轉(zhuǎn)儲(chǔ)和合并時(shí)多版本數(shù)據(jù)會(huì)被如何處理筷狼?
- 轉(zhuǎn)儲(chǔ)的時(shí)候會(huì)根據(jù)參數(shù) undo_retention 來決定保留多久的多版本數(shù)據(jù)瓶籽,默認(rèn) 1800 秒,超出時(shí)間的多版本數(shù)據(jù)會(huì)在轉(zhuǎn)儲(chǔ)時(shí)刪除埂材,如果還有事務(wù)要讀取被刪除的版本塑顺,會(huì)失敗。
- 不止轉(zhuǎn)儲(chǔ)時(shí)會(huì)刪俏险,mini minor merge茬暇、minor merge 時(shí)也會(huì)刪超出undo_retention時(shí)間的多版本數(shù)據(jù)
- 在合并時(shí),Major SSTable 只會(huì)保留最新版本的數(shù)據(jù)寡喝,并根據(jù) undo_retention 的值來決定是否保留上層 Mini SSTable、Minor SSTable 中的多版本
這會(huì)帶來一個(gè)問題:如果有一個(gè)事務(wù)需要讀取舊版本數(shù)據(jù)勒奇,可能會(huì)因?yàn)槎喟姹緮?shù)據(jù)被清理了無法讀取成功预鬓。
V4.1版本做調(diào)整,多版本數(shù)據(jù)上有一個(gè)引用計(jì)數(shù)器赊颠,當(dāng)引用計(jì)數(shù)器為 0(也就是沒有被任何事務(wù)讀雀穸)才會(huì)被刪除。不過竣蹦,數(shù)據(jù)盤滿的場景是例外顶猜,此時(shí)還是會(huì)強(qiáng)制刪除舊版本數(shù)據(jù)。
驗(yàn)證方法
下面設(shè)計(jì)一個(gè)實(shí)驗(yàn)進(jìn)行驗(yàn)證(V3 版本):
- 先觸發(fā)一次合并痘括,并將 undo_retention 設(shè)置成一個(gè)較小的值
alter system set max_kept_major_version_number=1;
alter system major freeze;
set global undo_retention=120;
- session1 開啟 serializable 隔離級(jí)別事務(wù)长窄,查詢表 tab_no_queue
set transaction_isolation='serializable';
start transaction;
select * from tab_no_queue where rownum<10;
- session2 更新表 tab_no_queue并提交
set transaction_isolation='serializable';
update tab_no_queue set ADDR='0' where mod(id,5) in (4);
commit;
- 等待 120 秒,session3 轉(zhuǎn)儲(chǔ) tab_no_queue 表
alter system minor freeze partition_id='0%0@1100611139453789';
查看轉(zhuǎn)儲(chǔ)完成纲菌,并且只發(fā)生 mini merge(也就是將 memtable 寫到磁盤的 mini sstable):- session1 再次執(zhí)行同樣的查詢