1. 程式人生 > >Greenplum的MVCC多版本控制的簡單介紹(主要涉及cmin,cmax,xmin,xmax說明)

Greenplum的MVCC多版本控制的簡單介紹(主要涉及cmin,cmax,xmin,xmax說明)

熟悉Greenplum資料庫的朋友應該都知道,GP底層是使用PostgreSQL資料庫來實行MPP架構的,而對於事務控制這一塊,也是使用PostgreSQL的多版本控制MVCC,實現了讀寫分離,顯然就會提高資料庫每秒查詢的效能。

在Read Commit事務隔離級別時,查詢請求只讀取查詢請求之前已經提交的事務的資料更改,對當前版本的資料並不影響;

而DML語句,會操作當前版本。因此做到了讀寫分離的目的,提高資料庫併發能力。

我們先來回顧一下PostgreSQL裡面的MVCC多版本控制。

在PostgreSQL中,每一個事務都會得到一個被稱作為 XID 的事務ID。這裡說的事務不僅僅是被 BEGIN - COMMIT 包裹的一組語句,還包括單條的insert、update或者delete語句。當一個事務開始時,PostgreSQL遞增XID,然後把它賦給這個事務。PostgreSQL還在系統裡的每一行記錄上都儲存了事務相關的資訊,這被用來判斷某一行記錄對於當前事務是否可見。舉個例子,當你插入一行記錄時,PostgreSQL會把當前事務的XID儲存在這一行中並稱之為 xmin。只有那些已提交的而且xmin比當前事務的XID小的記錄對當前事務才是可見的。這意味著,你可以開始一個新事務然後插入一行記錄,直到你提交( COMMIT )之前,你插入的這行記錄對其他事務永遠都是不可見的。等到提交以後,其他後建立的新事務就可以看到這行新記錄了,因為他們滿足了 xmin < XID 條件,而且建立那一行記錄的事務也已經完成。

對於 DELETE 和 UPDATE 來說,機制也是類似的,但不同的是對於它們PostgreSQL使用叫做 xmax 的值來判斷資料的可見性。這幅圖展示了在兩個併發的插入/讀取資料的事務中,MVCC在事務隔離方面是怎麼起作用的。

PostgreSQL使用xmin,xmax,cmin,cmax等標記來實現多版本,他們的含義為:

xmin:在建立記錄(tuple)時,記錄此時的事務id,後面每次update也會更新。

xmax: 在更新或刪除tuple或者lock時,記錄此時的事務id;如果記錄沒有被刪除,那麼此時為0。

cmin:插入該元組的命令在插入事務中的命令標識(從0開始累加)

cmax:刪除該元組的命令在插入事務中的命令標識(從0

開始累加)

但是對於Greenplum資料庫來說,它畢竟是基於多個postgres例項來實現MPP架構的資料庫,所以上面的標記的值可能與單個postgres有區別。下面我們示例中會說明。

#裝載資料,非並行,如果並行載入資料的話,可以考慮使用gpfdist或gpload等方式

zhangyun_db=# COPY test_mvcc from '/home/gpadmin/mvcc.txt' with delimiter as '|' null as '';

COPY 4

zhangyun_db=# select * from test_mvcc ;

id |   name   

----+-----------

4 | Hadoop

3 | Greenplum

2 | Hive

1 | Spark

(4 rows)

zhangyun_db=# select t.*, t.xmin, t.xmax, t.cmin, t.cmax from test_mvcc t;

id |    name    |  xmin  | xmax | cmin | cmax

----+------------+--------+------+------+------

8 | Flink      | 449908 |    0 |    0 |    0

4 | Hadoop     | 449906 |    0 |    0 |    0

5 | HBase      | 449775 |    0 |    0 |    0

7 | PostgreSQL | 457913 |    0 |    0 |    0

2 | Hive       | 449910 |    0 |    0 |    0

3 | Greenplum  | 449909 |    0 |    0 |    0

6 | HAWQ       | 449899 |    0 |    0 |    0

1 | Spark      | 449905 |    0 |    0 |    0

(8 rows)

從上圖可以看出,8條記錄的xmin是不一樣的(如果是PostgreSQL資料庫的話,這裡應該是一樣的,因為這些資料是通過同一個事務copy建立的)。

另外xmax都為0,說明資料自從匯入後就沒有被刪除。

下面我們來演示在Greenplum資料中執行update的情況:

請開啟兩個linux終端A和B,方便資料比對和檢視。

首先在終端A執行,但不提交:

zhangyun_db=# begin;

BEGIN

zhangyun_db=# update test_mvcc set name = 'Hive On Spark' where id = 2;

UPDATE 1

