CockroachDB学习笔记——[译]在CockroachDB中如何让在线模式更改成为可能
- 原文鏈接:https://www.cockroachlabs.com/blog/how-online-schema-changes-are-possible-in-cockroachdb/
- 原作者: Vivek Menezes
- 原文日期:Jan 20, 2016
- 譯:zifeiy
—— Stack Overflow serverfault 1
上面的問題在2010年發布,但是關于模式改變的停頓的焦慮仍然存在。
當我們在設計CockroachDB的模式改變引擎(schema change engine)的時候,我們希望更好地構建它。
我們希望提供一種更新表模式(只需運行alter table命令)的簡單方法,而不必讓應用程序遭受任何負面后果——包括停機時間。
我們希望模式更改是CockroachDB的內置特性,不需要額外的工具、資源或操作的自組織排序;
并且所有這些,對應用程序的讀/寫延遲沒有影響。
在這篇文章中,我將解釋我們的在線模式改變策略。
我將討論如何管理對架構元素(如列和索引)的更改,而不必強制停機。
這就是我們所做的
模式更改涉及更新模式以及添加或刪除與該更改相關聯的表數據。
兩個基本的分布式數據庫特性使得這一點特別棘手:
我們用于 維護一致的分布式模式緩存以及一致表數據 擁抱著 同時發生的模式的多個版本,我們可以在使用舊模式的同時推出我們的新的模式。
(譯者的理解:他可能是先繼續維護舊的模式,然后新建一個新的模式,然后再一步步地往新的模式里面填舊的模式里面的數據,當然這個時候新的模式里面的數據也會變動,反正就是一點一點的往舊的模式靠,等到某一個時間點和舊的模式保持同步了,好!立馬拋棄舊的模式,啟用新的模式。)
它在不持有鎖的情況下回填(或刪除)基礎表數據。
這個解決方案是由谷歌F1團隊所做的工作得出的。
安全模式展開(Safe schema rollout)
一個schema元素(它可以是索引或列,雖然在這篇文章的其余部分,我們將重點放在索引的情況下),有相關的數據,這些數據可以被SQL DML命令刪除、寫入或讀取(例如,插入INSERT、更新UPDATE、刪除DELETE、選擇SELECT)。
CockroachDB采用的策略是首次展現(rollout)一個新的索引,包括對這些DML命令進行刪除、寫入和讀取功能,一個接一個地以分級的方式,而不是同時進行。
添加一個新的索引遵循如下所述的離散階段:
在新版本的架構中,一個能力與所有先前授予的能力一起被授予。
為了正確起見,只有在整個集群使用包含所有先前授予的能力的架構之后,才可以授予新的能力。
因此,該過程在每個階段之前暫停,允許先前授予的功能在下一個功能可以被授予之前傳播到整個集群。
刪除索引按照相反的方向進行:
類似地,只有在前一個功能在整個群集上的撤銷傳播完之后才撤銷當前的功能。
刪除能力(Delete capability):避免虛假索引條目
通過將索引置于 DELETE_ONLY 狀態,來賦予這種功能。
擁有這種能力,SQL DML命令限制了他們自己:
- 刪除(DELETE)是完全有效的刪除行連同基礎索引數據。
- 更新(UPDATE)刪除舊索引條目,但限制自身不寫入新的條目。
- 插入(INSERT)和選擇(SELECT)忽略索引。
在下一階段授予索引的寫入能力的節點可以信任整個集群使用索引的刪除能力。
因此,當它接收到插入命令并插入一個行的索引條目時,另一個只有刪除能力的節點在看到同一行的刪除命令時,將正確刪除行的索引條目。
該索引將避免因懸空索引條目而中毒。
當模式改變丟棄索引時,僅在成功地將寫入能力撤回群集之后清除關聯索引數據;
整個集群只有刪除能力,允許安全清除。
寫入(Write capability)能力:避免丟失索引條目
這種能力是通過將索引放置在 WRITE_AND_DELETE_ONLY 狀態,授予刪除和寫入能力來實現的。
- 插入(INSERT)、更新(UPDATE)和刪除(DELETE)命令正常運行,根據需要添加或刪除索引項。
- 另一方面,選擇(SELECT)需要讀取能力,而忽略索引。
索引回填僅在整個群集能夠寫入之后才運行。
在回填過程中,在任何節點上接收的插入命令創建具有合法索引項的新行,并且不依賴于單獨的回填過程來創建行的索引條目。
回填完成后,將不會有缺失的索引條目。
讀取能力(Read capability)
這最后一個能力是通過使索引激活而授予的,并通過所有命令打開索引的完整使用。
快速模式展開(Fast schema rollout)
在模式更改過程的每個階段之間,允許整個集群收斂到表模式的最新版本。
一個簡單的模式緩存機制可能會使用5分鐘的TTL,但是這會迫使模式改變過程等待許多分鐘,然后才相信最新的版本是唯一的一個具有活躍狀態的和完全授予/撤銷的能力的版本。
在 CockroachDB 中,我們在模式版本上開發了租約(leases),以加快集群收斂到最新的模式版本,這又加速了模式改變過程。
在使用SQL DML命令的表模式之前,運行該命令的節點自一段重要的時間內獲得該模式的讀取租約(以分鐘為單位)。
當更新的表架構版本變為活動時,它將在整個集群上廣播,向新版本通知節點并使它們主動釋放舊版本上的租約。
如果某些節點不健康并且不主動釋放它們的租約,則 rollout 將等待租約過期,并將被延遲。
我們通過遵循以下兩條規則來讓模式更改策略變得簡單:
- 新租約只授予最新的模式版本。
- 有效租約只在兩個最新的模式版本上。
有關表租約的更詳細討論,請參見我們在Github倉庫上的RFC文檔。
可靠的模式展開(Reliable schema rollout)
模式更改由執行模式更改SQL命令的節點引導完成。
由于模式更改操作可能長時間運行,所以當執行它們的節點死亡時,它們需要重新啟動。
每個節點運行一個模式轉換器 goroutine,它能夠運行任何不完整的模式更改。
在執行模式更改之前,模式更改器 goroutine 首先獲取表上的獨占寫入租約,使其成為唯一指導模式更改的許可。
總結
在 CockroachDB 中,在線模式更改使用起來是很簡單的,模式更改展開的處理也是方便、快速和可靠的。
改變是不可避免的,現在是你不必擔心的時候了!
我們要感謝來自谷歌F1團隊的人們發布 在線模式更改 的類似實現,從中我們獲得了很多靈感。
Apptree. Stack Overflow. “Modifying columns of a very large mysql table with little or no downtime.” August 26, 2010.
轉載于:https://www.cnblogs.com/zifeiy/p/9315877.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的CockroachDB学习笔记——[译]在CockroachDB中如何让在线模式更改成为可能的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 结缘爬虫-序
- 下一篇: POJ 1185 炮兵阵地(状压DP)题