4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PostgreSQL 17がやってくる(8) transaction_timeout

Posted at

はじめに

にゃーん。
今回は小ネタ。
PostgreSQL 17に追加されるtransaction_timeoutパラメータについてついて調べてみた。

タイムアウトがいっぱい

PostgreSQLにはタイムアウト制御に関するパラメータがいろいろある。
このうち、セッション実行時に関するものだけでも以下のパラメータが存在する。

パラメータ名 context 説明
idle_in_transaction_session_timeout user IDLE IN TRANSACTION時間のタイムアウト値
idle_session_timeou user IDLE時間のタイムアウト値
lock_timeout user ロック処理のタイムアウト値
statement_timeout user 1つのSQL文実行時間のタイムアウト値。
transaction_timeout user PostgreSQL 17追加予定パラメータ。
本記事で説明。

transaction_timeout

transaction_timeoutパラメータはPostgreSQL 17に入る予定のパラメータだ。
この機能に関するcommitfest項目:Transaction timeout
Beta1のリリースノートだと以下の記載が該当する。

Add server variable transaction_timeout to restrict the duration of transactions

transaction_timeoutパラメータ

パラメータ名 transaction_timeout
context user
integer
デフォルト値 0
最小値 0
最大値 2147483647
  • 値が0の場合には、タイムアウト制御が無効とみなされる。
  • 他のタイムアウト関連のパラメータ(idle_in_transaction_session_timeoutまたはstatement_timeout)の設定値とは以下のような関係がある。
    • transaction_timeoutがidle_in_transaction_session_timeoutまたはstatement_timeoutより短いか等しい場合、長い方のタイムアウトは無視される。
  • contextはuserなので、セッションの最初にこのパラメータを指定することで、そのセッションに閉じた範囲でトランザクションのタイムアウト時間を設定する使い方がいいのかもしれない。

transaction_timeoutの使い所

このパラメータが有効なケースとしては、

  • トランザクション内で実行される個々のSQLの実行時間は短い。
  • しかしトランザクション内で実行されるSQLの数は多い。

ケースだと思われる。
例えばOLTP系のように1つのトランザクション内でレイテンシが小さいクエリを多数発行するような場合に、トランザクション全体として処理時間がかかっているようなときに、ロールバックさせたいというケースだろうか?

動作検証

動作検証時のバージョン

先日リリースされたPostgreSQL 17 Beta1を使用した。

検証内容

以下のようなトランザクションを実行する。
(文字列のみのSELECTとpg_sleep(1)を繰り返し実行する)

BEGIN;
SELECT 'in tx(1)';
SELECT pg_sleep(1);
SELECT 'in tx(2)';
SELECT pg_sleep(1);
SELECT 'in tx(3)';
SELECT pg_sleep(1);
SELECT 'in tx(4)';
COMMIT;

statement_timeout = 1500を設定した場合は、トランザクション内のどのSQLステートメントも1500msを超えることはないため、トランザクションは最後まで実行される。

$ psql postgres -ef st_timeout.sql
Null display is "(null)".
SET statement_timeout = 1500;
SET
Timing is on.
BEGIN;
BEGIN
Time: 0.075 ms
SELECT 'in tx(1)';
 ?column?
----------
 in tx(1)
(1 row)

Time: 0.224 ms
SELECT pg_sleep(1);
 pg_sleep
----------

(1 row)

Time: 1001.469 ms (00:01.001)
SELECT 'in tx(2)';
 ?column?
----------
 in tx(2)
(1 row)

Time: 0.180 ms
SELECT pg_sleep(1);
 pg_sleep
----------

(1 row)

Time: 1001.781 ms (00:01.002)
SELECT 'in tx(3)';
 ?column?
----------
 in tx(3)
(1 row)

Time: 0.195 ms
SELECT pg_sleep(1);
 pg_sleep
----------

(1 row)

Time: 1000.843 ms (00:01.001)
SELECT 'in tx(4)';
 ?column?
----------
 in tx(4)
(1 row)

Time: 0.181 ms
COMMIT;
COMMIT
Time: 0.123 ms
$

statement_timeout = 1500transaction_timeout=3000を設定した場合は、トランザクション内のどのSQLステートメントも1500msを超えることはないが、3回目のpg_sleep(1)の実行により、transaction_timeout=3000の閾値を超えてしまうためタイムアウトエラーとなり、そのセッションは終了する(単にトランザクションがアボートするだけではない)。

$ psql postgres -ef tx_timeout.sql
Null display is "(null)".
SET statement_timeout = 1500;
SET
SET transaction_timeout = 3000;
SET
Timing is on.
BEGIN;
BEGIN
Time: 0.085 ms
SELECT 'in tx(1)';
 ?column?
----------
 in tx(1)
(1 row)

Time: 0.228 ms
SELECT pg_sleep(1);
 pg_sleep
----------

(1 row)

Time: 1001.444 ms (00:01.001)
SELECT 'in tx(2)';
 ?column?
----------
 in tx(2)
(1 row)

Time: 0.166 ms
SELECT pg_sleep(1);
 pg_sleep
----------

(1 row)

Time: 1001.692 ms (00:01.002)
SELECT 'in tx(3)';
 ?column?
----------
 in tx(3)
(1 row)

Time: 0.162 ms
SELECT pg_sleep(1);
psql:tx_timeout.sql:16: FATAL:  terminating connection due to transaction timeout
psql:tx_timeout.sql:16: server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
psql:tx_timeout.sql:16: error: connection to server was lost
$

おわりに

今回はトランザクション全体の処理時間のタイムアウトを設定するtransaction_timeoutについて調べてみた。
個々のSQL文の処理時間は小さいけど、発行されるSQLの数が多い場合、あるいは発行SQL数が不定の場合などには、このパラメータを設定することで、トランザクションが長時間存在するような問題を解決できるかもしれない。

4
2
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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?