有没有办法查看 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)