Комментарии 20
Не, так не бывает, контрольные точки одна на другую никогда не нахлестываются. Сначала завершается одна, потом может начинаться другая.
Это, мне кажется, неправильная постановка вопроса. Если у нас работает контрольная точка (неспеша) и мы видим, что размер журнала приближается к пороговому значению, то нам не надо ни прерывать текущую точку, ни сразу после нее запускать следующую. Надо просто продолжить выполнение текущей, но ускориться.
Там какой-то такой адаптивный механизм и реализован. Деталей я сходу не вспомню, но если интересно, могу покопаться.
Надо просто продолжить выполнение текущей, но ускориться.
Ускорение ведь возможно вроде бы только за счет увеличения расходуемых ресурсов железа и то, наверное, есть предел распараллеливания, обусловленный самим алгоритмом.
Думаю тут интереснее в первую очередь не внутренности алгоритма, а возможность деградации производительности системы в связи с неоптимальным процессом выполнения контрольных точек.
Правильно ли я понял, что процесс checkpointer это популярный кандидат (один из кандидатов) на оптимизацию, если вдруг система «ни с того ни с сего» начала работать медленнее?
Ускорение возможно за счет того, что в обычном режиме контрольная точка не пишет данные на максимальной скорости. Она должна успеть записать все грязные буферы за время checkpoint_timeout × checkpoint_completion_target. Процесс сам регулирует задержки, чтобы уложиться в этот интервал. А когда надо ускориться, уменьшает задержку.
Проблема будет в том случае, когда даже на максимальной скорости контрольная точка не успевает уложиться в заданные рамки. Тогда надо либо сознательно увеличивать интервал (если он неоправданно маленький), либо колдовать с настройками ОС и железом. А со стороны PostgreSQL там оптимизировать-то нечего. Только не делать контрольные точки чаще, чем нужно.
Или алгоритм настолько умен, что даже рост нагрузки за счет ускорения можно прогнозировать? Вернее, есть параметр, ограничивающий его ресурсы, который я упустил, когда читал статью
Нет, никаких других ограничителей, кроме названных, нет.
Насчет деградации вопрос спорный. Сама по себе контрольная точка не начнет молотить быстрее, только если не возрастет нагрузка и можно будет не успеть. Поэтому теоретически должна быть не деградация, а просто некий предел производительности системы.
А деградация (как внезапный провал) будет в том случае, если ОС долго откладывает физическую запись на диск и потом начинает писать сразу и много. Мне это так видится.
В этом смысле любой фоновый асинхронный процесс — это хорошо, потому что нагружает систему равномерно. А любая синхронная деятельность (когда нельзя продолжать, пока что-то не сделано) — наоборот, плохо.
В заключение все нежурналируемые таблицы перезаписываются с помощью образов в init-файлах.
имеются ввиду слои init, которые остались на диске на момент отказа системы? Могут ли они быть повреждены, ведь они могут быть в неконсистентном состоянии (на то и WAL для других операций)
Конечно, ведь нельзя допустить, чтобы страница изменилась, пока ее записывают. Но читать ее ничто не мешает.
А если страница вытесняется на диск с целью заменить ее на новую с диска (все страницы буффера заняты, требуется вытеснение)? В этом случае «можно читать» вероятно, не работает, потому что содержимое страницы в какой-то момент полностью будет изменено.
Закрепление (aka pin) используется, когда процесс работает со страницей. При этом страницу можно не только читать, но и изменять в некоторых пределах. Но вытеснять нельзя — закрепление этого не позволяет.
Но в данном случае используется не закрепление, а другая блокировка, которая не дает странице меняться. Я про блокировки планирую подробно написать, как только с журналом закончу.
Будьте добры, ткните еще раз в объяснение такого факта:
чем реже можно позволить себе контрольные точки, тем лучше — это сокращает накладные расходы
логика, схожая с автовакуумом, здесь судя по всему не применима, когда лучше чаще на большие таблицы натравливать автовакуум, чтобы в один момент обрабатывать меньшее кол-во страниц.
В любом случае грязные страницы в буферном кэше должны попасть на диск. Только при увеличении checkpoint_timeout'a кол-во этих страниц будет больше на каждый чекпоинт. Или нет?
Что я упускаю? О каких именно накладных расходах речь?
Спасибо
Ой, я почему-то пропустил ваш комментарий. Но лучше поздно...
Накладные расходы связаны с двумя вещами.
Во-первых, контрольная точка не просто записывает грязные страницы, но и синхронизирует изменения с диском. Чем реже это происходит, тем меньше ввод-вывод. При короткой контрольной точке только успели поменять страницу — уже надо писать на диск. А при длинной страница может многократно измениться, и потом один раз записаться.
Во-вторых, при первом изменении страницы после завершения контрольной точки в журнал пишется полный образ (FPI, full page image). Это нужно, чтобы защититься от неатомарной записи страницы в случае сбоя. Поэтому чем реже контрольные точки, тем реже пишется FPI и тем меньше размер журнала.
Все это, конечно, в предположении, что одна и та же страница меняется неоднократно на протяжении какого-то времени.
Только при увеличении checkpoint_timeout'a кол-во этих страниц будет больше на каждый чекпоинт.
Тут не на количество надо смотреть, а на скорость. Да, страниц наверное будет больше, но и времени на их запись тоже больше. Поэтому поток примерно одинаковый.
WAL в PostgreSQL: 3. Контрольная точка