閱讀732 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Greenplum列存壓縮表事務機製

事務隔離級別

我們知道Heap表的事務隔離是通過MVCC實現,但是在列存表沒有記錄xmin,xmax等多版本信息,僅僅記錄了塊的元信息以及數據,那麼它是如何實現事務隔離的?
仍然借助於Heap表,沒創建一個列存表,同時創建一個heap輔助表表,通過select * from pg_appendonly可以看到輔助表的OID(segrelid),這個輔助表幾麵記錄了什麼呢?

typedef struct AOCSVPInfoEntry
{
        int64 eof;
        int64 eof_uncompressed;
} AOCSVPInfoEntry;

從這個結構體可以看出來,輔助表記錄了當前事務在列存文件中可見的結尾偏移量。如果其他連接插入了數據,列存文件變大了,但是當前事務還是隻能看到插入之前的結尾偏移量,多餘的數據是看不到的。

如圖所示,B事務新增的數據的EOF位置存在Heap表中,而Heap表滿足MVCC的,所以A事務看不到B事務中Heap表的變更,繼續使用A事務開始的是EOF。

6d16bfce2db5e8e9.png

總之,列存的事務原理是靠輔助Heap表實現的。

崩潰恢複

機器可能宕機、斷電等,事務需要回滾,數據可能部分寫,對於這些場景Greenplum列存是如何處理的呢?

cancel/kill等引起的正常事務回滾

在Greenplum列存表原理裏麵我們已經提到,並發導入是靠多個文件實現,也就是說每個Insert連接隻會負責一個列文件,假設事務開始的時候文件EOF為EOF_start, 導入後變成EOF_end,如果事務回滾,輔助Heap表裏麵記錄的EOF回滾到事務開始的EOF_start,回滾完成。下次事務導入將會從EOF_start繼續增加數據,覆蓋EOF_start--EOF_end之間的數據。

數據部分寫

Greenplum列存表是不寫XLOG的,那麼它是如何做到崩潰之後恢複的呢?

  • 每次commit提交強製做fsync,所以隻要事務提交,那麼磁盤數據就是一致的,崩潰恢複不影響。
  • 新的事務導入數據,強製新增block,不能使用上一個事務的block,即便上一個事務的block還沒有寫滿。這樣就不會存在複用上一個事務block寫數據時寫到一半出問題丟失上個事務block的數據。因此強烈不建議使用每次insert一條方式導入數據,這樣會產生的大量的block,每條記錄都對一個block,影響掃描性能。

最後更新:2017-08-15 15:32:27

  上一篇:go  雲服務器 ECS 實例自定義數據:自定義實例的管理員賬號
  下一篇:go  世平敏感信息安全檢查係統雲端版登陸阿裏雲市場