网易首页 > 网易号 > 正文 申请入驻

PostgreSQL-shared_buffers(双缓存)

0
分享至

关于shared_buffers

  • 这是一篇2018年写的,可以结合shared read一起看

什么是shred_buffer,我们为什么需要shared_buffers?

1.在数据库系统中,我们主要关注磁盘io,大多数oltp工作负载都是随机io,因此从磁盘获取非常慢。

2.为了解决这个问题,postgres将数据缓存在RAM中,以此来提高性能,即使ssd的情况下RAM也要快很多。

3.shared_buffers是一个8KB的数组,postgres在从磁盘中查询数据前,会先查找shared_buffers的页,如果命中,就直接返回,避免从磁盘查询。

shared_buffers存储什么?

1.表数据

2.索引,索引也存储在8K块中。

3.执行计划,存储基于会话的执行计划,会话结束,缓存的计划也就被丢弃。

什么时候加载shared_buffers?

1.在访问数据时,数据会先加载到os缓存,然后再加载到shared_buffers,这个加载过程可能是一些查询,也可以使用pg_prewarm预热缓存。

2.当然也可能同时存在os和shared_buffers两份一样的缓存(双缓存)。

3.查找到的时候会先在shared_buffers查找是否有缓存,如果没有再到os缓存查找,最后再从磁盘获取。

4.os缓存使用简单的LRU(移除最近最久未使用的缓存),而数据库采用的优化的时钟扫描,即缓存使用频率高的会被保存,低的被移除。

shared_buffers设置的合理范围

1.windows服务器有用范围是64MB到512MB,默认128MB

2.linux服务器建议设置为25%,亚马逊服务器设置为75%(避免双缓存,数据会存储在os和shared_buffers两份)

os缓存的重要性

数据写入时,从内存到磁盘,这个页面就会被标记为脏页,一旦被标记为脏页,它就会被刷新到os缓存,然后写入磁盘。所以如果os高速缓存大小较小,则它不能重新排序写入并优化io,这对于繁重的写入来说非常致命,因此os的缓存大小也非常重要。给予shared_buffers太大或太小都会损害性能。

查看shared_buffers,os缓存

这里需要使用到两个插件,pg_bufferscache系统已经自带可以直接创建扩展,pgfincore需要安装详细的步骤

查询 shared_buffers 占比和缓存情况:

SELECT
c.relname,
pg_size_pretty(count(*)*8192)ASpg_buffered,
round(100.0*count(*)/(SELECTsettingFROMpg_settingsWHEREname='shared_buffers')::integer,1)ASpgbuffer_percent,
round(100.0*count(*)*8192/pg_table_size(c.oid),1)ASpercent_of_relation,
round(sum(pages_mem)*4/1024,0)ASos_cache_MB,
round(100*sum(pages_mem)*4096/pg_table_size(c.oid),1)ASos_cache_percent_of_relation,
pg_size_pretty(pg_table_size(c.oid))ASrel_size
FROM
pg_classc
INNERJOINpg_buffercachebONb.relfilenode=c.relfilenode
INNERJOINpg_databasedON(b.reldatabase=d.oidANDd.datname=current_database()ANDc.relnamespace=(SELECToidFROMpg_namespaceWHEREnspname='public'))
GROUPBY
c.oid,c.relname
ORDERBY
3DESC
LIMIT30;

结果:

relname|pg_buffered|pgbuffer_percent|percent_of_relation|os_cache_mb|os_cache_percent_of_relation|rel_size
-------------------+-------------+------------------+---------------------+-------------+------------------------------+----------
pgbench_accounts|471MB|1.9|7.3|495|7.7|6416MB
pgbench_accounts_pkey|139MB|0.6|13.0|274|25.6|1071MB
pgbench_history|2704kB|0.0|86.9|3|99.2|3112kB
pgbench_branches_pkey|56kB|0.0|100.0|0|100.0|56kB
pgbench_tellers_pkey|240kB|0.0|100.0|0|100.0|240kB
pgbench_branches|2968kB|0.0|70.7|4|99.2|4200kB
pgbench_tellers|608kB|0.0|100.0|1|94.7|608kB

预热缓存和查看结果:

--表缓存预热
SELECTpg_prewarm('pgbench_accounts','buffer','main');
--索引预热
SELECTpg_prewarm('pgbench_accounts_pkey','buffer','main');
--预热后查看缓存
SELECT
c.relname,
pg_size_pretty(count(*)*8192)ASpg_buffered,
round(100.0*count(*)/(SELECTsettingFROMpg_settingsWHEREname='shared_buffers')::integer,1)ASpgbuffer_percent,
round(100.0*count(*)*8192/pg_table_size(c.oid),1)ASpercent_of_relation,
round(sum(pages_mem)*4/1024,0)ASos_cache_MB,
round(100*sum(pages_mem)*4096/pg_table_size(c.oid),1)ASos_cache_percent_of_relation,
pg_size_pretty(pg_table_size(c.oid))ASrel_size
FROM
pg_classc
INNERJOINpg_buffercachebONb.relfilenode=c.relfilenode
INNERJOINpg_databasedON(b.reldatabase=d.oidANDd.datname=current_database()ANDc.relnamespace=(SELECToidFROMpg_namespaceWHEREnspname='public'))
GROUPBY
c.oid,c.relname
ORDERBY
3DESC
LIMIT30;

