Php 如何手动触发错误“;由于与恢复错误冲突而取消语句”;我的postgresql回复方案?

Php 如何手动触发错误“;由于与恢复错误冲突而取消语句”;我的postgresql回复方案?,php,postgresql,Php,Postgresql,为了在我的postgresql热备用复制模式中测试各种设置,我需要重现以下错误: SQLSTATE[40001]: Serialization failure: 7 ERROR: canceling statement due to conflict with recovery DETAIL: User query might have needed to see row versions that must be removed. 因此,我尝试让2个进程1永远更新一个布尔字段及其对立面,

为了在我的postgresql热备用复制模式中测试各种设置,我需要重现以下错误:

SQLSTATE[40001]: Serialization failure: 7 ERROR:  canceling statement due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.
因此,我尝试让2个进程1永远更新一个布尔字段及其对立面,另一个从副本读取值

更新脚本如下(
loopUpdate.php
):

读取脚本如下(
/loopRead.php
):

我并行地执行它们:

# From one shell session
$ php ./loopUpdate.php 
# From another one shell session
$ php ./loopRead.php 
mydb_replica.c3rrdbjxxkk.eu-central-1.rds.amazonaws.com
是mydb.c3rrdbjxxkk.eu-central-1.rds.amazonaws.com的热备份读取副本

但是我无法使
loopRead.php
失败,错误如下:

SQLSTATE[40001]: Serialization failure: 7 ERROR:  canceling statement due to conflict with recovery
DETAIL:  User query might have needed to see row versions that must be removed.

据我所知,我试图重现的错误是因为postgresql
VACUUM
操作是在请求相当陈旧数据的读取副本上的活动读取事务期间执行的。那么,我如何使select语句在我的行的过时版本上进行选择呢?

为了引起您的错误,您需要通过
pg\u delay
postgresql函数对select查询本身施加巨大延迟,从而将查询更改为:

SELECT id, boolval, pg_sleep(1000000000) FROM mytable  WHERE id=52
因此,在单个事务中,您有一个“繁重”的查询,并最大限度地提高了导致PostgreSQL序列化错误的可能性

尽管细节会有所不同:

DETAIL:  User was holding shared buffer pin for too long.

在tat情况下,尝试在待机状态下将pg_延迟值从
100000000
降低到
10
,将
max_standby_streaming_delay
设置为0,并将
hot_standby_反馈设置为
off

然后在待机状态下启动事务:

SELECT *, pg_sleep(10) FROM atable;
然后从主服务器上的
atable
VACUUM(VERBOSE)
中删除
行。确保删除了一些行

然后您应该能够观察到复制冲突

DETAIL:  User was holding shared buffer pin for too long.
SELECT *, pg_sleep(10) FROM atable;