分区 table 上的 Postgres 错误(错误 42703 X 类型的属性 4 已被删除)
Postgres error on partitioned table (ERROR 42703 attribute 4 of type X has been dropped)
我正在将一个分区附加到我的分区 table 之一,但我收到一个我不明白的错误。
这是我创建分区的方式:
CREATE TABLE my_table_201906_partition (LIKE my_table_000000_partition
INCLUDING ALL)
这个 CREATE TABLE 工作正常。 my_table_000000_partition
是其父 my_table
的默认分区。
这就是我尝试将其附加到 table:
的方式
ALTER TABLE my_table ATTACH PARTITION my_table_201906_partition
FOR VALUES FROM ('2019-06-01 00:00:00+00') TO ('2019-07-01 00:00:00+00');
完整的错误是:
INFO: 00000: partition constraint for table "my_table_201906_partition" is implied by existing constraints
LOCATION: QueuePartitionConstraintValidation, tablecmds.c:14540
ERROR: 42703: attribute 4 of type my_table_000000_partition has been dropped
LOCATION: CheckVarSlotCompatibility, execExprInterp.c:1880
Time: 10.571 ms
知道错误的含义以及解决方法吗?
编辑:
amil 建议的查询结果
这是@amil 请求的查询:
select attrelid::regclass, attnum, attname
from pg_attribute
where attrelid in ('my_table'::regclass::oid,
'my_table_000000_partition'::regclass::oid)
and attnum > 0;
在下面的结果中,我弄乱了字段名称,但我注意将 some_field_1
调用到两个 table 的同一字段。字段 my_timestamp
是我用于范围分区的字段。
attrelid | attnum | attname
-------------------------------+--------+------------------------------
my_table_000000_partition | 1 | id
my_table_000000_partition | 2 | cust_id
my_table_000000_partition | 3 | some_field_1
my_table_000000_partition | 4 | ........pg.dropped.4........
my_table_000000_partition | 5 | my_timestamp
my_table_000000_partition | 6 | ........pg.dropped.6........
my_table_000000_partition | 7 | some_field_2
my_table_000000_partition | 8 | some_field_3
my_table_000000_partition | 9 | some_field_4
my_table_000000_partition | 10 | some_field_5
my_table_000000_partition | 11 | some_field_6
my_table_000000_partition | 12 | some_field_7
my_table_000000_partition | 13 | some_field_8
my_table_000000_partition | 14 | some_field_9
my_table_000000_partition | 15 | some_field_10
my_table_000000_partition | 16 | some_field_11
my_table | 1 | id
my_table | 2 | cust_id
my_table | 3 | some_field_1
my_table | 4 | my_timestamp
my_table | 5 | some_field_2
my_table | 6 | some_field_3
my_table | 7 | some_field_4
my_table | 8 | some_field_5
my_table | 9 | some_field_6
my_table | 10 | some_field_7
my_table | 11 | some_field_8
my_table | 12 | some_field_9
my_table | 13 | some_field_10
my_table | 14 | some_field_11
(30 rows)
我找到了附加新分区的解决方法:您需要先分离有问题的分区,然后再尝试附加新分区,然后重新附加有问题的分区:
CREATE TABLE my_table_201906_partition (LIKE my_table_000000_partition
INCLUDING ALL);
ALTER TABLE my_table DETACH PARTITION my_table_000000_partition;
ALTER TABLE my_table
ATTACH PARTITION my_table_201906_partition
FOR VALUES FROM ('2019-06-01 00:00:00+00') TO ('2019-07-01 00:00:00+00')
ALTER TABLE my_table ATTACH PARTITION my_table_000000_partition DEFAULT;
这样,旧分区的删除列就不会影响 ATTACH PARTITION ... FOR RANGE
命令。这意味着我不需要吸满 273GiB table.
此解决方法的唯一问题是您需要为每个要附加的分区执行此操作(直到错误解决)
编辑:
我认为 VACUUM FULL my_table_000000_partition
可以通过完全删除 "deleted" 列来永久解决问题,但是没有,错误仍然存在。
@MondoKin 的回答已经给出了一个解决方法,但让我添加一个关于错误的含义以及在这种情况下为什么会导致错误的答案。
此处看到的错误是 Postgres 执行程序在遇到使用关于 table 列的无效元数据构建的表达式时抛出的内部系统错误,在本例中是列值表达式引用 my_table_000000_partition
.
的删除属性
在涉及此类内部一致性检查的大多数情况下(几乎所有情况),用户不应期望他们会抛出错误。这种内部错误只能由损坏的内部状态(on-disk 或 in-memory)或 Postgres 的错误引起,在这种情况下,结果是后者。
谢天谢地,@MondoKin 向 Postgres 错误邮件列表报告了这个问题。如果感兴趣,请参阅此 link 到邮件列表存档:https://postgr.es/m/flat/15873-8c61945d6b3ef87c%40postgresql.org
我正在将一个分区附加到我的分区 table 之一,但我收到一个我不明白的错误。
这是我创建分区的方式:
CREATE TABLE my_table_201906_partition (LIKE my_table_000000_partition
INCLUDING ALL)
这个 CREATE TABLE 工作正常。 my_table_000000_partition
是其父 my_table
的默认分区。
这就是我尝试将其附加到 table:
的方式ALTER TABLE my_table ATTACH PARTITION my_table_201906_partition
FOR VALUES FROM ('2019-06-01 00:00:00+00') TO ('2019-07-01 00:00:00+00');
完整的错误是:
INFO: 00000: partition constraint for table "my_table_201906_partition" is implied by existing constraints
LOCATION: QueuePartitionConstraintValidation, tablecmds.c:14540
ERROR: 42703: attribute 4 of type my_table_000000_partition has been dropped
LOCATION: CheckVarSlotCompatibility, execExprInterp.c:1880
Time: 10.571 ms
知道错误的含义以及解决方法吗?
编辑:
amil 建议的查询结果
这是@amil 请求的查询:
select attrelid::regclass, attnum, attname
from pg_attribute
where attrelid in ('my_table'::regclass::oid,
'my_table_000000_partition'::regclass::oid)
and attnum > 0;
在下面的结果中,我弄乱了字段名称,但我注意将 some_field_1
调用到两个 table 的同一字段。字段 my_timestamp
是我用于范围分区的字段。
attrelid | attnum | attname
-------------------------------+--------+------------------------------
my_table_000000_partition | 1 | id
my_table_000000_partition | 2 | cust_id
my_table_000000_partition | 3 | some_field_1
my_table_000000_partition | 4 | ........pg.dropped.4........
my_table_000000_partition | 5 | my_timestamp
my_table_000000_partition | 6 | ........pg.dropped.6........
my_table_000000_partition | 7 | some_field_2
my_table_000000_partition | 8 | some_field_3
my_table_000000_partition | 9 | some_field_4
my_table_000000_partition | 10 | some_field_5
my_table_000000_partition | 11 | some_field_6
my_table_000000_partition | 12 | some_field_7
my_table_000000_partition | 13 | some_field_8
my_table_000000_partition | 14 | some_field_9
my_table_000000_partition | 15 | some_field_10
my_table_000000_partition | 16 | some_field_11
my_table | 1 | id
my_table | 2 | cust_id
my_table | 3 | some_field_1
my_table | 4 | my_timestamp
my_table | 5 | some_field_2
my_table | 6 | some_field_3
my_table | 7 | some_field_4
my_table | 8 | some_field_5
my_table | 9 | some_field_6
my_table | 10 | some_field_7
my_table | 11 | some_field_8
my_table | 12 | some_field_9
my_table | 13 | some_field_10
my_table | 14 | some_field_11
(30 rows)
我找到了附加新分区的解决方法:您需要先分离有问题的分区,然后再尝试附加新分区,然后重新附加有问题的分区:
CREATE TABLE my_table_201906_partition (LIKE my_table_000000_partition
INCLUDING ALL);
ALTER TABLE my_table DETACH PARTITION my_table_000000_partition;
ALTER TABLE my_table
ATTACH PARTITION my_table_201906_partition
FOR VALUES FROM ('2019-06-01 00:00:00+00') TO ('2019-07-01 00:00:00+00')
ALTER TABLE my_table ATTACH PARTITION my_table_000000_partition DEFAULT;
这样,旧分区的删除列就不会影响 ATTACH PARTITION ... FOR RANGE
命令。这意味着我不需要吸满 273GiB table.
此解决方法的唯一问题是您需要为每个要附加的分区执行此操作(直到错误解决)
编辑:
我认为 VACUUM FULL my_table_000000_partition
可以通过完全删除 "deleted" 列来永久解决问题,但是没有,错误仍然存在。
@MondoKin 的回答已经给出了一个解决方法,但让我添加一个关于错误的含义以及在这种情况下为什么会导致错误的答案。
此处看到的错误是 Postgres 执行程序在遇到使用关于 table 列的无效元数据构建的表达式时抛出的内部系统错误,在本例中是列值表达式引用 my_table_000000_partition
.
在涉及此类内部一致性检查的大多数情况下(几乎所有情况),用户不应期望他们会抛出错误。这种内部错误只能由损坏的内部状态(on-disk 或 in-memory)或 Postgres 的错误引起,在这种情况下,结果是后者。
谢天谢地,@MondoKin 向 Postgres 错误邮件列表报告了这个问题。如果感兴趣,请参阅此 link 到邮件列表存档:https://postgr.es/m/flat/15873-8c61945d6b3ef87c%40postgresql.org