日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

mysql oracle mvcc_PostgreSQL、Oracle/MySQL和SQL Server的MVCC实现原理方式

發布時間:2024/9/19 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql oracle mvcc_PostgreSQL、Oracle/MySQL和SQL Server的MVCC实现原理方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PostgreSQL、Oracle/MySQL和SQL Server的MVCC實現原理方式

關系數據庫管理系統使用MVCC(Multiversion Concurrency Control多版本并發控制)來避免寫操作堵塞讀操作的并發問題,MVCC也就是通過使用數據的多個版本保證并發讀寫不沖突的一種機制,不同的數據庫有不同的實現,這也是數據庫系統讓人頭疼的地方,關系數據庫表面看上去很簡單方便,使用標準的SQL語句操作讓人很放心,但是隨著系統規模增加,并發用戶增加,數據庫會出現性能降低的現象,這時我們可能需要從外部的微調進入到內部原理的深入研究,而每個數據庫內部實現并發的原理都是不同的,如果我們擁有多個不同的數據庫,那么需要不同的調校方法,這時作為生產系統的核心數據庫開始變得不那么讓人放心,本文提供了市面上幾種流行數據庫的內部MVCC不同的實現。

MVCC的兩種不同實現方式

第一種實現方式是將數據記錄的多個版本保存在數據庫中,當這些不同版本數據不再需要時,垃圾收集器回收這些記錄。這個方式被PostgreSQL和Firebird/Interbase采用,SQL Server使用的類似機制,所不同的是舊版本數據不是保存在數據庫中,而保存在不同于主數據庫的另外一個數據庫tempdb中/

第二種實現方式只在數據庫保存最新版本的數據,但是會在使用undo時動態重構舊版本數據,這種方式被Oracle和MySQL/InnoDB使用。

下面看看具體數據庫實現機制。

PostgreSQL的MVCC

在PostgreSQL中,當一行記錄被更新時,該行數據的新版本(稱為tuple)將被創建并插入表中,之前版本提供一個指針指向新版本,之前版本被標記為"expired"過期,但是還保留在數據庫直到垃圾收集器回收掉。

為了支持多版本,每個tuple有以下附加數據記錄:

xmin – 插入更新記錄和創建這個tuple的事務的ID

xmax – 刪除記錄或創建這個tuple新版本或刪除記錄的事務。這個字段初始是null.

事務狀態是保存在 $Data/pg_clog的CLOG中. 這個表包含每個事務狀態信息的兩個字節,可能的狀態有in-progress, committed, 或 ?aborted。 當一個事務結束后,PostgreSQL并不會將數據庫記錄的改變undo回滾的,它只是在CLOG標記事務為aborted . 一個PostgreSQL表可能包含許多這樣aborted退出事務的數據。

一個稱為Vacuum 清理進程會提供expired過期/aborted退出的記錄版本的垃圾回收,Vacuum 清理器也會刪除被垃圾回收的tuple相關的索引項。

一個tuple的xmin是有效且xmax無效時,它是可見的。 “Valid有效” 意味著 “或者是 committed 或代表當前事務”. 為了避免反復操作CLOG 表, PostgreSQL 在tuple中維持狀態標識,以表示tuple是否是“known committed” 或 “known aborted”.

Oracle的MVCC

Oracle是在回滾段(也就是‘undo log’)中保存舊版本, 一個事務ID并不是一個順序數字,而是由一系列數字組成,這些數字指向回滾段的頭部事務槽 (slot)。 回滾段能讓新事務能重用存儲,重用被已經提交或退出的舊事務使用過的事務槽,這種自動重用機制使得Oracle使用有限的回滾段可以管理大量的事務。

回滾段的頭部塊是用作一個事務表,這里保存著事務的狀態,稱為System Change Number或 SCN, Oracle并不是存儲頁面中的每個記錄的事務ID, 而是通過保存頁面中每行記錄的唯一事務ID的數組陣列節約空間使用, 只保存記錄的數組偏移量offset,和每個事務ID保存在一起的是一個指針,指向該頁事務創建的最后undo記錄,不僅表記錄是這種方式存儲,索引記錄也是使用同樣技術,這是Oracle和PostgreSQL主要區別之一.

當一個Oracle事務啟動時,它會標記一個當前事務狀態SCN. 當讀取一個表或一個索引頁時,Oracle使用SCN數字來決定該頁是否包含不應該讓當前事務知曉的事務影響效果, Oracle通過尋找相聯的回滾段頭部來檢查該事務的狀態,但是為了節約時間,第一次是真正查詢事務,查詢完成它的狀態會被記錄在該頁中以避免后來再次查詢,如果該頁被發現包含不可見事務的影響,Oracle通過undoing每個這樣的事務影響來重新創建該頁的舊版本。它掃描和每個事務有關的記錄,將這些事務效果應用到該頁,直至那些所有事務效果應用完成后被移除,以該方式創建的新頁再用于訪問其中的tuple。

Oracle中的記錄頭:

一個記錄頭部不會增長,總是有固定大小,對于非集群的表,記錄頭部是3個字節,一個字節被用于存儲標識,一個字節用于顯示記錄是否被鎖住(比如它被更新了但是沒有確認提交committed), ,一個字節用于列計數。

SQL Server的MVCC

在SQL Server數據庫內部使用記錄版本實現快照隔離和讀取提交,只有需要此項的數據庫才會必須開啟并且會產生相應的成本開銷。

當一個記錄被修改或刪除時,使用copy-on-write機制能夠有效地啟動版本,Row versioning–based 事務能夠有效地“view看到” 數據的從過去到現在的的前后一致的各種版本。

記錄版本Row version保存在版本存儲中,其駐留在主數據庫之外的tempdb數據庫中, ?更特別地,當一張表或索引中一個記錄被修改,新記錄將攜帶上執行修改的事務的 ”sequence_number”. 記錄的舊版本將被拷貝到版本存儲中, 新記錄包含一個指針指向版本存儲中的這個舊記錄,如果多個長運行 long-running事務存在,并且需要多個 ”版本versions”, 在版本存儲中的記錄也許包含指向該記錄更早版本的指針。

SQL Server的版本存儲清除:

SQL Server自動管理版本存儲的大小,維持一個清除線程來確保版本存儲中記錄版本數量不至于太長,超過需要,對于在快照隔離下運行的查詢,版本存儲保留記錄版本直到修改數據的事務完成,并且事務包含的任何需要修改數據的語句全部完成,對于在Read Committed 快照隔離下運行的SELECT語句 ,一個特別的記錄版本就再也不需要了,一旦SELECT語句執行完成就被移除。

如果tempdb已經沒有空閑空間, SQL Server會調用清除功能,增加文件的大小,當然前提是假設我們配置文件是自動增長的, ?如果磁盤已經沒有空間,文件不能自動增長, SQL Server會停止產生版本,如果這種情況發生,任何需要讀取版本的快照查詢因為空間限制將失敗。

SQL Server中記錄頭

4 字節

- 兩字節記錄元數據(記錄類型)

- 兩字節向前指向記錄中的NULL 位圖bitmap. 這是記錄(固定長度列)實際大小的差值offset.

版本標記Versioning tag – 這是一個14-byte結構,包含時間戳加一個指向tempdb中版本存儲的指針,這里時間戳是 trasaction_seq_number, 當需要支持一個版本操作時,加入版本信息到記錄中時的時間。

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的mysql oracle mvcc_PostgreSQL、Oracle/MySQL和SQL Server的MVCC实现原理方式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。