真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)

作者:沃趣科技首席數(shù)據(jù)庫架構(gòu)師 唐成

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)章貢,十多年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575



問題的提出


  • 有人問PostgreSQL數(shù)據(jù)庫中剛剛刪除的數(shù)據(jù)能否被恢復(fù)?

  • 或更進一步,如果如要在一個事務(wù)中做了一系列的更新、刪除、插入的操作后,把這個事務(wù)提交之后又后悔了,能否恢復(fù)到之前的狀態(tài)?


當(dāng)然如果數(shù)據(jù)庫有備份,可以直接從備份的數(shù)據(jù)中恢復(fù),本文討論的是沒有備份的情況下能否恢復(fù)。 

理論分析

從PostgreSQL多版本實現(xiàn)的原理上,這是有可能的。因為PostgreSQL的多版本原理是舊數(shù)據(jù)并不刪除: 

  • 對于刪除數(shù)據(jù)的操作,只是把行上的xmax改成當(dāng)前的事務(wù)id

  • 對于更新操作,只是把原先行上xmax改成當(dāng)前的事務(wù)id,并插入一個新行,而新行上的xmin置為當(dāng)前的事務(wù)id

  • 事務(wù)的狀態(tài)是記錄在commit log中的,如果事務(wù)提交,只是把commit log中相應(yīng)的事務(wù)狀態(tài)改成“已提交狀態(tài)(TRANSACTION_STATUS_COMMITTED )”,如果事務(wù)回滾,則把commit log中的事務(wù)狀態(tài)改成“事務(wù)回滾(TRANSACTION_STATUS_ABORTED )”


所以從理論上說,只要把在commit log中剛提交事務(wù)狀態(tài)從“TRANSACTION_STATUS_COMMITTED”改成“TRANSACTION_STATUS_ABORTED”,原先的事務(wù)就會做廢,就能回到事務(wù)之前的狀態(tài)。 

但這個恢復(fù)有一個前提就是舊版本的數(shù)據(jù)沒有被vacuum垃圾回收進程清理掉,如果舊版本的數(shù)據(jù)已被vacuum垃圾回收進程給清理掉了,就不能恢復(fù)了。所以如果作了刪除數(shù)據(jù)的操作后,馬上把數(shù)據(jù)庫停下來,這時autovacuum進程還沒有把舊版本的數(shù)據(jù)給清理掉時,數(shù)據(jù)是可以恢復(fù)的。 

但僅僅是把commit log中的事務(wù)狀態(tài)改一下,就能恢復(fù)數(shù)據(jù)嗎?答案也是否定的,事情沒有這么簡單,原因是多版本的可見性判斷不僅僅是由commit log中的事務(wù)狀態(tài)的決定的,行上還有t_infomask狀態(tài)位中的hint信息來決定。如果hint已表示該行上的事務(wù)已被提交,則不需要再到commit log中來查看事務(wù)的狀態(tài)了。這個功能主要是為了提高性能,因為到clog中判斷行的可見性,而clog中只有8個塊是緩存在共享內(nèi)存中的,如果判斷每個行都去查找clog,效率太低了。具體這一部分的內(nèi)容可以見我的另一篇blog: PostgreSQL中行的可見性判斷中t_infomask字段的作用 

所以要想恢復(fù)數(shù)據(jù),還需要把相應(yīng)表文件中各行上的t_infomask狀態(tài)中的hint標(biāo)志位給清除掉之后,數(shù)據(jù)才能恢復(fù)回來。 

恢復(fù)的工具

因為整個恢復(fù)的過程比較復(fù)雜,為此我寫了一個工具叫pg_fix,放在github上:https://github.com/osdba/pg_fix,供大家研究使用。 

首先使用這個工具可以查詢某一個表的數(shù)據(jù)文件中各行的狀態(tài): PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)


使用這個工具可以清理表的數(shù)據(jù)文件中的t_infomask中的hint信息,在清理hint狀態(tài)之前,先查看行上的t_maskinfo狀態(tài):  PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)


然后執(zhí)行下面命令清除行上的hint狀態(tài):  PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)


清除完后,我們再看行上的t_infomask狀態(tài):  PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)


查詢和改變事務(wù)的狀態(tài)的方法如下: 

查詢事務(wù)xid=11的狀態(tài)的命令如下:  PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)


修改事務(wù)xid=11的狀態(tài)的命令如下:  PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)

其中-s后的值表示要把事務(wù)改成什么狀態(tài),事務(wù)的狀態(tài)值有四種,為0~3,意思如下: 

  • #define TRANSACTION_STATUS_IN_PROGRESS 0x00

  • #define TRANSACTION_STATUS_COMMITTED 0x01

  • #define TRANSACTION_STATUS_ABORTED 0x02

  • #define TRANSACTION_STATUS_SUB_COMMITTED 0x03


當(dāng)然上面使用pg_fix工具直接修改表中數(shù)據(jù)和commit log中事務(wù)的狀態(tài)都必須是數(shù)據(jù)庫停下來的情況。 

另本文的目的主要是為了研究PostgreSQL的一些原理,所以以上這些操作通常不要拿到生產(chǎn)數(shù)據(jù)庫上去試!??!




網(wǎng)站標(biāo)題:PostgreSQL中刪除的數(shù)據(jù)能否恢復(fù)
文章起源:http://weahome.cn/article/jhehic.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部