В частности, в этом разделе postgres doc говорится, что я должен иметь возможность избежать сканирования раздела по умолчанию:
Перед выполнением команды ATTACH PARTITION рекомендуется создать ограничение CHECK для присоединяемой таблицы, соответствующее ожидаемому ограничению раздела, как показано выше. Таким образом, система сможет пропустить сканирование, которое в противном случае необходимо для проверки неявного ограничения раздела. Без ограничения CHECK таблица будет сканироваться для проверки ограничения раздела, удерживая блокировку ACCESS EXCLUSIVE для этого раздела. После завершения ATTACH PARTITION рекомендуется отбросить избыточное ограничение CHECK. Если присоединяемая таблица сама является многораздельной таблицей, то каждый из ее подразделов будет рекурсивно заблокирован и просканирован до тех пор, пока не встретится подходящее ограничение CHECK или не будут достигнуты конечные разделы.
Точно так же, если многораздельная таблица имеет раздел DEFAULT, рекомендуется создать ограничение CHECK, исключающее ограничение присоединяемого раздела. Если этого не сделать, то раздел DEFAULT будет просканирован, чтобы убедиться, что он не содержит записей, которые должны находиться в присоединяемом разделе. Эта операция будет выполняться при наложении блокировки ACCESS EXCLUSIVE на раздел DEFAULT. Если раздел DEFAULT сам по себе является секционированной таблицей, то каждый из его разделов будет рекурсивно проверяться таким же образом, как и присоединяемая таблица, как указано выше.
Но нижеследующее не работает для меня:
task_time
это not null
и относится к типу timestamp (6) with timezone
.
-- create new empty partition table
CREATE TABLE tasks_partitions.tasks_20230111
(LIKE tasks INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
-- add CHECK constraint on new partition
ALTER TABLE tasks_partitions.tasks_20230111 ADD CONSTRAINT tmp_20230111
CHECK (task_time >= '2023-01-11 00:00:00+00' AND task_time <= '2023-01-11 23:59:59.999999+00');
-- add CHECK constraint on default partition that excludes new partition constraint
ALTER TABLE tasks_partitions.tasks_20230111 ADD CONSTRAINT tmp20230111_default
CHECK (task_time < '2023-01-11 00:00:00+00' and task time > '2023-01-11 23:59:59.999999+00') NOT VALID;
-- attach partition
ALTER TABLE tasks ATTACH PARTITION tasks_partitions_tasks_20230111
FOR VALUES FROM ('2023-01-11 00:00:00+00') TO ('2023-01-11 23:59:59.999999+00')
Присоединение раздела по-прежнему удерживает AccessExclusiveLock
.
Удалил другой вопрос.
Эта операция всегда будет принимать блокировку ACCESS EXCLUSIVE
. Документация только говорит вам, как вы можете уменьшить время удерживания блокировки.
А что если нет раздела по умолчанию? В тестовом экземпляре я попытался отсоединить раздел по умолчанию, и все еще застрял в длительном сканировании и блокировке нового раздела для добавления. Правильно ли мое контрольное ограничение?
Это другой вопрос. Если столбец допускает значение NULL, ограничение также должно иметь проверку IS NOT NULL
.
Столбец не нулевой. Я могу открыть новый вопрос.
Для тех, кто смотрит на это в будущем, вот что я сделал: 1. Отсоедините раздел по умолчанию. 2. Переименуйте раздел по умолчанию. 3. Создайте новый пустой раздел для текущего диапазона дат. 4. Прикрепите новый пустой раздел для сегодняшнего диапазона дат. 5. Выберите данные на сегодняшнюю дату из старого раздела по умолчанию и в новый раздел для сегодняшнего диапазона дат. Я сделал это в одной транзакции, чтобы удерживать блокировку и предотвращать вставки или запросы к сегодняшнему диапазону дат, когда все данные не доступны. Затем я вернулся и создал разделы для старых данных и снова заполнил их из старой таблицы по умолчанию.
Раздел по умолчанию усложняет добавление новых разделов. Попробуйте обойтись без раздела по умолчанию.
Определенно хороший звонок, спасибо. Я отсоединил раздел по умолчанию для таблиц, которые я уже очистил, и решил проблему с созданием раздела. Теперь я создаю разделы через две недели каждый день с предупреждениями, если создание раздела не удается. Вот еще один вопрос, который я создал для ограничения новых разделов, не способных предотвратить сканирование и ACCESS EXCLUSIVE
блокировку: stackoverflow.com/questions/75100066/…
Пожалуйста, не делайте кросспост . Также спрашивали здесь: dba.stackexchange.com/questions/321918/…