暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PG原生解码工具pg_recvlogical的使用-在脑裂时帮我们找回丢失的数据

     数据库逻辑解码很有必要,也很有用处,多用于异构数据库逻辑复制中。另外逻辑解码在某些关键时候可以救命,比如主从脑裂的场景,如果在主备切换后原主库还有业务写入会造成脑裂,这时候如果创建了逻辑复制槽,那么可以将某段时间的xlog日志解码成sql语句,找回丢失的数据,这一点很有用。
     pg有很多逻辑解码的插件,其中pg原生的逻辑解码工具pg_recvlogical就可以使用,它使用默认的test_decoding的插件,该插件位于pg源码contrib/test_decoding目录下,需要先对该目录进行安装,安装完后会在pg安装目录的lib目录下创建test_decoding链接库文件。
     下面具体看看pg_recvlogical的使用以及在主备脑裂时候如何找回丢失的数据。
安装test_decoding插件
    [postgres@db1 ~]$ cd pgsql/postgresql-11.3/contrib/test_decoding/
    [postgres@db1 test_decoding]$ make && make install
    复制
    创建逻辑复制槽
      [postgres@db1 share]$ pg_recvlogical --create-slot -S logicslot -d test
      [postgres@db1 share]$ psql
      psql (11.3)
      Type "help" for help.


      postgres=# select * from pg_replication_slots;
      slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn
      -----------+---------------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------
      logicslot | test_decoding | logical | 24760 | test | f | f | | | 110980560 | 7F/B0178EB8 | 7F/B0178EF0
      (1 row)
      复制
           启动复制槽(后台启动会实时的将日志解码到制定的文件中,也可以不启动,在需要解码xlog时再启动解码)
        [postgres@db1 pginst1]$ pg_recvlogical --start -S logicslot -d test -f logical_decoding.log &
        复制
             测试一下实时解码
          [postgres@db1 pginst1]$ psql test
          psql (11.3)
          Type "help" for help.


          test=# create table test(id int);
          CREATE TABLE
          test=# insert into test values(1);
          INSERT 0 1


          [postgres@db1 pginst1]$ cat logical_decoding.log
          BEGIN 110980560
          COMMIT 110980560
          BEGIN 110980561
          table public.test: INSERT: id[integer]:1
          COMMIT 110980561
          复制
               模拟主备脑裂,找回原主库丢失的数据
               先将流复制环境改为异步(如果同步的话,备库提升后原主库无法写入,无法模拟原主库脑裂写入)
            postgres=# alter system set synchronous_standby_names='';
            ALTER SYSTEM
            postgres=# \q
            [postgres@HWFBS01 ~]$ pg_ctl reload
            server signaled
            [postgres@HWFBS01 ~]$ psql
            psql (11.3)
            Type "help" for help.


            postgres=# show synchronous_standby_names;
            synchronous_standby_names
            ---------------------------


            (1 row)
            复制
            查询主库lsn位置:
              postgres=# select pg_current_wal_lsn();
              pg_current_wal_lsn
              --------------------
              4C/47000060
              (1 row)
              复制
              备库直接提升为主库:
                [postgres@HWFBS02 ~]$ pg_ctl promote
                waiting for server to promote.... done
                server promoted
                复制
                原主库继续写入数据,模拟脑裂
                  test=# delete from test;
                  DELETE 32
                  test=# insert into test values(1);
                  INSERT 0 1
                  复制
                  查看原主库当前lsn位置
                    postgres=# select pg_current_wal_lsn();
                    pg_current_wal_lsn
                    --------------------
                    4C/470044E0
                    (1 row)
                    复制
                    使用pg_recvlogical进行日志区间解码
                      [postgres@HWFBS01 ~]$ pg_recvlogical --start -S logicslot -d test -I 4C/47000060 -E 4C/470044E0 -f 1.log
                      复制
                      查看解码的日志内容:
                        [postgres@HWFBS01 ~]$ cat 1.log
                        BEGIN 493416304
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        table public.test: DELETE: (no-tuple-data)
                        COMMIT 493416304
                        BEGIN 493416305
                        table public.test: INSERT: id[integer]:1
                        COMMIT 493416305
                        BEGIN 493416306
                        COMMIT 493416306
                        复制
                             通过日志发现test发生了一次delete全部数据,insert了一条数据,通过这些内容可以将应用丢失的数据找回。
                        使用逻辑解码有几点需要注意:
                        1、逻辑复制槽使用一定要注意因为无法消费造成主库的xlog堆积的问题
                        2、如果之前已经解码过一段区间的xlog,restart_lsn会进行推进,这时如果新解码的区间包含原有lsn区间,会忽略原来的xlog日志,也就是说连续对某段xlog进行两次解码,第二次是解码不出来内容的。
                        3、逻辑解码需要设置wal_level=logic,这个会大大增加wal大小,对性能有很大的损害,如果是高并发insert环境下,写逻辑解码日志的速度可能会成为瓶颈。

                        I Love PG
                        复制

                        关于我们

                        PostgreSQLPG2017PostgreSQLPG非盈利行业协会组织。我们致力于在中国PostgreSQLPostgreSQL

                        复制

                        欢迎投稿

                        做你的舞台,show出自己的才华 。

                        投稿邮箱:partner@postgresqlchina.com

                                            

                                            ——愿能安放你不羁的灵魂


                        技术文章精彩回顾




                        PostgreSQL学习的九层宝塔
                        PostgreSQL职业发展与学习攻略
                        2019,年度数据库舍 PostgreSQL 其谁?
                        Postgres是最好的开源软件
                        PostgreSQL是世界上最好的数据库
                        从Oracle迁移到PostgreSQL的十大理由
                        从“非主流”到“潮流”,开源早已值得拥有

                        PG活动精彩回顾




                        创建PG全球生态!PostgresConf.CN2019大会盛大召开
                        首站起航!2019“让PG‘象’前行”上海站成功举行
                        走进蓉城丨2019“让PG‘象’前行”成都站成功举行
                        中国PG象牙塔计划发布,首批合作高校授牌仪式在天津举行
                        群英论道聚北京,共话PostgreSQL
                        相聚巴厘岛| PG Conf.Asia 2019  DAY0、DAY1简报
                        相知巴厘岛| PG Conf.Asia 2019 DAY2简报
                        独家|硅谷Postgres大会简报
                        直播回顾 | Bruce Momjian:原生分布式将在PG 14版本发布

                        PG培训认证精彩回顾




                        中国首批PGCA认证考试圆满结束,203位考生成功获得认证!
                        中国第二批PGCA认证考试圆满结束,115位考生喜获认证!
                        重要通知:三方共建,中国PostgreSQL认证权威升级!
                        近500人参与!首次PGCE中级、第三批次PGCA初级认证考试落幕!
                        2020年首批 | 中国PostgreSQL初级认证考试圆满结束
                        一分耕耘一分收获,第五批次PostgreSQL认证考试成绩公布


                        复制
                        文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                        评论