有没有办法查看 Postgres 表具有什么样的副本标识,无论是使用 pgAdmin 还是通过查询?
嗨,我正在无限循环中连续读取逻辑复制流。我有另一个程序在同一个数据库中不断填充一个表。我注意到一段时间后(大约 5-10 分钟)。我总是得到例外
org.postgresql.util.PSQLException: Database connection failed when reading from copy
at org.postgresql.core.v3.QueryExecutorImpl.readFromCopy(QueryExecutorImpl.java:1035)
at org.postgresql.core.v3.CopyDualImpl.readFromCopy(CopyDualImpl.java:41)
at org.postgresql.core.v3.replication.V3PGReplicationStream.receiveNextData(V3PGReplicationStream.java:155)
at org.postgresql.core.v3.replication.V3PGReplicationStream.readInternal(V3PGReplicationStream.java:124)
at org.postgresql.core.v3.replication.V3PGReplicationStream.read(V3PGReplicationStream.java:70)
at com.datamirror.ts.scrapers.postgresqlscraper.PGStreamReceiver.main(PGStreamReceiver.java:60)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:220)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:140)
at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:109)
at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:67)
at org.postgresql.core.PGStream.receiveChar(PGStream.java:293)
at org.postgresql.core.v3.QueryExecutorImpl.processCopyResults(QueryExecutorImpl.java:1077)
at org.postgresql.core.v3.QueryExecutorImpl.readFromCopy(QueryExecutorImpl.java:1033)
Run Code Online (Sandbox Code Playgroud)
这是我的示例程序:
import java.nio.ByteBuffer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.postgresql.PGConnection;
import org.postgresql.PGProperty;
import org.postgresql.replication.LogSequenceNumber;
import org.postgresql.replication.PGReplicationStream;
public class PGStreamReceiver {
public static void main(String[] args) {
try {
LogSequenceNumber startLsn = …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 Debian 9 和 PG 11.1 的 2 个云实例之间设置逻辑复制。主服务器上的命令CREATE PUBLICATION成功,但是当我CREATE SUBSCRIPTION在预期的逻辑副本上启动该命令时,该命令无限期挂起。
在主服务器上,我可以看到复制槽已创建并且处于活动状态,并且我可以看到创建了一个新的 walsender 进程并“正在等待”,并且在主服务器的日志中我看到了这些行:
2019-01-14 14:20:39.924 UTC [8349] repl_user@db LOG: logical decoding found initial starting point at 7B0/6C777D10
2019-01-14 14:20:39.924 UTC [8349] repl_user@db DETAIL: Waiting for transactions (approximately 2) older than 827339177 to end.
Run Code Online (Sandbox Code Playgroud)
但仅此而已。命令CREATE SUBSCRIPTION永远不会结束。
Master 是一个插入量很大的数据库,比如每分钟 100 次,但它们总是被提交。所以不应该有任何长时间未提交的事务。
我尝试用谷歌搜索这个问题,但没有找到任何东西。我缺少什么?
Postgres 逻辑复制初始同步过程非常慢,尤其是在原始数据库很大的情况下。
我想知道是否可以从给定的 LSN 开始复制?
所需的工作流程将是
我没有找到任何允许执行步骤 4 的文档,有人知道这是否可能吗?
我正在使用逻辑复制将数据从 Postgres 10.4 复制到另一个 Postgres 10.4 实例。
订阅者有多个触发器将事件记录到单个表中。该表有一个触发器,它执行另一个函数(返回一个触发器)来为下游侦听器调用 NOTIFY。
审计表上的触发器如下所示:
CREATE TRIGGER queue_insert
AFTER INSERT ON schema_name.table_name FOR EACH ROW
EXECUTE PROCEDURE notify_downstream()
GO
Run Code Online (Sandbox Code Playgroud)
通知下游定义:
CREATE OR REPLACE FUNCTION schema_name.notify_downstream () RETURNS trigger AS
'
declare
message character varying;
begin
raise log ''notify running!'';
message := ''
{ "id": 'edited for brevity' }
'';
execute ''notify chan_name, '''''' || message || '''''''';
raise log ''Value: %'', message;
return new;
end;
'
LANGUAGE 'plpgsql'
GO
Run Code Online (Sandbox Code Playgroud)
使用日志记录,我能够证明这是在触发。我还可以看到有数据使用:
select pg_notification_queue_usage()
Run Code Online (Sandbox Code Playgroud)
问题是在我插入表中(读作:逻辑复制之外)以触发触发器之前,没有任何侦听器收到消息,然后侦听器收到通知应该从逻辑复制发送的所有消息。
所有这些都运行良好,直到我们转向逻辑复制(我们有一个已退役的本土解决方案,我对此一无所知)。
我没有收到任何可以给我任何线索的错误或奇怪的消息。我也打开了日志记录的详细程度,除了我添加到函数中以验证它们正在运行的日志语句之外,没有看到任何与 …
我有一个transactions有 2 亿行的普通表。
我决定使用逻辑复制将此表转换为声明式分区。
我在 node1 上创建了一个出版物,如下所示:
CREATE PUBLICATION transactions_pub FOR TABLE transactions;
Run Code Online (Sandbox Code Playgroud)
当我尝试在 node2 上创建订阅时,如下所示:
CREATE SUBSCRIPTION transactions_sub CONNECTION 'host=x.x.x.x port=5432 password=123456 user=replicator dbname=mydbname' PUBLICATION transactions_pub;
Run Code Online (Sandbox Code Playgroud)
返回此错误:
ERROR: logical replication target relation "public.transactions" is not a table
Run Code Online (Sandbox Code Playgroud)
是否可以使用逻辑复制将常规表复制到声明式分区表?
postgresql replication database-partitioning postgresql-11 logical-replication
我正在创建复制槽,并通过 JDBC 驱动程序将更改从 AWS Postgres RDS 流式传输到 java 进程。
我的复制槽创建代码如下所示。
final ReplicationSlotInfo replicationSlotInfo = pgConnection.getReplicationAPI()
.createReplicationSlot()
.logical()
.withSlotName(replicationSlotName)
.withOutputPlugin("wal2json")
.make();
Run Code Online (Sandbox Code Playgroud)
我使用以下代码获得复制流。
pgConnection.getReplicationAPI()
.replicationStream()
.logical()
.withSlotName(replicationSlotName)
.withSlotOption("include-xids", true)
.withSlotOption("include-timestamp", true)
.withSlotOption("pretty-print", false)
.withSlotOption("add-tables", "public.users")
.withStatusInterval(10, TimeUnit.SECONDS)
.start()
Run Code Online (Sandbox Code Playgroud)
当复制器 java 进程未运行时,WAL 大小会增加。这是我用来查找复制滞后的查询。
SELECT
slot_name,
pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)) AS replicationSlotLag,
active
FROM
pg_replication_slots;
Run Code Online (Sandbox Code Playgroud)
输出:
slot_name replicationslotlag active
data_stream_slot 100 GB f
Run Code Online (Sandbox Code Playgroud)
这种复制延迟会超过 RDS 磁盘,从而导致 RDS 关闭。
我以为wal_keep_segments会处理这个问题,它被设置为 32。但它不起作用。即使 Java 复制进程未运行,我是否还必须设置任何其他属性来避免这种情况。
我们的 postgresql 数据库(版本 11)实例中有两个逻辑复制槽,我们使用 pgJDBC 从这两个槽传输数据。我们确保定期发送反馈并将两个插槽的confirmed_flush_lsn(每10分钟)更新到同一位置。然而,从我们的数据中我们可以看出,两者的 restart_lsn 动作并不同步,并且大多数时候其中一个落后太多,无法不必要地保存 WAL 文件。以下是一些数据点来表明问题
Thu Dec 10 05:37:13 CET 2020
slot_name | restart_lsn | confirmed_flush_lsn
--------------------------------------+---------------+---------------------
db_dsn_metadata_src_private | 48FB/F3000208 | 48FB/F3000208
db_dsn_metadata_src_shared | 48FB/F3000208 | 48FB/F3000208
(2 rows)
Thu Dec 10 13:53:46 CET 2020
slot_name | restart_lsn | confirmed_flush_lsn
-------------------------------------+---------------+---------------------
db_dsn_metadata_src_private | 48FC/2309B150 | 48FC/233AA1D0
db_dsn_metadata_src_shared | 48FC/233AA1D0 | 48FC/233AA1D0
(2 rows)
Thu Dec 10 17:13:51 CET 2020
slot_name | restart_lsn | confirmed_flush_lsn
-------------------------------------+---------------+---------------------
db_dsn_metadata_src_private | 4900/B4C3AE8 | 4900/94FDF908
db_dsn_metadata_src_shared | 48FD/D2F66F10 | 4900/94FDF908 …Run Code Online (Sandbox Code Playgroud) 我是 PostgreSQL 逻辑复制的新手。我做了测试,在我向发布添加新表后,我发现复制不起作用,直到我重新创建订阅,我确定重新创建订阅不是最佳做法,请您告知如何制作订阅者为新表应用事务?
测试如下:
在主端和复制端创建第一个表:
create table rep_test (a int primary key, b int);
Run Code Online (Sandbox Code Playgroud)
在主端创建发布:
CREATE PUBLICATION rep_test_pub FOR table public.rep_test;
Run Code Online (Sandbox Code Playgroud)
在复制端创建订阅:
CREATE SUBSCRIPTION rep_test_sub CONNECTION 'host=XXX port=5432 dbname=rocket user=XXX password=XXX' PUBLICATION rep_test_pub WITH (copy_data = false);
Run Code Online (Sandbox Code Playgroud)
测试复制,复制有效。初级侧:
insert into rep_test values (1, 1); insert into rep_test values (2, 1);
Run Code Online (Sandbox Code Playgroud)
复制:
select * from rep_test;
*---*---*
| a | b |
*---*---*
| 1 | 1 |
| 2 | 1 |
*---*---*
Run Code Online (Sandbox Code Playgroud)
在主端和复制端创建一个新表
create table rep_test (a int primary …Run Code Online (Sandbox Code Playgroud)