如何安全地重命名 PostgreSQL 中的序列,最好在不停机的情况下?

Hen*_*k N 5 postgresql sequence postgresql-9.5 rename

由于某些原因,我们想要重命名生产数据库中的某些序列。

有没有一种方法可以在生产中安全地执行此操作,而不必先关闭与数据库的所有连接?

如果我们在 ID 序列中出现间隙(例如,它从 ID 123 跳到 ID 200 或其他),那很好,但我们显然不希望长锁导致延迟/错误,也不希望有任何重复 ID 和类似的风险。

我们在 Heroku 上使用 PostgreSQL 9.5.21。

我们已经查看了文档,但仍然不确定运行的后果

ALTER SEQUENCE old_id_seq RENAME TO new_id_seq;
ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('new_id_seq');
Run Code Online (Sandbox Code Playgroud)

在生产中。我想一个风险是如果mytable这两个命令之间发生了事情。但如果我们这样做怎么办:

-- Starting at a much higher value than the currently highest ID.
CREATE SEQUENCE new_id_seq START 200;

ALTER TABLE mytable ALTER COLUMN id SET DEFAULT nextval('new_id_seq');

DROP SEQUENCE old_id_seq;
Run Code Online (Sandbox Code Playgroud)

这样做有什么风险?

Lau*_*lbe 5

  • 如果在表列的子句中使用序列DEFAULT,则重命名序列就足够了。

    这是因为该DEFAULT子句不是存储adbin为字符串,而是存储为解析的表达式树(目录中的列pg_attrdef)。该表达式树不包含序列的名称,而是包含其对象 ID,重命名序列后该对象 ID 不会发生变化。psql像s这样的工具会\d根据解析的表达式重新构造字符串,因此该DEFAULT子句将显示为反映了重命名。

  • 如果序列名称在其他地方使用,例如在客户端代码或 PostgreSQL 函数中,则必须更改该代码中的名称。PostgreSQL 函数存储为字符串(prosrc目录中的列pg_proc),因此重命名序列可能会使使用该序列的函数失败。

    在这种情况下,如果您想避免错误,则必须暂停活动,直到更改代码并重命名序列。