Postgresql 9.x Replication – Streaming Log
Streaming log replication 은 Postgresql 9.0 부터 도입된 기능이다. 이 기능은 Primary 에서 Standby 서버로 직접 전송함으로서 replication delay 를 줄여준다. 따라서 pg_xlog 파일전송이 필요가 없다. 또 xlog 를 Streaming 으로 받기 위해서 Primary 서버에 REPLICATION 권한의 접속 계정이 필요하다.
Replication 권한 사용자 생성.
Primary 서버에서 REPLICATION 권한의 사용자를 다음과 같이 생성해준다.
1 |
CREATE ROLE repuser WITH REPLICATION PASSWORD '12345' LOGIN |
그리고 Standby 서버에서 Primary 접속을 위해서 pg_hba.conf 파일을 Standby 서버 접속을 허용해 줍니다.
1 2 3 |
# The standby server must connect with a user that has replication privileges. # TYPE DATABASE USER ADDRESS METHOD host replication repuser 192.168.96.26/32 md5 |
중요한 것은 DATABASE 에 반드시 ‘replication’ 이여야 한다.
Streaming Replication 을 위한 postgresql.conf 를 다음과 같이 설정한다.
1 2 3 4 5 |
wal_level = archive max_wal_senders = 2 wal_keep_segments = 32 archive_mode = on archive_command = 'cp %p /path_to/archive/%f' |
데이터백업/복구.
PostgreSQL 9.3 이후부터 pg_basebackup 명령어를 지원한다. 이 명령어는 REPLICATION 권한을 가진 사용자로 접속을해 Primary 의 데이터 디렉토리를 원격에서 로컬로 복제를 해준다.
Standby 서버를 추가할때에 Primary 서버의 데이터 디렉토리를 복제해야 한다. 앞에서 생성한 계정을 이용하면 된다.
1 2 3 4 5 6 7 8 |
]# sudo -u postgres /opt/pgsql-9.5.0/bin/pg_basebackup -h 192.168.96.24 -D /opt/pgsql-9.5.0/data -U repuser -v -P --xlog-method=stream Password: transaction log start point: 1/48000028 on timeline 1 pg_basebackup: starting background WAL receiver 486611/486611 kB (100%), 1/1 tablespace transaction log end point: 1/480000C0 pg_basebackup: waiting for background process to finish streaming ... pg_basebackup: base backup completed |
정상적으로 실행이 되면 위와같이 나온다.
Streaming logging replication
pg_basebackup 을 실행해 Primary 데이터 디렉토리가 복제했고 이로 인해서 postgresql.conf 파일도 Primary 것일 것이다. 이것을 최초의 파일로 교체해 준다.
그리고 recovery.conf 파일을 다음과 같이 작성해 준다.
1 2 3 |
standby_mode = on primary_conninfo = 'host=192.168.96.24 port=5432 user=repuser password=12345' trigger_file = '/tmp/postgresql.trigger.5432' |
그리고 Standby 서버를 시작해 준다.
로그파일을 보면 다음과 같이 나온다.
1 2 3 4 5 |
LOG: database system was interrupted; last known up at 2016-10-02 01:00:13 KST LOG: entering standby mode LOG: redo starts at 1/48000098 LOG: consistent recovery state reached at 1/480000C0 LOG: started streaming WAL from primary at 1/49000000 on timeline 1 |
그리고 프로세스를 살펴보면 다음과 같다.
1 2 3 4 5 6 7 |
]# ps aux | grep post postgres 1740 0.3 2.4 442504 25112 ? S 01:14 0:00 /opt/pgsql-9.5.0/bin/postgres -D /opt/pgsql-9.5.0/data postgres 1741 0.2 0.8 442544 8392 ? Ss 01:14 0:00 postgres: startup process recovering 00000001000000010000004A postgres 1746 0.0 0.7 442504 7820 ? Ss 01:14 0:00 postgres: checkpointer process postgres 1747 0.0 0.7 442504 8156 ? Ss 01:14 0:00 postgres: writer process postgres 1748 1.0 0.9 447256 9296 ? Ss 01:14 0:00 postgres: wal receiver process streaming 1/4B000000 root 1752 0.0 0.0 103284 764 pts/0 S+ 01:14 0:00 grep post |
Primary 서버에서 Streaming Replication 상태를 다음과 같이 조회해 볼수 있다.
1 |
SELECT S.pid, S.usesysid, U.rolname AS usename, S.application_name, S.client_addr, S.client_port, S.backend_start FROM pg_stat_get_activity(NULL) AS S, pg_authid U WHERE S.usesysid = U.oid AND S.datid = 0; |
혹은 pg_stat_replication 을 조회해도 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
postgres=# \x Expanded display is on. postgres=# select * from pg_stat_replication; -[ RECORD 1 ]----+------------------------------ pid | 10285 usesysid | 16668 usename | repuser application_name | walreceiver client_addr | 192.168.96.26 client_hostname | client_port | 41866 backend_start | 2016-10-02 01:14:40.954436+09 backend_xmin | state | streaming sent_location | 1/4E000000 write_location | 1/4E000000 flush_location | 1/4E000000 replay_location | 1/4E000000 sync_priority | 0 sync_state | async |
하지만 위 방법은 Standby 서버에는 접속할 수 없다. 접속을 시도하면 다음과 같은 에러를 낸다.
1 |
psql: FATAL: the database system is starting up |
Hot Standby 세팅.
Hot Standby 는 Standby 서버에 접속해 읽기전용의 SQL 연산을 수행할 수 있도록 해준다. 이를 위해서는 먼저 Primary 서버에서 다음과 같이 postgresql.conf 파일에 Hot Standby 설정을 해줘야 한다.
1 |
wal_level = 'hot_Standby' |
Standby 서버도 다음과 같이 설정을 변경해 준다.
1 |
hot_Standby = on |
이제 서버들을 재시작해줘야 하는데 순서가 중요하다. 다음과 같은 순서로 재시작을 해준다.
- Standby 서버 Shutdown
- Primary 서버 재시작.
- Standby 서버 시작.
Standby 서버의 log 파일을 살펴보면 다음과 같다.
1 2 3 4 5 6 7 |
]# tail -f data/logfile LOG: database system was interrupted; last known up at 2016-10-02 01:49:20 KST LOG: entering standby mode LOG: redo starts at 1/60000060 LOG: consistent recovery state reached at 1/60000130 LOG: database system is ready to accept read only connections LOG: started streaming WAL from primary at 1/61000000 on timeline 1 |
프로세스는 다음과 같이 나온다.
1 2 3 4 5 6 7 8 |
]# ps aux | grep post postgres 2049 0.4 2.4 442500 25140 ? S 01:49 0:00 /opt/pgsql-9.5.0/bin/postgres -D /opt/pgsql-9.5.0/data postgres 2050 0.4 0.8 442540 8440 ? Ss 01:49 0:00 postgres: startup process recovering 000000010000000100000062 postgres 2051 0.0 0.7 442500 7816 ? Ss 01:49 0:00 postgres: checkpointer process postgres 2052 0.0 0.7 442500 8096 ? Ss 01:49 0:00 postgres: writer process postgres 2054 0.0 0.7 163404 7648 ? Ss 01:49 0:00 postgres: stats collector process postgres 2055 1.1 0.9 447124 9292 ? Ss 01:49 0:00 postgres: wal receiver process streaming 1/62000060 root 2067 0.0 0.0 103284 764 pts/0 S+ 01:50 0:00 grep post |
테스트.
Primary 서버에 테이블을 하나 만들고 데이터를 입력해보고 이것이 Standby 서버로 잘 가는지를 살펴본다.
1 2 3 4 |
test=# CREATE TABLE guestbook (visitor_email text, vistor_id serial, date timestamp, message text); CREATE TABLE test=# INSERT INTO guestbook (visitor_email, date, message) values ('a@abc.com', current_date, 'This is a test.'); INSERT 0 1 |
그리고 Standby 서버에서 guestbook 테이블이 존재하고 데이터가 존재하는지 살펴본다.
1 2 3 4 5 6 7 8 9 10 11 12 |
test=# \d List of relations Schema | Name | Type | Owner --------+------------------------------+----------+---------- public | guestbook | table | postgres public | guestbook_vistor_id_seq | sequence | postgres test=# select * from guestbook; visitor_email | vistor_id | date | message ---------------+-----------+---------------------+----------------- a@abc.com | 1 | 2016-10-02 00:00:00 | This is a test. (1 row) |
잘 보이면 정상이다.