終端B檢視:

zhangyun_db=# select t.*, t.xmin, t.xmax, t.cmin, t.cmax from test_mvcc t;

id |    name    |  xmin  |  xmax  | cmin | cmax

----+------------+--------+--------+------+------

4 | Hadoop     | 449906 |      0 |    0 |    0

7 | PostgreSQL | 457913 |      0 |    0 |    0

6 | HAWQ       | 449899 |      0 |    0 |    0

2 | Hive       | 449910 | 450412 |    0 |    0

1 | Spark      | 449905 |      0 |    0 |    0

8 | Flink      | 449908 |      0 |    0 |    0

5 | HBase      | 449775 |      0 |    0 |    0

3 | Greenplum  | 449909 |      0 |    0 |    0

(8 rows)

可以看到,對於id為2的資料行的xmax發生了變化,但是資料本身是沒有變化的,因為終端A的事務還沒有提交。

接著,我們在終端A執行提交動作,如下:

zhangyun_db=# commit;

COMMIT

同時在終端B再檢視:

zhangyun_db=# select t.*, t.xmin, t.xmax, t.cmin, t.cmax from test_mvcc t;

id |     name      |  xmin  | xmax | cmin | cmax

----+---------------+--------+------+------+------

2 | Hive On Spark | 450412 |    0 |    0 |    0

6 | HAWQ          | 449899 |    0 |    0 |    0

5 | HBase         | 449775 |    0 |    0 |    0

7 | PostgreSQL    | 457913 |    0 |    0 |    0

4 | Hadoop        | 449906 |    0 |    0 |    0

3 | Greenplum     | 449909 |    0 |    0 |    0

8 | Flink         | 449908 |    0 |    0 |    0

1 | Spark         | 449905 |    0 |    0 |    0

(8 rows)

可以看到id為2的記錄,其xmin已經變化了。

根據上面的結果,不知道大家有沒有發現,對於Greenplum來說,更新或者刪除都沒有修改cmin和cmax的值。

在PostgreSQL中,cmin和cmax用於判斷同一個事務內的其他命令導致的行版本變更是否可見。如果一個事務內的所有命令嚴格順序執行,那麼每個命令總能看到之前該事務內的所有變更,不需要使用命令標識。然而一個事務記憶體在命令交替執行的情況,比如使用遊標進行查詢。Fetch遊標時看到的是宣告遊標時的資料快照而不是Fetch執行時,即宣告遊標後對資料的變更對該遊標不可見。

這一塊的內容,後續抽時間分析原始碼再寫一篇文章進行分析。

相關推薦

Greenplum的MVCC版本控制簡單介紹(主要涉及cmin,cmax,xmin,xmax說明)

熟悉Greenplum資料庫的朋友應該都知道,GP底層是使用PostgreSQL資料庫來實行MPP架構的,而對於事務控制這一塊,也是使用PostgreSQL的多版本控制MVCC,實現了讀寫分離,顯然就會

Postgres版本控制

hot tubple mvcc pg多版本控制 高並發控制肯定是數據必須達到的一個標準, 在並發操作中,對於同一個數據,同時讀和寫的兩個回話有可能產生不一致,所以出現了在高並發情況下如何保持性能又保持一致出現了MVCC,多版本並發實現MVCC的方法有兩種:1)寫數據時,將舊數據移到一個單獨的地

通過anaconda進行python版本控制

默認 創建 ins 版本控制 尋找 window 新版 需求 nbsp ---恢復內容開始--- linux與windows通用。 1. 假設電腦上已經轉好anaconda3. (anaconda 默認裝好了python3、jupyter、spyter) 2.

webpack版本控制方案

專案中有這麼一個需求,就是按需啟動mock功能。考慮到mock只是在特定情況下,所以考慮通過 cross-env 來處理。 cross-env修改生產環境變數 我想要的最終效果是npm run dev:mock 來啟動mock,所以先安裝 cross-env npm i --sa

Git: 一、版本控制系統介紹

版本控制 什麼是版本控制 版本控制是一套類似日誌系統,用來儲存檔案內容變更記錄的系統。 版本控制作用 版本控制可以幫助我們將檔案的修改記錄進行回溯到之前的狀態,然後,就可以對比檔案中的變化細節。 可以查到的資訊諸如:修改操作人、修改的檔案內容、修改時間等。 如果有

【mysql】--MVCC 版本控制

InnoDB的mvcc,是通過在每行記錄後面儲存兩個隱藏的列來實現的。這兩個列,一個儲存了行的建立時間,一個儲存行的過期時間(刪除時間)。儲存的並不是實際的時間,而是系統版本號。每一個新的事物,系統版本號都會遞增。 事物開始時刻的系統版本號會作為事務的版本號,用來和查詢到的每行記錄的版本號進行比

