7.5. 设置 PostgreSQL 以运行 Debezium 连接器
此 Debezium 发行版本只支持原生 pgoutput
逻辑复制流。要设置 PostgreSQL,使其使用 pgoutput
插件,您必须启用复制插槽,并配置具有足够特权的用户来执行复制。
详情包括在以下主题中:
7.5.1. 为 Debezium pgoutput
插件配置复制插槽
PostgreSQL 的逻辑解码使用复制插槽。要配置复制插槽,请在 postgresql.conf
文件中指定以下内容:
wal_level=logical max_wal_senders=1 max_replication_slots=1
这些设置指示 PostgreSQL 服务器,如下所示:
-
wal_level
- 使用 write-ahead 日志的逻辑解码。 -
max_wal_senders
- 使用最多一个单独的进程来处理 WAL 更改。 -
max_replication_slots
- 允许最多创建一个复制插槽来流传输 WAL 更改。
保证复制插槽可以保证保留 Debezium 所需的所有 WAL 条目,即使在 Debezium 中断期间也是如此。因此,务必要密切监控复制插槽以避免:
- 过多的内存消耗
- 任何条件,如目录 bloat,当复制插槽未使用过长时会出现这种情况
如需更多信息,请参阅 PostgreSQL 文档用于复制插槽。
熟悉 PostgreSQL write-ahead 日志的 mechanics 和 configuration 有助于使用 Debezium PostgreSQL 连接器。
7.5.2. 为 Debezium 连接器设置 PostgreSQL 权限
设置 PostgreSQL 服务器以运行 Debezium 连接器需要数据库用户可以执行复制。复制只能由具有适当权限的数据库用户执行,并且仅对配置的数量的主机执行。
虽然默认情况下,超级用户具有必要的 REPLICATION
和 LOGIN
角色,如 Security 中所述,最好不要为 Debezium 复制用户提供升级特权。相反,创建一个具有最低所需权限的 Debezium 用户。
先决条件
- PostgreSQL 管理权限。
流程
要为用户授予复制权限,请定义一个 至少具有
REPLICATION
和LOGIN
权限的 PostgreSQL 角色,然后将该角色授予该用户。例如:CREATE ROLE <name> REPLICATION LOGIN;
7.5.3. 设置特权,以便 Debezium 创建 PostgreSQL 出版物
来自为表创建的 publications 的 PostgreSQL 源表的 Debezium 流改变事件。出版物包含一组过滤的更改事件,这些事件由一个或多个表生成。每个发布中的数据会根据发布规格进行过滤。规范可由 PostgreSQL 数据库管理员或 Debezium 连接器创建。要允许 Debezium PostgreSQL 连接器创建发布并指定要复制到它们的数据,连接器必须使用数据库中的特定权限运行。
有几个选项可用于确定如何创建发布。通常,在设置连接器前,最好为要捕获的表手动创建发布。但是,您可以以允许 Debezium 自动创建发布的方式配置您的环境,并指定添加到其中的数据。
Debezium 使用 list 和 exclude list 属性来指定如何在发布中插入数据。有关启用 Debezium 创建发布的选项的更多信息,请参阅 publication.autocreate.mode
。
要使 Debezium 创建 PostgreSQL 发布,它必须以具有以下权限的用户运行:
- 数据库中的复制特权,将表添加到发布中。
-
数据库上的
CREATE
特权来添加发布。 -
表上的
SELECT
特权,以复制初始表数据。表所有者自动具有表的SELECT
权限。
要向发布添加表,用户必须是表的所有者。但是,由于源表已存在,您需要一种与原始所有者共享所有权的机制。要启用共享所有权,您可以创建一个 PostgreSQL 复制组,然后将现有的表所有者和复制用户添加到组中。
流程
创建复制组。
CREATE ROLE <replication_group>;
将表的原始所有者添加到组。
GRANT REPLICATION_GROUP TO <original_owner>;
将 Debezium 复制用户添加到组中。
GRANT REPLICATION_GROUP TO <replication_user>;
将表的所有权转让到 <
replication_group>
。ALTER TABLE <table_name> OWNER TO REPLICATION_GROUP;
对于 Debezium 指定捕获配置,必须将 publication.autocreate.mode
的值设置为 过滤
。
7.5.4. 配置 PostgreSQL 以允许使用 Debezium 连接器主机进行复制
要启用 Debezium 复制 PostgreSQL 数据,您必须将数据库配置为允许使用运行 PostgreSQL 连接器的主机进行复制。要指定允许使用数据库复制的客户端,请在基于 PostgreSQL 主机的身份验证文件 pg_hba.conf
中添加条目。有关 pg_hba.conf
文件的更多信息,请参阅 PostgreSQL 文档。
流程
在
pg_hba.conf
文件中添加条目,以指定可以使用数据库主机复制的 Debezium 连接器主机。例如,pg_hba.conf
文件示例:local replication <youruser> trust 1 host replication <youruser> 127.0.0.1/32 trust 2 host replication <youruser> ::1/128 trust 3
表 7.25. pg_hba.conf 设置的描述 项 描述 1
指示服务器允许在本地对 <
youruser&
gt; 进行复制,即在服务器机器上进行复制。2
指示服务器允许
localhost
上的 <youruser
> 使用IPV4
接收复制更改。3
指示服务器允许
localhost
上的 <youruser
> 使用IPV6
接收复制更改。
有关网络掩码的更多信息,请参阅 PostgreSQL 文档。
7.5.5. 配置 PostgreSQL 以管理 Debezium WAL 磁盘空间消耗
在某些情况下,PostgreSQL 磁盘空间可以被 WAL 文件使用,以激增或增加通常的比例。这种情况下有几个可能的原因:
连接器收到数据的 LSN 在服务器的
pg_replication_slots
视图的confirmed_flush_lsn
列中可用。此 LSN 旧数据不再可用,数据库负责回收磁盘空间。另外,在
pg_replication_slots
视图中,restart_lsn
列包含连接器可能需要的最旧的 WAL 的 LSN。如果confirmed_flush_lsn
的值定期增加和restart_lsn
lags 的值,则数据库需要回收空间。数据库通常会回收批处理块中的磁盘空间。这是预期的行为,用户不需要任何操作。
数据库中有很多更新被跟踪,但只有少量更新与连接器捕获更改的表和模式相关。这种情形可以通过定期的心跳事件轻松解决。设置
heartbeat.interval.ms
连接器配置属性。注意要使连接器从 heartbeat 表中检测和处理事件,您必须将表添加到 publication.name 属性指定的 PostgreSQL 出版物中。如果此发布要求您的 Debezium 部署,连接器将使用定义的发布。如果发布没有配置为自动复制数据库中
FOR ALL TABLES
的更改,您必须将 heartbeat 表明确添加到发布中,例如:
ALTER PUBLICATION < publicationName > ADD TABLE < heartbeatTableName > ;
PostgreSQL 实例包含多个数据库,其中一个是高流量数据库。Debezium 捕获另一个数据库中的更改,这些数据库与其它数据库相比是低流量。然后,Debezium 无法确认 LSN 作为每个数据库的复制插槽工作,而且 Debezium 不会被调用。当 WAL 由所有数据库共享时,使用的数量会增加,直到 Debezium 正在捕获更改的数据库发出事件。要克服这个问题,需要:
-
启用使用
heartbeat.interval.ms
连接器配置属性的定期心跳记录生成。 - 定期从 Debezium 捕获更改的数据库发出更改事件。
然后,一个单独的进程会通过插入新行或重复更新同一行来定期更新表。然后 PostgreSQL 会调用 Debezium,它会确认最新的 LSN 并允许数据库回收 WAL 空间。此任务可以通过
heartbeat.action.query
连接器配置属性进行自动处理。-
启用使用
在同一数据库服务器设置多个连接器
Debezium 使用复制插槽从数据库流更改。这些复制插槽以 LSN (Log Sequence Number)的形式维护当前位置,该位置是 Debezium 连接器消耗的 WAL 中的位置。这有助于 PostgreSQL 使 WAL 可用,直到 Debezium 处理为止。单个复制插槽只能针对单个消费者或进程存在,因为不同的消费者可能具有不同的状态,并且可能需要来自不同位置的数据。
由于复制插槽只能由单个连接器使用,因此每个 Debezium 连接器都需要创建一个唯一的复制插槽。虽然当连接器没有激活时,Postgres 可能会允许其他连接器消耗复制插槽 - 这可能会导致数据丢失,因为插槽将只发出每个更改 [请参阅 more]。
除了复制插槽外,Debebe 使用发布来流传输事件,在使用 pgoutput
插件时。与复制插槽类似,发布在数据库级别,并定义为一组表。因此,您需要为每个连接器有一个唯一的发布,除非连接器可用于同一组表。有关启用 Debezium 创建发布的选项的更多信息,请参阅 publication.autocreate.mode
有关如何为每个连接器设置唯一的复制插槽名称和发布名称,请参阅 slot.name
和 publication.name
。
7.5.6. 升级 Debezium 捕获的 PostgreSQL 数据库
当升级 Debezium 使用的 PostgreSQL 数据库时,您必须执行特定的步骤来防止数据丢失,并确保 Debezium 继续操作。通常,Debezium 能够应对网络故障和其他中断导致的中断。例如,当连接器监控的数据库服务器停止或崩溃时,在连接器重新建立与 PostgreSQL 服务器的通信后,它会继续从日志序列号(LSN)偏移记录的最后位置读取。连接器从 Kafka Connect offsets 主题检索有关最后一次记录的偏移信息,并查询配置的 PostgreSQL 复制插槽以获取具有相同值的日志序列号(LSN)。
要使连接器启动和捕获 PostgreSQL 数据库中的更改事件,必须存在复制插槽。但是,作为 PostgreSQL 升级过程的一部分,复制插槽会被删除,在升级完成后不会恢复原始插槽。因此,当连接器重启并请求复制插槽的最后已知的偏移时,PostgreSQL 无法返回信息。
您可以创建新的复制插槽,但您必须有超过创建新插槽才能防止数据丢失。新的复制插槽只能为创建插槽后发生的更改提供 LSNs;无法为升级前发生的事件提供偏移量。当连接器重启时,它会首先从 Kafka offsets 主题请求最后已知的偏移量。然后,它会向复制插槽发送请求,以返回从偏移主题中检索的偏移信息。但是,新的复制插槽无法提供连接器从预期位置恢复流所需的信息。然后,连接器会跳过日志中任何现有更改事件,且只从日志中的最新位置恢复流。这可能导致静默数据丢失:连接器没有为跳过的事件发出记录,而不提供任何信息来指示这些事件已被跳过。
有关如何执行 PostgreSQL 数据库升级以便 Debezium 能够继续捕获事件,同时最大程度降低数据丢失的风险,请参阅以下步骤。
步骤
- 临时停止写入数据库的应用程序,或将其置于只读模式。
- 备份数据库。
- 临时禁用对数据库的写入访问权限。
- 在阻止写操作保存到 write-ahead 日志(WAL)前,验证数据库中发生了的任何更改,并且 WAL LSN 是否反映在复制插槽上。
-
为连接器提供足够的时间,以捕获写入复制插槽的所有事件记录。
此步骤可确保在停机被考虑前发生的所有更改事件,并将其保存到 Kafka 中。 - 通过检查 flushed LSN 的值,验证连接器是否已消耗来自复制插槽的条目。
通过停止 Kafka Connect 来安全地关闭连接器。
Kafka Connect 会停止连接器,将所有事件记录刷新到 Kafka,并记录从每个连接器接收的最后一个偏移。
注意作为停止整个 Kafka Connect 集群的替代方案,您可以通过删除它来停止连接器。不要删除偏移主题,因为它可能由其他 Kafka 连接器共享。之后,在恢复对数据库的写入访问并准备好重启连接器后,您必须重新创建连接器。
-
作为 PostgreSQL 管理员,丢弃主数据库服务器上的复制插槽。不要使用
slot.drop.on.stop
属性来丢弃复制插槽。此属性仅用于测试。 - 停止数据库。
-
使用批准的 PostgreSQL 升级步骤(如
pg_upgrade
)或pg_dump
和pg_restore
执行升级。 -
(可选)使用标准 Kafka 工具从偏移存储主题中删除连接器偏移。
有关如何删除连接器偏移的示例,请参阅 如何删除 Debezium 社区常见问题解答中的连接器偏移。 - 重新启动数据库。
作为 PostgreSQL 管理员,在数据库上创建 Debezium 逻辑复制插槽。在启用对数据库进行写入前,您必须创建插槽。否则,Debezium 无法捕获更改,从而导致数据丢失。
有关设置复制插槽的详情,请参考 第 7.5.1 节 “为 Debezium
pgoutput
插件配置复制插槽”。- 验证在升级后是否仍然存在了定义 Debezium 要捕获的表的发布。如果发布不可用,请以 PostgreSQL 管理员身份连接到数据库,以创建新的发布。
-
如果需要在上一步中创建新发布,请更新 Debezium 连接器配置,将新发布的名称添加到
publication.name
属性。 - 在连接器配置中,重命名连接器。
-
在连接器配置中,将
slot.name
设置为 Debezium 复制插槽的名称。 - 验证新复制插槽是否可用。
- 恢复对数据库的写入访问权限,然后重新启动写入数据库的任何应用程序。
在连接器配置中,将
snapshot.mode
属性设置为never
,然后重启连接器。注意如果您无法验证 Debezium 是否完成了第 6 步中的所有数据库更改,您可以通过设置
snapshot.mode=initial
将连接器配置为执行新快照。如果需要,您可以通过检查升级前立即执行的数据库备份内容来确认连接器是否从复制插槽读取所有更改。
其他资源