172 похожих чатов

Привет, уткнулся я в проблему с партицированной таблицой. Таблица средне

большая 10Тб где-то.

Хотелось добавить бы (нуллабл и нет) колонку, но на таблицу берется write lock (пробовал на стейдже - все записи остановились и какбы нехорошо, сервисы попадают держать все в памяти).

Я так прикидываю ALTER ADD COLUMN займет 20 мин что много, есть варианты как это решить?

Из самого адекватного пришло такое: создать новую пустую партицированную таблицу с желаемыми колонками, и каждую партицию отцепить, добавить колонки и подцепить к новой. Муторно, но вроде заработает.

Есть варианты проще?

20 ответов

20 просмотров

Вообще, если не указывать параметр default value, то добавление колонки происходит очень быстро.

Oleg-Kovalov Автор вопроса
Роман Жарков
Вообще, если не указывать параметр default value, ...

всегда жил с такой мыслью, пока не сделал: ATLER TABLE foo ADD COLUMN bar DECIMAL; и не увидел падение записей по всем сервисам UPD: не это прикол какой-то, я только что повторил этот запрос (отмененный ранее) и оно отработало за полсекунды, втф

Oleg-Kovalov Автор вопроса
Oleg Kovalov
всегда жил с такой мыслью, пока не сделал: ATLER ...

хм, ПГ пересчитал какие-то статистики или что? я не троль: cryptowatch=> ALTER TABLE foo ADD COLUMN temp_test_column DECIMAL; ^CCancel request sent ERROR: canceling statement due to user request Time: 132392.104 ms (02:12.392) cryptowatch=> ALTER TABLE foo ADD COLUMN temp_test_column DECIMAL; ALTER TABLE Time: 663.706 ms cryptowatch=>

Oleg Kovalov
всегда жил с такой мыслью, пока не сделал: ATLER ...

Ему нужна эксклюзивная(?) блокировка на таблицу и оно будет ждать окончания всех пишущих транзакций. На это время действительно всё остановится. Автовакуум очень сильно умеет в длинные блокировки. Надо успеть «проскочить» с DDL. Есть даже набор крутилок для этого, но я по памяти не помню и не готов их искать.

Oleg-Kovalov Автор вопроса
Роман Жарков
Ему нужна эксклюзивная(?) блокировка на таблицу и ...

хм, то есть это неболее чем мое невезение? попать на блок в 2 минуты, а буквально на следующий раз в полсекунды? прикольно. осталось понять что мне ждать на проде, в цикле пробовать АЛЬТЕР и если не прошел за 10сек - отменять и повторять?)

Oleg Kovalov
хм, то есть это неболее чем мое невезение? попать ...

Ну, я не большой специалист, но общая канва такая :)

Oleg-Kovalov Автор вопроса
Роман Жарков
Ну, я не большой специалист, но общая канва такая ...

ок, походу я попробую еще подобавлять больше колонок в таблицу и посмореть поведение, спасибо что стейдж и прод 1к1 по объему. спасибо)

Oleg Kovalov
хм, то есть это неболее чем мое невезение? попать ...

насколько я понял, общая практика примерно такая: поставить statement_timeout в < 1 секунды и пытаться добавить колонку в цикле, пока не получится, на всякий случай с ограничением скажем в 1000 попыток.

Oleg-Kovalov Автор вопроса
Ilya Portnov
насколько я понял, общая практика примерно такая: ...

угу, походу, я такое встречал, но думал это больше паранойя, а вот оно как..спасибо за подсказку)

На самом деле дажэ с константным default value оно отработает такжэ быстро (ну, дождётся завершэния всех предыдущих транзакцый, которые использовали эту таблицу, чтобы получить свой лок).

Oleg-Kovalov Автор вопроса
Ilya Anfimov
На самом деле дажэ с константным default value оно...

ага, с 11 или 13й должно быть ок уже, но все равно не мой кейз) мне без дефолта пока добавить надо

Oleg Kovalov
хм, то есть это неболее чем мое невезение? попать ...

Вообще -- можно заранее посмотреть в pg_stat_activity, как там сейчас с блокировками этой таблицы. Ну и да, общая идея -- такая. Можно дажэ пару секунд таймаута, а не 10 -- если каталог в памяти (а на активно используемой базе он в памяти) -- то пройдёт и быстрее, чем за пару секунд.

Oleg-Kovalov Автор вопроса
Ilya Anfimov
Вообще -- можно заранее посмотреть в pg_stat_activ...

она постоянно юзается, может где-то рано утром там мало транзакций еще будет, но не уверен что это сильно поможет, ретрай кажется более чотким решением

Oleg Kovalov
она постоянно юзается, может где-то рано утром там...

pg_locks, кстати, а не pg_stat_activity. И да, смотреть -- кто держыт локи на эту таблицу и сколько он ужэ это делает. Если полчаса кто-то держыт, то, скорее всего, быстро не отдаст. Если миллисекунды -- то наоборот.

Oleg-Kovalov Автор вопроса
Ilya Anfimov
pg_locks, кстати, а не pg_stat_activity. И да, см...

там все краткосрочное, только 1 писатель (ну 1 сервис) и там коротенькие COPY и ничего другого

Oleg Kovalov
там все краткосрочное, только 1 писатель (ну 1 сер...

Значит, должно за секунду отработать. А где 10 секунд -- смотрите pg_stat_activity и pg_locks, на ком оно там висит.

Oleg-Kovalov Автор вопроса
Ilya Anfimov
Значит, должно за секунду отработать. А где 10 се...

буду мониторить, есть уже 1 подозреваемый после пары минут размышлений, спасибо)

Oleg Kovalov
там все краткосрочное, только 1 писатель (ну 1 сер...

А, кстати "1 писатель" -- в смысле все остальные читатели? Это тожэ важно, блокировка эксклюзивная и требует закончить всех читателей тожэ.

Oleg-Kovalov Автор вопроса
Ilya Anfimov
А, кстати "1 писатель" -- в смысле все остальные ч...

хм, мне казалось только write лочится, риды могут дальше работать (и метрики это подтверждали, только записи зависли) я все больше склоняюсь, что это был вакуум

Oleg-Kovalov Автор вопроса
Ilya Anfimov
А, кстати "1 писатель" -- в смысле все остальные ч...

да, проверили, BEGIN READ ONLY; и в другой сессии ALTER TABLE и все виснет, для меня это новость ,я на такое не напарывался (хотя в таком поведении есть смысл) чувствую дикий стыд за себя

Похожие вопросы

Обсуждают сегодня

30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
~ 2m21s  nix shell github:nixos/nixpkgs#stack ~  stack ghc -- --version error: … while calling the 'derivationStrict' builtin at /builtin/derivation.nix:...
Rebuild your mind.
6
Карта сайта