|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
Всем дорого времени суток. В ходе эксперимента возник такой вопрос при партицировании по блокировкам. Данные и примеры беру отсюда https://postgrespro.ru/docs/postgresql/12/ddl-partitioning -- Создание партицированной таблицы CREATE TABLE test.measurement ( city_id int not null, logdate date not null, peaktemp int, unitsales int ) PARTITION BY RANGE (logdate); -- Создание секций/партиций CREATE TABLE measurement_y2006m02 PARTITION OF test.measurement FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'); CREATE TABLE measurement_y2006m03 PARTITION OF test.measurement FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'); ... CREATE TABLE measurement_y2007m11 PARTITION OF test.measurement FOR VALUES FROM ('2007-11-01') TO ('2007-12-01'); CREATE TABLE measurement_y2007m12 PARTITION OF test.measurement FOR VALUES FROM ('2007-12-01') TO ('2008-01-01'); CREATE TABLE measurement_y2008m01 PARTITION OF test.measurement FOR VALUES FROM ('2008-01-01') TO ('2008-02-01'); Теперь Эксперимент: В 1-ой сессии выполняем BEGIN; SELECT count(*) FROM test.measurement WHERE logdate = DATE '2008-01-01'; Во 2-ой сессии делаем отдельную табличку CREATE TABLE test.measurement_y2017m01 (LIKE test.measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS); тут же делаем еще begin; ALTER TABLE test.measurement ATTACH PARTITION test.measurement_y2017m01 FOR VALUES FROM ('2017-01-01') TO ('2017-02-01'); и все напрочь зависает до тех пор, пока в 1-ой сессии не сделаем commit. Перед attach также пробовал делать ALTER TABLE test.measurement_y2017m01 ADD CONSTRAINT y2017m01 CHECK ( logdate >= DATE '2017-01-01' AND logdate < DATE '2017-02-01' ); но и это не помогает. По идее такого не должно быть. Так же плотно рассматривал интереснейшую статью на хабре https://habr.com/ru/company/postgrespro/blog/456716/ Но ни по справке, ни по статье с хабра у меня не получается обойти блокировку. Если у кого-то был аналогичный удачный опыт, то поделитесь пожалуйста. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2020, 19:44 |
|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
VladimirDz, Любой alter table требует блокировки на ту таблицу что alter им а открытые запросы этому мешают. Вы никакой alter table test.measurement не внесете пока есть открытые транзакции которые с ней работают. Это прекрасно все документировано https://www.postgresql.org/docs/12/explicit-locking.html#LOCKING-TABLES -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
17.08.2020, 19:52 |
|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
VladimirDz Теперь Эксперимент: В 1-ой сессии выполняем BEGIN; SELECT count(*) FROM test.measurement WHERE logdate = DATE '2008-01-01'; Во 2-ой сессии делаем отдельную табличку CREATE TABLE test.measurement_y2017m01 (LIKE test.measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS); тут же делаем еще begin; ALTER TABLE test.measurement ATTACH PARTITION test.measurement_y2017m01 FOR VALUES FROM ('2017-01-01') TO ('2017-02-01'); и все напрочь зависает до тех пор, пока в 1-ой сессии не сделаем commit. Я даже повторил эксперимент. Ничего в этом месте не повисает, всё работает. Отключить (detach) секцию без блокировки запросов нельзя, а подключить можно. Всё что могу предположить, что эксперимент проводите на версии меньше чем 12-я? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2020, 07:44 |
|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
Maxim Boguk Вы никакой alter table test.measurement не внесете пока есть открытые транзакции которые с ней работают. В 12-й версии для alter table .. attach partition понизили уровень блокировки на родительскую таблицу до SHARE UPDATE EXCLUSIVE. Это позволяет параллельно выполнять dml запросы к таблице. А вот для отключения секции (detach partition) по-прежнему требуется ACCESS EXCLUSIVE. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2020, 07:54 |
|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
Спасибо Павел Лузанов, так и есть. Я вчера действительно ошибся с версией. Пробовал на 11-ой. Сегодня поставил 12-ую и провел эксперимент. Все удачно. Еще раз привожу детали (теперь уже успешного эксперимента) ! Только для 12-ой версии постгреса в 1-ой сессии делаем блокировку так: BEGIN; SELECT count(*) FROM test.measurement WHERE logdate > DATE '2007-01-01'; проверяем в 1-ой SELECT relation::regclass::text, mode FROM pg_locks WHERE pid = pg_backend_pid() AND relation::regclass::text LIKE 'test.measurement%'; Получаем: -------------------------------------- relation | mode -------------------------------------- test.measurement | AccessShareLock -- во 2-ой сесии делаем отдельную табличку CREATE TABLE test.measurement_y2017m01 (LIKE test.measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS); и появляется отдельная табличка -- тоже во 2-ой сессии begin; ALTER TABLE test.measurement ATTACH PARTITION test.measurement_y2017m01 FOR VALUES FROM ('2017-01-01') TO ('2017-02-01'); -- Проверяем во 2-ой блокировки SELECT relation::regclass::text, mode FROM pg_locks WHERE pid = pg_backend_pid() AND relation::regclass::text LIKE 'test.measurement%'; Получаем ---------------------------------------------------------------------- relation | mode ---------------------------------------------------------------------- test.measurement | ShareUpdateExclusiveLock ---------------------------------------------------------------------- test.measurement_y2017m01 | AccessExclusiveLock ---------------------------------------------------------------------- во 2-ой commit; И секция добавляется.!!! Вспоминаем про первую сессию, которая все еще висит теперь можно и в 1-ой сделать. commit; P.S. А вот DROP TABLE test.measurement_y2017m01; действительно так и не будет работать, пока в первой сессии не сделаем комит (то есть пока висит 1-ая сессия удалить партицию не получится). ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2020, 09:45 |
|
Блокировка при секционировании
|
|||
---|---|---|---|
#18+
Сейчас еще с truncate попробовал провести такой же трюк. то есть завеил первую сессию и пока она висит во второй сделал truncate. Этот номер не проходит, вторая сессия с truncate будет висеть пока первая сиссия не будет закомичена. Еще раз спасибо Павлу за его материалы и ответы. Помогло очень разобраться. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.08.2020, 10:04 |
|
|
start [/forum/topic.php?fid=53&fpage=24&tid=1994517]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
34ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
42ms |
get tp. blocked users: |
2ms |
others: | 284ms |
total: | 402ms |
0 / 0 |