#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. Вы как-то изменили каталоги? В любом случае, не имея возможности воспроизвести проблему, мы не сможем ее решить.