Postgresql数据库主从流复制

Posted 蜷缩的蜗牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgresql数据库主从流复制相关的知识,希望对你有一定的参考价值。

       由于某个项目前期资源紧张,使用的Postgresql单节点数据库;为解决项目数据库安全性问题,小蜗牛应要求整理Postgresql数据库主从高可用方案,以下操作为部署主从流复制测试过程,后续整理pgpool高可用、负载均衡方案!

1、安装依赖

 
   
   
 
  1. yum install -y gcc-c++ zlib-devel vim openssh-clients

2、安装PG

 
   
   
 
  1. tar zxvf postgresql-9.3.4.tar.gz

  2. mkdir /opt/pgsql-9.3

  3. cd postgresql-9.3.4

  4. ./configure --prefix=/opt/pgsql-9.3/ --without-readline

  5. make -j 2

  6. make install

3、配置PG环境变量

 
   
   
 
  1. vim /etc/profile

  2. export PGHOME=/opt/pgsql-9.3

  3. export PGDATA=/var/lib/pgsql/9.3/data/

  4. export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PGHOME/lib/

  5. export PATH=$PGHOME/bin:$PATH:$HOME/bin

  6. source /etc/profile

3.1、添加postgres用户

 
   
   
 
  1. useradd postgres -d /var/lib/pgsql

4、配置PG主库

4.1、初始化PG数据库

 
   
   
 
  1. su - postgres

  2. initdb

4.2、启动PG数据库,并创建同步用户

 
   
   
 
  1. pg_ctl -D /var/lib/pgsql/9.3/data/ -l logfile start

  2. psql

  3. postgres# CREATE ROLE replica login replication encrypted password 'replica';

4.3、配置用户允许远程登录

 
   
   
 
  1. vi  /var/lib/pgsql/9.3/data/pg_hba.conf

  2. host    replication     replica     192.168.52.0/24                 trust

4.4、修改PG主库配置,并重启

 
   
   
 
  1. vi /var/lib/pgsql/9.3/data/postgresql.conf

  2. listen_addresses = '*'

  3. wal_level = hot_standby  # 这个是设置主为wal的主机

  4. max_wal_senders = 2 # 这个设置了可以最多有几个流复制连接,差不多有几个从,就设置几个

  5. wal_keep_segments = 7 设置流复制保留的最多的xlog数目

  6. wal_sender_timeout = 60s 设置流复制主机发送数据的超时时间

  7. max_connections = 100 # 这个设置要注意下,从库的max_connections必须要大于主库的

  8. pg_ctl -D /var/lib/pgsql/9.3/data/ -l logfile restart

5、配置PG备库

5.1、从库不用初始化,直接同步主库数据

 
   
   
 
  1. su - postgres

  2. pg_basebackup -F p --progress -D $PGDATA -h 192.168.52.101 -p 5432 -U replica --password

5.2、添加一个recovery.conf配置文件

 
   
   
 
  1. vim  $PGDATA/recovery.conf

  2. standby_mode = on  # 这个说明这台机器为从库

  3. primary_conninfo = 'host=192.168.52.101 port=5432 user=replica password=replica'  # 这个说明这台机器对应主库的信息

  4. trigger_file = '/var/lib/pgsql/9.3/data/postgresql.trigger.192.168.52.101'

  5. recovery_target_timeline = 'latest' # 这个说明这个流复制同步到最新的数据

5.3、修改PG从库配置

 
   
   
 
  1. vi $PGDATA/postgresql.conf

  2. max_connections = 1000 一般查多于写的应用从库的最大连接数要比较大

  3. hot_standby = on   说明这台机器不仅仅是用于数据归档,也用于数据查询

  4. max_standby_streaming_delay = 30s # 数据流备份的最大延迟时间

  5. wal_receiver_status_interval = 1s  # 多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间

  6. hot_standby_feedback = on # 如果有错误的数据复制,是否向主进行反馈

6、验证是否正常同步

