使用Docker在CentOS7上尝试实现PostgreSQL的逻辑复制

因为被告知「虽然只有一台实际服务器作为开发环境,但是请创建一个可以在两台生产环境中良好同步的机制」,所以在尝试了各种方法后,选择了其中一种方案。
由于我是PostgreSQL和Docker的新手,但是我设法让它们能够正常工作,所以在那个时候记录下了结果。
由于我的情况可能存在错误,请谅解。

想要做的事情

因为想要制造一个真实的氛围。

    • CentOS7

 

    PostgreSQL10.3

我想要以两台服务器的形式来构建它(不仅用作PostgreSQL服务器,而且作为开发服务器使用,所以这个配置)。

预先的状态

由于不再需要准备实机进行操作,可以使用自己的IDCF云(Ubuntu16.04)进行操作。

Docker的安装方式只是直接按照官方文档进行操作。

创建Docker容器

主控端

尽管我已经多次遇到这个问题,但是在Docker中创建CentOS7时,还是需要使用systemd命令和service命令。

Failed to get D-Bus connection: Operation not permitted

由於該程式無法啟動,請參考以下連結進行操作:

[Docker]コンテナCentOS7/Ubuntuのsystemctlでserviceが起動しない場合

# つなぎやすいようにネットワークの設定を入れる
$ sudo docker network create --driver bridge psql
# privilegedと/sbin/initがキモ 今回の内容的には-pのポートフォワードは必要なかったっぽい
$ sudo docker run --privileged --name=postgresql1 --net=psql -d -p 5431:5432 -p 8000:80 centos /sbin/init
# bashで入ってみる
$ sudo docker exec -it postgresql1 /bin/bash

奴隶方

确保名称和端口转发的设置不重叠。

$ sudo docker run --privileged --name=postgresql2 --net=psql -d -p 5433:5432 -p 8080:80 centos /sbin/init

准备 PostgreSQL 服务器(主从共用)

在补充了缺失的命令后,参考下面的链接进行操作,几乎是完全照搬执行。
https://weblabo.oscasierra.net/postgresql10-centos7-install/

# serviceコマンド等がなくて困るので
yum -y install initscripts && yum clean all
# wgetを入れる
yum -y install wget

wget https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-centos10-10-2.noarch.rpm
yum -y localinstall pgdg-centos10-10-2.noarch.rpm
yum -y install postgresql10-server
/usr/pgsql-10/bin/postgresql-10-setup initdb
systemctl enable postgresql-10
systemctl start postgresql-10

使得 PostgreSQL 服务器(仅限主服务器)能够从外部访问。

在实际工作中,我们一直重复着”无法连接”的操作,直到最后阶段才完成了这项工作。

只需要服务器端成为主控即可。

vi /var/lib/pgsql/10/data/postgresql.conf

大约在第59行。去掉”#”并且改写(因为这只是试验,所有都可以接受)。

listen_addresses = '*'                  # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
port = 5432                             # (change requires restart)

设置可以进一步连接的客户端。

vi /var/lib/pgsql/10/data/pg_hba.conf

在最后一段类似的内容旁边随意写上一点。

host    all             all             all                     trust

这个也只是尝试性的,所以我们都接受了,但实际上我觉得最好还是限定在特定地址等方面。

重启

service postgresql-10 restart

PostgreSQL的用户等配置(主/从共用)

我将在名为mydb的数据库中创建一个名为test_db的表,并进行复制。并且要保证test用户有权限执行此操作。因为这只是测试,所以权限可以适当设置。

# su postgres
$ createdb mydb
$ psql mydb
mydb=# CREATE TABLE test_db (
    id              SERIAL,
    name            varchar(80)
);
mydb=# CREATE ROLE test WITH LOGIN REPLICATION PASSWORD 'hogehoge';
mydb=# GRANT ALL ON test_db TO test;

复制设置

主机端

在进行逻辑复制时,参考这篇文章:http://tkrd.hatenablog.com/entry/2017/04/23/223936

vi /var/lib/pgsql/10/data/postgresql.conf

大约在第180行左右

wal_level = logical                     # minimal, replica, or logical

是否需要调整max_replication_slots?(尽管没有调整也能暂时运行)

service postgresql-10 restart

$ psql mydb
mydb=# CREATE PUBLICATION pub_srv1_test_db FOR TABLE test_db;

奴隷一方

由于可以将其视为不同的主机,所以端口号可以设置为5432。

$ psql mydb
mydb=# CREATE SUBSCRIPTION sub_srv2_test_db CONNECTION 'dbname=mydb host=postgresql1 port=5432 user=test' PUBLICATION pub_srv1_test_db;
NOTICE:  created replication slot "sub_srv2_test_db" on publisher
CREATE SUBSCRIPTION

在这个阶段尝试连接,如果连接设置出了问题,就会在这里失败。
哎呀,没有指定密码啊。。。
目前还有一些不太明白的地方,但总之它能够运行,所以就算了吧。。。(?)
由于这个原因,我查了一下,貌似是pg_hba.conf文件中的trust选项。
参考链接:https://www.postgresql.jp/document/10/html/auth-pg-hba-conf.html

host    mydb            test            samenet             password

这样做会需要密码(由于在同一网络下,使用明文应该可以)另外顺带一提,我也添加了允许由test用户连接的mydb数据库的权限。

mydb=# CREATE SUBSCRIPTION sub_srv2_test_db CONNECTION 'dbname=mydb host=postgresql1 port=5432 user=test' PUBLICATION pub_srv1_test_db;
ERROR:  could not connect to the publisher: fe_sendauth: no password supplied
mydb=# CREATE SUBSCRIPTION sub_srv2_test_db CONNECTION 'dbname=mydb host=postgresql1 port=5432 user=test password=hogehoge' PUBLICATION pub_srv1_test_db;
NOTICE:  created replication slot "sub_srv2_test_db" on publisher
CREATE SUBSCRIPTION

尝试一下

主控端

mydb=# insert into test_db (name) values('aaa');

只需要一个选项,用中国母语改写以下内容:

“スレーブ側”意为”奴隶一方”。

mydb=# select * from test_db;
 id | name
----+------
  1 | aaa
(1 row)

有什么东西动了。

其他

无论在主控端执行以下操作,从属端都不会改变

truncate test_db;

当在从属方面进行插入时。

mydb=# insert into test_db (name) values('aaa');
mydb=# select * from test_db;
 id | name
----+------
  1 | aaa
  1 | aaa

嗯,嗯。嘛,從奴隸端來說,基本上只需要讀取就可以了,所以這樣也可以。但是,id和name的值會被複製。
因為我熟悉MySQL,所以對於SERIAL和sequence表的存在有點難以理解。

心得或感触

第一次接触PostgreSQL,发现出现了相当多的过时信息,很难查找到相关的资料呢。。。而且怎么不能直接跳转到10版本的文档呢?

广告
将在 10 秒后关闭
bannerAds