在 Postgres 复制中查询 master

Jam*_*arl 8 postgresql

我试图找出是否有办法从已设置服务器复制的从属 PostgreSQL 服务器查询主服务器。

从奴隶,我可以:

SELECT pg_is_in_recovery()
Run Code Online (Sandbox Code Playgroud)

如果我在从站上,这会给我一个“t”结果,而在主站上给我一个“f”结果,这是第一步。

接下来,我想运行一个查询,该查询为我提供有关它正在复制的主节点的一些信息。最好是 IP 地址或主机名。

作为记录,我可以使用以下命令查询 master:

SELECT * from pg_stat_replication
Run Code Online (Sandbox Code Playgroud)

这会给我关于奴隶的信息。我希望有一种查询奴隶的互惠方法。

这可能吗?如果是这样,如何?

Mat*_*sOl 9

正如克雷格所说,没有办法通过 SQL 从从站获取主信息。

我曾经想出的一种解决方案是pg_read_file用来获取recovery.conf文件的内容,如:

SELECT pg_read_file('recovery.conf');
Run Code Online (Sandbox Code Playgroud)

有了这些信息,我们可以使用正则表达式轻松解析它以获取所有配置/值。我使用以下方法来完成它:

SELECT DISTINCT ON (rm[1]) rm[1] AS name, coalesce(replace(rm[4], '''''', ''''), rm[2]) AS setting FROM (
SELECT row_number() OVER() rn, confs, regexp_matches(confs, '^[\s]*([a-z_]+)[\s]*=[\s]*([A-Za-z_\200-\377]([-A-Za-z_0-9\200-\377._:/]*)|''(([^''\n]|\\.|'''')*)'')') AS rm
FROM regexp_split_to_table(pg_read_file('recovery.conf'), '\n') AS confs
) AS recovery_confs
ORDER BY rm[1], rn DESC;
Run Code Online (Sandbox Code Playgroud)

有了这个,只需选择您的配置:

WITH recconfs AS (
    SELECT DISTINCT ON (rm[1]) rm[1] AS name, coalesce(replace(rm[4], '''''', ''''), rm[2]) AS setting FROM (
    SELECT row_number() OVER() rn, confs, regexp_matches(confs, '^[\s]*([a-z_]+)[\s]*=[\s]*([A-Za-z_\200-\377]([-A-Za-z_0-9\200-\377._:/]*)|''(([^''\n]|\\.|'''')*)'')') AS rm
    FROM regexp_split_to_table(pg_read_file('recovery.conf'), '\n') AS confs
    ) AS recovery_confs
    ORDER BY rm[1], rn DESC
)
SELECT setting FROM recconfs WHERE name = 'primary_conninfo';
Run Code Online (Sandbox Code Playgroud)

正则表达式改编自 PG 的源文件guc-file.l,但我没有使用所有可能的变体,这意味着它只适用于字符串(不带引号或单引号),这对primary_conninfo.

在我看来,这种方法有两个问题:

  1. 我不保证这个正则表达式真的100% 完美,任何人都可以看到错误?
  2. 只有超级用户可以使用pg_read_file,但这并不是真正的问题,正如预期的那样,或者您可以将其包装在一个函数中(我这样做了,因为我想要一个非超级用户来检查它,在我的情况下是一个REPLICATION用户)。