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

[译]PG复制和自动故障转移--2

yanzongshuaiDBA 2022-04-28
239

PostgreSQL 的预写日志 (WAL) 示例

1)

    SELECT datname, oid FROM pg_database WHERE datname = 'postgres';
    datname | oid
    ----------+-------
    postgres | 15709
    Note the database OID, i.e. 15709
    复制

    2)

      SELECT oid,* from pg_tablespace;
      oid | spcname | spcowner | spcacl | spcoptions
      ------+------------+----------+--------+------------
      1663 | pg_default | 10 | |
      1664 | pg_global | 10 | |
      Note the table space OID, i.e. 1663
      复制

      3)

        SELECT pg_current_wal_lsn();
        pg_current_wal_lsn
        --------------------
        0/1C420B8
        Note the LSN, i.e. 0/1C420B8
        复制

        4)

        CREATE TABLE abc(a VARCHAR(10));

        5)

          SELECT pg_relation_filepath('abc');
          pg_relation_filepath
          ----------------------
          base/15709/16384
          Note the relation filename, base/15709/16384
          复制

          6)通过pg_waldump --path=/tmp/sd/pg_wal -start=0/1C420B8看下日志文件里内容。使用的是步骤3中的起始LSN。注意WAL中包含创建物理文件的指令:

            15709 → database postgres → noted in step 1
            16384 → table abc → noted in step 5
            复制

            rmgr

            Len(rec/tot)

            tx

            lsn

            prev

            desc

            XLOG   

            30/ 30

               0

            0/01C420B8

            0/01C42080

            NEXTOID 24576

            Storage

             42/ 42

               0

            0/01C420D8

            0/01C420B8

            CREATE base/15709/16384

            Heap   

            203/203

            1216

            0/01C42108

            0/01C420D8

            INSERT off 2, blkref #0: rel 1663/15709/1247 blk 0

            Btree  

             64/ 64

            1216

            0/01C421D8

            0/01C42108

            INSERT_LEAF off 298, blkref #0: rel 1663/15709/2703 blk 2

            Btree  

             64/ 64

            1216

            0/01C42218

            0/01C421D8

            INSERT_LEAF off 7, blkref #0: rel 1663/15709/2704 blk 5

            Heap   

             80/ 80

            1216

            0/01C42258

            0/01C42218

            INSERT off 30, blkref #0: rel 1663/15709/2608 blk 9

            Btree  

             72/ 72

            1216

            0/01C422A8

            0/01C42258

            INSERT_LEAF off 243, blkref #0: rel 1663/15709/2673 blk 51

            Btree  

             72/ 72

            1216

            0/01C422F0

            0/01C422A8

            INSERT_LEAF off 170, blkref #0: rel 1663/15709/2674 blk 61

            Heap   

            203/203

            1216

            0/01C42338

            0/01C422F0

            INSERT off 6, blkref #0: rel 1663/15709/1247 blk 1

            Btree  

            64/64

            1216

            0/01C42408

            0/01C42338

            INSERT_LEAF off 298, blkref #0: rel 1663/15709/2703 blk 2

            Btree  

             72/ 72

            1216

            0/01C42448

            0/01C42408

            INSERT_LEAF off 3, blkref #0: rel 1663/15709/2704 blk 1

            Heap   

             80/ 80

            1216

            0/01C42490

            0/01C42448

            INSERT off 36, blkref #0: rel 1663/15709/2608 blk 9

            Btree  

             72/ 72

            1216

            0/01C424E0

            0/01C42490

            INSERT_LEAF off 243, blkref #0: rel 1663/15709/2673 blk 51

            Btree  

             72/ 72

            1216

            0/01C42528

            0/01C424E0

            INSERT_LEAF off 97, blkref #0: rel 1663/15709/2674 blk 57

            Heap   

            199/199

            1216

            0/01C42570

            0/01C42528

            INSERT off 2, blkref #0: rel 1663/15709/1259 blk 0

            Btree  

             64/ 64

            1216

            0/01C42638

            0/01C42570

            INSERT_LEAF off 257, blkref #0: rel 1663/15709/2662 blk 2

            Btree  

             64/ 64

            1216

            0/01C42678

            0/01C42638

            INSERT_LEAF off 8, blkref #0: rel 1663/15709/2663 blk 1

            Btree  

             64/ 64

            1216

            0/01C426B8

            0/01C42678

            INSERT_LEAF off 217, blkref #0: rel 1663/15709/3455 blk 5

            Heap   

            171/171

            1216

            0/01C426F8

            0/01C426B8

            INSERT off 53, blkref #0: rel 1663/15709/1249 blk 16

            Btree  

             64/ 64

            1216

            0/01C427A8

            0/01C426F8

            INSERT_LEAF off 185, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C427E8

            0/01C427A8

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42828

            0/01C427E8

            INSERT off 54, blkref #0: rel 1663/15709/1249 blk 16

            Btree  

             72/ 72

            1216

            0/01C428D8

            0/01C42828

            INSERT_LEAF off 186, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42920

            0/01C428D8

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42960

            0/01C42920

            INSERT off 55, blkref #0: rel 1663/15709/1249 blk 16

            Btree  

             72/ 72

            1216

            0/01C42A10

            0/01C42960

            INSERT_LEAF off 187, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42A58

            0/01C42A10

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42A98

            0/01C42A58

            INSERT off 1, blkref #0: rel 1663/15709/1249 blk 17

            Btree  

             72/ 72

            1216

            0/01C42B48

            0/01C42A98

            INSERT_LEAF off 186, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42B90

            0/01C42B48

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42BD0

            0/01C42B90

            INSERT off 3, blkref #0: rel 1663/15709/1249 blk 17

            Btree  

             72/ 72

            1216

            0/01C42C80

            0/01C42BD0

            INSERT_LEAF off 188, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42CC8

            0/01C42C80

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42D08

            0/01C42CC8

            INSERT off 5, blkref #0: rel 1663/15709/1249 blk 17

            Btree  

             72/ 72

            1216

            0/01C42DB8

            0/01C42D08

            INSERT_LEAF off 186, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42E00

            0/01C42DB8

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

            171/171

            1216

            0/01C42E40

            0/01C42E00

            INSERT off 30, blkref #0: rel 1663/15709/1249 blk 32

            Btree  

             72/ 72

            1216

            0/01C42EF0

            0/01C42E40

            INSERT_LEAF off 189, blkref #0: rel 1663/15709/2658 blk 25

            Btree  

             64/ 64

            1216

            0/01C42F38

            0/01C42EF0

            INSERT_LEAF off 194, blkref #0: rel 1663/15709/2659 blk 16

            Heap   

             80/ 80

            1216

            0/01C42F78

            0/01C42F38

            INSERT off 25, blkref #0: rel 1663/15709/2608 blk 11

            Btree  

             72/ 72

            1216

            0/01C42FC8

            0/01C42F78

            INSERT_LEAF off 131, blkref #0: rel 1663/15709/2673 blk 44

            Btree  

             72/ 72

            1216

            0/01C43010

            0/01C42FC8

            INSERT_LEAF off 66, blkref #0: rel 1663/15709/2674 blk 46

            Standby

             42/ 42

            1216

            0/01C43058

            0/01C43010

            LOCK xid 1216 db 15709 rel 16384 

            Txn    

            405/405

            1216

            0/01C43088

            0/01C43058

            COMMIT 2019-03-04 07:42:23.165514 EST;... snapshot 2608 relcache 16384

            Standby

             50/ 50

               0

            0/01C43220

            0/01C43088

            RUNNING_XACTS nextXid 1217 latestCompletedXid 1216 oldestRunningXid 1217

            7)

              SELECT pg_current_wal_lsn();
              pg_current_wal_lsn
              --------------------
              0/1C43258
              (1 row)
              8)
              INSERT INTO abc VALUES('pkn');
              复制

              9)

              ./pg_waldump --path=/tmp/sd/pg_wal --start=0/1C43258

              使用步骤7)中的起始LSN

                1663 → pg_default tablespace → noted in step 2
                15709 → database postgres → noted in step 1
                16384 → table abc → noted in step 5
                复制

                rmgr

                Len (rec/tot)

                tx

                lsn

                prev

                desc

                Heap

                59/59

                1217

                0/01C43258

                0/01C43220

                INSERT+INIT off 1, blkref #0: rel 1663/15709/16384 blk 0

                Transaction

                34/34

                1217

                0/01C43298

                0/01C43258

                COMMIT 2019-03-04 07:43:45.887511 EST

                Standby

                54/54

                0

                0/01C432C0

                0/01C43298

                RUNNING_XACTS nextXid 1218 latestCompletedXid 1216 oldestRunningXid 1217; 1 xacts: 1217

                10)

                  SELECT pg_current_wal_lsn();
                  pg_current_wal_lsn
                  --------------------
                  0/1C432F8
                  (1 row)
                  11)
                  INSERT INTO abc VALUES('ujy');
                  复制

                  12)./pg_waldump --path=/tmp/sd/pg_wal –start=0/1C432F8使用步骤10)中的起始LSN

                  rmgr

                  Len (rec/tot)

                  tx

                  lsn

                  prev

                  desc

                  Heap       

                  59/59

                  1218

                  0/01C432F8

                  0/01C432C0

                  INSERT off 2, blkref #0: rel 1663/15709/16384 blk 0

                  Transaction

                  34/34

                  1218

                  0/01C43338

                  0/01C432F8

                  COMMIT 2019-03-04 07:44:25.449151 EST

                  Standby    

                  50/50

                     0

                  0/01C43360

                  0/01C43338

                  RUNNING_XACTS nextXid 1219 latestCompletedXid 1218 oldestRunningXid 1219

                  13)检查WAL段文件中的真实记录

                    ---------+---------------------------------------------------+----------------+
                    Offset | Hex Bytes | ASCII chars |
                    ---------+---------------------------------------------------+----------------+
                    00000060 | 3b 00 00 00 c3 04 00 00 28 00 40 02 00 00 00 00 |;.......(.@.....|
                    00000070 | 00 0a 00 00 ec 28 75 6e 00 20 0a 00 7f 06 00 00 |.....(un. ......|
                    00000080 | 5d 3d 00 00 00 40 00 00 00 00 00 00 ff 03 01 00 |]=...@..........|
                    00000090 | 02 08 18 00 09 70 6b 6e 03 00 00 00 00 00 00 00 |.....pkn........|
                    000000a0 | 22 00 00 00 c3 04 00 00 60 00 40 02 00 00 00 00 |".......`.@.....|
                    000000b0 | 00 01 00 00 dd 4c 87 04 ff 08 e4 73 44 e7 41 26 |.....L.....sD.A&|
                    000000c0 | 02 00 00 00 00 00 00 00 32 00 00 00 00 00 00 00 |........2.......|
                    000000d0 | a0 00 40 02 00 00 00 00 10 08 00 00 9e 01 36 88 |..@...........6.|
                    000000e0 | ff 18 00 00 00 00 00 00 00 00 00 03 00 00 c4 04 |................|
                    000000f0 | 00 00 c4 04 00 00 c3 04 00 00 00 00 00 00 00 00 |................|

                    00000100 | 3b 00 00 00 c4 04 00 00 c8 00 40 02 00 00 00 00 |;.........@.....|
                    00000110 | 00 0a 00 00 33 df b4 71 00 20 0a 00 7f 06 00 00 |....3..q. ......|
                    00000120 | 5d 3d 00 00 00 40 00 00 00 00 00 00 ff 03 01 00 |]=...@..........|
                    00000130 | 02 08 18 00 09 75 6a 79 04 00 00 00 00 00 00 00 |.....ujy........|
                    00000140 | 22 00 00 00 c4 04 00 00 00 01 40 02 00 00 00 00 |".........@.....|
                    00000150 | 00 01 00 00 96 2e 96 a6 ff 08 d8 f3 79 ed 41 26 |............y.A&|
                    00000160 | 02 00 00 00 00 00 00 00 32 00 00 00 00 00 00 00 |........2.......|
                    00000170 | 40 01 40 02 00 00 00 00 10 08 00 00 eb 6b 95 36 |@.@..........k.6|
                    00000180 | ff 18 00 00 00 00 00 00 00 00 00 03 00 00 c5 04 |................|
                    00000190 | 00 00 c5 04 00 00 c4 04 00 00 00 00 00 00 00 00 |................|
                    000001a0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
                    复制

                    PostgreSQL 中基于 WAL 的复制选项有哪些?

                    持续WAL归档

                    基于日志传送的复制 -- 文件级别

                    基于日志传送的复制 -- 块级

                    持续WAL归档

                    将生成的 WAL 文件复制到 pg_wal 子目录以外的任何位置以进行归档称为 WAL 归档。每次生成 WAL 文件时,PostgreSQL 都会调用用户提供的用于归档的脚本。该脚本可以使用 scp 命令将文件复制到一个或多个位置。该位置可以是 NFS 挂载。归档后,WAL 段文件可用于在任何指定时间点恢复数据库。

                    基于日志传送的复制 -- 文件级别

                    将日志文件复制到另一个 PostgreSQL 服务器以通过重放WAL文件来创建另一个备用服务器称为日志传送。此备用服务器配置为处于恢复模式,其唯一目的是在任何新 WAL 文件到达时回放它们。这第二台服务器(也称为备用服务器)然后成为主PostgreSQL服务器的热备份。备用数据库也可以配置为只读副本,它还可以提供只读查询。这称为热备份

                    基于日志传送的复制 -- 块级

                    流式复制改进了日志传送过程。无需等待WAL切换,而是在生成记录时发送记录,从而减少复制延迟。另一个改进是备用服务器将使用复制协议通过网络连接到主服务器。然后,主服务器可以直接通过此连接发送WAL记录,而无需依赖用户提供的脚本。

                    主服务器应该保留WAL段文件多久?

                    如果没有流复制,一旦归档脚本报告归档成功,就可以丢弃/回收崩溃恢复不需要的WAL文件。

                    但是,存在备后就会产生一个问题:只要最慢的备需要它们,服务器就需要保留 WAL 文件。例如,如果备数据库被关闭了一段时间,然后重新联机并向主数据库请求主数据库不再拥有的 WAL 文件,则复制失败并出现类似于以下内容的错误:

                    ERROR: requested WAL segment 00000001000000010000002D has already been removed

                    因此,主服务器应该跟踪备用服务器的落后程度,而不是删除/回收任何备用服务器仍然需要的 WAL 文件。此功能是通过复制槽提供的。

                    每个复制槽都有一个用于标识槽的名称。每个slot

                    1) 槽的消费者需要的最旧的 WAL 段文件。在检查点期间不会删除/回收比这更新的 WAL 段文件。

                    2) 槽的消费者需要保留的最早的事务 ID。任何比这更近的事务所需的行都不会被真空删除。

                    基于日志传送的复制

                    物理流复制

                     

                    PostgreSQL 数据库中的物理流复制是基于WAL的数据复制。在流式复制中,备用服务器连接到主服务器并使用复制协议接收 WAL 记录。

                    物理流复制有哪些优势?

                    1) 备用服务器不需要等待 WAL 文件填满,这改善了复制延迟。

                    2) 删除了对用户提供的脚本和服务器之间的中间共享存储的依赖。

                    PostgreSQL 中的 WAL Sender 和 WAL Receiver 是什么?

                    WAL receiver进程运行在备机上,使用 recovery.conf 的primary_conninfo参数中提供的连接详细信息,并使用 TCP/IP 连接连接到主服务器。

                    WAL sender是运行在主服务器上的另一个进程,负责在生成 WAL 记录时将其发送到备用服务器。WAL receiver WAL 记录保存在 WAL 中,就好像它们是由本地连接的客户端的客户端活动生成的一样。一旦 WAL 记录到达 WAL 段文件,备用服务器会不断地回放 WAL,以便备用服务器和主服务器是最新的。

                     

                    PostgreSQL 复制和故障转移设置

                    该设置由两台通过 LAN 连接的 CentOS 7 机器组成,其中安装了 PostgreSQL 版本 10.7。

                    配置流复制:

                    1)禁用并停止两台机器上的防火墙:

                      sudo firewall-cmd --state
                      sudo systemctl stop firewalld
                      sudo systemctl disable firewalld
                      sudo systemctl mask --now firewalld
                      复制

                      2)在主服务器上,允许复制连接和来自同一网络的连接。修改 pg_hba.conf

                        Local  all           all                       md5
                        host   all           all   172.16.214.167/24   md5
                        host   all           all   ::1/128             md5
                        local  replication   all                       md5
                        host   replication   all   172.16.214.167/24   md5
                        host replication all ::1/128 md5
                        复制

                        3)在主服务器上,编辑 postgresql.conf 修改以下参数

                          max_wal_senders = 10
                          wal_level = replica
                          max_replication_slots = 10
                          synchronous_commit = on
                          synchronous_standby_names = '*'
                          listen_addresses = '*'
                          复制

                          4)启动主服务器

                          ./postgres -D ../pr_data -p 5432

                          5)通过基础备份构建备

                            ./pg_basebackup
                            --pgdata=/tmp/sb_data/
                            --format=p
                            --write-recovery-conf
                            --checkpoint=fast
                            --label=mffb
                            --progress
                            --verbose
                            --host=172.16.214.167
                            --port=5432
                            --username=postgres
                            复制

                            6)检查base backup label文件

                              START WAL LOCATION: 0/2000028 (file 000000010000000000000002)
                              CHECKPOINT LOCATION: 0/2000060
                              BACKUP METHOD: streamed
                              BACKUP FROMmaster
                              START TIME2019-02-24 05:25:30 EST
                              LABEL: mffb
                              复制

                              7)在基本备份中,在 recovery.conf 中添加以下行:

                              primary_slot_name = 'node_a_slot'

                              8)检查 tmp/sb_data/recovery.conf 文件

                                standby_mode = 'on'
                                primary_conninfo = 'user=enterprisedb
                                password=abc123
                                host=172.16.214.167
                                port=5432
                                sslmode=prefer
                                sslcompression=1
                                krbsrvname=postgres
                                target_session_attrs=any'
                                primary_slot_name = 'node_a_slot'
                                复制

                                9)连接到主服务器并发出以下命令:

                                  edb=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot');
                                        slot_name  | xlog_position
                                      -------------+---------------
                                       node_a_slot |
                                  (1 row)
                                  复制

                                    edb=# SELECT slot_name, slot_type, active FROM pg_replication_slots;
                                          slot_name  | slot_type | active
                                        -------------+-----------+--------
                                         node_a_slot | physical  | f
                                    (1 row)
                                    复制

                                    10)将基础备份传输到备用服务器:

                                    scp tmp/sb_data.tar.gz abbas@172.16.214.166:/tmp

                                    sudo mv tmp/sb_data /opt/PostgreSQL/10/

                                    sudo chown postgres:postgres /opt/PostgreSQL/10/sb_data/

                                    sudo chown -R postgres:postgres /opt/PostgreSQL/10/sb_data/

                                    sudo chmod 700 /opt/PostgreSQL/10/sb_data/

                                    11)启动备

                                    ./postgres -D ../sb_data/ -p 5432

                                    主上显示:

                                    LOG:  standby "walreceiver" is now a synchronous standby with priority 1

                                    备上显示:

                                    LOG:  database system was interrupted; last known up at 2018-10-24 15:49:55

                                    LOG:  entering standby mode

                                    LOG:  redo starts at 0/3000028

                                    LOG:  consistent recovery state reached at 0/30000F8

                                    LOG:  started streaming WAL from primary at 0/4000000 on timeline 1

                                    12)连接到主服务器并发出一些简单的命令:

                                      -bash-4.2$ ./edb-psql -p 5432 edb
                                      Password:
                                      psql.bin (10.7)
                                      Type "help" for help.


                                      create table abc(int, b varchar(250));
                                      insert into abc values(1,'One');
                                      insert into abc values(2,'Two');
                                      insert into abc values(3,'Three');
                                      复制

                                      13)检查备上数据

                                        ./psql -p 5432 -U postgres postgres
                                        Password for user postgres:
                                        psql.bin (10.7)
                                        Type "help" for help.


                                        postgres=# select * from abc;
                                        a |   b   
                                        ---+-------
                                        1 | One
                                        2 | Two
                                        3 | Three
                                        (3 rows)
                                        复制

                                        PostgreSQL 手动故障转移步骤是什么?

                                        1)使主崩溃

                                        2)备上执行promote提升主

                                           ./pg_ctl promote -D ../sb_data/

                                        server promoting

                                        3)连接提升的备用服务器并插入一行:

                                          -bash-4.2$ ./edb-psql -p 5432 edb
                                          Password:
                                          psql.bin (10.7)
                                          Type "help" for help.
                                          edb=# insert into abc values(4,'Four');
                                          复制

                                          此插入工作正常的事实意味着备用服务器(否则为只读服务器)已被提升为新的主服务器

                                          如何在 PostgreSQL 中自动进行故障转移和复制

                                          使用 EDB Postgres Failover Manager (EFM) 可以轻松设置自动故障转移。在每个主节点和备用节点上下载并安装 EFM后,您可以创建一个EFM 集群,该集群由一个主节点、一个或多个备用节点和一个可选的见证节点组成,该节点在发生故障时确认断言。

                                          EFM 持续监控系统运行状况并根据系统事件发送电子邮件警报。当发生故障时,它会自动切换到最新的备用服务器,并重新配置所有其他备用服务器以识别新的主服务器。它还重新配置负载平衡器(例如 pgPool)并防止脑裂(当两个节点都认为它们是主节点时)发生。

                                          PostgreSQL 的 repmgr

                                          另一个开源工具是 repmgr(复制管理器),它还管理 PostgreSQL 集群的复制和故障转移。EDB为安装和运行 repmgr for PostgreSQL提供了深入的教程。正确配置后,repmgr 可以检测主服务器何时发生故障并执行自动故障转移

                                          https://www.enterprisedb.com/postgres-tutorials/how-implement-repmgr-postgresql-automatic-failover

                                          原文

                                          https://www.enterprisedb.com/postgres-tutorials/postgresql-replication-and-automatic-failover-tutorial


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

                                          评论