暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL之alter table add column会锁表吗

8800

首先答案是: 会锁表,且获得的是ACCESS EXCLUSIVE锁,但是不同情况下,锁的持有时间会不同。

  • 当列的默认值为NULL时,该列的添加应该非常快,因为它不需要重写表:它只是系统表中的更新。

  • 当列具有非NULL的默认值时,它取决于PostgreSQL版本: 11.0及之后的版本,不会立即重写所有的行,所以它应该和NULL的情况一样快。但是对于版本10或更早的表,它是完全重写的,因此根据表的大小,它可能非常昂贵。

第一种情况,当列的默认值是null时,即

    ALTER TABLE users ADD COLUMN score int;

    这个操作很快,新列的信息被添加到system catolog中,而不需要rewrite table。

    第二种情况,当列具有非null的默认值时,即

      ALTER TABLE users ADD COLUMN score int NOT NULL DEFAULT 0;

      关于上面提到的“在11.0及之后的版本,不会立即重写所有的行”, 这一点我们可以看11.0的release note。

      参考:https://www.postgresql.org/docs/11/release-11.html

      它里面有这样的一段话:

      Allow ALTER TABLE to add a column with a non-null default without doing a table rewrite (Andrew Dunstan, Serge Rielau) This is enabled when the default value is a constant.

      https://www.postgresql.org/docs/11/release-11.html

      允许Alter Table添加非空默认列而不重写表,当默认值为常量时启用此功能。

      问题

      1、怎么理解重写表?

      当添加带有默认值的列时,PostgreSQL需要创建所有行的新版本并将它们存储在磁盘上。

      2、11.0是怎么实现这一点的?

      pg_attribute中新增了两个字段:atthasmissing和attmissingval。注:pg_attribute是一个系统表,该系统表存储所有表的字段信息,数据库中每个表的每个字段在pg_attribute表中都有一行记录。

      在ALTER TABLE时,当新增stable或immutable表达式(非volatile)作为默认值时,即评估表达式的值作为常量,存入新增列在pg_attribute元数据中的attmissingval字段中,同时将atthasmissing标记为true。

      注:stable、immutable、volatile是pg的函数稳定性状态。

      atthasmissing:当缺少默认值时设置为true。

      attmissingval:包含缺失的值。

      当扫描返回行时,它们检查这些新字段并在适当的地方返回缺失的值(即atthasmissing)。插入到表中的新行在创建时选择默认值,因此在返回其内容时不需要检查athasmissing。

      3、测试一下11.0的情况。

      a.创建测试表,新增若干数据。

        create unlogged table t_table(id int, info text);

        b.添加测试数据。

          insert into t_table select generate_series(1,1000000),repeat(md5(random()::text),10);

          c.添加非空默认列

            alter table t_table add column c1 text default 'test';

            d.查看pg_attribute。

              select * from pg_attribute where attrelid='t_table'::regclass and attname='c1';

              可以看到atthasmissing=t, attmissingval为test。

              参考:https://stackoverflow.com/questions/19525083/does-adding-a-null-column-to-a-postgres-table-cause-a-lock

              https://github.com/postgres/postgres/commit/16828d5c0273b4fe5f10f42588005f16b415b2d8

              https://billtian.github.io/digoal.blog/2018/05/18/01.html

              https://dataegret.com/2018/03/waiting-for-postgresql-11-pain-free-add-column-with-non-null-defaults/

              文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论