6.1、主库查看

 
   
   
 
  1. $ psql

  2. psql (9.3.4)

  3. Type "help" for help.

  4. postgres=# select client_addr,sync_state from pg_stat_replication;

  5.  client_addr   | sync_state

  6. ----------------+------------

  7. 192.168.52.102 | async

  8. (1 row)

  9. postgres=#

6.2、通过查看进程

ps aux | grep postgres 
主节点有如下进程

 
   
   
 
  1. postgres  74442  0.0  0.2 258652  2424 ?        Ss   15:02   0:00 postgres: wal sender process replica 192.168.52.102(58199) streaming 0/30101D0

从节点有如下进程

 
   
   
 
  1. postgres   1676  0.0  0.0 113328   748 ?        Ss   15:01   0:00 postgres: stats collector process

6.3、通过主库增删改查验证

 
   
   
 
  1. postgres@master ~]$ psql

  2. psql (9.3.4)

  3. Type "help" for help.

  4. postgres=# create table t_user(id int primary key,name varchar(30));

  5. CREATE TABLE

  6. postgres=# \dt

  7.         List of relations

  8. Schema |  Name  | Type  |  Owner  

  9. --------+--------+-------+----------

  10. public | t_user | table | postgres

  11. (1 row)

  12. postgres=# insert into t_user values(1,'kbson');

  13. INSERT 0 1

  14. postgres=# insert into t_user values(2,'kbsonlong');                                                          

  15. INSERT 0 1

  16. postgres=# select * from t_user;

  17. id |   name    

  18. ----+-----------

  19.  1 | kbson

  20.  2 | kbsonlong

  21. (2 rows)

  22. postgres=#

从库查看是否同步

 
   
   
 
  1. [postgres@slave ~]$ psql

  2. psql (9.3.4)

  3. Type "help" for help.

  4. postgres=# \dt

  5. No relations found.   ##最开始从库并没有表

  6. postgres=# \dt

  7.         List of relations

  8. Schema |  Name  | Type  |  Owner  

  9. --------+--------+-------+----------

  10. public | t_user | table | postgres

  11. (1 row)

  12. postgres=# select * from t_user;

  13. id |   name    

  14. ----+-----------

  15.  1 | kbson

  16.  2 | kbsonlong

  17. (2 rows)

  18. postgres=#


7、手动测试切换主从

7.1、手动停止主库,模拟主库宕机

 
   
   
 
  1. [postgres@master data]$ pg_ctl stop

此时查看从库会提示连接不上主库

 
   
   
 
  1. LOG:  replication terminated by primary server

  2. DETAIL:  End of WAL reached on timeline 1 at 0/3000518.

  3. FATAL:  could not send end-of-streaming message to primary: no COPY in progress

  4. LOG:  record with zero length at 0/3000518

  5. FATAL:  could not connect to the primary server: server closed the connection unexpectedly

  6.        This probably means the server terminated abnormally

  7.        before or while processing the request.

  8. FATAL:  could not connect to the primary server: could not connect to server: Connection refused

  9.        Is the server running on host "192.168.52.101" and accepting

  10.        TCP/IP connections on port 5432?

  11. FATAL:  could not connect to the primary server: could not connect to server: Connection refused

  12.        Is the server running on host "192.168.52.101" and accepting

  13.        TCP/IP connections on port 5432?

7.2、从库手动生成触发文件

在从库生成一个触发文件,就是在配置从库中recovery.conf中配置的trigger_file

 
   
   
 
  1. [postgres@kbsonlong data]$ touch /var/lib/pgsql/9.3/data/postgresql.trigger.5432

  2.    [postgres@kbsonlong data]$ ll /var/lib/pgsql/9.3/data/postgresql.trigger.5432

  3. -rw-rw-r-- 1 postgres postgres 0 Jul 30 17:49 /var/lib/pgsql/9.3/data/postgresql.trigger.5432

