问题描述
PostgreSL 中的逻辑复制是基于逻辑解析(Logical Decoding)的发布订阅模型,原理是主库(发布端)将 WAL日志流解析成一定格式的数据流,订阅节点(从节点)收到解析后的WAL数据流后进行应用来达到数据同步的目的。 在数据同步完成之后或者出现问题之后,我们可能需要在订阅端删除已经存在的订阅,这时候可能会出现如下两种报错:
rudonx=# drop subscription alltabsub;
ERROR: could not drop the replication slot "rds_data_slot" on publisher
DETAIL: The error was: ERROR: replication slot "rds_data_slot" does not exist
```
`
另外一种报错如下:
````undefined
rudonx=# drop subscription alltabsub;
ERROR: could not connect to publisher when attempting to drop the replication slot "alltabsub"
DETAIL: The error was: could not connect to server: Connection timed out
Is the server running on host "68.79.10.116" and accepting
TCP/IP connections on port 5432?
HINT: Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot.
```
`
当问题出现之后,我们该如何分析并处理此类报错?
# 问题分析
当在订阅端删除订阅时,订阅端会连接到发布端的实例上,删除相关的 replication slot 来达到释放资源的目的。
当发布端的逻辑复制槽被意外的清理,或者是逻辑复制中的发布端实例不可达时,会导致 `drop subscription` 失败。
# 解决方案
首先建议检查是否远程主机有不可达的情况,可以通过 `telnet` 命令进行检查,其次可以在发布端使用如下命令检查复制槽是否有非预期的删除:
````undefined
postgres=# select * from pg_replication_slots;
```
`
最后我们可以使用如下三条命令删除已经存在的订阅:
````undefined
rudonx=# alter subscription xxxx disable;
rudonx=# alter subscription xxxx SET (slot_name = NONE);
rudonx=# drop subscription xxxx ;
```
`
**注意**
上述命令会帮我们删除订阅,如果在订阅端复制槽依然存在,请手动删除无用的复制槽以避免磁盘空间被耗尽的风险。
**如果您有其他问题,欢迎您联系火山引擎**[技术支持服务](https://console.volcengine.com/ticket/createTicketV2/)