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

扩展插件 -- 人大金仓KingbaseES sys_prewarm 扩展

原创 金仓数据库 2023-07-25
1645

Oracle 在查询数据 可以通过cache hint 将所要访问的数据cache 到数据库buffer;对于KingbaseES,如何将数据加载到cache 了?sys_prewarm 扩展插件可以实现数据的cache。

PS:预热数据也没有对缓存驱逐的特殊保护,因此其他系统活动可能会在读取后不久将新的预热块驱逐出去;反之,预热也可能从高速缓存中驱逐其他数据。由于这些原因,预热通常在启动时最有用,当缓存大部分为空时。

一、准备数据

test=# create table prewarm_test1(id integer,name text);
CREATE TABLE
test=# insert into prewarm_test1 select generate_series(1,3000000),md5(random()::text);
INSERT 0 3000000
test=# select pg_size_pretty(pg_relation_size('prewarm_test1')); 
 pg_size_pretty 
----------------
 195 MB
(1 row)

create table prewarm_test2 as select * from prewarm_test1;

create index ind_prewarm_test2 on prewarm_test2(id);

二、select 操作与 cache

1、统计cache信息的脚本

为了取得cache 的信息,必须安装 sys_buffercache 扩展插件。cache 统计的脚本如下:

select c.relname, count(*) as buffers
from sys_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;

2、全表访问

为了保证数据准确,在访问之前,必须先重启下数据库(清理shared_buffer)。以下是数据库刚启动是的buffer 状态:

                 relname                 | buffers 
-----------------------------------------+---------
 pg_attribute                            |      36
 pg_class                                |      25
 pg_proc                                 |      13

全表访问 1 次后的buffer 状态:

test=# select count(*) from prewarm_test1;
  count  
---------
 3000000
(1 row)

                    relname                    | buffers 
-----------------------------------------------+---------
 prewarm_test1                                 |      96
 pg_attribute                                  |      36
 pg_class                                      |      25

再次 全表访问后的状态:

test=# select count(*) from prewarm_test1;                                                              
  count  
---------
 3000000
(1 row)

                   relname                    | buffers 
-----------------------------------------------+---------
 prewarm_test1                                 |     192
 pg_attribute                                  |      36
 pg_class                                      |      25

结论:可以看到全表全表访问并不会把全部的数据缓存。对于大小超过shared_buffer/4的表进行全表扫描时,不会使用全部的shared_buffer,而是只使用很少一部分的shared_buffer。

3、索引访问

test=# end;
test=# \set SQLTERM /
test=# declare
test-#   v_temp integer;
test-# begin
test-#   for i in 1..3000000 loop
test-#     select id into v_temp from prewarm_test2 where id=i;
test-#   end loop;
test-# end;
test-# /
ANONYMOUS BLOCK

                 relname                 | buffers 
-----------------------------------------+---------
 prewarm_test2                           |   12287
 ind_prewarm_test2                       |    4044
 pg_class                                |      25

结论:通过索引访问的块,会缓存在cache中

三、sys_prewarm 

1、创建sys_prewarm 扩展

test=# create extension sys_prewarm;
CREATE EXTENSION
test=# \dx+ sys_prewarm
           Objects in extension "sys_prewarm"
                   Object description                   
--------------------------------------------------------
 function autoprewarm_dump_now()
 function autoprewarm_start_worker()
 function sys_extend(regclass,bigint)
 function sys_prewarm(regclass,text,text,bigint,bigint)
(4 rows)

2、sys_prewarm 函数定义

create function pg_prewarm(
  regclass,
  mode text default buffer,
  fork text default main,
  first_block int8 default null,
  last_block int8 default null
)
returns int8
as module_pathname, pg_prewarm
language c
  • regclass:要做prewarm的表名
  • mode:prewarm模式。prefetch表示异步预取到os cache;read表示同步预取;buffer表示同步读入PG的shared buffer
  • fork:relation fork的类型。一般用main,其他类型有visibilitymap和fsm
  • first_block & last_block:开始和结束块号。表的first_block=0,last_block可通过pg_class的relpages字段获得
  • RETURNS int8:函数返回pg_prewarm处理的block数目(整型)

3、验证sys_prewarm 函数

test=# select sys_prewarm('prewarm_test1');
 sys_prewarm 
-------------
       25000
(1 row)


                    relname                    | buffers 
-----------------------------------------------+---------
 prewarm_test1                                 |   16026
 pg_proc                                       |     114
 pg_attribute                                  |      36

结论:运行 sys_prewarm 后,可以看到数据被有效缓存了。

4、sys_extend 函数

sys_extend 用于预先一次性扩展数据文件大小,避免数据增长的同时在去扩展文件,可以有效的提升性能。

Tips :对于fdatasync , 文件的尺寸(st_size)如果变化,是需要立即同步的,否则OS一旦崩溃,即使文件的数据部分已同步,由于metadata没有同步,依然读不到修改的内容。而最后访问时间(atime)/修改时间(mtime)是不需要每次都同步的,只要应用程序对这两个时间戳没有苛刻的要求,基本无伤大雅。

test=# select relname,relpages from sys_class where relname='prewarm_test1';
relname        | relpages
---------------+----------
prewarm_test1  | 25000
(1 row)


test=# select sys_extend('prewarm_test1',10000);
 sys_extend 
------------
 t
(1 row)

test=# analyze prewarm_test1;
ANALYZE
test=# select relname,relpages from sys_class where relname='prewarm_test1';
relname        | relpages
---------------+----------
prewarm_test1  | 35000
(1 row)

这里表示数据文件的大小扩展 10000 个数据块。

 

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

评论