Published on

PostgreSQL 的流复制

Authors

PostgreSQL 主从同步最直接的效果即使备份数据库。配合其它的解决方案,也可以起到读写分离,负载均衡的效果。一般情况下,生产环境主从同步是不可或缺的。可以最大限度的降低硬件损坏带来的负面影响,甚至可以做到无缝转移。PostgreSQL 主从同步是通过重做事务日志来实现的。本文采用的方法是通过流复制的方法来传递数据库的事务日志。使用流复制的方法,只要主库有新的日志产生,就会马上传递到从库。流复制传递日志的方式有两种,一种是异步方式,一种是同步方式。如果使用同步的方式,主库与备库的数据是完全同步,备库不会落后于主库,当主备切换时,可以做到零数据丢失。如果使用异步方式,事务提交之后不必传到从库即可返回,所以从库一般会落后于主库。

本文的实验环境是CentOS6.7,PostgreSQL 9.4.6。

创建从库的过程可以分为两大步骤,一是需要生成一个基础备份文件,第二就是把基础备份文件拷贝到备库上,然后配置从库的 recovery.conf 启动在 Standby 模式下,这样就完成了 Standby 数据库的搭建。

主库的关键配置大致如下:

wal_level = hot_standby  # 这个是设置主为wal的主机
max_wal_senders = 32 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个
wal_keep_segments = 256 # 设置流复制保留的最多的xlog数目
wal_sender_timeout = 60s # 设置流复制主机发送数据的超时时间
max_connections = 100 # 这个设置要注意下,从库的max_connections必须要大于主库的

在主库上建立复制用户:

CREATE ROLE repl login replication encrypted password 'GzgE50bBToH6rNyA';

在主库 pg_hba.conf 增加一个可以登录的用户(修改后需要重新加载配置文件):

host    replication     repl     10.47.8.17/32                 md5

在从库上做如下操作:

mkdir /home/postgres/pgdata/data2

pg_basebackup -F p --progress -D /home/postgres/pgdata/data2 -h 192.168.1.100 -p 5432 -U repl -P -x -R --password -l light_backup

cd /home/postgres/pgdata/
mv data data.backup
mv data2 data

修改 postgresql.conf 文件 设置 hot_standby = on

启动从库,至此,主从配置已经完成。

验证主从复制,是否在进行 目前主从两边数据库的状态:

postgres=# \l
                                List of databases
      Name       |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------------+----------+----------+---------+-------+-----------------------
 dbself_20160401 | dbself   | UTF8     | C       | C     |
 light           | postgres | UTF8     | C       | C     |
 postgres        | postgres | UTF8     | C       | C     |
 template0       | postgres | UTF8     | C       | C     | =c/postgres          +
                 |          |          |         |       | postgres=CTc/postgres
 template1       | postgres | UTF8     | C       | C     | =c/postgres          +
                 |          |          |         |       | postgres=CTc/postgres
(5 rows)

我们首先在主库上创建一个数据库,然后观察从库的状态:

postgres=# create database test_repl;
CREATE DATABASE

我们在从库上查看是否已经有变化:

postgres=# \l
                                List of databases
      Name       |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------------+----------+----------+---------+-------+-----------------------
 dbself_20160401 | dbself   | UTF8     | C       | C     |
 light           | postgres | UTF8     | C       | C     |
 postgres        | postgres | UTF8     | C       | C     |
 template0       | postgres | UTF8     | C       | C     | =c/postgres          +
                 |          |          |         |       | postgres=CTc/postgres
 template1       | postgres | UTF8     | C       | C     | =c/postgres          +
                 |          |          |         |       | postgres=CTc/postgres
 test_repl       | postgres | UTF8     | C       | C     |
(6 rows)

可以看到主库上创建的数据库已经被同步到从库。

其实,PostgreSQL已经提供了系统视图 pg_stat_replication,来让我们来查看主从复制的状况。 可以看一下视图的结构:

postgres=# \d pg_stat_replication
          View "pg_catalog.pg_stat_replication"
      Column      |           Type           | Modifiers
------------------+--------------------------+-----------
 pid              | integer                  |
 usesysid         | oid                      |
 usename          | name                     |
 application_name | text                     |
 client_addr      | inet                     |
 client_hostname  | text                     |
 client_port      | integer                  |
 backend_start    | timestamp with time zone |
 backend_xmin     | xid                      |
 state            | text                     |
 sent_location    | pg_lsn                   |
 write_location   | pg_lsn                   |
 flush_location   | pg_lsn                   |
 replay_location  | pg_lsn                   |
 sync_priority    | integer                  |
 sync_state       | text                     |

看一下运行运行状态(在主库执行):

postgres=# select pid, usesysid, usename, client_addr, client_port, state, sync_state, sync_priority from pg_stat_replication;
 pid  | usesysid | usename |  client_addr  | client_port |   state   | sync_state | sync_priority
------+----------+---------+---------------+-------------+-----------+------------+---------------
 4872 | 16463522 | repl    | 10.27.251.122 |       53075 | streaming | async      |             0
(1 row)
  • 2018.08.24 更新在从库查看主从同步的方式
  • 2018.09.02 更新最后一个在主库执行运行状态的视图