在30分钟内尝试实施PostgreSQL的灾备解决方案
你好!我是Insight Technology的松尾。
本文介绍了一种支持Oracle Database SE / SQL Server / PostgreSQL 的DR解决方案,即Dbvisit StandbyMP的试用环境。我们将利用这个环境来实际体验当灾难发生时,数据库是如何切换的。从准备环境到实际测试,大约只需要30分钟,而且是免费的。所以,如果您正在考虑数据库的DR产品,或者想要了解更多信息的话,请务必试一试。
首先,什么是PostgreSQL的DR(灾难恢复)策略?
数据库的灾备(Disaster Recovery,DR,灾难恢复)是一种机制,它在发生灾害或故障时,通过物理上将生产环境数据库(原始数据库)的副本保留在远离的地方,并在出现灾害时切换并使用数据库。在PostgreSQL中,通常使用流式复制或WAL文件传输来构建灾备。它作为标准功能内置,但在使用时需要修改配置文件或通过命令行进行操作,基本上是基于文本的操作。我认为对于精通PostgreSQL的工程师来说没有问题,但我认为不可能一直让这样的工程师准备好应对灾害。请想象一下当发生故障导致生产环境无法使用时,需要适应许多环境的情况。使用DR软件可以轻松管理和确认DR配置,并自动切换到备用环境等操作。
来体验DR软件吧!
本文介绍了使用适用于Oracle Database SE / SQL Server / PostgreSQL的DR软件Dbvisit StandbyMP的测试环境(Test drive),并通过设置以及在PostgreSQL上进行的实际体验来切换到主服务器和备用服务器(Switch over)以及故障切换(在故障发生时自动切换到备用服务器)。测试环境中提供了用于体验的PostgreSQL,因此可以轻松进行体验。
预约试驾和启动车辆的申请
我们开始进行试驾吧。访问https://testdrive.dbvisit.com/ 后,您将看到以下界面。

只需输入姓名和电子邮件地址。立即开始输入吧。

开始构建测试驾驶。大约需要2分钟完成,期间可以观看产品介绍视频♪构建完成后,将显示所需的访问信息等。

当您访问「START HERE」上所列的「CONTROL CENTER HOMEPAGE」中的URL时,将会显示登录页面。

在登录界面上,使用同样显示为“START HERE”的用户名称和密码进行登录。登录后,可以通过左侧菜单中的“SETTING”选项将语言更改为日语。更改后,会再次返回登录界面,并显示日语的登录界面。

DR的构造和操作
现在我们马上来注册PostgreSQL。请点击“Start with PostgreSQL”。一旦点击,将会弹出一个选择已注册(已安装了Dbvisit的代理程序)数据库的画面。

选择带有「psql1~」标识的数据库。同样地,在Standby(备机)中选择带有「psql2~」标识的数据库。

点击「创建配置」。 PostgreSQL DR配置将被注册到仪表板上。

在这个阶段,只有DR配置被注册,因此点击“立即设置吗?”。在这里,可以选择Dbvisit StandbyMP支持的复制方法,但如果没有特殊要求,应选择持续地使用PostgreSQL日志(WAL)流式传输。此外,还可以选择热备份或温备份。热备份允许读取访问,而温备份则不允许读取访问。
最后,点击“创建备用数据库”,创建一个备用数据库。

当创建了一个待命数据库,仪表板上的待命数据库将变为“热备用”。

那么,PostgreSQL目前处于什么样的状态呢?
我会尝试登录到已设置了PostgreSQL的主机上进行SSH登录。我们分别看看psql1和psql2。需要注意的是,SSH登录所需的信息包含在部署后显示的信息中。根据选择的WAL流式传输方式,看起来正在使用PostgreSQL的流复制功能。因此,让我们尝试使用确认复制状态的命令进行确认。
在初级方面
postgres@psql1:~$ psql -U postgres
psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1))
Type "help" for help.
postgres=# select * from pg_stat_replication;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time
------+----------+----------+------------------+----------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------+-------------------------------
1595 | 10 | postgres | 14/main | 13.211.163.199 | | 48354 | 2023-10-11 15:16:06.005274+00 | | streaming | 4/6000148 | 4/6000148 | 4/6000148 | 4/6000148 | | | | 0 | async | 2023-10-11 15:24:14.632479+00
(1 row)
在待机状态下
postgres=# select * from pg_stat_wal_receiver;
pid | status | receive_start_lsn | receive_start_tli | written_lsn | flushed_lsn | received_tli | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo
------+-----------+-------------------+-------------------+-------------+-------------+--------------+------------------------------+-------------------------------+----------------+-------------------------------+-----------+---------------------------------------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1977 | streaming | 4/6000000 | 1 | 4/6000148 | 4/6000148 | 1 | 2023-10-11 15:29:15.07852+00 | 2023-10-11 15:29:15.078463+00 | 4/6000148 | 2023-10-11 15:19:44.239284+00 | dbvisit_1 | psql1-43E255BE16DD4A02.mp-standby.com | 5432 | user=postgres password=******** channel_binding=prefer dbname=replication host=psql1-43E255BE16DD4A02.mp-standby.com port=5432 fallback_application_name=14/main sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any
(1 row)
尝试创建或检查一个适当的表,您将能够确认它是否被复制。举个例子,
主要方面
postgres=# create table table1 (col1 int);
CREATE TABLE
postgres=# insert into table1 values (1);
INSERT 0 1
在待命的一侧
postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+--------+-------+----------
public | table1 | table | postgres
(1 row)
postgres=# select * from table1;
col1
------
1
(1 row)
postgres=# insert into table1 values(2);
ERROR: cannot execute INSERT in a read-only transaction
切换
在双方数据库都处于运行状态下,将主数据库与备用数据库进行切换的操作称为”切换”。无论数据库类型如何,Dbvisit StandbyMP都可以通过相同的操作进行切换。
执行切换操作,请在仪表板上的目标配置中点击“处理”。然后从右侧显示的菜单中选择“切换”。

当出现确认画面时,从那里执行切换操作。

我认为,当我查看仪表盘画面时,可以确认数据库已被更换。
当检查数据库的状态时,可以看到… 角色确实已经交换了。
在psql1(Standby)端上,
postgres=# select * from pg_stat_wal_receiver;
pid | status | receive_start_lsn | receive_start_tli | written_lsn | flushed_lsn | received_tli | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo
------+-----------+-------------------+-------------------+-------------+-------------+--------------+-------------------------------+-------------------------------+----------------+------------------------------+-----------+---------------------------------------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2112 | streaming | 4/8000000 | 1 | 4/9000158 | 4/9000158 | 1 | 2023-10-11 15:38:46.041232+00 | 2023-10-11 15:38:46.041319+00 | 4/9000158 | 2023-10-11 15:38:15.99787+00 | dbvisit_1 | psql2-43E255BE16DD4A02.mp-standby.com | 5432 | user=postgres password=******** channel_binding=prefer dbname=replication host=psql2-43E255BE16DD4A02.mp-standby.com port=5432 fallback_application_name=14/main sslmode=prefer sslcompression=0 sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any
(1 row)
在主要的psql2一侧
postgres=# select * from pg_stat_replication;
pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time
------+----------+----------+------------------+---------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------+-----------+------------+---------------+------------+-------------------------------
2242 | 10 | postgres | 14/main | 54.253.33.159 | | 38038 | 2023-10-11 15:37:03.772446+00 | | streaming | 4/9000060 | 4/9000060 | 4/9000060 | 4/9000060 | | | | 0 | async | 2023-10-11 15:37:36.615552+00
(1 row)
自动故障转移
好的,接下来我们来尝试自动故障转移。自动故障转移是在主服务器发生故障时,自动将备用服务器切换为主服务器的功能。
首先,在Dbvisit StandbyMP中,默认情况下未设置自动故障切换,因此需要先进行自动故障切换的设定。请从右侧菜单中选择自动故障切换选项。

在「紧急操作」中选择“执行自动故障转移”并保存设置。

