Postgresql 12.5 «связь уже существует» при использовании «создать таблицу, если она не существует»

#postgresql #partition

Вопрос:

Я использую PostgreSQL 12.5 на AWS для миллионов событий. Мои таблицы разбиты на разделы изо дня в день, поэтому, когда приходит запрос, я использую «СОЗДАТЬ ТАБЛИЦУ, ЕСЛИ ОНА НЕ СУЩЕСТВУЕТ»… РАЗДЕЛ» синтаксис для каждого запроса.

Я ожидаю пропустить команду, если таблица уже существует. Но PostgreSQL этого не сделал. PostgreSQL пытался создавать таблицы несколько раз вместо того, чтобы пропускать.

Журналы ошибок PostgreSQL следующие

 2021-05-30 00:00:00 UTC:IP_ADDRESS(24921):dbname@username:[16666]:ERROR:  relation "tablename_20210530" already exists
2021-05-30 00:00:00 UTC:IP_ADDRESS(24921):dbname@username:[16666]:STATEMENT:  CREATE TABLE IF NOT EXISTS tablename_20210530 PARTITION OF tablename FOR VALUES FROM ('2021-05-30') TO ('2021-05-31')
 

Исключение SQL выглядит следующим образом;

 {
    "errorType": "error",
    "errorMessage": "relation "tablename_20210530" already exists",
    "code": "42P07",
    "length": 110,
    "name": "error",
    "severity": "ERROR",
    "file": "heap.c",
    "line": "1155",
    "routine": "heap_create_with_catalog",
    "stack": [
        "error: relation "tablename_20210530" already exists",
        "    at Parser.parseErrorMessage (/var/task/node_modules/pg-protocol/dist/parser.js:278:15)",
        "    at Parser.handlePacket (/var/task/node_modules/pg-protocol/dist/parser.js:126:29)",
        "    at Parser.parse (/var/task/node_modules/pg-protocol/dist/parser.js:39:38)",
        "    at Socket.<anonymous> (/var/task/node_modules/pg-protocol/dist/index.js:10:42)",
        "    at Socket.emit (events.js:315:20)",
        "    at addChunk (internal/streams/readable.js:309:12)",
        "    at readableAddChunk (internal/streams/readable.js:284:9)",
        "    at Socket.Readable.push (internal/streams/readable.js:223:10)",
        "    at TCP.onStreamRead (internal/stream_base_commons.js:188:23)"
    ]
}
 

Есть идеи, почему это происходит?

Версия PostgreSQL:

 PostgreSQL 12.5 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11), 64-bit
 

Схема Таблицы:

 create table tablename
(
    id bigint default nextval('tablename_partition_id_seq'::regclass) not null,
    col1 timestamp(0) default CURRENT_TIMESTAMP not null,
    col2 varchar(255) not null,
    constraint tablename_partition_pkey
        primary key (id, col1)
)
partition by RANGE ("col1");

create table tablename_20210530
partition of tablename
(
    constraint tablename_20210530_pkey
        primary key (id, col1)
)
FOR VALUES FROM ('2021-05-30 00:00:00') TO ('2021-05-31 00:00:00');
 

Инструкция SQL:

 CREATE TABLE IF NOT EXISTS tablename_20210530 PARTITION OF tablename FOR VALUES FROM ('2021-05-30') TO ('2021-05-31');
 

Мой код запускает инструкцию create перед инструкцией insert в соответствии с тысячами запросов. Потому что каждый запрос имеет другое значение «col1». И я не могу это контролировать. таким образом, инструкция create table выполняется каждый раз.

Комментарии:

1. Я не могу воспроизвести это ни с одной версией PostgreSQL. Пожалуйста, укажите свою версию PostgreSQL и приведите полный пример.

2. @LaurenzAlbe Я только что добавил версию и примеры.

3. После исправления ошибок в вашем SQL-скрипте (последовательность не существует, дублируется определение первичного ключа) я не смог воспроизвести проблему и получил NOTICE: relation "tablename_20210530" already exists, skipping . Либо вы делаете что-то другое, либо вы подключены не к той базе данных, или что-то в этом роде, или это не обычный PostgreSQL.

4. Спасибо за вашу поддержку. Я сожалею о схеме, я скопировал ее из инструмента IDE. Честно говоря, для нас это не важный случай, и наша логика могла бы справиться с ним, когда произошла эта ошибка. Кроме того, до сих пор мы никогда не получали этой ошибки. Я думаю, что это не просто ошибка. Может быть, это важно для кого-то, поэтому я создал этот вопрос. Мы используем это утверждение в течение длительного времени, и мы не получили никаких ошибок в разделе. Это может быть связано с нагрузкой. Потому что, как я уже сказал, PostgreSQL выполняет тысячи запросов в секунду.

5. Вы как-то изменили каталоги? В любом случае, не имея возможности воспроизвести проблему, мы не сможем ее решить.