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