结果:

relname|pg_buffered|pgbuffer_percent|percent_of_relation|os_cache_mb|os_cache_percent_of_relation|rel_size
-------------------+-------------+------------------+---------------------+-------------+------------------------------+----------
pgbench_accounts|6414MB|26.1|100.0|6414|100.0|6416MB
pgbench_accounts_pkey|139MB|0.6|13.0|274|25.6|1071MB
pgbench_history|2704kB|0.0|86.9|3|99.2|3112kB
pgbench_branches_pkey|56kB|0.0|100.0|0|100.0|56kB
pgbench_tellers_pkey|240kB|0.0|100.0|0|100.0|240kB
pgbench_branches|2968kB|0.0|70.7|4|99.2|4200kB
pgbench_tellers|608kB|0.0|100.0|1|94.7|608kB

如何设定shared_buffers?

使用pg_buffercache可查看缓存使用情况,以及命中次数和脏块

缓存命中数

--缓存命中数
SELECTusagecount,count(*),isdirty
FROMpg_buffercache
GROUPBYisdirty,usagecount
ORDERBYisdirty,usagecount;

结果:

usagecount|count|isdirty
-----------+---------+---------
1|6651|f
2|762250|f
3|54684|f
4|12630|f
5|3940|f
|2305573|

数据在缓存中的占比:

--数据在缓存中占比
SELECT
c.relname,
pg_size_pretty(count(*)*8192)ASbuffered,
round(100.0*count(*)/(SELECTsettingFROMpg_settingsWHEREname='shared_buffers')::integer,1)ASbuffers_percent,
round(100.0*count(*)*8192/pg_relation_size(c.oid),1)ASpercent_of_relation
FROM
pg_classc
INNERJOINpg_buffercachebONb.relfilenode=c.relfilenode
INNERJOINpg_databasedON(b.reldatabase=d.oidANDd.datname=current_database())
GROUPBY
c.oid,c.relname
ORDERBY
3DESC
LIMIT10;

结果:

relname|buffered|buffers_percent|percent_of_relation
-----------------------+-----------+-----------------+---------------------
pgbench_accounts|6414MB|26.1|100.0
pgbench_accounts_pkey|1071MB|4.4|100.0
pg_amop|56kB|0.0|87.5
pg_cast|16kB|0.0|100.0
pg_constraint|8192bytes|0.0|100.0
pg_index|32kB|0.0|100.0
pg_opclass|16kB|0.0|66.7
pg_namespace|8192bytes|0.0|100.0
pg_operator|120kB|0.0|100.0
pg_amproc|40kB|0.0|100.0

从结果看出,缓存中存储了完整的表和索引,占总缓存的30%,占比较低,缓存剩余很多。

1.如果大量的usagecount都是4或者5,那表明shared_buffers不够,应该扩大shared_buffers;

2.如果大量的usagecount都是0或者1,那表明shared_buffers过大,应该减小shared_buffers;

每当共享内存中使用一个块时,它就会增加一次时钟扫描算法,范围从1-5。4和5标识极高的使用数据块,高使用可能会保留在shared_buffers中(有空间),如果需要更高使用率的空间,则低使用率的块将被移除,一般简单的插入或者更新会将使用次数设置为1。

缓存占比低。可以确定的是如果我们的数据集非常小,那么设置较大的shared_buffers,没什么区别。

pgbench性能测试(shared_buffers 128MB,4GB,8GB,24GB)

PostgreSQL默认测试脚本,含UPDATE、INSERT还有SELECT等操作。通过修改shared_buffers大小来测试tps。

数据库版本:PostgreSQL 10.4 (ArteryBase 5.0.0, Thunisoft)

操作系统配置:CentOS Linux release 7 ,32GB内存,8 cpu

测试参数:初始化5000w数据:pgbench -i -s 500 -h localhost -U sa -d pgbench

测试方法:pgbench -c 500 -t 20 -n -r pgbench 模拟500客户端,每个客户端20个事务,每种配置参数执行三次,记录tps值。

数据库物理大小:数据库总大小7503 MB,其中表总大小pgbench_accounts:7487 MB,索引pgbench_accounts_pkey :1071 MB

测试脚本:

