主要作用是查看pg的共享池中缓存的对象信息
- 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)
isdirty :t表示脏块
预热功能使用pg_prevarm函数,方便将数据缓存到OS缓存中或PG缓存中
比如生产系统中,数据库重启了,此时发起的业务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
参数说明:
regclass :数据库对像,通常情况为表名
mode :加载模式
prefetch:异步地将数据预加载到操作系统缓存
read:最终结果和 prefetch 一样,但它是同步方式,支持所有平台
buffer:将数据预加载到数据库缓存
fork
main :主表
fsm:空间空间地图
vm:可见性地图
first_block :开始prewarm的数据块
last_block :最后 prewarm 的数据块
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
- 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)
- pg_ctl restart
-
- echo 3 > /proc/sys/vm/drop_caches
- 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
分别测试read和buffer模式下的效果
- pg_ctl restart
-
- echo 3 > /proc/sys/vm/drop_caches
- testdb=# select pg_prewarm('t1', 'read', 'main');
- pg_prewarm
- ------------
- 163935
- (1 row)
- 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)
- 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
总结:缓存到OS缓存中和PG缓存中,两者性能差异不大。但比不预热的情况下效果提升明显。
| 预热 | 参数 | 耗时 |
| 否 | 无 | 3586.400 ms |
| 是 | read | 658.997 ms |
| 是 | buffer | 683.353 ms |
将数据库对象CACHE到OS层面的缓存
- testdb=# CREATE EXTENSION pgfincore;
- CREATE EXTENSION
- 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)
参数说明
relpath:文件位置及名称
segment:文件段编号
os_page_size:OS page或block大小
rel_os_pages:对象占用系统缓存需要的页面个数
pages_mem:对象已经占用缓存页面个数
group_mem:在缓存中连续的页面组的个数
os_pages_free:OS剩余的page数
databit:加载信息的位图
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
将数据库对象刷出OS CACHE
对当前对象设置dontneed标记。dontneed标记的意思就是当操作系统需要释放内存时优先释放标记为dontneed的pages。
- 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)