LoginSignup
4
1

More than 3 years have passed since last update.

PostgreSQLレプリケーション構成で、バッファ・ピンのリカバリ競合を発生させる方法

Posted at

方法1: バッファ・ピンを取得したまま長時間走るクエリの利用

  • ① レプリケーション構成をセットアップする。
  • ② マスタで、テーブルを作成する。
CREATE TABLE test1 AS SELECT id FROM generate_series(1, 10) id;
  • ③ マスタで、テーブルから1レコード削除する。
DELETE FROM test1 WHERE id = 1;
  • ④ スタンバイで、バッファ・ピンを取得したまま長時間走るクエリを実行する。このクエリは、テーブルを外部表、pg_sleep()を内部表とするネストループ結合により実現する。
SELECT * FROM test1 LEFT JOIN pg_sleep(600) ON id = 2;
  • ⑤ マスタで、テーブルに対してVACUUMを実行する。
VACUUM test1;
  • ⑥ max_standby_streaming_delayで指定された競合待ちの時間が経過すると、スタンバイで、④のクエリがキャンセルされて、以下のエラーメッセージが出力される。
ERROR:  canceling statement due to conflict with recovery
DETAIL:  User was holding shared buffer pin for too long.

方法2: カーソルの利用

  • ① レプリケーション構成をセットアップする。
  • ② マスタで、テーブルを作成する。
CREATE TABLE test2 AS SELECT id FROM generate_series(1, 10) id;
  • ③ マスタで、テーブルから1レコード削除する。
DELETE FROM test2 WHERE id = 1;
  • ④ スタンバイで、テーブルをスキャンするカーソルを作成して、1件レコードを取得する。
BEGIN;
DECLARE testcursor CURSOR FOR SELECT * FROM test2;
FETCH NEXT testcursor;
  • ⑤ マスタで、テーブルに対してVACUUMを実行する。
VACUUM test2;
  • ⑥ max_standby_streaming_delayで指定された競合待ちの時間が経過すると、スタンバイで、④のトランザクションを実行していたセッションが強制終了されて、以下のエラーメッセージが出力される。
FATAL:  terminating connection due to conflict with recovery
DETAIL:  User was holding shared buffer pin for too long.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1