--事务延迟(毫秒)
\setaidrandom(1,100000*:scale)
\setbidrandom(1,1*:scale)
\settidrandom(1,10*:scale)
\setdeltarandom(-5000,5000)
--执行事务
BEGIN;
UPDATEpgbench_accountsSETabalance=abalance+:deltaWHEREaid=:aid;
SELECTabalanceFROMpgbench_accountsWHEREaid=:aid;
UPDATEpgbench_tellersSETtbalance=tbalance+:deltaWHEREtid=:tid;
UPDATEpgbench_branchesSETbbalance=bbalance+:deltaWHEREbid=:bid;
INSERTINTOpgbench_history(tid,bid,aid,delta,mtime)VALUES(:tid,:bid,:aid,:delta,CURRENT_TIMESTAMP);
END;

结果:

statementlatenciesinmilliseconds:
0.002\setaidrandom(1,100000*:scale)
0.001\setbidrandom(1,1*:scale)
0.001\settidrandom(1,10*:scale)
0.001\setdeltarandom(-5000,5000)
9.478BEGIN;
14.575UPDATEpgbench_accountsSETabalance=abalance+:deltaWHEREaid=:aid;
6.758SELECTabalanceFROMpgbench_accountsWHEREaid=:aid;
130.573UPDATEpgbench_tellersSETtbalance=tbalance+:deltaWHEREtid=:tid;
786.933UPDATEpgbench_branchesSETbbalance=bbalance+:deltaWHEREbid=:bid;
5.355INSERTINTOpgbench_history(tid,bid,aid,delta,mtime)VALUES(:tid,:bid,:aid,:delta,CURRENT_TIMESTAMP);
1242.835END;

未预热缓存测试结果:

--TPS测试结果
SELECT
'shared_buffers=128MB(默认)'ASconfig,
249ASfirst_time,
126ASsecond_time,
145ASthird_time,
173ASaverage_tps
UNION
SELECT
'shared_buffers=4GB',
357,
357,
373,
362
UNION
SELECT
'shared_buffers=8GB',
362,
363,
415,
380
UNION
SELECT
'shared_buffers=24GB',
378,
368,
397,
381;

shared_buffers设置为8GB(25%)和设置为24GB(75%)差别不大。

预热缓存测试结果:

--TPS测试结果
SELECT
'shared_buffers=128MB(默认)'ASconfig,
211ASfirst_time,
194ASsecond_time,
207ASthird_time,
204ASaverage_tps
UNION
SELECT
'shared_buffers=4GB',
1225,
1288,
1321,
1278
UNION
SELECT
'shared_buffers=8GB',
1176,
1291,
1144,
1203
UNION
SELECT
'shared_buffers=24GB',
1285,
1250,
1309,
1281;

当shared_buffers=4GB时,数据6GB不能完全装下,所以优先预热索引,将索引加载到缓存,然后再加载数据。可以看到最终shared_buffers=4GB的tps和8GB,24GB表现差别不大。

内存结构

1.本地内存:work_mem,maintenance_work_mem,temp_buffer,进程分配

2.共享内存:shared_buffers,wal buffers,commitLog buffer

本地内存*max_connections+共享内存+服务器使用内存<=总内存

小结

1.大多数情况设置shared_buffers为内存的25%,当然为了最优可以根据命中,以及缓存占比调整。

2.设置shared_buffers为75%和25%相差不大,也和数据量一共只有7G+有关系。但是os系统缓存同样重要,而设置为75%,可能会超过总内存。

3.设置所有的缓存需要注意不要超过总内存大小。

4.在预热数据的过程中可以考虑先做索引的预热,因为要做索引的情况加载索引会比较慢。

#PG数据库工程师的摇篮#PostgreSQL考试#PostgreSQL培训

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
太吓人!23/24赛季身价涨幅前十:亚马尔+9000万!帕尔默+6500万

太吓人!23/24赛季身价涨幅前十:亚马尔+9000万!帕尔默+6500万

直播吧
2024-06-09 21:22:32
女排参加欢迎晚宴,朱婷低调,张常宁袁心玥畅聊,刁琳宇有心事

女排参加欢迎晚宴,朱婷低调,张常宁袁心玥畅聊,刁琳宇有心事

热血排球通
2024-06-10 04:40:49
细思极恐!央视评论员探秘特斯拉!

细思极恐!央视评论员探秘特斯拉!

科技黑盒
2024-06-09 21:12:42
普京对俄军士兵很大方,只要在乌克兰打过仗,就能在远东分一块地

普京对俄军士兵很大方,只要在乌克兰打过仗,就能在远东分一块地

西斋青简
2024-06-09 14:45:02
后续!王思聪发文回应私生子传闻:不要来撒酒疯 女方紧急闭麦

