PostgreSQL中刪除的資料能否恢復
作者:沃趣科技首席資料庫架構師 唐成
問題的提出
作者:沃趣科技首席資料庫架構師 唐成
問題的提出
-
有人問PostgreSQL資料庫中剛剛刪除的資料能否被恢復?
-
或更進一步,如果如要在一個事務中做了一系列的更新、刪除、插入的操作後,把這個事務提交之後又後悔了,能否恢復到之前的狀態?
當然如果資料庫有備份,可以直接從備份的資料中恢復,本文討論的是沒有備份的情況下能否恢復。
理論分析
從PostgreSQL多版本實現的原理上,這是有可能的。因為PostgreSQL的多版本原理是舊資料並不刪除:
-
對於刪除資料的操作,只是把行上的xmax改成當前的事務id
-
對於更新操作,只是把原先行上xmax改成當前的事務id,並插入一個新行,而新行上的xmin置為當前的事務id
-
事務的狀態是記錄在commit log中的,如果事務提交,只是把commit log中相應的事務狀態改成“已提交狀態(TRANSACTION_STATUS_COMMITTED )”,如果事務回滾,則把commit log中的事務狀態改成“事務回滾(TRANSACTION_STATUS_ABORTED )”
所以從理論上說,只要把在commit log中剛提交事務狀態從“TRANSACTION_STATUS_COMMITTED”改成“TRANSACTION_STATUS_ABORTED”,原先的事務就會做廢,就能回到事務之前的狀態。
但這個恢復有一個前提就是舊版本的資料沒有被vacuum垃圾回收程式清理掉,如果舊版本的資料已被vacuum垃圾回收程式給清理掉了,就不能恢復了。所以如果作了刪除資料的操作後,馬上把資料庫停下來,這時autovacuum程式還沒有把舊版本的資料給清理掉時,資料是可以恢復的。
但僅僅是把commit log中的事務狀態改一下,就能恢復資料嗎?答案也是否定的,事情沒有這麼簡單,原因是多版本的可見性判斷不僅僅是由commit log中的事務狀態的決定的,行上還有t_infomask狀態位中的hint資訊來決定。如果hint已表示該行上的事務已被提交,則不需要再到commit log中來檢視事務的狀態了。這個功能主要是為了提高效能,因為到clog中判斷行的可見性,而clog中只有8個塊是快取在共享記憶體中的,如果判斷每個行都去查詢clog,效率太低了。具體這一部分的內容可以見我的另一篇blog: PostgreSQL中行的可見性判斷中t_infomask欄位的作用
所以要想恢復資料,還需要把相應表檔案中各行上的t_infomask狀態中的hint標誌位給清除掉之後,資料才能恢復回來。
恢復的工具
因為整個恢復的過程比較複雜,為此我寫了一個工具叫pg_fix,放在github上:https://github.com/osdba/pg_fix,供大家研究使用。
首先使用這個工具可以查詢某一個表的資料檔案中各行的狀態:
使用這個工具可以清理表的資料檔案中的t_infomask中的hint資訊,在清理hint狀態之前,先檢視行上的t_maskinfo狀態:
然後執行下面命令清除行上的hint狀態:
清除完後,我們再看行上的t_infomask狀態:
查詢和改變事務的狀態的方法如下:
查詢事務xid=11的狀態的命令如下:
修改事務xid=11的狀態的命令如下:
其中-s後的值表示要把事務改成什麼狀態,事務的狀態值有四種,為0~3,意思如下:
-
#define TRANSACTION_STATUS_IN_PROGRESS 0x00
-
#define TRANSACTION_STATUS_COMMITTED 0x01
-
#define TRANSACTION_STATUS_ABORTED 0x02
-
#define TRANSACTION_STATUS_SUB_COMMITTED 0x03
當然上面使用pg_fix工具直接修改表中資料和commit log中事務的狀態都必須是資料庫停下來的情況。
另本文的目的主要是為了研究PostgreSQL的一些原理,所以以上這些操作通常不要拿到生產資料庫上去試!!!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28218939/viewspace-1976067/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【北亞資料恢復】誤刪除oracle表和誤刪除oracle表資料的資料恢復方法資料恢復Oracle
- 【NetApp資料恢復案例】針對NetApp誤刪除資料的恢復APP資料恢復
- [20210930]bbed恢復刪除的資料.txt
- Sybase ASE資料庫恢復,Sybase資料恢復,資料誤刪除恢復工具READSYBDEVICE資料庫資料恢復dev
- 【儲存資料恢復案例】Netapp誤操作刪除lun的資料恢復資料恢復APP
- 【儲存資料恢復】NetApp儲存誤刪除的資料恢復案例資料恢復APP
- sd卡中的資料夾刪除了怎麼恢復,SD卡刪除的檔案如何恢復SD卡
- Sybase SQL Anywhere(ASA)資料庫恢復,ASA資料恢復,資料誤刪除恢復工具ReadASADBSQL資料庫資料恢復
- 【伺服器資料恢復】LINUX誤刪除、格式化的資料恢復伺服器資料恢復Linux
- 【伺服器資料恢復】NetApp儲存誤刪除的資料恢復案例伺服器資料恢復APP
- 【伺服器資料恢復】NetApp儲存中lun被誤刪除的資料恢復過程伺服器資料恢復APP
- 恢復Oracle資料庫誤刪除資料的語句Oracle資料庫
- 【資料庫資料恢復】LINUX環境下ORACLE資料庫誤刪除的資料恢復資料庫資料恢復LinuxOracle
- SQL Server資料庫恢復,SQL Server資料恢復,SQL Server資料誤刪除恢復工具SQLRescueSQLServer資料庫資料恢復
- 【儲存資料恢復】HP EVA儲存誤刪除VDISK的資料恢復案例資料恢復
- 【伺服器資料恢復】EMC Unity儲存誤刪除的資料恢復案例伺服器資料恢復Unity
- 【伺服器資料恢復】EMC Isilon儲存誤刪除的資料恢復案例伺服器資料恢復
- 伺服器資料恢復-LINUX誤刪除/格式化資料的資料恢復方案伺服器資料恢復Linux
- PostgreSQL刪除表中重複資料SQL
- 【oracle資料庫資料恢復】誤操作導致的資料庫誤刪除的資料恢復案例Oracle資料庫資料恢復
- 誤刪除儲存SqlServer資料庫資料恢復SQLServer資料庫資料恢復
- 誤刪除資料了怎麼辦?小編交易誤刪除資料的恢復方法
- 【伺服器資料恢復】伺服器誤刪除lun如何恢復資料?伺服器資料恢復
- MySQL資料庫表誤刪除恢復(一)MySql資料庫
- 伺服器資料恢復—NTFS誤操作刪除/格式化的資料恢復案例伺服器資料恢復
- 寶塔資料庫恢復 mysql資料庫丟失恢復 mysql資料庫刪除庫恢復 寶塔mysql資料庫恢復資料庫MySql
- 電腦裡刪除的檔案怎麼恢復,資料恢復方法大全資料恢復
- 【資料庫資料恢復】HP-UX系統ORACLE資料庫被誤刪除的資料恢復資料庫資料恢復UXOracle
- linux下恢復誤刪除oracle的資料檔案LinuxOracle
- [20190213]學習bbed-恢復刪除的資料.txt
- 伺服器資料恢復—EMC儲存資料卷被誤刪除如何恢復資料?伺服器資料恢復
- Mysql資料庫delete刪除後資料恢復報告MySql資料庫delete資料恢復
- 【伺服器資料恢復】伺服器誤刪除卷怎麼恢復資料伺服器資料恢復
- 【虛擬化資料恢復】KVM虛擬機器誤刪除資料恢復案例資料恢復虛擬機
- 【北亞資料恢復】zfs檔案系統的伺服器誤刪除的資料恢復資料恢復伺服器
- 誤刪除ESXi虛擬機器資料恢復虛擬機資料恢復
- EMC NAS中虛擬機器被誤刪除的資料恢復案例虛擬機資料恢復
- [Oracle]Oracle資料庫資料被修改或者刪除恢復資料Oracle資料庫
- 【伺服器資料恢復】LINUX誤刪除、誤格式化怎麼恢復資料?伺服器資料恢復Linux