Open ohmycto opened 5 years ago
@secoint сделайте вызов функции select set_enable_parent('visitors', false)
. После partition pruning должен заработать
@maksm90 нет, это не помогает.
@maksm90 нет, это не помогает.
Покажите вывод select * from pathman_config_params where partrel = 'visitors'::regclass
select * from pathman_config_params where partrel = 'visitors'::regclass;
partrel | enable_parent | auto | init_callback | spawn_using_bgw
----------+---------------+------+---------------+-----------------
visitors | f | t | | f
(1 строка)
select * from pathman_config_params where partrel = 'visitors'::regclass; partrel | enable_parent | auto | init_callback | spawn_using_bgw ----------+---------------+------+---------------+----------------- visitors | f | t | | f (1 строка)
А теперь вывод:
explain update visitors set updated_at = now() where id = 1 and account_id = 1
explain delete from visitors where id = 1 and account_id = 1
и ещё
table pathman_concurrent_part_tasks
explain update visitors set updated_at = now() where id = 1 and account_id = 1
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Update on visitors (cost=0.57..258.79 rows=101 width=2750)
Update on visitors
Update on visitors_0
Update on visitors_1
Update on visitors_2
...
Update on visitors_99
-> Index Scan using visitors_pkey on visitors (cost=0.57..2.99 rows=1 width=2936)
Index Cond: (id = 1)
Filter: (account_id = 1)
-> Index Scan using visitors_0_account_id_idx on visitors_0 (cost=0.42..2.45 rows=1 width=3121)
Index Cond: (account_id = 1)
Filter: (id = 1)
...
(405 строк)
explain delete from visitors where id = 1 and account_id = 1
-- совершенно аналогично update
table pathman_concurrent_part_tasks;
userid | pid | dbid | relid | processed | status
--------+-----+------+-------+-----------+--------
(0 строк)
Хм, у меня ваш кейс не воспроизводится. Может проблема в триггере? Он у вас поставлен только на родительскую таблицу?
Нет, все таблицы имеют триггеры:
\d+ visitors_80
...
Ограничения-проверки:
"pathman_visitors_80_check" CHECK (get_hash_part_idx(hashint4(account_id), 100) = 80)
Наследует: visitors
Вы ранее дали совет обновиться, потом убрали его. Это не поможет?
Хм, у меня ваш кейс не воспроизводится. Может проблема в триггере? Он у вас поставлен только на родительскую таблицу?
Прошу прощения, вы же про триггер, а не про ограничения... да, триггер только на родительской:
\d visitors
...
Триггеры:
search_columns_update BEFORE INSERT OR UPDATE ON visitors FOR EACH ROW EXECUTE PROCEDURE visitors_search_trigger()
Дочерних таблиц: 100 (чтобы просмотреть и их, воспользуйтесь \d+)
На дочерних триггеров нет.
Вы ранее дали совет обновиться, потом убрали его. Это не поможет?
На вашей версии pg_pathman у меня partition pruning тоже cрабатывает
триггер только на родительской
Походу, проблема в нём. Мне нужно тогда подольше времени, чтобы воспроизвести ваш кейс.
На staging-сервере на тестовой базе обновили pg_pathman 1.4.12 => 1.4.13 и это сработало! UPDATE/DELETE ходят только в нужные партиции! Сейчас ещё поэкспериментирую и попробуем в основной базе.
К сожалению в продакшене обновление не помогло. Видимо там что-то с базой. Я написал на info@postgrespro.ru запрос о помощи.
@maksm90
Походу, проблема в нём. Мне нужно тогда подольше времени, чтобы воспроизвести ваш кейс.
Может ли быть такое, что работает не правильно из-за того, что процесс VACUUM ANALYZE convead.visitors;
ещё не завершился? Таблица была порядка 150 Gb и он идёт уже 4+ часа после разбиения на партиции.
Может ли быть такое, что работает не правильно из-за того, что процесс
VACUUM ANALYZE convead.visitors;
ещё не завершился? Таблица была порядка 150 Gb и он идёт уже 4+ часа после разбиения на партиции.
Возможно, надо смотреть
VACUUM прошёл, ситуация в целом немного изменилась: теперь команда select set_enable_parent('visitors', false)
действительно меняет поведение и планировщик начинает смотреть только в нужную партицию, но когда я это делаю, начинают сыпаться совершенно безобидные запросы с ошибкой variable not found in subplan target list
. Приходится возвращать настройку обратно. Но в любом случае даже с включенной родительской таблицей должно не так ведь работать, должна быть лишь +1 строка в плане.
VACUUM прошёл, ситуация в целом немного изменилась: теперь команда
select set_enable_parent('visitors', false)
действительно меняет поведение и планировщик начинает смотреть только в нужную партицию, но когда я это делаю, начинают сыпаться совершенно безобидные запросы с ошибкойvariable not found in subplan target list
. Приходится возвращать настройку обратно. Но в любом случае даже с включенной родительской таблицей должно не так ведь работать, должна быть лишь +1 строка в плане.
Согласен. Мы рассмотрим проблему partition pruning при включенном родителе. А заодно дополним partition_table_concurrently
, чтобы родитель выключался после окончания разброса записей по секциям. И разберёмся с vacuum родительской таблицы и активностью родителя при нём.
Спасибо за кейс. @arssher FYI
Problem description
Есть таблица
visitors
с колонкойaccount_id
.Таблица была разбита на 100 партиций по хэш-функции от
account_id
следующим образом:Всё разбилось, данные разложились. Пример дочерней таблицы:
Проблема
При UPDATE и DELETE запросах, не смотря на явное указание ключа партиции, планировщик просматривает все 100 партиций, например:
При этом SELECT-запросы работают нормально:
Environment