我怎样才能检查我的数据库是否需要更多的内存?

你将如何检查你的postgresql数据库实例是否需要更多的RAM内存来处理他们当前的工作数据?

如果你在Linux上,你的总物理内存应该大于磁盘上的数据库大小,以尽量减lessI / O。 最终,整个数据库将在OS读取caching中,I / O将仅限于将更改提交到磁盘。 我更喜欢通过运行“du-shc $ PGDATA / base”来查找数据库大小 – 该方法将所有数据库聚合为一个数字。 只要你比这更大,那应该没问题。

另外,您可以查看堆和索引块提取的高速caching命中率。 这些测量到PostgreSQL的共享缓冲区的命中率。 这些数字可能有点误导 – 即使它可能在共享缓冲区caching中未命中,它仍然可能在操作系统读取caching中命中。 尽pipe如此,共享缓冲区中的命中仍然比操作系统读取caching中的命中要便宜(反过来,它的价格比不得不返回到磁盘要便宜几个数量级)。

为了查看共享缓冲区命中率,我使用这个查询:

SELECT relname, heap_blks_read, heap_blks_hit, round(heap_blks_hit::numeric/(heap_blks_hit + heap_blks_read),3) FROM pg_statio_user_tables WHERE heap_blks_read > 0 ORDER BY 4 LIMIT 25; 

这给了你25个最差的违规者,其中至less有一个块必须从“磁盘”(也可以是操作系统读取caching或实际的磁盘I / O)中取出的所有表中都没有缓冲区caching。 您可以增加WHERE子句中的值,或为heap_blks_hit添加其他条件以过滤掉很less使用的表。

通过用“idx”全局replacestring“heap”,可以使用相同的基本查询来检查每个表的总索引命中率。 看看pg_statio_user_indexes得到一个按指数细分。

有关共享缓冲区的简要说明:在Linux中,一个好的经验法则是将configuration参数shared_buffers设置为RAM的1/4,但不超过8GB。 这不是一个硬性规定,而是调整服务器的一个很好的起点。 如果你的数据库只有4GB,并且你有一个32GB的服务器,8GB的共享缓冲区实际上是过量的,你应该可以将其设置为5或6GB,并且还有空间用于未来的增长。

我做了这个SQL来显示表与磁盘命中率:

 -- perform a "select pg_stat_reset();" when you want to reset counter statistics with all_tables as ( SELECT * FROM ( SELECT 'all'::text as table_name, sum( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk, sum( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables) ) a WHERE (from_disk + from_cache) > 0 -- discard tables without hits ), tables as ( SELECT * FROM ( SELECT relname as table_name, ( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk, ( (coalesce(heap_blks_hit,0) + coalesce(idx_blks_hit,0) + coalesce(toast_blks_hit,0) + coalesce(tidx_blks_hit,0)) ) as from_cache FROM pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables) ) a WHERE (from_disk + from_cache) > 0 -- discard tables without hits ) SELECT table_name as "table name", from_disk as "disk hits", round((from_disk::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% disk hits", round((from_cache::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% cache hits", (from_disk + from_cache) as "total hits" FROM (SELECT * FROM all_tables UNION ALL SELECT * FROM tables) a ORDER BY (case when table_name = 'all' then 0 else 1 end), from_disk desc 

在这里输入图像描述

正如Heroku doc所说:

 SELECT 'cache hit rate' AS name, sum(heap_blks_hit) / (sum(heap_blks_hit) + sum(heap_blks_read)) AS ratio FROM pg_statio_user_tables;