Skip to content

スタンバイサーバーにおいて、pg_statsinfodプロセスのメモリ使用量が増加し続けます。 #18

@okano-naoki000

Description

@okano-naoki000

[事象]
スタンバイサーバーにおいて、pg_statsinfodプロセスのメモリ使用量が増加し続けます。

[環境]
pg_statsinfo: 17.0 (それ以前のバージョンでも発生します)。
OS: RHEL 8.10
PostgreSQL: 17.6

[再現方法]
再現手順を後述の[再現手順]にまとめました。
スタンバイサーバーではpg_statsinfo.repository_serverをデフォルト
(スタンバイサーバー自身をリポジトリDBとなる)の場合に発生します。

[調査]
こちらで調査した結果、writerスレッドのrecv_writer_queue()関数に問題があると考えています。

スタンバイサーバーをリポジトリDBに指定した場合、get_instid()関数内で実行される
BEGIN TRANSACTION READ WRITEに失敗するため、get_instid()関数はNULLを返します。
その場合、recv_writer_queue()関数では、後続のキューに対する処理がされず、
スナップショットに関するデータがキューに残り続けます。
さらに、recv_writer_queue()関数はwriter_queue = NILのままdelay()を行うため、
writerスレッドがdelay()している間、collectorスレッドは新しいスナップショットを
作成してしまいます。

[仕様について]
pg_statsinfo.repository_serverをデフォルト値が'dbname=postgres'であるため、
スタンバイサーバー自身をリポジトリDBに指定できる仕様であると認識しています。
そのため、上記の[事象]はメモリリークの障害と考えています。

[再現手順]
単純化のため、スタンバイサーバーのみを作成しています。
事象を見やすくするため、snapshot_intervalの変更とテーブルの作成をしています。
psコマンドのRSSの値が増加し続けます。

  install_dir="${HOME}/pgsql"
  export PATH=${install_dir}/bin:${PATH}
  export LD_LIBRARY_PATH=${install_dir}/lib
  export PGPORT="5432"
  export PGDATABASE="postgres"
  export PGDATA=`pwd`"/inst"

  pg_ctl stop; rm -rf ${PGDATA}; initdb
  echo "pg_statsinfo.snapshot_interval = 30s" >> ${PGDATA}/postgresql.conf
  echo "shared_preload_libraries = 'pg_statsinfo'" >> ${PGDATA}/postgresql.conf
  sudo rm -rf /run/pg_statsinfo; sudo mkdir /run/pg_statsinfo; sudo chown `whoami`:`whoami` /run/pg_statsinfo

  pg_ctl start -D ${PGDATA} -w
  for i in `seq 100`; do psql -c "CREATE TABLE test_tb_${i} (test_col int);"; done

  touch ${PGDATA}/standby.signal
  pg_ctl restart -w
  while :; do echo "=== `date` ==="; ps aux | grep -e pg_statsinfod -e USER | grep -v grep; sleep 60; done

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions