PG wal日誌解析工具功能加強並改名爲WalMiner

使用軟件遇到問題可先更新代碼(歡迎提交bug)~~node

開發羣組:811105058歡迎任何使用者git

 

XlogMiner是從PostgreSQL的WAL(write ahead logs)日誌中解析出執行的SQL語句的工具,並能生成出對應的undo SQL語句。此版本使用限制較大,須要將wal級別設置爲logical,並且須要將表設置爲IDENTITY FULL模式。這會加重wal日誌的膨脹,下降數據庫性能。爲迎合PG日誌名稱的改變,現將XlogMiner更名爲WalMiner。新的開源地址爲:https://gitee.com/movead/XLogMinersql

WalMiner功能加強

1.WalMiner支持解析minimal級別以上的任何wal日誌級別。數據庫

2.無需將表設置爲IDENTITY FULL模式。bash

3.增長對系統表修改的wal記錄的解析。工具

4.修復發生relfilenode變化後,異庫解析失敗的bug。post

WalMiner帶來的新的限制

walminer能夠完整的解析出給定的wal日誌中第一個checkpoint點以後的全部wal記錄。第一個checkpoint點以前的delete和update記錄可能會解析失敗,以下。性能

UPDATE "public"."t1" SET VALUES(NULL) (NOTICE:wal is not enought.);

若是必定須要將此記錄解析出來,那麼只須要增長更早的wal日誌便可。測試

使用方法一

1.編譯安裝

代碼下載地址:https://gitee.com/movead/XLogMiner/releasesui

編譯安裝:將下載的代碼中的walminer目錄放置到數據庫代碼的contrib目錄下,執行make;make install

[lichuancheng@IP43 walminer]$ pwd
/work/src/lichuancheng/postgresql-11.1/contrib/walminer
[lichuancheng@IP43 walminer]$ make;make install

2.建立extension

postgres=# create extension walminer;
CREATE EXTENSION
postgres=#

3.插入測試數據

postgres=# create table t2(i int,j int, k varchar);
CREATE TABLE
postgres=# insert into t2 values(1,1,'qqqqqq');
INSERT 0 1
postgres=# insert into t2 values(2,2,'wwwwww');
INSERT 0 1
postgres=# insert into t2 values(3,3,'eeeee');
INSERT 0 1
postgres=# update t2 set k = '1111qqqqq' where i = 1; 
UPDATE 1
postgres=# delete from t2 where j = 2;
DELETE 1
postgres=# insert into t2 values(4,4,'44444rrrrrr');
INSERT 0 1
postgres=# select pg_walfile_name(pg_current_wal_lsn());
     pg_walfile_name      
--------------------------
 00000001000000000000000A
(1 row)

postgres=# select pg_switch_wal();
 pg_switch_wal 
---------------
 0/A003508
(1 row)

postgres=#

手動備份這個須要解析的wal日誌(此處我沒有開歸檔,作這個手動備份防止wal日誌被數據庫移除)

[lichuancheng@IP43 pg_wal]$ cp 00000001000000000000000A 111/
[lichuancheng@IP43 pg_wal]$

4.指定須要解析的wal日誌

(wal日誌能夠放置在任意位置,也可同時指定多個wal日誌)

postgres=# select walminer_wal_add('pg_wal/111/00000001000000000000000A');
NOTICE:  Get data dictionary from current database.
  walminer_wal_add  
--------------------
 1 file add success
(1 row)

5.執行解析

解析方法1:
postgres=# select walminer_start('NULL','NULL',0,0);
   walminer_start    
---------------------
 walminer sucessful!
(1 row)
解析方法2:(此種解析在$PGDATA/walminer/temp目錄下會記錄系統表的變動狀況)
postgres=# select walminer_start('NULL','NULL',0,0,true);
   walminer_start    
---------------------
 walminer sucessful!

6.解析結果查看