后续!王思聪发文回应私生子传闻:不要来撒酒疯 女方紧急闭麦

西瓜爱娱娱
2024-06-09 15:14:53
迪拜,一个比缅北更恐怖的地方!幸好贫穷又救了我一命!好可怕啊

迪拜,一个比缅北更恐怖的地方!幸好贫穷又救了我一命!好可怕啊

有趣的羊驼
2024-06-09 20:19:23
张兰卖惨:在北京无房产,汪小菲名下无资产,马筱梅会哭晕吗?

张兰卖惨:在北京无房产,汪小菲名下无资产,马筱梅会哭晕吗?

综艺停车场
2024-06-10 04:16:16
首例!深圳一老板在办公室摆放烟灰缸,被罚款5000元

首例!深圳一老板在办公室摆放烟灰缸,被罚款5000元

景来律师
2024-06-09 00:08:22
女排让步国足!央视直播计划出炉,女排男足晋级生死战,志在出线

女排让步国足!央视直播计划出炉,女排男足晋级生死战,志在出线

理工男评篮球
2024-06-09 15:40:12
孙铭徽松口气!辽篮老将转会广厦,33岁威力不减,李楠想横刀夺爱

孙铭徽松口气!辽篮老将转会广厦,33岁威力不减,李楠想横刀夺爱

体坛大事记
2024-06-09 16:43:23
遗憾!国米中国行确认取消:张康阳离队!巴黎马竞多特也不来了!

遗憾!国米中国行确认取消:张康阳离队!巴黎马竞多特也不来了!

风过乡
2024-06-09 21:38:48
德国总理:反对将欧洲汽车市场与外国竞争隔绝

德国总理:反对将欧洲汽车市场与外国竞争隔绝

财联社
2024-06-09 07:12:11
小S爆料具俊晔已经回韩国,网友发现大S爱的一直都是汪小菲

小S爆料具俊晔已经回韩国,网友发现大S爱的一直都是汪小菲

姜子说书
2024-06-07 18:20:01
中国男乒四大"富二代":梁靖崑玩弄女明星感情,王楚钦深陷三角恋

中国男乒四大"富二代":梁靖崑玩弄女明星感情,王楚钦深陷三角恋

凤幻洋
2024-06-09 11:03:37
儿媳照顾50岁农村公公,酒后公公行夫妻之事,公公:儿媳经验丰富

儿媳照顾50岁农村公公,酒后公公行夫妻之事,公公:儿媳经验丰富

魅老八足球
2024-05-13 13:49:37
以前几百天卖不掉,如今挂牌1天“秒售”,“老破小”突然火了!机构:二手房价格泡沫基本消除

以前几百天卖不掉,如今挂牌1天“秒售”,“老破小”突然火了!机构:二手房价格泡沫基本消除

每日经济新闻
2024-06-09 22:38:08
把最漂亮的孩子放在c位大家就会觉得所有的孩子都很漂亮

把最漂亮的孩子放在c位大家就会觉得所有的孩子都很漂亮

粤姐说情感
2024-06-03 11:36:09
这一夜,CBA的体面,被崔永熙的球探报告撕了个粉碎

这一夜,CBA的体面,被崔永熙的球探报告撕了个粉碎

热血排球通
2024-06-09 15:00:07
湖南省又一副厅长被双开,严重违纪违法!

湖南省又一副厅长被双开,严重违纪违法!

白马惊天剑
2024-06-09 21:26:08
突发!上海发生一起交通事故,伤者太惨,已不忍心看

突发!上海发生一起交通事故,伤者太惨,已不忍心看

宿舍说科普
2024-06-10 02:25:59
2024-06-10 06:58:44
PGCCC兰亭集序
PGCCC兰亭集序
分享关于pg的信息
5文章数 95关注度
往期回顾 全部

科技要闻

王传福隔空回应余承东!半个车圈大佬发声

头条要闻

放话"不夺冠游回去" 南京公安龙舟队三场比赛未进决赛

头条要闻

放话"不夺冠游回去" 南京公安龙舟队三场比赛未进决赛

体育要闻

独行侠绿军会师总决赛 他成了最尴尬的人

娱乐要闻

汤唯抵达巴黎将担任奥运火炬手

财经要闻

疯狂抄底,中东土豪横扫中国资产!

汽车要闻

营收99亿亏损50亿+ 蔚来一季度财报出炉

态度原创

亲子
家居
游戏
本地
公开课

亲子要闻

7个月宝宝被爸爸肚皮弹倒一脸不可置信 网友:“没有危险的时候,爸爸就是最大的危险!”

家居要闻

柔和婉转 让阳光洒满空间

梦幻西游175服战大唐搭配思路别具一格,竞对同门兄弟重拳出击

本地新闻

我和我的家乡|踏浪营口,心动不止一夏!

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版