此时日志会提示找到触发文件,自动切换为新的主库

 
   
   
 
  1. LOG:  trigger file found: /var/lib/pgsql/9.3/data/postgresql.trigger.5432

  2. LOG:  redo done at 0/30004B0

  3. LOG:  last completed transaction was at log time 2017-07-30 17:38:43.592351+08

  4. LOG:  selected new timeline ID: 2

  5. LOG:  archive recovery complete

  6. LOG:  database system is ready to accept connections

  7. LOG:  autovacuum launcher started

7.3、新的主库生成测试数据

在新的主库写入测试数据,方便后面旧的主库恢复为从库是查看是否同步数据

 
   
   
 
  1. postgres=# select * from t_user;

  2. id |   name    

  3. ----+-----------

  4.  1 | kbson

  5.  2 | kbsonlong

  6. (2 rows)

  7. postgres=# insert into t_user values(3,'kbsonlong3');  

  8. insert into t_user values(4,'kbsonlong4');  

  9. insert into t_user values(5,'kbsonlong5');  INSERT 0 1

  10. postgres=# INSERT 0 1

  11. postgres=#

  12. INSERT 0 1

  13. postgres=# select * from t_user;

  14. id |    name    

  15. ----+------------

  16.  1 | kbson

  17.  2 | kbsonlong

  18.  3 | kbsonlong3

  19.  4 | kbsonlong4

  20.  5 | kbsonlong5

  21. (5 rows)

  22. postgres=#

7.4、旧的主库恢复为新的从库

7.4.1 生成recovery.conf

 
   
   
 
  1. [postgres@master data]$ cat recovery.conf |grep -v '^#'

  2.    standby_mode = on

  3.    primary_conninfo = 'host=192.168.52.102 port=5432 user=replica password=replica'   ##注意host指向新的主库

  4.    trigger_file = '/var/lib/pgsql/9.3/data/postgresql.trigger.5432'

  5.    recovery_target_timeline = 'latest'

  6.    [postgres@master data]$

7.4.2 启动新的从库,并查看数据是否同步

 
   
   
 
  1. pg_ctl start

  2. [postgres@master data]$ psql

  3. psql (9.3.4)

  4. Type "help" for help.

  5. postgres=# select * from t_user;

  6. id |    name    

  7. ----+------------

  8.  1 | kbson

  9.  2 | kbsonlong

  10.  3 | kbsonlong3

  11.  4 | kbsonlong4

  12.  5 | kbsonlong5

  13. (5 rows)

  14. postgres=# insert into t_user values(6,'kbsonlong6');  

  15. ERROR:  cannot execute INSERT in a read-only transaction

  16. STATEMENT:  insert into t_user values(6,'kbsonlong6');

  17. ERROR:  cannot execute INSERT in a read-only transaction

  18. postgres=#

可以看到刚才在新的主库写入的测试数据已经同步,并且无法再次新的从库写入数据



# 8、配置启动脚本


PostgreSQL的开机自启动脚本位于PostgreSQL源码目录的contrib/start-scripts路径下

 

Linux文件即为linux系统上的启动脚本

## 8.1、修改linux文件属性,添加X属性


    #chmod a+x linux


## 8.2、 复制linux文件到/etc/init.d目录下,更名为postgresql


    #cp linux /etc/init.d/postgresql

 

## 8.3、修改/etc/init.d/postgresql文件的两个变量


    prefix设置为postgresql的安装路径:/opt/pgsql-9.3

    PGDATA设置为postgresql的数据目录路径:/var/libg/pgsql/9.3/data

 

 

## 8.4、执行service postgresql start,就可以启动PostgreSQL服务


    #service postgresql start

 

## 8.5、设置postgresql服务开机自启动


    #chkconfig --add postgresql


以上是关于Postgresql数据库主从流复制的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSql基于Standby的异步流主从复制

postgreSQL主从复制

PostgreSQL 9.5.5主从实现之异步流复制(Hot Standby)

Postgresql主从配置

PostgreSQL 9.5.5主从实现之异步流复制(Hot Standby)

PostgreSQL 9.5.5主从实现之异步流复制(Hot Standby)