PostgreSQL 提供了将所执行的修改通过 SQL 以流的方式传送给外部消费者的方法。这种功能可以被用于复制方案以及审计。在流中被送出的更改通过逻辑复制槽标识。
流式传输这些更改的格式由使用的输出插件决定。每一个输出插件都能访问每一个由 INSERT产生的新行以及每一个由 UPDATE创建的新行版本。UPDATE和DELETE 的旧行版本的可用性取决于配置的复制标识。
逻辑解码的概念
逻辑解码是一种将对数据库表的所有持久更改抽取到一种清晰、易于理解的格式的处理,这种技术允许在不了解数据库内部状态的详细知识的前提下解释该格式。
在PostgreSQL中,逻辑解码通过解码预写式日志的内容来实现。
复制槽
一个复制槽在一个PostgreSQL集簇的所有数据库之间具有一个唯一的标识符。槽在使用它们的连接之间保持独立。
在常规的操作中,一个逻辑槽只会把每次的更改发出一次。只有在检查点时才会持久化每一个逻辑槽的当前位置,因此如果发生崩溃,逻辑槽可能会回到一个较早的 LSN,这会导致服务器重启时重新发送最近的更改。逻辑解码客户端负责避免多次处理同一消息导致的副作用。
对于同一个数据库可能会存在多个独立的槽。每一个槽有自己的状态,允许不同的消费者从该数据库的更改流中的不同点开始接收更改。对于大多数应用, 每一个消费者都将要求一个单独的槽。
逻辑复制槽完全不知道接收者的状态。甚至可能会有多个不同的接收者在不同时间使用同一个槽,它们将只是从上一个接收者停止消费更改的地方开始得到更改。但在任一给定时刻,只有一个接收者可以从一个槽中消费更改。
复制槽可以在崩溃时保留,并且不知道其消费者的状态。即便没有连接使用它们,它们也将阻止移除所需的资源。这会消耗存储,因为只要还有一个复制槽需要, WAL和来自于系统目录的行就不能被VACUUM移除。因此如果不再需要一个槽,那就应该删除它。
输出插件
输出插件将数据从预写式日志的内部表示转换成复制槽的消费者所需的格式。
导出快照
当使用流复制接口(CREATE_REPLICATION_SLOT) 创建一个新的复制槽时,一个快照将被导出,在它所显示的数据库状态之后所有的更改都将被包括在更改流中。通过使用 SET TRANSACTION SNAPSHOT读取槽被创建时的数据库状态,可以用来创建一个新的复制。不需要快照导出的应用程序可以使用NOEXPORT_SNAPSHOT选项。
流复制协议接口
创建一个复制槽,例如:
postgres=# SELECT * FROM pg_create_physical_replication_slot('slot_1');
slot_name | lsn
-----------+-----
slot_1 |
(1 row)
查看复制槽当前状态信息:
postgres=# select * from pg_replication_slots;
slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_l
sn
-----------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+------------------
---
slot_1 | | physical | | | f | f | | | | |
(1 row)
删除一个复制槽,例如:
postgres=# SELECT * FROM pg_drop_replication_slot('slot_1');
pg_drop_replication_slot
--------------------------
(1 row)
这些命令只能在一个复制连接上使用。 pg_replication_slots 视图和 pg_stat_replication 视图分别提供了有关复制槽和流复制连接的当前状态的信息。这些视图适用于物理和逻辑复制。
逻辑解码的同步复制支持
逻辑解码可以被用来构建同步复制方案,该方案具有和流复制的同步复制相同的用户接口。要想这样做的话,流复制接口必须被用来流式传出数据。
一个通过逻辑解码接收更改的同步复制机将工作在一个单一数据库的范围内。 因为与之相反的是,synchronous_standby_names 当前是服务器范围的,这意味着如果有多于一个数据库被活跃地使用,这种技术将无法正常工作。
By Kalath