Postgresql和MYSQL如何選擇

這篇文章主要介紹了Postgresql和MySQL如何選擇,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

成都創(chuàng)新互聯(lián)是專業(yè)的達州網(wǎng)站建設公司,達州接單;提供成都做網(wǎng)站、網(wǎng)站建設,網(wǎng)頁設計,網(wǎng)站設計,建網(wǎng)站,PHP網(wǎng)站建設等專業(yè)做網(wǎng)站服務;采用PHP框架,可快速的進行達州網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!

經(jīng)??吹接腥藢戧P于鎖的事情,但常常感覺給人一個感覺,數(shù)據(jù)庫的ACID 是通過鎖來控制的,實際上數(shù)據(jù)庫的ACID 控制是復雜的,MVCC 就是一個對資源并發(fā)訪問時的提高并發(fā)訪問的有效的方法

在首次定義ACID事務屬性時,假定具有可串行性。為了提供嚴格的可序列化事務結(jié)果,使用了2PL(兩階段鎖定)機制。在使用2PL時,每次讀操作都需要一個共享鎖獲取,而寫操作則需要一個獨占鎖。

保持數(shù)據(jù)的完整性,作為一個重要的經(jīng)驗法則,對事務性處理DBs的所有修改都應該在原子事務下進行。而且,每個事務都應該使數(shù)據(jù)庫處于一致的狀態(tài),隔離是最難處理的實踐????。從理論上講,非常簡單,他隔離保證了所有事務的執(zhí)行,即使它們同時運行,也“好像”它們是串行執(zhí)行的??蓪嵺`中,它要復雜得多在保持合理性能的同時保持隔離.

多版本并發(fā)控制(MVCC),會創(chuàng)建行的“先前版本”(“快照”),并將該行的“先前版本”提供給任何可能嘗試并發(fā)運行的其他事務,而不是在有人開始讀取該行時鎖定該行。這是有道理的——畢竟,在提交第一個事務之前,不會考慮更改DB的狀態(tài)。

寫到這,會比較枯燥,下面就開始講點和實際數(shù)據(jù)庫貼邊的 MVCC 實現(xiàn)。

就目前掌握的數(shù)據(jù)庫類型,大致解決MVCC的方式有兩種

1 新的數(shù)據(jù)與舊數(shù)據(jù)分離轉(zhuǎn)移到一個地方,例如undo log,其他人讀數(shù)據(jù)時,從回滾段中把舊的數(shù)據(jù)讀出來,Oracle和MySQL中的innodb引擎是這樣做的。

2寫新數(shù)據(jù)時,舊數(shù)據(jù)不刪除,而是把新數(shù)據(jù)插入,新舊數(shù)據(jù)在一起。PostgreSQL就是使用的這種實現(xiàn)方法。

那么我們可以對比一下這兩種方式的不同

1  Postgresql 中通過行設計和xact 的方式來解決MVCC的問題, 我們可以通過一個表的查詢 xmin,xmax,cmin,cmax 來查看相關的原理。

Postgresql和MYSQL如何選擇

下面的這段代碼解釋了PG上關于 tuple 設計上的一些原理

typedef struct HeapTupleFields { TransactionId t_xmin;   /* inserting xact ID *

/TransactionId t_xmax;   /* deleting or locking xact ID *

/union{   CommandId t_cid;   /* inserting or deleting command ID, or both *

/   TransactionId t_xvac; /* VACUUM FULL xact ID */}    t_field3; } HeapTupleFields;

  • t_xmin 表現(xiàn)的是產(chǎn)生這個行或更高這行的事務ID

  • t_xmax 表現(xiàn)的是刪除或鎖定這個元組的事務ID

  • t_cid 包含cmin和cmax兩個字段,標識在一個事務里面的這些行的操作順序,例如插入5行,那這5行的插入順序是什么,那些tuple 對那些tuple是可見的,這個是一個事務級的可見性的展示。

  • t_xvac 存儲的是VACUUM FULL 命令的事務ID

當插入一行時,postgres將在該行中存儲XID并將其稱為xmin。已經(jīng)提交的并且xmin小于當前事務的XID的每一行對事務都是可見的。這意味著您可以啟動一個事務并插入一行,而在該事務提交之前,其他事務不會看到該行。一旦提交并創(chuàng)建了其他事務,它們就能夠查看新行,因為它們滿足xmin < XID條件——并且創(chuàng)建該行的事務已經(jīng)完成。

下面我們看看postgresql 表結(jié)構(gòu),以city表為例

Postgresql和MYSQL如何選擇

一個表中都有的字段 tableoid,cmax,xmax,cmin,xmin

select attname, attnum, atttypid::regtype, attisdropped::text from pg_attribute where attrelid = 'city'::regclass;

我們舉一個例子就能很好的解釋MVCC 的具體操作

我們選擇一個city 表,然后我們開兩個事物,一個更新city_id 1 - 20 另一個事物更新city_id 21 40 

事務1

Postgresql和MYSQL如何選擇

事務2

Postgresql和MYSQL如何選擇

不在事務1 和事務2 中看到的

Postgresql和MYSQL如何選擇

從上面可以總結(jié)出

1 每個事務更改操作都會觸發(fā) xmin xmax ,改變 

2 每個事務的更改xmin 只會在自己的事務內(nèi)部看的到,而xmax 就是別的事務正在更改的信息標記

Postgresql和MYSQL如何選擇

這樣MVCC 的初步功能就可以進行下去了,所以postgresql 沒有頁鎖,只有表鎖和行鎖。

這樣做的優(yōu)點就是事務的回滾非常迅速,但需要經(jīng)常性的 vacuum

反觀MYSQL 的MVCC 采用的是undo log的方式,這和ORACLE 的方式雷同,MVCC 的功能實現(xiàn)并不是在每行中實現(xiàn)的,innodb存儲引擎對undo的管理采用段的方式,rollback segment稱為回滾段,每個回滾段中有1024個undo log segment。(MYSQL 8 已經(jīng)有改變)


使所有回滾段(rsegs)駐留在所選的UNDO表空間中不活動。Inactive意味著這些回滾段不會分配給新的事務。清除系統(tǒng)將繼續(xù)釋放不再需要的回滾段。這將分配給回滾段的頁面標記為空閑,并減少回滾的邏輯大小。

通過上面的一個UNDO 表空間的大概的流程,可以提出幾個問題

1 回滾段是有數(shù)量限制的,回滾段的數(shù)量限制就是這個數(shù)據(jù)庫系統(tǒng)的同一個時間可以執(zhí)行事務的數(shù)量的限制,每個回滾段維護一個頁頭,每個頁面會劃分1024slot 每個slot 會對應一個事務,所以MYSQL 5.7(8.0重新設計了UNDOLOG)另外即使是只讀的事務,只要有對臨時表的寫入,也是分配回滾段的。

例如MYSQL的事務在prepare 階段,insert undo 和 update undo的狀態(tài)為prepare,調(diào)用trx_undo_set_state_at_prepare,對對應的undo log slot頭頁面(trx_undo_t::hdr_page_no),將頁面段頭的TRX_UNDO_STATE設置為TRX_UNDO_PREPARED,同時修改其他對應字段。

在commit 階段,Undo狀態(tài)為TRX_UNDO_CACHED,則加入到回滾段的insert_undo_cached鏈表上,或者將該undo所占的segment及其所占用的回滾段的slot全部釋放掉,修改當前回滾段的大小,并釋放undo對象所占的內(nèi)存,如果是Update_undo操作,則insert_undo不放到History list上。最后事務提交后將回滾段的計數(shù)器減一。

其實就是將事務ID 和 回滾段的指針連接起來,同時MYSQL的行中也有兩個字段來記錄,針對MYSQL 表每一行 都有 6個字節(jié)的 db_trx_id , 7個字節(jié)的 db_roll_ptr ,undo log對于update或者delete操作,每一行都保存了一個事務Id,修改事務Id為當前Session的事務id,生成數(shù)據(jù)行事務之前的版本,將當前行的回滾指針指向事務之前的版本。對于insert操作,將當前行的回滾指針指為空,因為insert沒有事務操作之前的版本。

數(shù)據(jù)庫如果在執(zhí)行事務的過程中想要回滾,必然要考慮并發(fā)和回滾,這就造成隨著并發(fā)和回滾的需求,導致占用更多的磁盤空間,而在事務提交后就需要清理掉這些無用的東西,POSTGRESQL 叫 VACUUM ,MYSQL 叫 Purge ,在InnoDB中,更新后的行的最新版本只保留在表中。舊版本的行在回滾段,而刪除后的行版本則保留在原處,并標記為以后的清理。因此,須從表本身清理標記任何已刪除的行,并從回滾段中清除任何更新后的舊版本的行。查找被刪除的記錄所需的所有信息。

所以從設計結(jié)構(gòu)上來說postgresql 的結(jié)構(gòu)設計要簡單,MYSQL ORACLE 的結(jié)構(gòu)設計要復雜,并且POSTGRESQL 也沒有redo等結(jié)構(gòu),所以針對POSTGRESQL 最大的問題就是VACUUM , 而MYSQL  INNODB ,則會面對redo ,undo ,purge 等方面的I/O 壓力。

純個人認為,postgresql 在不考慮vacuum 的情況下,性能上的瓶頸要小于MYSQL 方面的復雜結(jié)構(gòu)上產(chǎn)生的影響(可以在非頻繁工作期間進行一些其他的回收方式)。postgresql 在使用中要給出的磁盤空間要有余量,mysql  在這方面上要好一些。

所以單純說那個 better ,沒有什么意義,有意義的是你掌握了多少他們的特性  knowledge

Postgresql和MYSQL如何選擇

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Postgresql和MYSQL如何選擇”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!

本文題目:Postgresql和MYSQL如何選擇
網(wǎng)頁URL:http://muchs.cn/article22/jogpjc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站品牌網(wǎng)站制作、網(wǎng)站設計小程序開發(fā)、面包屑導航云服務器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

綿陽服務器托管