由于某些原因,我们想重命名生产数据库中的一些序列。
有没有办法在生产中安全地做到这一点,而不必先关闭与数据库的所有连接?
如果我们在 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');
在生产中。我想一个风险是如果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;
这样做有什么风险?
如果在
DEFAULT
表列的子句中使用了序列,重命名序列就足够了。那是因为
DEFAULT
子句不是作为字符串存储的,而是作为解析后的表达式树(adbin
目录中的列pg_attrdef
)存储的。该表达式树不包含序列的名称,但它的对象 ID,通过重命名序列不会改变。psql
' 之类的工具\d
从解析的表达式中重新构造一个字符串,因此该DEFAULT
子句将显示为反映重命名。如果序列名称在其他地方使用,例如在您的客户端代码或 PostgreSQL 函数中,您必须更改该代码中的名称。PostgreSQL 函数存储为字符串(
prosrc
catalog 中的列pg_proc
),因此重命名序列可能会使使用该序列的函数失败。在这种情况下,如果您想避免错误,您将不得不暂停活动,直到您更改代码并重命名序列。
我认为上述方法不能解决您的问题。在这两种情况下,PostgreSQL 都将获取表上的锁,并且应用程序必须等待 ALTER 命令完成。
上面的命令应该很快,你不需要跟随
重命名序列后。PostgreSQL 内部知道名称已更改。