KingbaseES sys_prewarm 扩展
Oracle 在查询数据 可以通过cache hint 所访问的数据cache 到数据库buffer,对于KingbaseES,如何将数据加载到cache 了?sys_prewarm 扩展插件可以实现数据的cache
一、准备数据
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 个数据块。
KINGBASE研究院