我有一些表格在PostgreSQL 12.9中被声明为类似以下代码:
-- This table is written in old style
create table old_style_table_1 (
id bigserial not null primary key,
...
);
-- This table uses new feature
create table new_style_table_2 (
id bigint generated by default as identity,
...
);
第二个表格似乎是使用在第10版本中引入的identity标识进行声明的。
时间流逝,我们已经对旧表进行了分区,同时保留了原始序列:
CREATE TABLE partitioned_old_style_table_1 (LIKE old_style_table_1 INCLUDING DEFAULTS) PARTITION BY HASH (user_id);
CREATE TABLE partitioned_new_style_table_2 (LIKE new_style_table_2 INCLUDING DEFAULTS) PARTITION BY HASH (user_id);
他们的 id
列的数据定义语言(DDL)似乎是 id bigint default nextval('old_style_table_1_id_seq') not null
和 id bigint default nextval('new_style_table_2_id_seq') not null
。
到目前为止,一切都运作良好。分区表证明是一个巨大的福音,我们决定通过删除它们来淘汰旧表。
DROP TABLE old_style_table_1, new_style_table_2;
-- [2BP01] ERROR: cannot drop desired object(s) because other objects depend on them
-- Detail: default value for column id of table old_style_table_1 depends on sequence old_style_table_1_id_seq
-- default value for column id of table new_style_table_2 depends on sequence new_style_table_2_id_seq
在一番思考后,我发现在 Postgres 中,序列可能拥有所有者,因此我选择更改它们:
ALTER SEQUENCE old_style_table_1_id_seq OWNED BY partitioned_old_style_table_1.id;
DROP TABLE old_style_table_1;
-- Worked out flawlessly
ALTER SEQUENCE new_style_table_2_id_seq OWNED BY partitioned_new_style_table_2.id;
ALTER SEQUENCE new_style_table_2_id_seq OWNED BY NONE;
-- Here's the culprit of the question:
-- [0A000] ERROR: cannot change ownership of identity sequence
所以,显然这个列的 pg_attribute.attidentity 被设置为 'd'
,这使我不能:
• 改变该列的默认值:
ALTER TABLE new_style_table_2 ALTER COLUMN id SET DEFAULT 0;
-- [42601] ERROR: column "id" of relation "new_style_table_2" is an identity column
• 删除默认值:
ALTER TABLE new_style_table_2 ALTER COLUMN id DROP DEFAULT;
-- [42601] ERROR: column "id" of relation "new_style_table_2" is an identity column
-- Hint: Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead.
• 放弃标识、列或整个表(新表已依赖序列):
ALTER TABLE new_style_table_2 ALTER COLUMN id DROP IDENTITY IF EXISTS;
-- or
ALTER TABLE new_style_table_2 DROP COLUMN id;
-- or
DROP TABLE new_style_table_2;
-- result in
-- [2BP01] ERROR: cannot drop desired object(s) because other objects depend on them
-- default value for column id of table partitioned_new_style_table_2 depends on sequence new_style_table_2_id_seq
我查阅了文档,它提供了设置 SET IDENTITY
或 ADD IDENTITY
的方法,但没有提供取消或更改为一次性序列的方法,而不是试图删除现有序列。
➥ 那么,我如何从列-序列对中删除身份标识,以便它不会影响使用此序列的其他表?
更新:在本地主机上运行了UPDATE pg_attribute SET attidentity='' WHERE attrelid=16816;
,仍然收到[2BP01]
和[0A000]
错误信息。:/
尽管我设法执行了DROP DEFAULT
值部分,但似乎走到了死胡同。
START
似乎只接受文字,不接受SELECT nextval('old_sequence')
这样的语句。我不喜欢手动操作生产数据库的想法,但我也没有访问pg_catalog
的权限,所以...好吧,谢谢。:D - XobotunBIGINT
,10^5的增量与其10^19的范围相比微不足道。尽管如此,我们的部署实践非常严格,这意味着新版本需要在测试环境中“沉睡”一两天,以收集性能数据并记录新的错误。由于现在和迁移应用于生产之间的时间跨度,冒险出现不一致的ID似乎比停机五分钟更糟糕。至少我是这么认为的,在这个项目上也是如此。 :D 谢谢,我今天会与团队讨论这个问题。也许我们会将这些未使用的表截断直到某个停机时间... - Xobotun