Skip to content

Commit 8d5e4ee

Browse files
author
xiongcc
committed
optimization
1 parent d107dc8 commit 8d5e4ee

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

How to redefine a PK without downtime.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ ADD PRIMARY KEY (new_column);
3434

3535
让我们深入探讨细节 — NOT NULL 值得这么做。我们会有很多好消息和坏消息。我们将深入探讨与主键不一定相关但仍相关的细节。最终我们将回到重新定义主键的任务。请耐心听我说。
3636

37-
**坏消息:**不幸的是,向现有列添加 `NOT NULL` 约束意味着 PostgreSQL 需要执行长时间的全表扫描,而在此期间会获取 `ALTER TABLE` 持有的 `AccessExclusiveLock`,这显然不是我们想要的。
37+
坏消息:不幸的是,向现有列添加 `NOT NULL` 约束意味着 PostgreSQL 需要执行长时间的全表扫描,而在此期间会获取 `ALTER TABLE` 持有的 `AccessExclusiveLock`,这显然不是我们想要的。
3838

39-
**好消息:**自 PostgreSQL 11 起,我们可以通过一些技巧来应对这一问题。如果我们需要添加一个带有 `NOT NULL` 的列,我们可以受益于 PG11 的新功能 — 新列的非阻塞 `DEFAULT`,并将其与 `NOT NULL` 结合起来,例如:
39+
好消息:自 PostgreSQL 11 起,我们可以通过一些技巧来应对这一问题。如果我们需要添加一个带有 `NOT NULL` 的列,我们可以受益于 PG11 的新功能 — 新列的非阻塞 `DEFAULT`,并将其与 `NOT NULL` 结合起来,例如:
4040

4141
```sql
4242
ALTER TABLE t1
@@ -51,16 +51,16 @@ ADD COLUMN new_id int8 NOT NULL DEFAULT -1;
5151
5252
而且由于所有行都是预先填充的 ("虚拟地",但这并不重要),我们可以立即获得 `NOT NULL`,避免长时间等待。
5353

54-
**坏消息:**这种方法仅适用于新列。如果我们要对现有列添加 `NOT NULL` 约束,这个方法行不通。
54+
坏消息:这种方法仅适用于新列。如果我们要对现有列添加 `NOT NULL` 约束,这个方法行不通。
5555

56-
**好消息:**如果我们只是需要一个"not null",而不考虑其具体定义,我们可以使用 `CHECK` 约束。`CHECK` 约束的好处在于,它的定义可以分为两个阶段:
56+
好消息:如果我们只是需要一个"not null",而不考虑其具体定义,我们可以使用 `CHECK` 约束。`CHECK` 约束的好处在于,它的定义可以分为两个阶段:
5757

5858
1. 首先,我们可以定义 `CHECK (col1 IS NOT NULL)` 并使用 `NOT VALID` ,这样操作很快,不会阻塞其他会话,因为不会立即检查现有的数据行 (不过仍会阻塞 — 它仍然是一个 ALTER TABLE,但只持续很短的时间;当然,仍然需要重试机制和较低的 lock_timeout,参照 [Zero-downtime Postgres schema migrations need this: lock_timeout and retries](https://postgres.ai/blog/20210923-zero-downtime-postgres-schema-migrations-lock-timeout-and-retries))。
5959
2. 然后,我们执行 `ALTER TABLE ... VALIDATE CONSTRAINT ...` 来进行校验,这一步虽然慢,但不会阻塞其他操作。
6060

61-
**坏消息:**由于我们的最终目标是重新定义主键,因此 `CHECK` 约束对我们无效,因为主键需要真正的 `NOT NULL` 约束。
61+
坏消息:由于我们的最终目标是重新定义主键,因此 `CHECK` 约束对我们无效,因为主键需要真正的 `NOT NULL` 约束。
6262

63-
**好消息:**在 PG12+ 中,有一项优化允许 `NOT NULL` 约束依赖于现有的 `CHECK (... IS NOT NULL)` 约束:
63+
好消息:在 PG12+ 中,有一项优化允许 `NOT NULL` 约束依赖于现有的 `CHECK (... IS NOT NULL)` 约束:
6464

6565
>Allow ALTER TABLE ... SET NOT NULL to avoid unnecessary table scans
6666
>

0 commit comments

Comments
 (0)