gerrit配置使用replication插件

最终实现的效果如下图所示
image

实现员工下带代码从一个从gerrit下载,上传代码到主gerrit上。

首先是主gerrit服务器上面要配置一下ssh相关的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
gerrit2@gerrit-master:~$ cat -n .ssh/config 

# 这个是上海site的配置
Host gerrit-sh.example.com
User gerrit2
Hostname 10.0.12.18
IdentityFile ~/.ssh/id_rsa
PreferredAuthentications publickey
StrictHostKeyChecking no
UserKnownHostsFile /dev/null

# 这个是西安site的配置
Host gerrit-xi.example.com
User gerrit2
Hostname 192.168.38.175
IdentityFile ~/.ssh/id_rsa
PreferredAuthentications publickey
StrictHostKeyChecking no
UserKnownHostsFile /dev/null


然后是需要配置replication.config 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
replication.config 
[remote "gerrit-sh"]
url = gerrit2@gerrit-sh.example.com:/home/gerrit2/review_site/git/${name}.git
projects = "^git/android/.*"
projects = "^git/shared/.*"
projects = "^git/aosp/.*"
projects = "^Permission_parent/.*"
projects = "All-Projects"
projects = "All-Users"

push = +refs/*:refs/*
mirror = true

replicatePermissions=true
threads = 16
replicationDelay = 5

[remote "gerrit-xi"]
url = gerrit2@gerrit-xi.example.com:/home/gerrit2/review_site/git/${name}.git
projects = "^git/android/.*"
projects = "^Permission_parent/.*"
projects = "All-Projects"
projects = "All-Users"

push = +refs/heads/*:refs/heads/*
push = +refs/users/*:refs/users/*
push = +refs/meta/*:refs/meta/*

mirror = true
replicatePermissions=true
threads = 8
replicationDelay = 5

一、PostgreSQL通过WAL日志构建高可靠性原理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
PostgrepSQL在数据目录的子目录pg_xlog子目录中维护了一个WAL日志文件,可以把WAL日志备份到另外一台备份服务器,
通过重做WAL日志的方式在备服务器上恢复数据(类似Oracle的redo日志)。

WAL日志复制到另外一台备份服务器可以有两种方式:

1、 WAL日志文件复制

此种方式是写完一个WAL日志后,才把WAL日志文件拷贝到备份数据库中。这样通常备份会落后主库一个WAL日志文件,
当主数据库发生故障时,主数据库的WAL文件并没有填充完毕未传输(默认16MB)、或者时延等原因导致WAL文件没有
传输完毕,会导致被数据库可能存在一定的数据丢失。此种方式是postgreSQL9.0前版本主要提供的WAL日志复制机制。

采用此方式的WAL复制,需要:

主数据库的wal_level配置为archive或以上。
PostgreSQL 9.1之后提供了一个很方便的工具pg_basebackup,使用完成一次基础备份到备数据库。
后续产生WAL文件,可以通过archive_command参数调度命令传输至备机。


2、流复制(Streaming Replication)

流复制是PostgreSQL 9.0之后才提供的新的传递WAL日志的方法。通过流复制,备库不断的从主库同步相应的数据,
并在备库apply每个WAL record,这里的流复制每次传输单位是WAL日志的record。它的好处是只要主库一产生日志,
就会马上传递到备库,同WAL日志文件相比有更低同步延迟。

同时PostgreSQL9.0之后提供了Hot Standby能力,备库在应用WAL record的同时也能够提供只读服务。

PostgreSQL的流复制最多支持1主8备、支持级联复制(主->备1,备1->备2)。


WAL流复制支持同步、异步方式:

异步流复制模式中,主库提交的事务不会等待备库接收WAL日志流并返回确认信息,因此异步流复制模式下主库与备库的数据版本上
会存在一定的处理延迟,延迟的时间主要受主库压力、备库主机性能、网络带宽等影响,当正常情况下,主备的延迟通常在毫秒级的
范围内,当主库宕机,这个延迟就主要受到故障发现与切换时间的影响而拉长,不过虽然如此,这些数据延迟的问题,可以从架构或
相关自动化运维手段不断优化设置。

同步流复制模式中,要求主库把WAL日志写入磁盘,同时等待WAL日志记录复制到备库、并且WAL日志记录在任何一个备库写入磁盘后,
才能向应用返回Commit结果。一旦所有备库故障,在主库的应用操作则会被挂起,所以此方式建议起码是1主2备。

二、搭建PostgreSQL数据库异步流复制环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
前提,数据库安装完毕。以主、备库如下规划为例:

主库地址/端口 10.150.149.84 / 5432

备库地址/端口 10.150.149.84 / 5432

备主流复制用户名/密码 u_standby / standby123

数据库用户名 postgre


PostgreSQL主备数据库的同步设置主要涉及如下文件:

pg_hba.conf postgresql 主库访问规则文件
postgresql.conf postgresql 主库配置文件
recovery.conf postgresql 备库访问主库配置文件
.pgpass postgresql 备库访问主库的密码文件

正常主备流复制情况下:
主库需要pg_hba.conf、postgresql.conf
备库需要recovery.conf、.pgpass

实际操作中,建议主、备库上都配置这四个文件,因为主、备库角色是随着倒换变更的。注:recovery.conf文件在备库上是recovery.conf,在主库上配置为recovery.done。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
主库配置:
1、配置postgresql.conf

wal_level = hot_standby # minimal, replica, or logical 使得日志支持Streaming Replication 指定写入到wal中的信息,默认是minimal,
只写从crash中恢复或者快速shutdown需要的信息。 replica 是在minimal的基础上添加wal archiving需要的信息。logical 增加逻辑编码需要的信息。
minimal wal不包含从base backup和wal log重新构造数据库数据的信息。replica或者logical可以。老版本的参数archive或者hot_standby 在这里被映射到replica模式
注意:(In releases prior to 9.6, this parameter also allowed the values archive and hot_standby. These are still accepted but mapped to replica.
因此,要启用 WAL 归档(archive_mode)和流复制,必须使用replica或更高级别。)
max_wal_senders = 2 # max number of walsender processes 这个设置了可以最多有几个流复制连接,几个并发的standby数据库就设置几个
wal_keep_segments = 256 设置流复制保留的最多的xlog数目,不要设置太小导致WAL日志还没有来得及传送到standby就被覆盖。一个WAL文件默认16M
hot_standby = on # "on" allows queries during recovery 设置为备库时是否支持可读
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'






2.配置pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD

host all all 127.0.0.1/32 trust

host all all ::1/128 trust

host replication u_standby 10.10.10.0/32 trust
其中:
1) u_standby为在主库上创建的用于备库连接主库进行流复制的用户,此用户需要用户需要有REPLICATION权限和LOGIN权限。开户如:
create user u_standby SUPERUSER LOGIN password 'standby123';
2) 10.10.10.0/32为备库地址段+掩码;也可配置为具体的standby数据库地址+掩码,可配置多条。用于指定哪些地址的standby数据用哪个用户名/密码到主库获取WAL日志数据。使用地址段格式,则地址段内的IP都可以无密码对此数据库进行访问,安全性可能会降低。因此,在生产环境中建议严格按照具体主机IP方式配置。


3、 (可选)配置recovery.done、.pgpass
同备库recovery.conf、.pgpass配置。recovery.conf中如下IP、端口、用户名要对应备库信息:

primary_conninfo = 'host=10.10.10.1 port=5432 user=u_standby' 备库连接主库地址、端口、用户名、密码


3.启动服务,创建用户

ALTER USER postgres WITH PASSWORD '123456';
CREATE ROLE repl WITH PASSWORD '123456' REPLICATION LOGIN;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
备库配置:

1. 修改postgresql.conf
hot_standby = on # "on" allows queries during recovery 设置为备库时是否支持可读

2. 配置recovery.conf
standby_mode = on

recovery_target_timeline = 'latest'

primary_conninfo = 'host=10.10.10.1 port=5432 user= u_standby password=standby123 ' 本库为备库会,连接主库地址、端口、用户名、密码

3.设置连接主库密码.pgpass
  10.10.10.1: 5432:replication: u_standby:standby123 //备库都主库同步WAL日志使用

  10.10.10.2: 5432:replication: u_standby:standby123 //倒换后,主库降备库,新备库使用


4、 配置完毕需重启数据库

  pg_ctl start


1
2
3
4
5
6
7
8
9
10
11
12
13
1、识别当前库主、备角色:

方式一:

  postgres=# select pg_is_in_recovery(); 结果是f则为主库,t为备库。

方式二:

  pg_controldata 结果为cluster state是in production则为主库;结果为cluster state是in archive recovery则为备库。

方式三:

  Select pid, application_name, client_addr, client_port, state, sync_state from pg_stat_replication 查询到结果为主库,查询不到结果为备库。

三. PostgreSQL建立Hot Standby的Replication机制

PostgreSQL建立Hot Standby的Replication机制 (from https://note.qidong.name/2018/09/postgresql-hot-standby/)

1
2
3
4
5
安装PostgreSQL
sudo apt install postgresql

Ubuntu 16.04上,PostgreSQL版本为9.5,配置文件的目录为/etc/postgresql/9.5/main/。 以下的配置文件都在此目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
master机:

1. 先去创建一个同步专用账户repl:
$ sudo su - postgres
$ psql
postgres=# create user repl replication password '******';

2. 然后修改两个配置文件。 其一是postgresql.conf:

listen_addresses = '*' # what IP address(es) to listen on; 修改为星号, 高级一点可以只限制某几个IP地址.

wal_level = hot_standby # minimal, archive, hot_standby, or logical # 修改这里, 18.04上好像默认是 replica

max_wal_senders = 32 # max number of walsender processes
wal_keep_segments = 64 # in logfile segments, 16MB each; 0 disables

hot_standby = on # "on" allows queries during recovery


其二是pg_hba.conf文件:
# TYPE DATABASE USER ADDRESS METHOD

# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
host replication repl 0.0.0.0/0 md5 加上这一行
最后一行就是允许repl的访问连接。
完成修改后,重启服务。

sudo systemctl restart postgresql.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
slave机
修改前,先停止服务。
sudo systemctl stop postgresql.service
先做首次备份(需要输入前面repl用户的密码):
mv /var/lib/postgresql/9.5/main/ /var/lib/postgresql/9.5/main.slave.origin/ # 把原来的数据库备份一下.
pg_basebackup -h pg_master -U repl -p 5432 -F p -P -x -R -D /var/lib/postgresql/9.5/main/ -l 20180907

-l是设置一个label标识这次备份

然后修改一个配置,postgresql.conf:

hot_standby = on # 从库主要改这里

最后新增一个配置,recovery.conf:
standby_mode = 'on'
primary_conninfo = 'host=主库的IP port=5432 user=repl password=********'


完成修改后,启动服务。
sudo systemctl start postgresql.service


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
注意:创建好用户(角色)之后需要连接的话,还需要修改2个权限控制的配置文件(pg_hba.conf、pg_ident.conf)。并且创建用户(user)和创建角色(role)一样,唯一的区别是用户默认可以登录,而创建的角色默认不能登录。创建用户和角色的各个参数选项是一样的。
Tip:安装PostgreSQL会自动创建一个postgres用户,需要切换到该用户下访问PostgreSQL。

CREATE USER/ROLE name [ [ WITH ] option [ ... ] ] : 关键词 USER,ROLE; name 用户或角色名;

where option can be:

SUPERUSER | NOSUPERUSER :超级权限,拥有所有权限,默认nosuperuser。
| CREATEDB | NOCREATEDB :建库权限,默认nocreatedb。
| CREATEROLE | NOCREATEROLE :建角色权限,拥有创建、修改、删除角色,默认nocreaterole。
| INHERIT | NOINHERIT :继承权限,可以把除superuser权限继承给其他用户/角色,默认inherit。
| LOGIN | NOLOGIN :登录权限,作为连接的用户,默认nologin,除非是create user(默认登录)。
| REPLICATION | NOREPLICATION :复制权限,用于物理或则逻辑复制(复制和删除slots),默认是noreplication。
| BYPASSRLS | NOBYPASSRLS :安全策略RLS权限,默认nobypassrls。
| CONNECTION LIMIT connlimit :限制用户并发数,默认-1,不限制。正常连接会受限制,后台连接和prepared事务不受限制。
| [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL :设置密码,密码仅用于有login属性的用户,不使用密码身份验证,则可以省略此选项。可以选择将空密码显式写为PASSWORD NULL。
加密方法由配置参数password_encryption确定,密码始终以加密方式存储在系统目录中。
| VALID UNTIL 'timestamp' :密码有效期时间,不设置则用不失效。
| IN ROLE role_name [, ...] :新角色将立即添加为新成员。
| IN GROUP role_name [, ...] :同上
| ROLE role_name [, ...] :ROLE子句列出一个或多个现有角色,这些角色自动添加为新角色的成员。 (这实际上使新角色成为“组”)。
| ADMIN role_name [, ...] :与ROLE类似,但命名角色将添加到新角色WITH ADMIN OPTION,使他们有权将此角色的成员资格授予其他人。
| USER role_name [, ...] :同上
| SYSID uid :被忽略,但是为向后兼容性而存在。

四. 配置PostgreSQL数据库流复制(replication stream)环境

配置PostgreSQL数据库流复制(replication stream)环境 (from https://blog.csdn.net/jacktonny1/article/details/50787200)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
第一步:在两个环境中分别安装postgresql数据库

在主库中修改postgresql.conf,把listen_addresses改成"*",默认只有localhost能登陆数据库。

第二步:在主库中创建流复制用户

CREATE USER replicator replication LOGIN CONNECTION LIMIT 5 ENCRYPTED PASSWORD '123456';
CREATE ROLE replicator WITH PASSWORD 'replicator123456' REPLICATION LOGIN; 用这个

第三步:修改主库pg_hba.conf文件
在最后添加如下行。

host replication replicator 0.0.0.0/0 md5
host replication replicator all md5 用这个

第四步:修改主库postgresql.conf文件
修改如下几个参数
wal_level = hot_standby
max_wal_senders = 1
hot_standby = on

max_wal_senders是Slave库的节点数,有多少个slave库就设多少。

wal_level是write ahead log参数值,设置流复制务必将此值更新成hot_standby。

修改后记得重启数据库。
max_wal_senders = 6 用这个
wal_keep_segments = 8

第五步:基础备份复制到备库服务器
登陆备库服务器,运行如下命令从主库复制文件。如果备库PGDATA目录有文件先需要删除。 或者采用停止数据库服务,然后整套打包压缩/var/lig/postgresql/目录的方法.
pg_basebackup -D $PGDATA -h pg_master -U repuser -p 5432 -F p -W # 这个是这次的命令
pg_basebackup -D $PGDATA -h pg_master -U repuser -p 5432 -F p -P -x -R -l 20180907 # 这个是上面的一个命令
-l是设置一个label标识这次备份


第六步:修改备库配置信息
添加recovery.conf文件。
$ cp $PGHOME/share/postgresql/recovery.conf.sample $PGDATA/recovery.conf
$ vi recovery.conf --新增以下三行
standby_mode = 'on'
trigger_file = '/data/pgsql/pg.trigger' # 这个可以不要
primary_conninfo = 'host=192.168.2.101 port=5432 user=repuser password=123456 keepalives_idle=60'

第七步:启动备数据库,检查是否启动成功。
查看主库是否有类似这个进程:
postgres: wal sender process repuser 192.168.2.102(45446) streaming 0/C01EDB8
查看备库是否有类似这个进程:
postgres: wal receiver process streaming 0/C01ED28
如果都有就可以在主库新建一个数据库测试下,一切没问题后流复制环境就算搭建好了。

















如果不执行打包备份的就会报下面的错误
2020-06-13 19:41:27.846 CST [2130] FATAL: database system identifier differs between the primary and standby
2020-06-13 19:41:27.846 CST [2130] DETAIL: The primary's identifier is 6837792782634720479, the standby's identifier is 6837792749942320236.
2020-06-13 19:41:32.851 CST [2131] FATAL: database system identifier differs between the primary and standby
2020-06-13 19:41:32.851 CST [2131] DETAIL: The primary's identifier is 6837792782634720479, the standby's identifier is 6837792749942320236.
2020-06-13 19:41:37.857 CST [2132] FATAL: database system identifier differs between the primary and standby
2020-06-13 19:41:37.857 CST [2132] DETAIL: The primary's identifier is 6837792782634720479, the standby's identifier is 6837792749942320236.