mysql版本控制-MVCC

一、定義 多版本控制: 指的是一種提高併發的技術。最早的資料庫系統,只有讀讀之間可以併發,讀寫,寫讀,寫寫都要阻塞。引入多版本之後,只有寫寫之間相互阻塞,其他三種操作都可以並行,這樣大幅度提高了InnoDB的併發度。在內部實現中,與Postgres在資料行上實現多版本不同,InnoDB是在und

從壹開始前後端分離 [.netCore 填坑 ] 三十四║Swagger:API版本控制,帶來的思考

前言 大家週二好呀,.net core + Vue 這一系列基本就到這裡差不多了,今天我又把整個系列的文章下邊的全部評論看了一下(我是不是很負責哈哈),提到的問題基本都解決了,還有一些問題,已經在QQ群裡討論過了,今天再寫一篇,然後給這個系列畫一個暫時的句號吧,這些天也考慮寫點兒啥,希望看到的小夥伴給點

Swagger版本控制實現

並不會 parameter 保持 bsp efault class nuget urn ati 最近前後端分離的項目越來越多,API的對接對於前後端開發交流得最多的一塊內容,一個好的API文檔生成工具就顯得非常重要,選取了Swagger文檔生成工具作為項目的文檔生成工具,考

web api 版本控制重要的兩個類

1、版本路徑替換 public class ReplaceVersionWithExactValueInPath : IDocumentFilter     {      &nb

web api 版本控制重要的兩個類

ram key ict parameter mov path The ace als 1、版本路徑替換 public class ReplaceVersionWithExactValueInPath : IDocumentFilter { publi

app版本控制的服務端解決方案

1.應用場景 手機客戶端按一定週期發版,但是客戶不一定會及時更新到最新版本,所以需要服務端能支援舊版手機客戶端。 服務端支援舊版手機客戶端的方式主要有: 相同的介面支援不同版本手機端的請求,需要服務端介面做好相容 相同的介面支援不同版本手機端的請求,但

c++的類的封裝/繼承/型的簡單介紹

 本篇文章僅僅從很表層來介紹一個C++語言中的類,包括什麼是類,類的封裝性/繼承性和多型性。高手直接跳過吧,看了浪費時間,新手或者想溫習一下的可以瀏覽看看。 1. 什麼是類? 到底什麼是類(class)??類就是一種型別,是使用者自己定義的一個型別,和內建型別如int/float/double類似,  用一

利用pyenv實現python的版本控制

多版本 人的 環境 bin installer python 版本 正常 配置環境變量 情況 在學習和利用python開發的很多情況下,需要多版本的Python並存。此時需要在系統中安裝多個Python,但又不能影響系統自帶的 Python。pyenv 就是這樣一個 Pyt

基於Spring cloud ribbon實現版本控制

在我們使用spring mvc單體架構時, 我們可以通過uri,或者請求頭做多版本路由,雖然同一個功能需要維護多個版本的介面,但是對於系統而言,不會因為新增一個介面版本而影響到老使用者。當我們使用spring cloud構建微服務平臺時,也希望能做到這一點,然而

linux jdk 使用alternatives版本控制

inux onf linu oca alter java版 目錄 ive 控制 安裝配置 需要配置兩個內容,分別是java和javac命令,指定jdk目錄和優先級:alternatives --install /usr/bin/java java /usr/local/j

python版本控制操作方法

pyenv是一個能簡易地在多個Python版本中進行切換的工具,它簡單而優雅。 pyenv有以下功能: 進行全域性的Python版本切換 為單個專案提供對應的Python版本 使用環境變數能讓你重寫Python版本 能在同一時間在不同版本間進

Spring Cloud Gateway 擴充套件支援版本控制及灰度釋出

灰度釋出 什麼是灰度釋出,概念請參考,我們來簡單的通過下圖來看下,通俗的講: 為了保證服務升級過程的平滑過渡提高客戶體驗,會一部分

net core webapi版本控制與swagger(nswag)配置

前言 首先希望webapi 支援多版本,swagger針對不同的版本可進行互動。多版本控制基於Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 包,swagger可以選擇Swashbuckle.AspNetCore和nswag.AspNetCo

關於版本控制軟體以及Git的簡單介紹

以下內容從Pro Git這本書獲取,該書的PDF下載連結 https://git-scm.com/book/zh/v2 本章介紹開始使用 Git 前的相關知識。我們會先了解一些版本控制工具的歷史背景,然後試著讓 Git 在你的系統上跑起來,直到最後配置好,可以正