這篇文章主要介紹了Postgresql和MySQL如何選擇,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
成都創(chuàng)新互聯(lián)是專(zhuān)業(yè)的達(dá)州網(wǎng)站建設(shè)公司,達(dá)州接單;提供成都做網(wǎng)站、網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行達(dá)州網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
經(jīng)常看到有人寫(xiě)關(guān)于鎖的事情,但常常感覺(jué)給人一個(gè)感覺(jué),數(shù)據(jù)庫(kù)的ACID 是通過(guò)鎖來(lái)控制的,實(shí)際上數(shù)據(jù)庫(kù)的ACID 控制是復(fù)雜的,MVCC 就是一個(gè)對(duì)資源并發(fā)訪問(wèn)時(shí)的提高并發(fā)訪問(wèn)的有效的方法
在首次定義ACID事務(wù)屬性時(shí),假定具有可串行性。為了提供嚴(yán)格的可序列化事務(wù)結(jié)果,使用了2PL(兩階段鎖定)機(jī)制。在使用2PL時(shí),每次讀操作都需要一個(gè)共享鎖獲取,而寫(xiě)操作則需要一個(gè)獨(dú)占鎖。
保持?jǐn)?shù)據(jù)的完整性,作為一個(gè)重要的經(jīng)驗(yàn)法則,對(duì)事務(wù)性處理DBs的所有修改都應(yīng)該在原子事務(wù)下進(jìn)行。而且,每個(gè)事務(wù)都應(yīng)該使數(shù)據(jù)庫(kù)處于一致的狀態(tài),隔離是最難處理的實(shí)踐????。從理論上講,非常簡(jiǎn)單,他隔離保證了所有事務(wù)的執(zhí)行,即使它們同時(shí)運(yùn)行,也“好像”它們是串行執(zhí)行的??蓪?shí)踐中,它要復(fù)雜得多在保持合理性能的同時(shí)保持隔離.
多版本并發(fā)控制(MVCC),會(huì)創(chuàng)建行的“先前版本”(“快照”),并將該行的“先前版本”提供給任何可能?chē)L試并發(fā)運(yùn)行的其他事務(wù),而不是在有人開(kāi)始讀取該行時(shí)鎖定該行。這是有道理的——畢竟,在提交第一個(gè)事務(wù)之前,不會(huì)考慮更改DB的狀態(tài)。
寫(xiě)到這,會(huì)比較枯燥,下面就開(kāi)始講點(diǎn)和實(shí)際數(shù)據(jù)庫(kù)貼邊的 MVCC 實(shí)現(xiàn)。
就目前掌握的數(shù)據(jù)庫(kù)類(lèi)型,大致解決MVCC的方式有兩種
1 新的數(shù)據(jù)與舊數(shù)據(jù)分離轉(zhuǎn)移到一個(gè)地方,例如undo log,其他人讀數(shù)據(jù)時(shí),從回滾段中把舊的數(shù)據(jù)讀出來(lái),Oracle和MySQL中的innodb引擎是這樣做的。
2寫(xiě)新數(shù)據(jù)時(shí),舊數(shù)據(jù)不刪除,而是把新數(shù)據(jù)插入,新舊數(shù)據(jù)在一起。PostgreSQL就是使用的這種實(shí)現(xiàn)方法。
那么我們可以對(duì)比一下這兩種方式的不同
1 Postgresql 中通過(guò)行設(shè)計(jì)和xact 的方式來(lái)解決MVCC的問(wèn)題, 我們可以通過(guò)一個(gè)表的查詢(xún) xmin,xmax,cmin,cmax 來(lái)查看相關(guān)的原理。
下面的這段代碼解釋了PG上關(guān)于 tuple 設(shè)計(jì)上的一些原理
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)生這個(gè)行或更高這行的事務(wù)ID
t_xmax 表現(xiàn)的是刪除或鎖定這個(gè)元組的事務(wù)ID
t_cid 包含cmin和cmax兩個(gè)字段,標(biāo)識(shí)在一個(gè)事務(wù)里面的這些行的操作順序,例如插入5行,那這5行的插入順序是什么,那些tuple 對(duì)那些tuple是可見(jiàn)的,這個(gè)是一個(gè)事務(wù)級(jí)的可見(jiàn)性的展示。
t_xvac 存儲(chǔ)的是VACUUM FULL 命令的事務(wù)ID
當(dāng)插入一行時(shí),postgres將在該行中存儲(chǔ)XID并將其稱(chēng)為xmin。已經(jīng)提交的并且xmin小于當(dāng)前事務(wù)的XID的每一行對(duì)事務(wù)都是可見(jiàn)的。這意味著您可以啟動(dòng)一個(gè)事務(wù)并插入一行,而在該事務(wù)提交之前,其他事務(wù)不會(huì)看到該行。一旦提交并創(chuàng)建了其他事務(wù),它們就能夠查看新行,因?yàn)樗鼈儩M(mǎn)足xmin < XID條件——并且創(chuàng)建該行的事務(wù)已經(jīng)完成。
下面我們看看postgresql 表結(jié)構(gòu),以city表為例
一個(gè)表中都有的字段 tableoid,cmax,xmax,cmin,xmin
select attname, attnum, atttypid::regtype, attisdropped::text from pg_attribute where attrelid = 'city'::regclass;
我們舉一個(gè)例子就能很好的解釋MVCC 的具體操作
我們選擇一個(gè)city 表,然后我們開(kāi)兩個(gè)事物,一個(gè)更新city_id 1 - 20 另一個(gè)事物更新city_id 21 40
事務(wù)1
事務(wù)2
不在事務(wù)1 和事務(wù)2 中看到的
從上面可以總結(jié)出
1 每個(gè)事務(wù)更改操作都會(huì)觸發(fā) xmin xmax ,改變
2 每個(gè)事務(wù)的更改xmin 只會(huì)在自己的事務(wù)內(nèi)部看的到,而xmax 就是別的事務(wù)正在更改的信息標(biāo)記
這樣MVCC 的初步功能就可以進(jìn)行下去了,所以postgresql 沒(méi)有頁(yè)鎖,只有表鎖和行鎖。
這樣做的優(yōu)點(diǎn)就是事務(wù)的回滾非常迅速,但需要經(jīng)常性的 vacuum
反觀MYSQL 的MVCC 采用的是undo log的方式,這和ORACLE 的方式雷同,MVCC 的功能實(shí)現(xiàn)并不是在每行中實(shí)現(xiàn)的,innodb存儲(chǔ)引擎對(duì)undo的管理采用段的方式,rollback segment稱(chēng)為回滾段,每個(gè)回滾段中有1024個(gè)undo log segment。(MYSQL 8 已經(jīng)有改變)
使所有回滾段(rsegs)駐留在所選的UNDO表空間中不活動(dòng)。Inactive意味著這些回滾段不會(huì)分配給新的事務(wù)。清除系統(tǒng)將繼續(xù)釋放不再需要的回滾段。這將分配給回滾段的頁(yè)面標(biāo)記為空閑,并減少回滾的邏輯大小。
通過(guò)上面的一個(gè)UNDO 表空間的大概的流程,可以提出幾個(gè)問(wèn)題
1 回滾段是有數(shù)量限制的,回滾段的數(shù)量限制就是這個(gè)數(shù)據(jù)庫(kù)系統(tǒng)的同一個(gè)時(shí)間可以執(zhí)行事務(wù)的數(shù)量的限制,每個(gè)回滾段維護(hù)一個(gè)頁(yè)頭,每個(gè)頁(yè)面會(huì)劃分1024slot 每個(gè)slot 會(huì)對(duì)應(yīng)一個(gè)事務(wù),所以MYSQL 5.7(8.0重新設(shè)計(jì)了UNDOLOG)另外即使是只讀的事務(wù),只要有對(duì)臨時(shí)表的寫(xiě)入,也是分配回滾段的。
例如MYSQL的事務(wù)在prepare 階段,insert undo 和 update undo的狀態(tài)為prepare,調(diào)用trx_undo_set_state_at_prepare,對(duì)對(duì)應(yīng)的undo log slot頭頁(yè)面(trx_undo_t::hdr_page_no),將頁(yè)面段頭的TRX_UNDO_STATE設(shè)置為T(mén)RX_UNDO_PREPARED,同時(shí)修改其他對(duì)應(yīng)字段。
在commit 階段,Undo狀態(tài)為T(mén)RX_UNDO_CACHED,則加入到回滾段的insert_undo_cached鏈表上,或者將該undo所占的segment及其所占用的回滾段的slot全部釋放掉,修改當(dāng)前回滾段的大小,并釋放undo對(duì)象所占的內(nèi)存,如果是Update_undo操作,則insert_undo不放到History list上。最后事務(wù)提交后將回滾段的計(jì)數(shù)器減一。
其實(shí)就是將事務(wù)ID 和 回滾段的指針連接起來(lái),同時(shí)MYSQL的行中也有兩個(gè)字段來(lái)記錄,針對(duì)MYSQL 表每一行 都有 6個(gè)字節(jié)的 db_trx_id , 7個(gè)字節(jié)的 db_roll_ptr ,undo log對(duì)于update或者delete操作,每一行都保存了一個(gè)事務(wù)Id,修改事務(wù)Id為當(dāng)前Session的事務(wù)id,生成數(shù)據(jù)行事務(wù)之前的版本,將當(dāng)前行的回滾指針指向事務(wù)之前的版本。對(duì)于insert操作,將當(dāng)前行的回滾指針指為空,因?yàn)閕nsert沒(méi)有事務(wù)操作之前的版本。
數(shù)據(jù)庫(kù)如果在執(zhí)行事務(wù)的過(guò)程中想要回滾,必然要考慮并發(fā)和回滾,這就造成隨著并發(fā)和回滾的需求,導(dǎo)致占用更多的磁盤(pán)空間,而在事務(wù)提交后就需要清理掉這些無(wú)用的東西,POSTGRESQL 叫 VACUUM ,MYSQL 叫 Purge ,在InnoDB中,更新后的行的最新版本只保留在表中。舊版本的行在回滾段,而刪除后的行版本則保留在原處,并標(biāo)記為以后的清理。因此,須從表本身清理標(biāo)記任何已刪除的行,并從回滾段中清除任何更新后的舊版本的行。查找被刪除的記錄所需的所有信息。
所以從設(shè)計(jì)結(jié)構(gòu)上來(lái)說(shuō)postgresql 的結(jié)構(gòu)設(shè)計(jì)要簡(jiǎn)單,MYSQL ORACLE 的結(jié)構(gòu)設(shè)計(jì)要復(fù)雜,并且POSTGRESQL 也沒(méi)有redo等結(jié)構(gòu),所以針對(duì)POSTGRESQL 最大的問(wèn)題就是VACUUM , 而MYSQL INNODB ,則會(huì)面對(duì)redo ,undo ,purge 等方面的I/O 壓力。
純個(gè)人認(rèn)為,postgresql 在不考慮vacuum 的情況下,性能上的瓶頸要小于MYSQL 方面的復(fù)雜結(jié)構(gòu)上產(chǎn)生的影響(可以在非頻繁工作期間進(jìn)行一些其他的回收方式)。postgresql 在使用中要給出的磁盤(pán)空間要有余量,mysql 在這方面上要好一些。
所以單純說(shuō)那個(gè) better ,沒(méi)有什么意義,有意義的是你掌握了多少他們的特性 knowledge
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Postgresql和MYSQL如何選擇”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
本文題目:Postgresql和MYSQL如何選擇
網(wǎng)頁(yè)URL:http://jinyejixie.com/article22/jogpjc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、品牌網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、小程序開(kāi)發(fā)、面包屑導(dǎo)航、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)