客服微信
本文为云贝教育 刘峰 原创,请尊重知识产权,转发请注明出处,不接受任何抄袭、演绎和未经注明出处的转载。
一、pg_buffercache
postgres=# create extension pg_buffercache; CREATE EXTENSION
postgres=# \d pg_buffercache View "public.pg_buffercache" Column | Type | Collation | Nullable | Default ------------------+----------+-----------+----------+--------- bufferid | integer | | | relfilenode | oid | | | reltablespace | oid | | | reldatabase | oid | | | relforknumber | smallint | | | relblocknumber | bigint | | | isdirty | boolean | | | usagecount | smallint | | | pinning_backends | integer | | |
postgres=# \d List of relations Schema | Name | Type | Owner --------+----------------+-------+---------- public | pg_buffercache | view | postgres public | t1 | table | postgres (2 rows)
postgres=# select count(1) from pg_buffercache where relfilenode='t1'::regclass; count ------- 0 (1 row)
0表示没有缓存
postgres=# select count(1) from t1; count ------- 1 (1 row) postgres=# select count(1) from pg_buffercache where relfilenode='t1'::regclass; count ------- 1 (1 row)
postgres=# select * from pg_buffercache where relfilenode='t1'::regclass; bufferid | relfilenode | reltablespace | reldatabase | relforknumber | relblocknumber | isdirty | usagecount | pinning_backends ----------+-------------+---------------+-------------+---------------+----------------+---------+------------+------------------ 1006 | 16388 | 1663 | 5 | 0 | 0 | f | 1 | 0 (1 row)
有记录表示被缓存
isdirty :f表示不是脏块
postgres=# update t1 set id=22 where id=1; UPDATE 1
postgres=# select * from pg_buffercache where relfilenode='t1'::regclass; bufferid | relfilenode | reltablespace | reldatabase | relforknumber | relblocknumber | isdirty | usagecount | pinning_backends ----------+-------------+---------------+-------------+---------------+----------------+---------+------------+------------------ 1006 | 16388 | 1663 | 5 | 0 | 0 | t | 2 | 0 (1 row)
比如生产系统中,数据库重启了,此时发起的业务SQL,就会发生物理读
语法
pg_prewarm( regclass, --预热的relation mode text default 'buffer', --使用预热的方法 fork text derfault 'main', --relation fork被预热 first_block int8 default null, --预热的第一块号 last_block int8 default null --预热的最后一个块号 ) return int8; prefetch/read:缓存到os cache buffer:缓存到os cache和pg shared buffers
参数说明:
create EXTENSION pg_prewarm
testdb=# show shared_buffers; shared_buffers ---------------- 128MB (1 row) testdb=# create table t1 ( id int,name varchar(100),c1 varchar(200),c2 varchar(200)); CREATE TABLE testdb=# insert into t1 select id,md5(id::varchar),md5(md5(id::varchar)),md5(md5(md5(id::varchar))) from generate_series(1,10000000) as id; INSERT 0 10000000
1、查看表体积
testdb=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+------------------------+-----------+----------+--------- id | integer | | | name | character varying(100) | | | c1 | character varying(200) | | | c2 | character varying(200) | | | testdb=# \dt+ t1 List of relations Schema | Name | Type | Owner | Persistence | Access method | Size | Descr iption --------+------+-------+----------+-------------+---------------+---------+------ ------- public | t1 | table | postgres | permanent | heap | 1281 MB | (1 row) testdb=# SELECT pg_size_pretty(pg_total_relation_size('t1')); pg_size_pretty ---------------- 1281 MB (1 row)
2、重启数据库并消除OS缓存
pg_ctl restart echo 3 > /proc/sys/vm/drop_caches
3、查看执行计划
testdb=# explain analyze select count(*) from t1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------- Finalize Aggregate (cost=217018.73..217018.74 rows=1 width=8) (actual time=3584.950..3585.012 rows=1 loops=1) -> Gather (cost=217018.52..217018.73 rows=2 width=8) (actual time=3584.897..3584.981 rows=3 loops=1) Workers Planned: 2 Workers Launched: 2 -> Partial Aggregate (cost=216018.52..216018.53 rows=1 width=8) (actual time=3559.160..3559.160 rows=1 loops=3) -> Parallel Seq Scan on t1 (cost=0.00..205601.81 rows=4166681 width=0) (actual time=0.193..3373.351 rows=3333333 loops=3) Planning Time: 4.743 ms Execution Time: 3586.400 ms (8 rows)
缓存1G的数据,耗时3586.400 ms
1、重启数据库并消除OS缓存
pg_ctl restart echo 3 > /proc/sys/vm/drop_caches
2、预热数据到OS缓存
testdb=# select pg_prewarm('t1', 'read', 'main'); pg_prewarm ------------ 163935 (1 row)
3、查看执行计划
testdb=# explain analyze select count(*) from t1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ Finalize Aggregate (cost=217018.73..217018.74 rows=1 width=8) (actual time=657.884..658.970 rows=1 loops=1) -> Gather (cost=217018.52..217018.73 rows=2 width=8) (actual time=657.516..658.959 rows=3 loops=1) Workers Planned: 2 Workers Launched: 2 -> Partial Aggregate (cost=216018.52..216018.53 rows=1 width=8) (actual time=652.264..652.265 rows=1 loops=3) -> Parallel Seq Scan on t1 (cost=0.00..205601.81 rows=4166681 width=0) (actual time=0.092..405.615 rows=3333333 loops=3) Planning Time: 0.126 ms Execution Time: 658.997 ms (8 rows)
4、预热到数据库缓存中
testdb=# select pg_prewarm('t1', 'buffer', 'main'); pg_prewarm ------------ 163935 (1 row)
5、查看执行计划
testdb=# explain analyze select count(*) from t1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ Finalize Aggregate (cost=217018.73..217018.74 rows=1 width=8) (actual time=681.629..683.325 rows=1 loops=1) -> Gather (cost=217018.52..217018.73 rows=2 width=8) (actual time=681.485..683.319 rows=3 loops=1) Workers Planned: 2 Workers Launched: 2 -> Partial Aggregate (cost=216018.52..216018.53 rows=1 width=8) (actual time=674.079..674.080 rows=1 loops=3) -> Parallel Seq Scan on t1 (cost=0.00..205601.81 rows=4166681 width=0) (actual time=0.025..445.632 rows=3333333 loops=3) Planning Time: 0.039 ms Execution Time: 683.353 ms (8 rows)
缓存1G的数据,耗时683.353 ms
预热
|
参数
|
耗时
|
否
|
无
|
3586.400 ms
|
是
|
read
|
658.997 ms
|
是
|
buffer
|
683.353 ms
|
3.1 安装插件
testdb=# CREATE EXTENSION pgfincore; CREATE EXTENSION
3.2 查看对象缓存信息
testdb=# select * from pgfincore ('t1'); relpath | segment | os_page_size | rel_os_pages | pages_mem | group_mem | os_pages_free | databit | pages_dirty | group_dirty --------------------+---------+--------------+--------------+-----------+-----------+---------------+---------+-------------+------------- base/16391/33102 | 0 | 4096 | 262144 | 262144 | 1 | 1191325 | | 0 | 0 base/16391/33102.1 | 1 | 4096 | 65726 | 65726 | 1 | 1191325 | | 0 | 0 (2 rows)
参数说明
pgsysconf与pgsysconf_pretty
查看当前OS块大小及使用情况 testdb=# select * from pgsysconf(); os_page_size | os_pages_free | os_total_pages --------------+---------------+---------------- 4096 | 1190139 | 1997572 (1 row) testdb=# select * from pgsysconf_pretty(); os_page_size | os_pages_free | os_total_pages --------------+---------------+---------------- 4096 bytes | 4649 MB | 7803 MB (1 row)
pgfadvise_willneed
将数据库对象缓存到OS CACHE
testdb=# select * from pgfadvise_willneed('t1'); relpath | os_page_size | rel_os_pages | os_pages_free --------------------+--------------+--------------+--------------- base/16391/33102 | 4096 | 262144 | 1190033 base/16391/33102.1 | 4096 | 65726 | 1190033 (2 rows)
pgfadvise_dontneed
testdb=# select * from pgfadvise_dontneed('t1'); relpath | os_page_size | rel_os_pages | os_pages_free --------------------+--------------+--------------+--------------- base/16391/33102 | 4096 | 262144 | 1452085 base/16391/33102.1 | 4096 | 65726 | 1517801 (2 rows) testdb=# select * from pgfincore ('t1'); relpath | segment | os_page_size | rel_os_pages | pages_mem | group_mem | os_pages_free | databit | pages_dirty | group_dirty --------------------+---------+--------------+--------------+-----------+-----------+---------------+---------+-------------+------------- base/16391/33102 | 0 | 4096 | 262144 | 0 | 0 | 1517805 | | 0 | 0 base/16391/33102.1 | 1 | 4096 | 65726 | 0 | 0 | 1517805 | | 0 | 0 (2 rows)