暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

pg_buffercache扩展的介绍和使用

原创 董小姐 恩墨学院 2023-12-22
288

介绍

pg_buffercache模块提供了一种实时检测共享缓冲区的方法。这个模块提供了一个C函数:pg_buffercache_pages,它返回一个记录的集合和一个视图:pg_buffercache,它包装了这个函数来更方便的使用。默认情况下,公共访问会从这两者中撤回,来预防潜在的安全问题。
共享缓存中的每个缓冲区都有一行。未使用的缓冲区除了bufferid以外的所有列为null。共享系统目录被显示为属于数据库零。
当访问pg_buffercache视图时,内部缓冲区管理器会锁住足够长的时间来拷贝所有这个视图会展示的缓冲区状态数据。这确保了这个视图产生一个一致的结果集,同时不会不必要的长时间阳碍正常的缓冲区活动。虽然如此,但是如果这个视图被频繁读取的话,会对数据库性能产生些影响。
pg_buffercache这个视图中各列定义的详细解释如下:

创建扩展

进入指定库创建扩展
postgres=# create extension pg_buffercache;
CREATE EXTENSION

使用

--创建两个数据库
create database test; 
create database mydb;
--test库 创建pg_buffercache扩展
\c test
create extension pg_buffercache;

--查看pg_buffercache模块脚本内容
cd /pgdb/pgsql/share/extension
[postgres@localhost extension]$ more pg_buffercache--1.2.sql
/* contrib/pg_buffercache/pg_buffercache--1.2.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION pg_buffercache" to load this file. \quit

-- Register the function.
CREATE FUNCTION pg_buffercache_pages()
RETURNS SETOF RECORD
AS 'MODULE_PATHNAME', 'pg_buffercache_pages'
LANGUAGE C PARALLEL SAFE;

-- Create a view for convenient access.
CREATE VIEW pg_buffercache AS
	SELECT P.* FROM pg_buffercache_pages() AS P
	(bufferid integer, relfilenode oid, reltablespace oid, reldatabase oid,
	 relforknumber int2, relblocknumber int8, isdirty bool, usagecount int2,
	 pinning_backends int4);

-- Don't want these to be available to public.
REVOKE ALL ON FUNCTION pg_buffercache_pages() FROM PUBLIC;
REVOKE ALL ON pg_buffercache FROM PUBLIC;


--看看缓冲区缓存的内容
test=# SELECT DISTINCT reldatabase FROM pg_buffercache;
 reldatabase 
-------------
            
       16479
       16478
       13892
           0
(5 rows)

--在缓存中找到两个数据库的某些部分。带0的记录表示缓存区尚未使用:
test=# \! oid2name
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  16478           fuwa  pg_default
  16480           mydb  pg_default
  13892       postgres  pg_default
  13891      template0  pg_default
      1      template1  pg_default
  16479           test  pg_default

--用一些其他视图再次连接,以获得更清晰的结果
select c.relname, count(*) as buffers from pg_class c join pg_buffercache b on b.relfilenode = c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) group by c.relname order by 2 desc;

可以看到主要是数据字典视图。许多数据字典表和视图会提供各种对象、对象类型、权限等的相关信息。这些为集群共同管理者记录活动;pg_class是其中一个类目表。这个表的其中一列是relname。尽管它看上去像是要存储关系/表名称,它也可以为其他对象类型存储数据。我们应该将它与列relkind一起使用。列relkind告诉我们记录指向的对象类型。relkind可能包括这些值,如r表、i索引、s序列、v视图等。
--检查缓冲区语句中增加查询条件 c.relname not like 'pg%'
select c.relname, count(*) as buffers from pg_class c join pg_buffercache b on b.relfilenode = c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) 
where c.relname not like 'pg%'
group by c.relname order by 2 desc;

 relname | buffers 
---------+---------
(0 rows)

--尝试使用用户创建的表填充缓冲区。test库构造测试数据。
CREATE TABLE emp(id serial, first_name varchar(50)) ;
INSERT INTO emp(first_name) VALUES('Jayadeva') ;
SELECT * FROM emp;

 id | first_name 
----+------------
  1 | Jayadeva
(1 row)


--重复查询,检查缓冲区是否包含新创建的表及其序列
select c.relname, count(*) as buffers from pg_class c join pg_buffercache b on b.relfilenode = c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) 
where c.relname not like 'pg%'
group by c.relname order by 2 desc;

    relname     | buffers 
----------------+---------
 emp            |       1
 emp_id_seq     |       1



--对检查缓冲区语句稍作修改,isdirty标记是t
select c.relname, b.isdirty from pg_class c join pg_buffercache b on b.relfilenode = c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) 
where c.relname not like 'pg%';

    relname     | isdirty 
----------------+---------
 emp            | t
 emp_id_seq     | t

--更新数据,重复查询缓存区,页面表脏
UPDATE emp SET first_name ='Newname' ;

select c.relname, b.isdirty from pg_class c join pg_buffercache b on b.relfilenode = c.relfilenode inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database()) 
where c.relname not like 'pg%';

    relname     | isdirty 
----------------+---------
 emp            | t
 emp_id_seq     | t

--强制设置检查点:
CHECKPOINT;

--重复查询,页面不为脏:
    relname     | isdirty 
----------------+---------
 emp            | f
 emp_id_seq     | f

参考链接:https://blog.csdn.net/asmartkiller/article/details/118150232

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论