sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLシステムカタログを理解して読む

    データベースの管理は簡単な作業ではなく、内部で何が起こっているのかを知らなくても簡単にイライラする可能性があります。新しいインデックスが役立つかどうか、特定の時点でのデータベースのトランザクションカウント、またはいつでもデータベースに接続しているユーザーを見つけようとする場合でも、管理者がデータベースのパフォーマンスを真に知ることができるデータが重要です。幸いなことに、PostgreSQLでは、これらすべてのデータがPostgreSQLシステムカタログで利用できます。

    PostgreSQLシステムカタログは、データベース内の他のすべてのオブジェクトなどに関するメタデータを含むテーブルとビューを備えたスキーマです。これにより、さまざまな操作がいつ発生するか、テーブルやインデックスにアクセスする方法、データベースシステムがメモリから情報を読み取っているのか、ディスクからデータをフェッチする必要があるのか​​を知ることができます。

    ここでは、システムカタログの概要を確認し、それを読み取る方法と、そこから有用な情報を引き出す方法を強調します。メタデータの中には単純なものもあれば、実際に役立つ情報を生成するために少し消化する必要があるものもあります。いずれにせよ、PostgreSQLは、データベース自体について必要な情報を構築するための優れたプラットフォームを提供してくれます。

    PostgreSQLカタログ

    PostgreSQLは、データベースとクラスターに関するメタデータ情報をスキーマ「pg_catalog」に保存します。この情報は、PostgreSQL自体が物事自体を追跡するために部分的に使用されますが、外部の人やプロセスがデータベースの内部も理解できるように表示されます。

    PostgreSQLカタログには、かなり堅実なルールがあります。見て、触れないでください。 PostgreSQLは他のアプリケーションと同じようにこのすべての情報をテーブルに保存しますが、テーブル内のデータはPostgreSQL自体によって完全に管理されているため、絶対的な緊急事態が発生しない限り変更しないでください。その後でも再構築が必要になる可能性があります。

    >

    いくつかの便利なカタログテーブル、データの読み取り方法、およびデータ自体で実行できる巧妙なことについて説明します。カタログには、ここでは取り上げないテーブルがかなりありますが、これらのさまざまなテーブルのすべての情報は、PostgreSQLの公式ドキュメントに記載されています。

    システム全体のメタデータ

    カタログでクエリできるテーブルの大部分は「システム全体」のテーブルです。接続しているデータベースは関係ありません。データはクラスター全体を表し、単一のデータベースは表しません。

    データベース情報

    一般的なデータベース情報はpg_databaseに保存され、統計はpg_stat_databaseに保存されます。

    pg_database:

    postgres=# SELECT oid,* FROM pg_database WHERE datname = 'severalnines';
    -[ RECORD 1 ]-+-------------
    oid           | 16396
    datname       | severalnines
    datdba        | 10
    encoding      | 6
    datcollate    | en_US.UTF-8
    datctype      | en_US.UTF-8
    datistemplate | f
    datallowconn  | t
    datconnlimit  | -1
    datlastsysoid | 13804
    datfrozenxid  | 548
    datminmxid    | 1
    dattablespace | 1663
    datacl        |

    テーブルpg_databaseには、クラスター内のすべてのデータベースの行が含まれています。これには、すぐに使用できる3つのデータベース(postgres、template0、およびtemplate1)が含まれます。この行には、エンコード、接続制限、およびその他の基本的なメタデータに関する情報が含まれています。

    関心のある列:

    oid-オブジェクト識別子。直接参照されない限り、クエリ出力には表示されません。この番号は、クラスターデータディレクトリ / base /<データベースのoid>内のディレクトリと一致します。
    datname-データベースの名前。
    datdba-データベースの所有者、oidはpg_authidを参照します。 .oid。
    encoding-このデータベースの文字エンコードpg_encoding_to_char()は、読み取り可能な名前に変換されます。
    datconnlimit-データベースで許可される同時接続の最大数。
    dattablespace-このデータベースのデフォルトのテーブルスペース。pg_tablespace.oidを参照します。

    pg_stat_database:

    postgres=# SELECT * FROM pg_stat_database WHERE datname = 'severalnines';
    -[ RECORD 1 ]--+------------------------------
    datid          | 13805
    datname        | postgres
    numbackends    | 2
    xact_commit    | 477460
    xact_rollback  | 13
    blks_read      | 417
    blks_hit       | 16488702
    tup_returned   | 252376522
    tup_fetched    | 2637123
    tup_inserted   | 114
    tup_updated    | 3
    tup_deleted    | 1
    conflicts      | 0
    temp_files     | 0
    temp_bytes     | 0
    deadlocks      | 0
    blk_read_time  | 0
    blk_write_time | 0
    stats_reset    | 2018-02-04 19:52:39.129052+00

    この統計テーブルは、興味深く有用なデータを取得する場所です。このテーブルの各行には、各データベースのライブデータが含まれており、変更を監視したい場合は、定期的にエクスポートして、時間をかけて追跡することができます。

    トランザクション

    トランザクション情報は、xact_commit列とxact_rollback列にあります。これらの列には、データベースがコミットしたトランザクションとロールバックしたトランザクションの数がそれぞれ含まれています。これは、データベースがどれだけアクティブであるかを示すのに役立つだけでなく、エラーが発生したり、驚くべき速度でロールバックしたりする可能性のあるプログラムで発生する可能性のある障害を特定するのに役立ちます。

    ディスクとメモリへのアクセス

    データがディスクまたはメモリから取得されるかどうかに関する情報は、blks_read列とblks_hit列に格納されます。 Blks_readは、このデータベースがディスクから読み取ったブロックの数を示し、blks_hitは、PostgreSQLのバッファキャッシュ(shared_buffersパラメータで表される)で見つかったブロックの数を示します。 RAMはディスクよりもはるかに高速であるため、理想的にはblks_hitがblks_readよりも一貫して高くなり、そうでない場合は、使用可能なメモリを再評価できます。

    タプル

    次のいくつかの列はタプルを扱います。 Tup_returnedは、データベースに返される行の数です。これは、テーブルからの場合は順次スキャンによって読み取られる行の数、またはインデックスからの場合に返されるインデックスエントリの数です。 Tup_fetchedは、データベースにフェッチされた行の数です。つまり、ビットマップスキャンの結果であり、テーブルからの場合はビットマップスキャンによってフェッチされたテーブル行の数、インデックスを使用している場合は単純なインデックススキャンによってフェッチされたテーブル行の数です。

    また、tup_inserted、tup_updated、およびtup_deletedがあります。これは、このデータベースでそれぞれ挿入、更新、および削除されたタプルの数を表します。これは、データがデータベースにどのように出入りするかを理解するのに役立ちます。タプルを更新および削除すると行が無効になるため、これらの列の値が高い場合は、データベースアクティビティのニーズを満たすように自動真空操作を調整する必要があります。

    競合

    問題のデータベースがスタンバイサーバーである場合、「リカバリモード」にあるスタンバイとの競合が原因でキャンセルされたクエリの数を追跡する方法として、列の競合が役立ちます。スタンバイクラスターでない場合、この列は無視できます。

    一時ファイル/データ

    クエリは一時ファイルに書き込む必要がある場合があります。これは、接続に割り当てられたwork_memの量が使い果たされ、メモリではなくディスクでソート操作を続行する必要がある場合に発生する可能性があります。列temp_filesは、作成されたこれらのファイルの数を追跡し、temp_bytesは、使用されたすべての一時ファイルの合計サイズを追跡します。このデータは、work_memのチューニングを通知したり、一時ファイルのサイズが大きすぎる場合に再書き込みを使用できるクエリを見つけたりするのに役立ちます。

    デッドロック

    デッドロック列は、デッドロックが発生した回数を追跡します。デッドロックは、他の方法ではエラーにならないクエリのエラーを引き起こす可能性があるため、これを追跡し、アプリケーションがお互いに足を踏み入れていないことを確認することをお勧めします。

    読み取りおよび書き込み時間

    列blk_read_timeおよびblk_write_timeは、データベース内のバックエンドがデータの読み取りと書き込みに費やす合計ミリ秒数を追跡します。これは、ディスクの読み取り/書き込み速度を比較/改善する場合に役立ちます

    統計のリセット

    この列stats_resetは、この行に記載されている統計が最後にリセットされたときのタイムスタンプ(タイムゾーン付き)を示しています。 null値は、開始以来リセットされていないことを意味します。あるいは、データベースがクラッシュして、これらの統計が消去された可能性もあります。

    チェックポイントとバックグラウンドライター

    pg_stat_bgwriter

    postgres=# SELECT * FROM pg_stat_bgwriter;
    -[ RECORD 1 ]---------+------------------------------
    checkpoints_timed     | 47829
    checkpoints_req       | 2
    checkpoint_write_time | 7323
    checkpoint_sync_time  | 38
    buffers_checkpoint    | 76
    buffers_clean         | 0
    maxwritten_clean      | 0
    buffers_backend       | 5
    buffers_backend_fsync | 0
    buffers_alloc         | 440
    stats_reset           | 2018-02-04 19:52:34.712832+00

    PostgtreSQLクラスターは、いくつかの異なる方法でディスクへのデータの書き込みを管理します。 「ダーティバッファ」(ディスクから読み取られてから変更されたが、まだその変更がディスクに書き込まれていないメモリ内のデータ)に関しては、これはチェックポイントまたはバックグラウンドライターのいずれかによって行われます。ダーティバッファは、解放または再割り当てする前にディスクに書き込む必要があるため、これらのプロセスが微調整されていることを確認することが重要です。この表は、すべてがどのように機能しているかを明らかにするのに役立ちます。

    チェックポイント

    チェックポイントは、スケジュールどおり(checkpoint_timeoutパラメーターで表される)、または最後のチェックポイント以降に最大量のWALファイルが使用され、チェックポイントを強制する必要がある場合に発生します。いずれにせよ、チェックポイントはダーティバッファをディスクに書き込み、それを追跡する4つの列があります。

    checkpoints_timed列とcheckpoints_req列には、スケジュールされたチェックポイントの数(時間指定)と要求されたチェックポイントの数(強制とも呼ばれます)が表示されます。 checkpoint_reqの上昇値が高い場合は、max_wal_size値が不十分であることを示している可能性があります。

    列checkpoint_write_timeおよびcheckpoint_sync_timeは、チェックポイントプロセスがディスクへの書き込みと同期に費やした合計時間(ミリ秒単位)を記録します。

    最後に、buffers_checkpointは、チェックポイントによってディスクに書き込まれるバッファーの総数です。

    バックグラウンドライター

    バックグラウンドライターは、ダーティバッファーをディスクに書き込む別個のプロセスであり、チェックポインターが実行する必要のある作業の量を理想的に削減します。

    列buffers_cleanは、バックグラウンドプロセスによってディスクに書き込まれたバッファーの数を表します。 buffers_checkpointと比較すると、各プロセスで処理されるワークロードの量がわかります(バックグラウンドライターは、バッファーが頻繁に変更される場合はバッファーを複数回書き込む可能性があるのに対し、時間指定のチェックポイントではそれほど頻繁ではない可能性があるという知識が追加されています)。

    >

    Maxwritten_cleanは、バックグラウンドライターが実行するたびにフラッシュするページの最大数に達した回数を表します(bgwriter_lru_maxpagesパラメーターで制御されます)。

    一般的なバッファ

    残りの列には、一般的なバッファー情報が表示されます。buffers_backendは、バックグラウンドライターやチェックポインターではなく、バックエンドが自身に書き込む必要のあるバッファーの数です。buffers_backend_fsyncは、バックエンドが独自のfsync呼び出しを実行する必要があった回数のカウントです。 buffers_allocは、一般的に割り当てられているバッファーの数を示します。

    データベースアクティビティとロック

    現在のユーザーアクティビティを表示する2つのビュー、pg_stat_activityとpg_locksがあります。照会すると、これらはデータベースへの現在の接続に関する情報と、データベースがどのような関係に対してどのような種類のロックを持っているかを示します。

    pg_stat_activity

    postgres=# SELECT * FROM pg_stat_activity;
    -[ RECORD 1 ]----+--------------------------------
    datid            | 13805
    datname          | severalnines
    pid              | 29730
    usesysid         | 10
    usename          | postgres
    application_name | psql
    client_addr      |
    client_hostname  |
    client_port      | -1
    backend_start    | 2018-07-21 02:29:48.976588+00
    xact_start       | 2018-07-21 02:30:03.73683+00
    query_start      | 2018-07-21 02:30:03.73683+00
    state_change     | 2018-07-21 02:30:03.736835+00
    wait_event_type  |
    wait_event       |
    state            | active
    backend_xid      |
    backend_xmin     | 559
    query            | SELECT first_name FROM customers WHERE customers_sid = 472;
    backend_type     | client backend
    一般情報

    pg_stat_activityビューには、データベースへのすべての接続の行と、それに関するいくつかの基本情報が表示されます。列datnameは接続が実際に接続されているデータベースを表し、pidはデータベースホスト自体の接続のプロセスIDであり、usesysidとusenameは接続されているデータベースユーザーを表します。

    クライアントのソースの場合、client_addrは接続元のホストのIPアドレスであり、nullはローカルのUNIXソケット接続であることを意味します。

    タイムスタンプ

    特定のものがいつ開始されたかを示す4つのタイムスタンプ列があります。backend_startは接続が実際に確立されたとき、xact_startは現在のトランザクションが開始されたとき(クライアントに開いているトランザクションがない場合はnull)、query_startは現在または最新のクエリが開始されたときです。 state_changeは、接続の状態が最後に変更された時刻です。

    接続ステータス

    pg_stat_activityの最後のビットは、接続の実際のステータスをカバーします。クエリがロックを解放するために別のクエリを待機している場合、wait_event_typeには待機イベントの種類に関する情報が含まれ、wait_event列には待機イベント名が表示されます。これは長いリストですが、詳細についてはPostgreSQLのドキュメントを参照してください。

    最後に、「状態」列には、現在の接続がどの状態にあるか(アクティブ、アイドル、トランザクションのアイドルなど)が表示され、クエリ列には、実行中の実際のクエリ、または最近実行されたクエリが表示されます。

    pg_lock

    SELECT * FROM pg_locks;
    -[ RECORD 1 ]------+----------------
    locktype           | virtualxid
    database           |
    relation           |
    page               |
    tuple              |
    virtualxid         | 3/475862
    transactionid      |
    classid            |
    objid              |
    objsubid           |
    virtualtransaction | 3/475862
    pid                | 29730
    mode               | ExclusiveLock
    granted            | t
    fastpath           | t

    クエリアクティビティを調べる場合、pg_locksテーブルはpg_stat_activityと連携して機能します。リレーションにロックがかけられると、その情報はpg_locksに保存されます。 pg_stat_activityのpidを使用して、pg_locksにクエリを実行し、接続にロックが設定されている可能性のある関係、それらのロックの種類、およびロックが付与されているかどうかを確認できます。

    最も重要な列は、pg_stat_activityのpidと一致する「pid」、pg_classのOIDと一致する「relation」、保持されているロックモードの名前を示す「mode」、およびロックインの有無を示す「granted」です。質問が許可されました。

    レプリケーション情報

    PostgreSQLにはレプリケーション機能が組み込まれているため、レプリケーション自体のパフォーマンスとステータスに光を当てるビューがいくつかあります。

    pg_stat_replicationを表示: すべてのWAL送信者プロセスの行が含まれ、その状態、作業中のWALファイルの場所、およびレプリケーション用のWALデータを受信して​​いるスタンバイホストの接続情報に関する情報が含まれます。

    pg_stat_wal_receiverを表示: クラスターがスタンバイの場合、これには、ホストからのレシーバープロセスに関する統計を示す単一の行が含まれます。

    pg_stat_subscriptionを表示: WALデータをスタンバイノードに送信する場合、ここの各行はそのサブスクリプションを表し、サブスクリプションのステータスに関する情報が含まれます。

    pg_replication_slotsを表示: クラスタに存在するすべてのレプリケーションスロットとその現在の状態のリストが含まれています。

    データベース固有のメタデータ

    各データベース内には、照会されているデータベースに固有の情報を含むカタログテーブルのコレクションがあります。これらのテーブルから特定のデータを探している場合は、クエリを発行するときに適切なデータベースに接続されていることを確認する必要があります。

    ここでデータ分析の核心が入り、ユーザーデータがどのようにアクセスされているかを確認できます。テーブルからインデックス、シーケンス、データベースに入ってデータをフェッチまたは変更するクエリまで、それらのアクションと影響はこれらのテーブルに保存されます。その情報を確認して、データベースの管理に関する情報に基づいた決定を下すことができます。道路。

    テーブルメタデータ

    ユーザーテーブルに関するメタデータは、次の2つのテーブルに保存され、それぞれに、システムで作成されたすべてのユーザーテーブルの行があります。テーブルpg_stat_user_tablesには、テーブルへのユーザーアクセスに関する統計が含まれ、pg_statio_user_tablesには、各テーブルのI/O統計が含まれます。

    注:ここにあるデータは必ずしも100%完全であるとは限らず、テーブルを頻繁に分析して正確にする必要があります。自動分析はこれをカバーしますが、自動分析プロセスを適切に調整して、各テーブルに関する適切な統計を保持できるようにします。統計がオフになっているように見える場合は、テーブルでANALYZEを手動で実行すると、統計が更新されます。

    テーブルpg_stat_user_tables:

    severalnines=> SELECT * FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 'history';
    -[ RECORD 1 ]-------+---------
    relid               | 2766788
    schemaname          | public
    relname             | history
    seq_scan            | 13817
    seq_tup_read        | 466841
    idx_scan            | 12251
    idx_tup_fetch       | 127652
    n_tup_ins           | 11
    n_tup_upd           | 13
    n_tup_del           | 3
    n_tup_hot_upd       | 13
    n_live_tup          | 3
    n_dead_tup          | 21
    n_mod_since_analyze | 19
    last_vacuum         |
    last_autovacuum     |
    last_analyze        |
    last_autoanalyze    |
    vacuum_count        | 0
    autovacuum_count    | 0
    analyze_count       | 0
    autoanalyze_count   | 0

    ユーザーテーブルの統計には、かなりの数のデータがあります。

    テーブルアクセス方法

    クライアントがテーブルのデータにアクセスする場合、直接またはインデックスを介してアクセスします。列「seq_scan」は、テーブルが受信したシーケンシャルスキャンの数をカウントし、「seq_tup_read」は、そのプロセスを通じて読み取られたタプルの数をカウントします。列「idx_scan」は、テーブルのインデックスがデータのフェッチに使用された回数をカウントします。

    テーブルタプルアクティビティ

    これで、テーブル上のさまざまなアクティビティをカウントする列がいくつかできました。

    「n_tup_ins」は、挿入されたタプルの数を追跡します

    「n_tup_upd」は、更新されたタプルの数を追跡します

    「n_tup_del」は、削除されたタプルの数を追跡します

    テーブルタプルの状態

    更新と削除が原因で、アクティブなデータではなくなった死んだタプルが存在する可能性があり、バキュームプロセスによって最終的にそれらが解放されます。列「n_tup_ins」と「n_tup_ins」は、それぞれ生きているタプルと死んでいるタプルの数を追跡します。デッドタプルが特定のポイントに達すると、自動バキュームの設定に応じて、自動バキュームが開始されます。

    テーブル真空アクティビティ

    テーブルの保守はVACUUMまたはAUTOVACUUMのいずれかを介して行われ、統計はANALYZEまたはAUTOANALYZEを介して収集されます。次の4つの列には、「last_vacuum」、「last_autovacuum」、「last_analyze」、「last_autoanalyze」の各操作が最後に実行された日付が含まれています。

    また、前のアクションが発生した回数を単純にカウントする、さらに4つの便利な列があります。これらを使用して、「vacuum_count」、「autovacuum_count」、「analyze_count」、「autoanalyze_count」のどのテーブルが最もアクティビティを取得しているかを確認できます。

    テーブルpg_statio_user_tables:

    severalnines=> SELECT * FROM pg_statio_user_tables WHERE schemaname = 'public' AND relname = history;
    -[ RECORD 1 ]---+---------
    relid           | 2766788
    schemaname      | public
    relname         | history
    heap_blks_read  | 4
    heap_blks_hit   | 63081
    idx_blks_read   | 5
    idx_blks_hit    | 44147
    toast_blks_read | 0
    toast_blks_hit  | 0
    tidx_blks_read  | 0
    tidx_blks_hit   | 0

    I / O出力は、データが内部でどのようにアクセスされているかを理解するのに役立ちます。列「heap_blks_read」は、このテーブルで読み取られたディスクブロックの数を表し、「heap_blks_hit」は、このテーブルのメモリから読み取られたバッファブロックを表します。これは、テーブルにアクセスするクエリが常にディスクに移動する必要があるのか​​、メモリからデータをフェッチする必要があるのか​​を知るのに役立ちます。

    表のインデックス統計には、「idx_blks_read」列と「idx_blks_hit」列で同じ情報が表示されます。

    最後に、テーブルにTOASTテーブルがある場合、列「toast_blks_hit」と「toast_blks_read」はトーストテーブルを追跡し、「tdix_blks_read」と「tdix_blks_read」はそれらのトーストテーブルのインデックスを追跡します。

    インデックスメタデータ

    pg_stat_user_indexes

    severalnines=> SELECT * FROM pg_stat_user_indexes WHERE indexrelname = 'history_pkey';
    -[ RECORD 1 ]-+-------------
    relid         | 2766797
    indexrelid    | 2766934
    schemaname    | public
    relname       | history
    indexrelname  | history_pkey
    idx_scan      | 43910
    idx_tup_read  | 98147
    idx_tup_fetch | 98147

    対応するテーブルと同様に、このテーブルには特にインデックスに関する情報が含まれています。インデックスごとに1行、このテーブルは、「idx_scan」列でインデックスがスキャンされた回数、「idx_tup_read」で読み取られたタプルの数、「idx_tup_fetch」で実際にフェッチされたライブ行の数を示しています。

    pg_statio_user_indexes

    severalnines=> SELECT * FROM pg_statio_user_indexes WHERE indexrelname = 'history_pkey';
    -[ RECORD 1 ]-+-------------
    relid         | 2766797
    indexrelid    | 2766934
    schemaname    | public
    relname       | history
    indexrelname  | history_pkey
    idx_blks_read | 2
    idx_blks_hit  | 49380

    pg_statio_user_indexesの場合、データに使用できる2つの列は「idx_blks_read」と「idx_blks_hit」で、ディスクとメモリから読み取られたブロックの数を表します。

    今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする

    このデータで何ができるでしょうか?

    クリエイティブに!特定のテーブルへのクエリが非常に遅いと思われる場合は、そのアクティビティを経時的に追跡し、取得するシーケンシャルスキャンの数とインデックススキャンの数を確認し、データのディスクまたはメモリに送信されるかどうかを確認します。

    大きなテーブルが頻繁に自動バキュームされ続ける場合は、ライブからデッドタプルまでを時間の経過とともに追跡します。特に、自動バキュームを微調整してより速く完了する必要がある場合や、テーブルがパーティション分割の候補である場合もあります。

    データがディスクまたはメモリからいつ取得されるかを確認できるため、時間の経過とともにメモリとディスクの比率を作成し、その比率が1日を通して低下するかどうかを特定できます。

    私たちがカバーしたテーブルの量は、データベースの内部動作について知るのに役立つ主要なデータである大物を超えました。ただし、システムカタログには、状況に応じて役立つデータを含むテーブルがさらにたくさんあります。以前のように他の表を読むと、データベースの状態全般に関する洞察が得られます。

    PostgreSQLカタログのテーブルまたはビューの詳細については、こちらの公式ドキュメントと、こちらの統計コレクターに関する情報をご覧ください。


    1. ブール列のSQLAlchemyfunc.count

    2. IntegrityErrorの重複キー値が一意の制約に違反しています-django/postgres

    3. SQLServerの論理AND演算子とは-SQLServer/TSQLチュートリアルパート120

    4. BLOBを除くすべてのフィールドでSELECTDISTINCTを実行するにはどうすればよいですか?