好吧,现在让我们来尝试自动故障转移。
立即使主数据库无法使用。在这里,我们试图强制终止PostgreSQL进程。通过ssh登录到psql2(因为现在正在执行故障切换,所以psql2是主数据库),确认进程ID后,强制终止进程。
postgres@psql2:~$ ps aux | grep postgres
postgres 1162 0.0 0.2 1468732 42056 ? Ssl 01:16 0:01 /PSQL_DATA/dbvisit/standbymp/bin/dbvagentmanager service run
postgres 1919 0.0 0.2 1464904 33460 ? Sl 01:20 0:02 /PSQL_DATA/dbvisit/standbymp/bin/dbvhelper -agentManagerId m0aaqak8xqg5 -directorId 3snp568w9w3ia -hostAddress psql2-7B921FA345BF47AC.mp-standby.com -natsAddress controlcenter-7b921fa345bf47ac.mp-standby.com -natsPort 5533 -configurationType PostgreSQL -helperProcessKey postgresql:m0aaqak8xqg5
postgres 2063 0.0 0.1 218672 30080 ? Ss 02:10 0:00 /usr/lib/postgresql/14/bin/postgres -D /var/lib/postgresql/14/main -c config_file=/etc/postgresql/14/main/postgresql.conf
postgres 2064 0.0 0.0 73208 6944 ? Ss 02:10 0:00 postgres: 14/main: logger
postgres 2066 0.0 0.0 218672 7364 ? Ss 02:10 0:00 postgres: 14/main: checkpointer
postgres 2067 0.0 0.0 218672 8516 ? Ss 02:10 0:00 postgres: 14/main: background writer
postgres 2068 0.0 0.0 218672 11588 ? Ss 02:10 0:00 postgres: 14/main: walwriter
postgres 2069 0.0 0.0 219344 9924 ? Ss 02:10 0:00 postgres: 14/main: autovacuum launcher
postgres 2070 0.0 0.0 73440 7108 ? Ss 02:10 0:00 postgres: 14/main: stats collector
postgres 2071 0.0 0.0 219088 9156 ? Ss 02:10 0:00 postgres: 14/main: logical replication launcher
postgres 2083 0.0 0.0 219964 14532 ? Ss 02:10 0:00 postgres: 14/main: walsender postgres 52.64.9.21(38302) streaming 4/7000060
root 2097 0.1 0.0 17164 10672 ? Ss 02:11 0:00 sshd: postgres [priv]
postgres 2117 0.1 0.0 17036 9472 ? Ss 02:11 0:00 /lib/systemd/systemd --user
postgres 2118 0.0 0.0 170552 6708 ? S 02:11 0:00 (sd-pam)
postgres 2180 0.0 0.0 17300 7820 ? S 02:11 0:00 sshd: postgres@pts/0
postgres 2181 0.0 0.0 9100 4992 pts/0 Ss 02:11 0:00 -bash
postgres 2198 0.0 0.0 10460 3200 pts/0 R+ 02:12 0:00 ps aux
postgres 2199 0.0 0.0 7004 2304 pts/0 R+ 02:12 0:00 grep postgres
让我们杀掉进程 ID 为2063的那个。
postgres@psql2:~$ kill -KILL 2063
postgres@psql2:~$ ps aux | grep postgres
postgres 1162 0.0 0.2 1468732 35624 ? Ssl 01:16 0:01 /PSQL_DATA/dbvisit/standbymp/bin/dbvagentmanager service run
postgres 1919 0.0 0.2 1464904 33332 ? Sl 01:20 0:02 /PSQL_DATA/dbvisit/standbymp/bin/dbvhelper -agentManagerId m0aaqak8xqg5 -directorId 3snp568w9w3ia -hostAddress psql2-7B921FA345BF47AC.mp-standby.com -natsAddress controlcenter-7b921fa345bf47ac.mp-standby.com -natsPort 5533 -configurationType PostgreSQL -helperProcessKey postgresql:m0aaqak8xqg5
root 2097 0.0 0.0 17164 10672 ? Ss 02:11 0:00 sshd: postgres [priv]
postgres 2117 0.0 0.0 17036 9472 ? Ss 02:11 0:00 /lib/systemd/systemd --user
postgres 2118 0.0 0.0 170552 6708 ? S 02:11 0:00 (sd-pam)
postgres 2180 0.0 0.0 17300 7820 ? S 02:11 0:00 sshd: postgres@pts/0
postgres 2181 0.0 0.0 9100 4992 pts/0 Ss 02:11 0:00 -bash
postgres 2212 0.0 0.0 10460 3200 pts/0 R+ 02:13 0:00 ps aux
postgres 2213 0.0 0.0 7004 2304 pts/0 R+ 02:13 0:00 grep postgres
postgres@psql2:~$
确认了流媒体的断开以及主要监控的失败。

在设置中,经过 3 次确认失败后,将启动故障转移,并确认 psql1 已经设置为在线状态。

最后
我体验了使用Dbvisit StandbyMP进行PostgreSQL的切换操作(从DR环境切换)以及自动故障转移(在主要环境宕机时自动切换)。
Dbvisit StandbyMP 还支持除了之前介绍的PostgreSQL之外,Oracle Database和SQL Server。希望以下页面也能对您有所帮助。
如果不使用这样的软件,在灾害发生时进行从备份中恢复等操作是一项相当繁琐的工作,需要建立严密的步骤。再次强调,想象一下发生故障导致无法使用生产环境等情况时,需要对许多环境进行适应。利用灾难恢复产品,预先准备好以确保在灾害发生时能够继续经营。