postgres=# \x
Expanded display is on.
postgres=# select record_database,record_user,op_text,op_undo from walminer_contents;
-[ RECORD 1 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | INSERT INTO "public"."t2"("i", "j", "k") VALUES(1, 1, 'qqqqqq');
op_undo         | DELETE FROM "public"."t2" WHERE "i"=1 AND "j"=1 AND "k"='qqqqqq' AND ctid = '(0,1)';
-[ RECORD 2 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | INSERT INTO "public"."t2"("i", "j", "k") VALUES(2, 2, 'wwwwww');
op_undo         | DELETE FROM "public"."t2" WHERE "i"=2 AND "j"=2 AND "k"='wwwwww' AND ctid = '(0,2)';
-[ RECORD 3 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | INSERT INTO "public"."t2"("i", "j", "k") VALUES(3, 3, 'eeeee');
op_undo         | DELETE FROM "public"."t2" WHERE "i"=3 AND "j"=3 AND "k"='eeeee' AND ctid = '(0,3)';
-[ RECORD 4 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | UPDATE "public"."t2" SET "k" = '1111qqqqq' WHERE "i"=1 AND "j"=1 AND "k"='qqqqqq';
op_undo         | UPDATE "public"."t2" SET "k" = 'qqqqqq' WHERE "i"=1 AND "j"=1 AND "k"='1111qqqqq' AND ctid = '(0,4)';
-[ RECORD 5 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | DELETE FROM "public"."t2" WHERE "i"=2 AND "j"=2 AND "k"='wwwwww';
op_undo         | INSERT INTO "public"."t2"("i", "j", "k") VALUES(2, 2, 'wwwwww');
-[ RECORD 6 ]---+------------------------------------------------------------------------------------------------------
record_database | postgres
record_user     | lichuancheng
op_text         | INSERT INTO "public"."t2"("i", "j", "k") VALUES(4, 4, '44444rrrrrr');
op_undo         | DELETE FROM "public"."t2" WHERE "i"=4 AND "j"=4 AND "k"='44444rrrrrr' AND ctid = '(0,5)';

postgres=#

使用方法二

可使用測試數據庫解析生產庫的wal日誌。

(1)須要使用select walminer_build_dictionary(PATH);在生產庫生成數據字典,而後將生成的數據字典和須要解析的wal日誌放到測試庫能夠獲取的路徑。

(2)在測試庫使用select walminer_load_dictionary(PATH);加載數據字典

(3)指定wal日誌->執行解析->查看解析結果

具體使用方法在開源代碼中的readme中查看。

使用限制

1.本版本只解析DML語句,不處理DDL語句
將來改動:DDL語句的解析已放入todolist,可能會逐步支持各類DDL語句

2.執行了刪除表、truncate表、更改表的表空間、更改表字段的類型、vacuum full,這樣的DDL語句後,發生DDL語句以前的此表相關的DML語句不會再被解析。
應對措施:建議在執行表結構變動以前,先保存一份數據字典,用來保證能夠解析歷史wal日誌。
將來改動:如今已經考慮在walminer內增長保存數據字典的功能

3.解析結果依賴於數據字典。(舉例:建立表t1,全部者爲user1,可是中間將全部者改成user2。那解析結果中,全部t1相關操做全部者都將標示爲user2)
應對措施:建議在執行表結構變動以前,先保存一份數據字典,用來保證能夠解析歷史wal日誌。
將來改動:如今已經考慮在walminer內增長保存數據字典的功能

4.解析結果中undo字段的ctid屬性是發生變動「當時」的值,若是由於vacuum等操做致使ctid發生變動,這個值將不許確。對於有可能存在重複行的數據,
咱們須要經過這個值肯定undo對應的tuple條數,不表明能夠直接執行該undo語句。

5.執行了表字段drop的DDL語句後,發生DDL語句以前的這個字段相關的值都會被解析爲encode('AD976BC56F',hex)的形式,另外自定義類型也會解析爲這種形式

6.只能解析與數據字典時間線一致的wal文件

7.WalMiner是我的出品,暫時未進行全面測試。

8.[20190309新增]不建議使用walminer解析大宗copy語句(在同一個事務中插入大量數據行)產生的wal日誌,

  這會致使解析過程當中的效率低下和內存佔用太高。

 

WalMiner的改進原理

    舊版本的工具xlogminer的解析來源是當前wal record所記錄的"變動點"。它不會從FPW裏的page裏獲取數據進行wal記錄的解析。而新版本的walminer不只能夠解析當前wal記錄的FPW,並且還對解析過程當中出現的全部FPW進行記錄和redo。所以walminer能夠解析低級別的wal日誌,能夠不須要將表設置爲DENTITY FULL模式。

    以下圖所示,咱們加載了從000000030000075100000050開始的不少wal日誌。000000030000075100000050到00000003000007510000005A的wal日誌可能會由於它依賴的wal日誌不足而沒法徹底解析(表現爲一些DML記錄沒有具體數據),在提示時間或LSN(2019-03-21 13:57:46+08 or 751/5a711300)以後的數據會徹底解析。

 

聯繫我

發現bug或者有好的建議能夠經過郵箱(lchch1990@sina.cn)聯繫我。

相關文章
相關標籤/搜索