目录
在金仓数据库KingbaseES中,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 sys_size_pretty(sys_relation_size('prewarm_test1'));
- sys_size_pretty
- ----------------
- 195 MB
- (1 row)
-
- create table prewarm_test2 as select * from prewarm_test1;
-
- create index ind_prewarm_test2 on prewarm_test2(id);
为了取得cache 的信息,必须安装 sys_buffercache 扩展插件。cache 统计的脚本如下:
- select c.relname, count(*) as buffers
- from sys_buffercache b
- inner join sys_class c on b.relfilenode = sys_relation_filenode(c.oid)
- and b.reldatabase in (0, (select oid from sys_database where datname = current_database()))
- group by c.relname
- order by 2 desc;
为了保证数据准确,在访问之前,必须先重启下数据库(清理shared_buffer)。
数据库刚启动是的buffer 状态:
- relname | buffers
- -----------------------------------------+---------
- sys_attribute | 36
- sys_class | 25
- sys_proc | 13
全表访问 1 次后的buffer 状态:
- test=# select count(*) from prewarm_test1;
- count
- ---------
- 3000000
- (1 row)
-
- relname | buffers
- -----------------------------------------------+---------
- prewarm_test1 | 96
- sys_attribute | 36
- sys_class | 25
再次 全表访问后的状态:
- test=# select count(*) from prewarm_test1;
- count
- ---------
- 3000000
- (1 row)
-
- relname | buffers
- -----------------------------------------------+---------
- prewarm_test1 | 192
- sys_attribute | 36
- sys_class | 25
结论:可以看到全表全表访问并不会把全部的数据缓存。对于大小超过shared_buffer/4的表进行全表扫描时,不会使用全部的shared_buffer,而是只使用很少一部分的shared_buffer。
- 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
- sys_class | 25
结论:通过索引访问的块,会缓存在cache中
- 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)
- create function sys_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, sys_prewarm
- language c
- test=# select sys_prewarm('prewarm_test1');
- sys_prewarm
- -------------
- 25000
- (1 row)
-
-
- relname | buffers
- -----------------------------------------------+---------
- prewarm_test1 | 16026
- sys_proc | 114
- sys_attribute | 36
结论:运行 sys_prewarm 后,可以看到数据被有效缓存了。
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 个数据块。