我们的系统写入了大量数据(一种大数据系统)。写入性能足以满足我们的需求,但读取性能真的太慢了。
我们所有表的主键(约束)结构都相似:
timestamp(Timestamp) ; index(smallint) ; key(integer).
Run Code Online (Sandbox Code Playgroud)
一个表可以有数百万行,甚至数十亿行,而一个读请求通常是针对特定时间段(时间戳/索引)和标记的。查询返回大约 20 万行是很常见的。目前,我们每秒可以读取大约 15k 行,但我们需要快 10 倍。这是可能的,如果是,如何?
注意: PostgreSQL 是和我们的软件一起打包的,所以不同客户端的硬件是不一样的。
它是一个用于测试的虚拟机。VM 的主机是具有 24.0 GB RAM 的 Windows Server 2008 R2 x64。
Server 2008 R2 x64
2.00 GB of memory
Intel Xeon W3520 @ 2.67GHz (2 cores)
Run Code Online (Sandbox Code Playgroud)
postgresql.conf
优化shared_buffers = 512MB (default: 32MB)
effective_cache_size = 1024MB (default: 128MB)
checkpoint_segment = 32 (default: 3)
checkpoint_completion_target = 0.9 (default: 0.5)
default_statistics_target = 1000 (default: 100)
work_mem = 100MB (default: 1MB)
maintainance_work_mem = 256MB …
Run Code Online (Sandbox Code Playgroud) 我试图让 PostgreSQL 积极地自动清空我的数据库。我目前已按如下方式配置自动真空吸尘器:
我注意到自动真空仅在数据库未加载时才会启动,因此我遇到死元组比活元组多得多的情况。有关示例,请参阅随附的屏幕截图。其中一张表有 23 个活动元组,但有 16845 个死元组等待真空。这太疯狂了!
当测试运行完成并且数据库服务器空闲时,自动真空开始,这不是我想要的,因为我希望自动真空在死元组数量超过 20% 活元组 + 50 时启动,因为数据库已经配置。服务器空闲时的自动真空对我来说是无用的,因为生产服务器预计会在持续时间内达到 1000 次更新/秒,这就是为什么即使服务器负载不足我也需要自动真空运行。
有什么我想念的吗?如何在服务器负载较重时强制运行自动吸尘器?
更新
这可能是一个锁定问题吗?有问题的表是通过插入后触发器填充的汇总表。这些表以 SHARE ROW EXCLUSIVE 模式锁定,以防止并发写入同一行。
我在 Ubuntu 上使用 PostgreSQL 9.1。VACUUM ANALYZE
仍然推荐预定,还是 autovacuum 足以满足所有需求?
如果答案是“视情况而定”,那么:
我问是因为预定的时间VACUUM ANALYZE
会影响我的报告。它运行了 5 个多小时,本周我不得不杀死它两次,因为它影响了常规的数据库导入。check_postgres
不会报告数据库有任何显着膨胀,所以这不是真正的问题。
从文档中,autovacuum 也应该处理事务 ID 环绕。问题是:我还需要一个VACUUM ANALYZE
吗?
n_live_tup
and n_dead_tup
in pg_stat_user_tables
or是什么意思pgstattuple
?