Marlock Homes Diary

備忘録。忘れないように書きます。

PostgreSQLのキャッシュ状態の確認方法

PostgreSQLのキャッシュ(shard_buffers)に乗っているオブジェクトは、
contribのpg_buffercacheを利用して確認することが可能です。(とても便利)


0. 確認した環境の情報

# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.3 (Maipo)
# uname -r
3.10.0-514.el7.x86_64
$ /usr/bin/python --version
Python 2.7.5
-- 後述のpgpagecacheで利用
$ psql
postgres=# select version();
                                                 version

---------------------------------------------------------------------------------------------------------
 PostgreSQL 10.0 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11), 64-bit
(1 row)

1. pg_buffercacheによる確認例

postgres=# CREATE EXTENSION pg_buffercache ;
CREATE EXTENSION
postgres=# SELECT c.relname, count(*) AS buffers
             FROM pg_buffercache b INNER JOIN pg_class c
             ON b.relfilenode = pg_relation_filenode(c.oid) AND
                b.reldatabase IN (0, (SELECT oid FROM pg_database
                                      WHERE datname = current_database()))
             GROUP BY c.relname
             ORDER BY 2 DESC
             LIMIT 10;
             relname             | buffers
---------------------------------+---------
 pgbench_accounts                |    1644
 pg_attribute                    |      35
 pg_proc                         |      25
 pg_depend_reference_index       |      15
 pg_class                        |      14
 pg_statistic                    |      11
 pg_depend                       |      10
 pg_attribute_relid_attnum_index |      10
 pg_operator                     |       9
 pg_proc_proname_args_nsp_index  |       8
(10 rows)

https://www.postgresql.org/docs/10/static/pgbuffercache.html

PostgreSQLは、OSのファイルシステムキャッシュを活用するアーキテクチャであるため、
shard_buffers上にキャッシュされていない場合でも、OSのファイルシステムキャッシュ(ページキャッシュ)にPostgreSQLのオブジェクト(テーブルなど)が乗っていれば、ディスクへのアクセスは不要になります。

性能関連の調査等でOSファイルシステムのキャッシュにどの程度、オブジェクトがキャッシュされているのかを、
把握する必要があるケースもあると考えおります。(あまりないと思いますが)

OSファイルシステムPostgreSQLのオブジェクトが乗っているか否かを確認するツールとして、
Pythonで実装されたpgpagecacheを見つけたので確認してみたいと思います。
pgpagecacheの利用には、pg_buffercacheが必要です。(CREATE EXTENSION pg_buffercache ;が必要)

3. pgpagecacheの入手と解凍

$ wget https://pypi.python.org/packages/d7/94/274b82c8d735e70b9ba4eb060b7fdfbc780271a6bbf8dcf2ed6fd7a090ca/pgpagecache-0.1.tar.gz#md5=54cdf058813a45249f82e32cdced2727
--2017-12-30 23:57:24--  https://pypi.python.org/packages/d7/94/274b82c8d735e70b9ba4eb060b7fdfbc780271a6bbf8dcf2ed6fd7a090ca/pgpagecache-0.1.tar.gz
$ tar xvzf pgpagecache-0.1.tar.gz

4. 依存パッケージの入手

$ /usr/bin/pip install tabulate
$ /usr/bin/pip install psycopg2

5. pgpagecacheによる確認例

$ /usr/bin/python ./pgpagecache-0.1/pgpagecache/pgpagecache.py -u postgres -p xxxxxxx -d postgres -H localhost -P 5410 -b /home/postgres10/data/base/
PageCache Usage
---------------

| DB Name   | Table                                     |   Cached Pages |   Total Pages |   Ratio (%) |   Bytes |
|-----------+-------------------------------------------+----------------+---------------+-------------+---------|
| postgres  | pg_ts_dict_dictname_index                 |              0 |             4 |      0      |       0 |
| postgres  | pg_foreign_data_wrapper_name_index        |              0 |             2 |      0      |       0 |
| postgres  | pg_toast_13052                            |              0 |             0 |      0      |       0 |
| postgres  | pg_subscription_rel_srrelid_srsubid_index |              0 |             2 |      0      |       0 |
| postgres  | pg_toast_3596_index                       |              0 |             2 |      0      |       0 |
| postgres  | pg_am_oid_index                           |              0 |             4 |      0      |       0 |
| postgres  | pg_inherits_relid_seqno_index             |              0 |             2 |      0      |       0 |
| postgres  | pg_proc_oid_index                         |              0 |            20 |      0      |       0 |
[省略]
| postgres  | pgbench_accounts_pkey                     |              0 |           552 |      0      |       0 |
[省略]
PostgreSQL BufferCache Usage
----------------------------

| DB Name   | Table                             |    Bytes |
|-----------+-----------------------------------+----------|
| postgres  | pgbench_accounts                  | 13467648 |
| postgres  | pg_operator                       |   122880 |
| postgres  | pg_depend_reference_index         |   122880 |
| postgres  | pg_statistic                      |    90112 |


※ 表示される値についてこれから調査したいと考えております。


https://pypi.python.org/pypi/pgpagecache/0.1


参考情報
Python 3系で実行した場合エラーになりました。

$ /opt/anaconda3/bin/python --version
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
$ /opt/anaconda3/bin/python ./pgpagecache-0.1/pgpagecache/pgpagecache.py -u postgres -p xxxxxxx -d postgres -H localhost -P 5410 -b /home/postgres10/data/base/
  File "./pgpagecache-0.1/pgpagecache/pgpagecache.py", line 80
    print "Failed to mmap %s (errno: %d)" % (filename, get_errno())
                                        ^
SyntaxError: invalid syntax