Ошибка Postgres для многораздельной таблицы (ошибка 42703 атрибута 4 типа X была удалена) - PullRequest
2 голосов
/ 25 июня 2019

Я присоединяю раздел к одной из разделенных таблиц и получаю ошибку, которую не понимаю.

Вот как я создал свой раздел:

CREATE TABLE my_table_201906_partition (LIKE my_table_000000_partition
                                        INCLUDING ALL)

Этот CREATE TABLE работал нормально. my_table_000000_partition является разделом по умолчанию его родителя my_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

Есть идеи, что может означать ошибка и как ее решить?

Edit:

Результат запроса, предложенного 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 вызывал одно и то же поле обеих таблиц. Поле 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)

Ответы [ 2 ]

3 голосов
/ 26 июня 2019

@ Ответ MondoKin уже дает обходной путь, но позвольте мне добавить ответ о том, что означает ошибка и почему она возникла в этом случае.

Ошибка, наблюдаемая здесь, является внутренней системной ошибкой, выдаваемой исполнителем Postgres, когда он встречает выражение, созданное с использованием недопустимых метаданных о столбце таблицы, которое в данном случае является выражением значения столбца, которое ссылается на атрибут отбрасывания my_table_000000_partition .

В большинстве случаев, связанных с такими внутренними проверками согласованности (почти все), пользователи не должны ожидать появления ошибок. Такие внутренние ошибки могут быть вызваны только поврежденным внутренним состоянием (на диске или в памяти) или ошибкой Postgres ', которая в этом случае оказалась последней.

К счастью, @MondoKin сообщил об этой проблеме в список рассылки об ошибках Postgres. Посмотрите эту ссылку на архив списка рассылки, если вы заинтересованы: https://postgr.es/m/flat/15873-8c61945d6b3ef87c%40postgresql.org

1 голос
/ 26 июня 2019

Я нашел обходной путь для присоединения моего нового раздела к таблице без необходимости сначала VACUUM FULL my_table_000000_partition.

Решение состоит в том, чтобы отсоединить проблемный раздел перед попыткой присоединить новый раздел, а затем снова установить проблемный раздел:

 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. Это означает, что мне не нужно пылесосить стол 273 ГБ.

Единственная проблема, связанная с этим обходным решением, заключается в том, что вам нужно сделать это для каждого раздела, который вы хотите присоединить (до тех пор, пока ошибка не будет устранена)

...