【问题标题】:Is there any case of table rewrite on add nullable column?添加可为空的列是否存在表重写的情况?
【发布时间】:2021-05-21 07:42:32
【问题描述】:

一方面,文档明确指出

当使用 ADD COLUMN 添加列并且非易失性 DEFAULT 为 指定时,在语句时评估默认值,并且 结果存储在表的元数据中。该值将用于 所有现有行的列。如果未指定 DEFAULT,则为 NULL 用过的。在这两种情况下都不需要重写表。

https://www.postgresql.org/docs/12/sql-altertable.html

另一方面,我听说由于元组标题结构,在某些情况下可能会重写表。

文档指出,有三个字段负责空值存储行为

仅当 HEAP_HASNULL 位设置为 t_infomask。如果它存在,它就在固定标题之后开始,并且 占用足够的字节以使每个数据列有一个位(即 等于 t_infomask2 中的属性计数的位数。在 此位列表,1 位表示非空,0 位表示空。什么时候 位图不存在,所有列都假定为非空。

https://www.postgresql.org/docs/12/storage-page-layout.html

我使用此信息和pageinspect 扩展来查看在添加或删除可空列时元组标题发生了什么。在所有情况下,当我添加或删除可为空的列时,我发现存在的元组永远不会更改它们的标题。

所以,我找不到任何证据表明表可能会被重写。字段t_infomask, t_infomask2, t_bits 永远不会改变它们的值。

我错过了什么吗?我可以说向大容量表添加可为空的列就磁盘活动而言绝对安全(排除排他锁定的事实)?

【问题讨论】:

  • 很难对未具名的消息来源可能告诉您的内容做出有意义的评论。你知道他们在说什么版本吗?
  • 不,我不知道确切的版本。我同意,这看起来像谣言。这就是我决定询问社区的原因。

标签: postgresql postgresql-12


【解决方案1】:

PostgreSQL v11 中的行为发生了变化。在此之前,添加具有非 NULL 默认值的列将重写表。

关键是从 v11 开始,元组和它的头部不必修改,添加这样的列只是元数据的更改。 pageinspect 不会看到这一点。 NULL 值永远不会存储在元组中,只有 NULL 位图,如果表列之一可以为空,则存在。

【讨论】:

猜你喜欢
  • 2021-10-23
  • 1970-01-01
  • 2015-08-18
  • 1970-01-01
  • 2013-07-02
  • 2021-08-02
  • 2010-12-09
  • 2017-04-26
  • 1970-01-01
相关资源
最近更新 更多