91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PostgreSQL中刪除的數據能否恢復

發布時間:2020-09-12 04:53:25 來源:網絡 閱讀:825 作者:沃趣科技 欄目:數據庫

作者:沃趣科技首席數據庫架構師 唐成



問題的提出


  • 有人問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供大家研究使用。 

首先使用這個工具可以查詢某一個表的數據文件中各行的狀態: PostgreSQL中刪除的數據能否恢復


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


然后執行下面命令清除行上的hint狀態:  PostgreSQL中刪除的數據能否恢復


清除完后,我們再看行上的t_infomask狀態:  PostgreSQL中刪除的數據能否恢復


查詢和改變事務的狀態的方法如下: 

查詢事務xid=11的狀態的命令如下:  PostgreSQL中刪除的數據能否恢復


修改事務xid=11的狀態的命令如下:  PostgreSQL中刪除的數據能否恢復


其中-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的一些原理,所以以上這些操作通常不要拿到生產數據庫上去試!!!




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绿春县| 乌什县| 莱西市| 芜湖市| 昆明市| 曲水县| 江口县| 甘谷县| 宽甸| 铜川市| 淳化县| 醴陵市| 新郑市| 吉安县| 荃湾区| 襄城县| 来凤县| 夏河县| 南康市| 蓝山县| 阿拉尔市| 黑河市| 金坛市| 泗水县| 湖州市| 石阡县| 长治市| 南通市| 固阳县| 柘荣县| 沛县| 唐海县| 区。| 文登市| 眉山市| 泾川县| 班戈县| 华安县| 辛集市| 金阳县| 万载县|