http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s
据说有一些清理必须在块上完成,即使它们只接收到插入,并且可以在第一次选择块(减慢读取)或在真空期间进行清理.这是真的,如果是的话,究竟要做什么清理?
tl; dr:在提交数据后读取数据的第一个进程将设置提示位.这将弄脏页面,创建写入活动. VACUUM(但不是其他命令)做的另一件事是将页面标记为全部可见,如果合适的话. VACUUM最终将不得不在桌面上冻结元组.插入后需要完成的工作不是真正清理,至少不是VACUUM通常做的其他工作.在我详细介绍之前,请注意这个答案是基于当前(未发布的)9.6代码,我忽略了流复制的影响,即使它可能会影响可见性.
因为MVCC,每次Postgres评估一个元组是否应该对查询可见时,它必须考虑是否提交了创建元组的事务(记录在xmin隐藏字段中)以及其他一些标准.该检查很昂贵,因此只要知道所有当前打开的事务都可以看到事务,就会在元组头上设置“提示位”来指示该事务.该位的设置会弄脏页面,这意味着必须将其写入磁盘.如果读取数据的下一个命令是突然创建大量写入流量的SELECT,则这可能会非常混乱.在insert提交后运行VACUUM将避免这种情况.另一个重要的区别是VACUUM将始终在页面上提示元组(只要它在页面上获得清理锁定),但大多数其他命令只会提示如果在命令启动之前提交插入事务.
写入所有这些提示位的一个重点是可以限制VACUUM(并且默认情况下会禁止autovacuum).其他命令不受限制,并将尽快生成脏数据.
VACUUM是将页面标记为全可见的唯一方法,这是某些 *** 作(特别是仅索引扫描)的重要性能考虑因素.如果你做一个大的插入,很可能有很多页面只有新插入的元组. VACUUM可能会将这些页面标记为全部可见,但前提是VACUUM启动时最早运行的事务比插入数据的事务更新.
由于MVCC的工作方式,插入超过20亿次交易之前的元组必须标记为“frozen”.默认情况下,autovacuum将启动每200M事务.在批量插入后将vacuum_freeze_min_age设置为0运行手动真空有助于减少其影响.更积极的是,您可以在插入后在桌面上运行VACUUM FREEZE.这将在下一次冻结扫描发生时“重置时钟”.
如果您想了解具体细节,请在lazy_scan_heap()内调用HeapTupleSatisfIEsVacuum()后查看HEAPTUPLE_liVE案例.另请参阅HeapTupleSatisfIEsVacuum()本身,并将其与HeapTupleSatisfIEsMVCC()进行比较.
我的另外两个演讲可能很有趣.第一个视频可以从http://www.pgcon.org/2015/schedule/events/829.en.html开始,而第二个视频(我觉得有点好)可以在https://www.youtube.com/watch?v=L8nErzxPJjQ
总结以上是内存溢出为你收集整理的postgresql – 在仅接收INSERT的表上运行VACUUM是否值得?全部内容,希望文章能够帮你解决postgresql – 在仅接收INSERT的表上运行VACUUM是否值得?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)