从 MySQL 用户的角度看 PostgreSQL 复制设置

大家好,
我是开发团队野生队的成员 Mandai。
本文总结了在 PostgreSQL 9.4 中使用同步复制所需的设置。
我们公司通常使用 MySQL,但
即使 PostgreSQL 和 MySQL 是相同的关系数据库管理系统,使用起来还是有点令人困惑。
效果出乎意料的好,我非常满意,所以
我想总结一下我的经验,希望大家都能尝试一下。
这次的流程比较冗长复杂,所以我将向您展示菜单。
我想继续执行上述步骤。
PostgreSQL 复制(主数据库端工作)
,我们是在极其特殊的情况下工作:
为一个已经全面运行的数据库设置复制功能顺便说一句,这种情况其实更刺激。
作为一项一般性任务
我想应该是这样的。
假设本地网络中的主数据库已分配 IP 地址 192.168.1.1,从数据库已分配 IP 地址 192.168.1.2。
创建复制用户
首先,我们从简单的开始:创建一个名为 repl_user 的用户用于复制。
登录到主数据库后,使用以下查询创建该用户。
创建用户 repl_user 复制密码 '[password]';
对 pg_hba.conf 的补充
接下来,编辑 pg_hba.conf 文件。
在这里,您需要启用从数据库,使其能够使用您之前创建的 repl_user 用户。
主机复制 repl_user 192.168.1.2/32 md5
将 IP 地址更改为从库的 IP 地址。
如果您要创建多个从库,则需要相应地调整 IP 子网掩码;但
如果只创建一个从库,则 /32 子网掩码应该就可以了。
编辑 postgresql.conf
接下来,我们将编辑 postgresql.conf 文件。
在这里,我们将添加和更改与复制相关的设置。
所有必要的设置项都已被注释掉,您可以通过取消注释来启用它们。
这比 MySQL 更人性化。
复制所需的设置如下:
墙水平
此项设置WAL文件中要包含多少信息。
WAL 存储级别分为三级:minimal、archive 和 hot_standby。
默认值为 minimal,足以满足正常运行需求。
要设置复制,您需要归档级别或更高级别,因此在这种情况下,我们将把它设置为 hot_standby。
wal_level = 热备
同步提交
此设置决定在事务执行完毕后,是否等待 wal 文件写入完成才向客户端返回成功。
默认情况下是开启的,写入 wal 文件后会向客户端返回响应。
如果将其关闭,则写入 WAL 文件失败时,交易数据将会丢失,并且报告给客户端的状态也会有所不同。
但是,就数据本身而言,交易中的数据只会丢失,不会出现任何不一致的情况。
这意味着有可能向客户端返回成功消息,但该消息实际上并非成功。
这提高了对客户端的响应速度,但唯一的问题似乎是它偶尔(多久一次取决于交易失败的程度)会返回一个错误信息(或者这是唯一的问题吗?)。
这次我们就让它开着吧。
synchronous_commit = on
存档模式
开启归档模式后,您可以将 wal 文件存储在与普通 wal 存储区域不同的区域中。
如果发生复制延迟,从服务器会按顺序跟踪未应用的 WAL 文件。
然而,默认存储区域中 WAL 文件的生命周期非常短,因此它们无法承受长时间的延迟。
如果延迟严重到无法恢复,则必须重新输入数据,这将非常耗时。
为了解决这个问题,我们将 wal 文件复制到默认存储区域之外,这样无论其生命周期如何,我们都可以处理较长的复制延迟。
复制的 wal 文件不会继续累积(但请注意,如果出现延迟,它们可能会残留),因此无需批量单独删除它们。
这次,我们将保持启用状态。
archive_mode = 开启
归档命令
如果 archive_mode = on,则设置保存 wal 文件的命令。通常情况下,您会使用 cp 命令。
该命令中可以使用几个替换字符串来指示源 wal 文件,因此我们将使用它们。
- %f ・・・ wal 文件的文件名
- %p ・・・ 目标 wal 文件的绝对路径
archive_command = '[用于保存 wal 文件的控制台命令]'
max_wal_senders
设置要连接的从数据库数量。
通常情况下,对于通过 pg_basebackup 命令进行的连接,此值应设置为从数据库数量加 1。
max_wal_senders = 2 # 从节点数量 + 1
同步备用名称
请列出要连接为从数据库的数据库名称。
您无法连接到此处未列出的从数据库。
synchronous_standby_names = "db_slave1" # 如果您有多个从库,请添加以逗号分隔的数据库名称
重启主数据库
至此,主数据库端的配置完成。从
数据库端也可以进行配置(原因稍后解释),但这会使 postgresql.conf 文件难以理解,因此这次我们将逐个进行配置。
此时,请重启 PostgreSQL 以使更改生效。
顺便提一下,我查阅PostgreSQL的启动命令时发现,启动方式有很多种,但似乎有些方法由于安装方式不同而无法正常工作。
我一直使用的启动命令如下:
# 通过 initd /etc/init.d/postgresql-9.4 [start|stop|restart] # 通过 pg_ctl su postgres -c "/usr/pgsql-9.4/bin/pg_ctl [start|stop|restart] -D /var/lib/pgsql/9.4/data -m fast"
两者都需要以 root 用户身份运行,但我用 yum 安装 PostgreSQL 后,它们都能正常工作。
如果要启动两个 PostgreSQL 进程,
则需要使用 pg_ctl
在从数据库端进行工作
接下来我们将继续进行从服务器端的配置。
我们假设从数据库服务器上已安装 PostgreSQL,
并且版本号一致。
使用 pg_basebackup 复制主备份
首先,使用 pg_basebackup 复制整个主数据集。
您可以将 $PGDATA 目录复制到默认位置以外的其他位置,但这样一来,如果您通过 initd 启动数据库,则需要在 /etc/init.d/postgresql 脚本中修改 $PGDATA 路径。
在本例中,我们将数据复制到默认位置 /var/lib/pgsql/9.4/data。
重命名现有数据目录以进行备份。
从主库复制数据的 pg_basebackup 命令如下:
pg_basebackup -h 192.168.1.1 -U repl_user -D /var/lib/pgsql/9.4/data -P --xlog
根据数据库的大小,复制过程可能需要一些时间才能完成。
如果您进入复制后的数据目录,您会发现 pg_hba.conf 和 postgresql.conf 文件也已被复制。
正如在关于编辑主数据库端 postgresql.conf 文件的章节中提到的,从数据库的设置也可以在主数据库端进行配置,因为主数据库端的 postgresql.conf 文件会被复制。
作为主数据库运行的数据库会跳过作为从数据库运行所需的设置,反之亦然,所以我认为这是一个好主意。
编辑 postgresql.conf 文件(从服务器端)
为从服务器配置 postgresql.conf 文件。
热备
这是 PostgreSQL 热备用模式的设置项。
运行在热备用模式下的服务器无法执行任何更新操作,并且会变成只读数据库。
但是,仅此一项并不能启用复制功能;只有当 hot_standby 开启且 recovery.conf(稍后创建)存在时,复制功能才会启用。
热备用 = 开启
创建 recovery.conf
无需从头创建此文件;已有示例文件,您可以复制并修改它。
示例 recovery.conf 文件位于 /usr/pgsql-9.4/share 目录下,请将其复制到 /var/lib/pgsql/9.4/data 目录下。
cp /usr/pgsql-9.4/share/recovery.conf.sample /var/lib/pgsql/9.4/data/recovery.conf
编辑 recovery.conf
recovery.conf 文件中有两个地方需要编辑。
完成这些步骤后,复制设置就完成了!
待机模式
开启 standby_mode 后,即使最后一个 wal 文件已接收并处理完毕,系统仍将继续运行,等待下一个 wal 文件。
备用模式 = 开启
主连接信息
输入连接到主数据库的信息。
请特别注意主数据库的 postgresql.conf 文件中 synchronous_standby_names 列出的名称中是否包含 application_name 部分。
除此之外,其他都和我读到的一样。
primary_conninfo = 'host=192.168.1.1 port=5432 user=repl_user password=[password] application_name=db_slave1'
从重启从数据库到检查复制
完成上述设置后,即可重启从数据库。
重启命令与主数据库相同。
重启完成后,应该会开始复制,请从主数据库端检查复制进度。
登录到主数据库并运行以下查询:
select * from pg_stat_replication; -[ RECORD 1 ]----+------------------------------ pid | 12345 usesysid | 12345 usename | repl_user application_name | db_slave1 client_addr | 192.168.1.2 client_hostname | client_port | 43210 backend_start | 2016-06-12 17:01:07.923879+09 backend_xmin | state | streaming sent_location | 27/B4EED5F8 write_location | 27/B4EED5F8 flush_location | 27/B4EED5F8 replay_location | 27/B4EED5C0 sync_priority | 0 sync_state | async
如果状态项为流式传输,则表示当前正在执行复制。
可以在 sent_location、write_location、flush_location 和 replay_location 中查看数据同步状态。
- sent_location 是指示 WAL 文件已从主数据库发送到从数据库的地址。
- write_location 是指示数据已写入从缓冲区区域多远位置的地址。
- flush_location 是指示数据已写入从盘磁盘区域的地址。
- replay_location 是指示已导入到从数据库中的数据量的地址。
四个地址会随着数据量的增加而增加,因此您可以一目了然地看到进度。
在上面的例子中,直到 sent_location、write_location 和 flush_location 的地址都相同,这表明到目前为止的状态是最新的。
虽然 replay_location 略有延迟,但它目前以异步模式执行,因此只要不出现明显的同步偏差,就不会被察觉。
就这样。
0