postgresql create index concurrently過程描述

chenfeng發表於2021-04-06

PostgreSQL支援在不鎖定寫入的情況下建立索引。透過指定的concurrently選項來呼叫此方法create index。使用

此選項時,PostgreSQL必須對錶進行兩次掃描,此外,它還必須等待所有可能修改或使用索引終止的現有事務。

因此,此方法比標準索引構建需要更多的總工作量,並且需要花費更長的時間才能完成。但是,由於它允許在建立索引的同時

繼續進行正常操作,因此該方法對於在生產環境中新增新索引很有用。當然,索引建立所帶來的 額外CPU和I / O負載可能會減慢其他操作的速度。


在併發索引構建中,實際上是透過一個事務將索引輸入到系統目錄中,然後在另外兩個事務中進行兩次表掃描。在每個表掃描

之前,索引構建必須等待修改該表的現有事務終止。在第二次掃描之後,索引構建必須等待在第二次 掃描之前終止具有快照的所有事務,如果涉及的索引是部分索引或其他索引,則包括在其他表上的併發索引構建的任何階段

使用的事務。具有不是簡單列引用的列。然後,最後可以將索引標記為可以使用了,

並且CREATE INDEX命令終止。但是,即使那樣,索引也可能無法立即用於查詢:在最壞的情況下,只要存在早於索引構建

開始的事務,就不能使用該索引。


使用create index concurrently建立索引,主要分為三個階段,掃描兩次TABLE。


create index concurrently idx_b_2 on b (id);    

階段如下:


1、開啟事務1,拿到當前snapshot1。


2、掃描B表前,等待所有修改過B表(寫入、刪除、更新)的事務結束。


3、掃描B表,並建立索引。


4、結束事務1。


5、開啟事務2,拿到當前snapshot2。


6、再次掃描B表前,等待所有修改過B表(寫入、刪除、更新)的事務結束。


7、在snapshot2之後啟動的事務對B表執行的DML,會修改這個idx_b_2的索引。


8、再次掃描B表,更新索引。(從TUPLE中可以拿到版本號,在snapshot1到snapshot2之間變更的記錄,將其合併到索引)


9、上一步更新索引結束後,等待事務2之前開啟的持有snapshot的事務結束。


10、結束索引建立。索引可見。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-2766634/,如需轉載,請註明出處,否則將追究法律責任。

相關文章