加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

postgresql – 在仅接收INSERT的表上运行VACUUM是否值得?

发布时间:2020-12-13 16:24:05 所属栏目:百科 来源:网络整理
导读:在2015年的re:Invent谈话中,AWS提到真空应该不仅在更新或删除之后运行,而且在插入之后运行.以下是谈话的相关部分: http://www.youtube.com/watch?v=tZXp19q8RFot=16m2s 据说有一些清理必须在块上完成,即使它们只接收到插入,并且可以在第一次选择块(减慢读
在2015年的re:Invent谈话中,AWS提到真空应该不仅在更新或删除之后运行,而且在插入之后运行.以下是谈话的相关部分:

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读