ablog

不器用で落着きのない技術者のメモ

Aurora PostgreSQL での VACUUM とリードレプリカでの SELECT のコンフリクト

設定

  • Aurora PostgreSQL の DB Cluster Parameter Group で max_standby_streaming_delay を最小値の 1 秒に設定。
max_standby_streaming_delay=1000

手順

  • Writer
postgres=> create table test1 (col1 int);
postgres=> insert into test1 values (generate_series(1,1000000));
postgres=> update test1 set col1=1 where col1 = 2;
postgres=> select relname, n_live_tup, n_dead_tup FROM pg_stat_user_tables where relname ='test1';

 relname | n_live_tup | n_dead_tup
---------+------------+------------
 test1   |    1000000 |          1--Reader で select 実行後に vacuum を実行
postgres=> vacuum test1;
  • Reader
postgres=> select count(*) from test1 a , test1 b, test1 c;
ERROR:  canceling statement due to conflict with recovery
DETAIL:  User was holding shared buffer pin for too long.
# セッションが切れる。

環境

  • Aurora PostgreSQL 11.7
  • db.r5.xlarge
  • Writer: 1 、Reader: 1

追記(2020/12/22):

同じ環境と設定で "User was holding shared buffer pin for too long" とは違うケースで追加検証してみた。RDS PostgreSQL での VACUUM とリードレプリカでの SELECT のコンフリクト - ablog の RDS とは違って、エラーは発生しなかった。

  • Writer
postgres=> create table test1 (col1 int);
postgres=> insert into test1 values (generate_series(1,100000));
postgres=> delete from test1 where col1 > 50000;
--Replica で select 実行後に vacuum を実行
postgres=> vacuum test1;
  • Reader
postgres=> select count(*) from test1 a , test1 b, test1 c;