如何在只读事务中不执行INSERT

How to not execute INSERT in read-only transaction

Postgres 服务器处于热备模式。 使用异步流式二进制复制。

类似

的命令
INSERT INTO logfile (logdate) values (current_date)

导致错误

cannot execute INSERT in a read-only transaction.

也许应该改为

INSERT INTO logfile (logdate) 
SELECT current_date
WHERE   ???

应该使用什么where条件? 它应该从 Postgres 9.0 开始工作 如果直接 where 子句是不可能的,也许可以在 where 中使用一些 plpgsql 函数。

也许

show transaction_read_only

应捕获结果或可以使用某些功能。

另外,应用程序可以确定数据库在启动时是否为只读。应该显示用于此的 transaction_read_only 结果。

运行 INSERT 在备用服务器上是不可能的纯(非过程)SQL 因为当服务器处于备用模式时,所有数据修改查询都是在计划阶段被拒绝,在执行之前。

PL/PgSQL 中的条件句是可能的。

DO $code$
BEGIN
  IF NOT pg_is_in_recovery() THEN
    INSERT INTO logfile (logdate) VALUES (current_date);
  END IF;
END;
$code$;

但是,可能不推荐这样做 - 通常最好测试 pg_is_in_recovery() 一次(在应用程序代码中)然后采取相应的行动。

我使用的是 pg_is_in_recovery() 系统函数而不是 transaction_read_only GUC,因为它们并不完全相同。但是,如果您愿意,请使用:

SELECT current_setting('transaction_read_only')::bool

更多信息:DO command, conditionals in PL/PgSQL, system information functions