01
提到事務(wù)ID,就不得不提PostgreSQL的MVCC機(jī)制。
PostgreSQL沒(méi)有類似于Oracle的undo來(lái)保證MVCC,其數(shù)據(jù)一致性通過(guò)使用一種多版本模型來(lái)維護(hù)。
這就意味著每個(gè) SQL 語(yǔ)句看到的都只是一小段時(shí)間之前的數(shù)據(jù)快照,而不管底層數(shù)據(jù)的當(dāng)前狀態(tài)。
這樣可以保護(hù)語(yǔ)句不會(huì)看到可能由其他在相同數(shù)據(jù)行上執(zhí)行更新的并發(fā)事務(wù)造成的不一致數(shù)據(jù),為每一個(gè)數(shù)據(jù)庫(kù)會(huì)話提供事務(wù)隔離。
主要有如下特點(diǎn):
A) 基于事務(wù)ID
B) ?級(jí)多版本,且都存儲(chǔ)于頁(yè)面內(nèi)部
C) ?回滾段,?內(nèi)存儲(chǔ)
D) ?次update操作,產(chǎn)?記錄的兩個(gè)版本
02
MVCC元組結(jié)構(gòu)如下:
Xmin: 插入該行版本或者回滾的事務(wù)ID。對(duì)一個(gè)邏輯行的每一次更新都將創(chuàng)建一個(gè)新的行版本。
Xmax: 刪除事務(wù)或更新事務(wù)的事務(wù)ID,對(duì)于未刪除的行版本為0。對(duì)于一個(gè)可見(jiàn)的行版本,該列值也可能為非零。這通常表示刪除事務(wù)或更新事務(wù)還沒(méi)有提交,或者一個(gè)刪除或更新嘗試被回滾。
Cmin: 插入事務(wù)中的命令標(biāo)識(shí)符(從0開(kāi)始)。
Cmax: 刪除事務(wù)中的命令標(biāo)識(shí)符,或者為0。
Ctid: 行版本在其表中的物理位置。注意盡管ctid可以被用來(lái)非常快速地定位行版本,但是一個(gè)行的ctid會(huì)在被更新或者被VACUUM FULL移動(dòng)時(shí)改變。因此,ctid不能作為一個(gè)長(zhǎng)期行標(biāo)識(shí)符。應(yīng)使用主鍵來(lái)標(biāo)識(shí)邏輯行。
03
下面介紹下DML對(duì)應(yīng)的MVCC信息:
Insert場(chǎng)景:
從上圖我們可以看到insert時(shí),xmin記錄了新插入行的事務(wù)id,xmax為0。
接下來(lái)我們update來(lái)看看:
先在session A執(zhí)行update。
session A沒(méi)有提交或者回滾的情況下,在session B查看事務(wù)ID如下:
此時(shí)我們發(fā)現(xiàn)在可見(jiàn)的行版本中,xmin記錄了回滾時(shí)的事務(wù)ID,xmax記錄了更新事務(wù)ID。
當(dāng)我們?cè)趕ession A commit之后,xmin的值就會(huì)變成該行更新時(shí)的事務(wù)ID值。
最后來(lái)看看delete:
先在session A執(zhí)行delete。
session A沒(méi)有提交或者回滾的情況下,在session B查看事務(wù)ID如下:
我們可以發(fā)現(xiàn)xmax記錄的是delete時(shí)的事務(wù)id。在session A commit之后, id = 10這行已不可見(jiàn)。
04
從上述DML的事務(wù)ID來(lái)看,PostgreSQL事務(wù)可見(jiàn)性需要依賴行頭的事務(wù)號(hào),如果一個(gè)行版本的xmin(插入事務(wù)ID)小于或等于當(dāng)前事務(wù)ID,那這個(gè)就相當(dāng)于“過(guò)去的”事務(wù),這是對(duì)其他session是可見(jiàn)的。
如果行版本的xmin(插入事務(wù)ID)大于當(dāng)前事務(wù)id,那它是屬于“未來(lái)的”,并且對(duì)當(dāng)前事務(wù)是不可見(jiàn)。但是因?yàn)槭聞?wù) ID 是32位的,且循環(huán)使用。一個(gè)長(zhǎng)時(shí)間(超過(guò) 40 億個(gè)事務(wù))運(yùn)行的集簇,XID 計(jì)數(shù)器回卷到 0,并且本來(lái)屬于過(guò)去的事務(wù)突然間就變成了屬于未來(lái),這意味著之前的行均變成不可見(jiàn)。
這就是事務(wù)ID回卷問(wèn)題,數(shù)據(jù)丟失。
為了避免發(fā)生這種情況,有必要至少每 20 億個(gè)事務(wù)就清理每個(gè)數(shù)據(jù)庫(kù)中的每個(gè)表。
事務(wù)ID復(fù)用圖:
清理原理如下:
PostgreSQL保留了一個(gè)特殊的XID(FrozenTransactionId),這個(gè)XID并不遵循普通XID的比較規(guī)則 并且總是被認(rèn)為比任何普通 XID要老。
這也意味著這個(gè)插入XID為FrozenTransactionId的行版本對(duì)于所有當(dāng)前和未來(lái)事務(wù)來(lái)說(shuō)當(dāng)然都是可見(jiàn)的。
這個(gè)行為就被稱之為凍結(jié)(freeze),由VACUUM去把行標(biāo)記為凍結(jié)。
因此,一旦一個(gè)行版本被凍結(jié),這樣它們對(duì)所有普通事務(wù)來(lái)說(shuō)都是“在過(guò)去”,而不管回卷問(wèn)題。并且這樣的行版本將一直有效直到被刪除,不管它有多舊。
05
這里介紹下涉及凍結(jié)的三個(gè)重要參數(shù):
參數(shù)一:vacuum_freeze_table_age
VACUUM通常會(huì)跳過(guò)不含有任何死亡行版本的頁(yè)面,但是不會(huì)跳過(guò)那些含有帶舊 XID 值的行版本的頁(yè)面。要保證所有舊的行版本都已經(jīng)被凍結(jié),需要對(duì)整個(gè)表做一次掃描。
vacuum_freeze_table_age就是控制VACUUM什么時(shí)候這樣做,如果該表經(jīng)過(guò)vacuum_freeze_table_age減去vacuum_freeze_min_age個(gè)事務(wù)還沒(méi)有被完全掃描過(guò),則會(huì)強(qiáng)制一次全表清掃。
官檔建議vacuum_freeze_table_age設(shè)置成0.95 * autovacuum_freeze_max_age,因?yàn)?.95的乘數(shù)為在防回卷自動(dòng)清理發(fā)生之前運(yùn)行一次手動(dòng)VACUUM留出了一些空間。
將它設(shè)置得太接近可能導(dǎo)致防回卷自動(dòng)清理,即使該表最近因?yàn)榛厥湛臻g的目的被清理過(guò),而較低的值將導(dǎo)致更頻繁的全表掃描。
參數(shù)二:autovacuum_freeze_max_age
任何包含比autovacuum_freeze_max_age配置參數(shù)所指定的年齡更老的 XID 的未凍結(jié)行的表上調(diào)用自動(dòng)清理,即便自動(dòng)清理被禁用,也會(huì)被強(qiáng)制開(kāi)啟。
參數(shù)三:vacuum_freeze_min_age
說(shuō)的通俗點(diǎn)就是事務(wù)信息保留的時(shí)間,其控制在其行版本被凍結(jié)前一個(gè) XID 值應(yīng)該有多老。如果被凍結(jié)的行將很快會(huì)被再次修改,增加這個(gè)設(shè)置可以避免不必要的工作。
當(dāng)然這個(gè)不能設(shè)置過(guò)小,因?yàn)樗赡軐?dǎo)致VACUUM做無(wú)用的工作:如果該行在被替換成FrozenXID之后很快就被修改(導(dǎo)致該行獲得一個(gè)新的 XID),那么凍結(jié)一個(gè)行版本就是浪費(fèi)時(shí)間。
因此該設(shè)置應(yīng)該足夠大,這樣直到行不再可能被修改之前,它們都不會(huì)被凍結(jié)。
注:
VACUUM freeze操作涉及全表掃,對(duì)IO有一定影響,所以要盡量避免在高峰期自動(dòng)觸發(fā)。應(yīng)該主動(dòng)監(jiān)控?cái)?shù)據(jù)庫(kù)年齡并在低峰期做VACUUM freeze。
06
vacuum freeze日常操作步驟:
1) 查詢數(shù)據(jù)庫(kù)年齡:
SELECT datname, age(datfrozenxid) FROM pg_database;
2) 查詢指定表的年齡:
select relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_size from
pg_class where relname = test1;
3) 這查詢按照最老的XID排序,查看大于1G而且是排名前20的表:
select relname, age(relfrozenxid) as xid_age, pg_size_pretty(pg_table_size(oid)) as table_size
from pg_class where relkind = r and pg_table_size(oid) > 1073741824
order by xid_age desc limit 20;
--vacuum前事務(wù)年齡為 61436
relname | xid_age | table_size
----------------+---------+------------
test_tab | 31260 | 4327 MB
4) 建議使用vacuum freeze來(lái)對(duì)指定的表進(jìn)行xid 凍結(jié)清理:
vacuum full freeze xxx.xxxx;
--vacuum后事務(wù)年齡變?yōu)?
relname | xid_age | table_size
----------------+---------+------------
test_tab | 0 | 4327 MB
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/129667.html
摘要:前言居中是網(wǎng)頁(yè)布局中再常見(jiàn)不過(guò)的一種方式了,今天我們就來(lái)聊聊居中的那點(diǎn)事。我是水平居中的同樣是針對(duì)塊級(jí)元素才有效果。來(lái)看代碼我是水平居中的必須配合來(lái)使用來(lái)可以實(shí)現(xiàn)居中的效果。方法二我是垂直居中的注意此方法要考慮的兼容性問(wèn)題。 前言:居中是網(wǎng)頁(yè)布局中再常見(jiàn)不過(guò)的一種方式了,今天我們就來(lái)聊聊css居中的那點(diǎn)事。 我們主要從這幾個(gè)方面來(lái)了解下居中: 水平居中 垂直居中 水平垂直居中 水平...
摘要:所謂對(duì)稱加密,就是加密和解密使用同一秘鑰,這也是這種加密算法最顯著的缺點(diǎn)之一。非對(duì)稱加密算法由于對(duì)稱加密在通信加密領(lǐng)域的缺陷,年和提出了非對(duì)稱加密的概念。非對(duì)稱加密,其主要缺點(diǎn)之一就是慢,適合加密少量數(shù)據(jù)。 1. 加密的目的 加密不同于密碼,加密是一個(gè)動(dòng)作或者過(guò)程,其目的就是將一段明文信息(人類或機(jī)器可以直接讀懂的信息)變?yōu)橐欢慰瓷先](méi)有任何意義的字符,必須通過(guò)事先約定的解密規(guī)則才能將...
摘要:所謂對(duì)稱加密,就是加密和解密使用同一秘鑰,這也是這種加密算法最顯著的缺點(diǎn)之一。非對(duì)稱加密算法由于對(duì)稱加密在通信加密領(lǐng)域的缺陷,年和提出了非對(duì)稱加密的概念。非對(duì)稱加密,其主要缺點(diǎn)之一就是慢,適合加密少量數(shù)據(jù)。 1. 加密的目的 加密不同于密碼,加密是一個(gè)動(dòng)作或者過(guò)程,其目的就是將一段明文信息(人類或機(jī)器可以直接讀懂的信息)變?yōu)橐欢慰瓷先](méi)有任何意義的字符,必須通過(guò)事先約定的解密規(guī)則才能將...
摘要:不過(guò)這種方式有問(wèn)題,目前查到的大部分過(guò)程都是會(huì)在服務(wù)器新建出一個(gè)文件,等下載完畢在做刪除,還沒(méi)有找到可以跨過(guò)這一步的方式。 showImg(https://segmentfault.com/img/remote/1460000018850368); Content-Disposition / Content-Type Content-Disposition http 頭部的 Conte...
摘要:從最大的同性社交平臺(tái)獲取數(shù)據(jù)好了,言歸正傳,回到題目。烏云密布的爬蟲百度網(wǎng)盤這件事,是我不想看到的,這類安全問(wèn)題的一個(gè)共同特點(diǎn)用戶自身確實(shí)存在問(wèn)題。 本文作者:夏之冰雪,i春秋簽約作家 《我在百度網(wǎng)盤上看到上萬(wàn)條車主個(gè)人信息,企業(yè)、政府高官信息、各種數(shù)據(jù)庫(kù)和無(wú)窮無(wú)盡的盜版》,一時(shí)間,這篇文章就火了,火爆程度另百度猝不及防。 其實(shí)呢,這事真不能全怪百度,畢竟用戶分享出去了。之所以引起這么...
摘要:移動(dòng)精英開(kāi)發(fā)社群的第期,也是圍繞架構(gòu)這個(gè)話題進(jìn)行討論。本次我們希望結(jié)合實(shí)際開(kāi)發(fā)中遇到的問(wèn)題,來(lái)聊聊移動(dòng)端的架構(gòu)設(shè)計(jì)。這樣的模式改進(jìn)一些,可能會(huì)更適合移動(dòng)端架構(gòu)。潘衛(wèi)杰之前我們公司移動(dòng)端的大項(xiàng)目就是插座式開(kāi)發(fā)的,批量出各個(gè)行業(yè)的。 此前,58 同城的技術(shù)委員會(huì)執(zhí)行主席沈劍在 OneAPM 的技術(shù)公開(kāi)課上分享過(guò)一個(gè)主題,「好的架構(gòu)不是設(shè)計(jì)出來(lái)的,而是演技出來(lái)的」。因?yàn)閷?duì)很多創(chuàng)業(yè)公司而言,隨...
閱讀 1346·2023-01-11 13:20
閱讀 1684·2023-01-11 13:20
閱讀 1132·2023-01-11 13:20
閱讀 1858·2023-01-11 13:20
閱讀 4100·2023-01-11 13:20
閱讀 2704·2023-01-11 13:20
閱讀 1385·2023-01-11 13:20
閱讀 3597·2023-01-11 13:20