半个PostgreSQL DBA,热衷于数据库相关的技术。我的ppt分享https://pan.baidu.com/s/1eRQsdAa https://github.com/chenhuajun https://chenhuajun.github.io
分类: Mysql/postgreSQL
2020-04-04 13:00:28
最近在walminer基础做了不少修改,以支持我们的使用场景。详细参考
修改也花了不少精力和时间,这个过程中有些东西想记录下来,方便以后查阅。
所以,这篇东西有点像流水账。
解析WAL的第一步是要了解WAL的文件格式,我觉得最详细易懂最值得看的资料是下面这个。
但是,以上还不够。细节的东西还是要看源码。我主要看的是写WAL记录的地方。
walminer作者李传成的博客里也有不少WAL解析相关的文章,是后来才发现的,我还没有看过。
walminer解析WAL的入口是pg_minerXlog()函数。其主要过程如下
walminer把WAL记录中tuple变成SQL的过程比较有意思,中间用了一个VALUES的临时格式。
以下面这个UPDATE语句为例
update tb1 set c1='3xy' where id=3;
其解析过程中涉及到的一些调用点如下:
- pg_minerXlog()
- ->sqlParser()
- ->XLogMinerRecord()
- ->XLogMinerRecord_heap()
- ->minerHeapUpdate(XLogReaderState *record, XLogMinerSQL *sql_simple, uint8 info)
- 1. 获取更新前后的tuple值(字符串格式)
- ->getTupleInfoByRecord()
- ->getTupleData_Update()
- ->mentalTup()
- ->mentalTup_nulldata()
- ->mentalTup_valuedata()
- tupleInfo:VALUES(-3, '3x')"
- tupleInfo_old:VALUES(3, NULL)
- 2. 生成中间redo SQL
- ->getUpdateSQL(sql_simple, tupleInfo, tupleInfo_old,...)
- sql_simple:UPDATE \"public\".\"tb1\" SET VALUES(3, '3xy') WHERE VALUES(3, '3x')
- 3. 生成中间undo SQL
- ->getUpdateSQL(&srctl.sql_undo, tupleInfo_old, tupleInfo,...)
- srctl.sql_undo:UPDATE \"public\".\"tb1\" SET VALUES(3, '3x') WHERE VALUES(-3, '3xy')"
- 4. 生成最终undo SQL
- 将中间中" VALUES"之后部分抹去,从rrctl.values,rrctl.nulls,rrctl.values_old,rrctl.nulls_old重新生成SQL后半部分。
- ->reAssembleUpdateSql(&srctl.sql_undo,true);
- srctl.sql_undo:UPDATE "public"."tb1" SET "c1" = '3x' WHERE "id"=3 AND "c1"='3xy' AND ctid = '(0,10)';
- pg_minerXlog()
- ->sqlParser()
- ->parserUpdateSql()
- 4. 生成最终redo SQL
- ->reAssembleUpdateSql(sql_ori, false)
- sql_ori:UPDATE "public"."tb1" SET "c1" = '3xy' WHERE "id"=3 AND "c1"='3x';
walminer是个非常棒的工具,填补了PG的一个空白。 但是,在我们准备把它推向生产时发现了不少问题。
对这些已知的问题,都进行了改进。主要有下面几点
修改后的walminer参考
后续希望这些修改能合到源库里。
walminer在功能和使用场景上和MySQL的binlog2sql是非常接近的。
binlog2sql对自己的场景描述如下:
binlog2sql已经有很多生产部署的案例,但是walminer好像还没有。 其中原因,我想除了修改版已经解决的那些问题,walminer作为闪回工具,还有进一步改进的空间。
我考虑主要有以下几点可以改进的