Контролните точки могат да бъдат голямо препятствие за инсталациите на PostgreSQL с тежък запис. Първата стъпка към идентифициране на проблеми в тази област е да се следи колко често се случват, което наскоро получи по-лесен за използване интерфейс, добавен към базата данни.
Контролните точки са периодични операции по поддръжка, които базата данни извършва, за да се увери, че всичко, което е кешира в паметта, е синхронизирано с диска. Идеята е, че след като го завършите, можете да премахнете необходимостта да се притеснявате за по-стари записи, поставени в дневника за предварителна запис на базата данни. Това означава по-малко време за възстановяване след срив.
Проблемът с контролните точки е, че те могат да бъдат много интензивни, тъй като за завършване е необходимо записване на всеки един бит от променените данни в буферния кеш на базата данни на диска. Имаше редица функции, добавени към PostgreSQL 8.3, които ви позволяват да наблюдавате по-добре контролните точки и да ги намалите, като разпределите активността за по-дълъг период от време. Написах дълга статия за тези промени, наречена Checkpoints и Background Writer, която разглежда промените, но това е доста сухо четиво.
Това, което вероятно искате да знаете, е как да наблюдавате контролните точки на вашата производствена система и как да разберете ако се случват твърде често. Въпреки че нещата са се подобрили, "скокове на контролни точки", при които дисковият I/O става наистина тежък, все още са възможни дори в текущите версии на PostgreSQL. И не помага, че конфигурацията по подразбиране е настроена за много малко дисково пространство и бързо възстановяване при срив, а не за производителност. Параметърът checkpoint_segments, който е един вход за това колко често се случва контролна точка, е по подразбиране 3, което принуждава контролна точка след само 48MB запис.
Можете да разберете честотата на контролната точка по два начина. Можете да включите log_checkpoints и да наблюдавате какво се случва в регистрационните файлове. Можете също да използвате изгледа pg_stat_bgwriter, който дава преброяване на всеки от двата източника за контролни точки (преминаване на време и извършване на запис), както и статистика за това колко работа са свършили.
Основният проблем с това да улесните това Доскоро беше невъзможно да се нулират броячите вътре в pg_stat_bgwriter. Това означава, че трябва да направите моментна снимка с времеви печат, да изчакате известно време, да направите още една моментна снимка, след което да извадите всички стойности, за да извлечете полезна статистика от данните. Това е болка.
Стига мъка, че написах пластир, за да го улесня. С текущата версия за разработка на базата данни, вече можете да извикате pg_stat_reset_shared(‘bgwriter’) и да върнете всички тези стойности обратно на 0. Това позволява да се следва практика, която е била често срещана в PostgreSQL. Преди 8.3 имаше параметър с име stats_reset_on_server_start, който можете да включите. Това нулира всички вътрешни статистически данни на сървъра всеки път, когато го стартирате. Това означаваше, че можете да извикате удобната функция pg_postmaster_start_time(), да сравните с текущото време и винаги да имате точен брой операции/секунда на всяка налична статистика в системата.
Все още не е автоматично, но сега че нулирането на тези споделени части е възможно, можете да го направите сами. Първият ключ е да интегрирате изчистването на статистиката в последователността на стартиране на вашия сървър. Скрипт като този ще работи:
pg_ctl start -l $PGLOG -w
psql -c "select pg_stat_reset();"
psql -c "select pg_stat_reset_shared('bgwriter');"
Обърнете внимание на "-w" на командата за стартиране там – това ще накара pg_ctl да изчака, докато сървърът приключи със стартирането, преди да се върне, което е жизненоважно, ако искате незабавно да изпълните оператор срещу него.
Ако сте го направили това и началният час на вашия сървър е по същество същият като когато фоновата статистическа информация е започнала събирането на данни, вече можете да използвате тази забавна заявка:
SELECT
total_checkpoints,
seconds_since_start / total_checkpoints / 60 AS minutes_between_checkpoints
FROM
(SELECT
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time())) AS seconds_since_start,
(checkpoints_timed+checkpoints_req) AS total_checkpoints
FROM pg_stat_bgwriter
) AS sub;
И получете прост отчет за това колко често се случват контролни точки във вашата система. Резултатът изглежда така:
total_checkpoints | 9
minutes_between_checkpoints | 3.82999310740741
Това, което правите с тази информация, е да гледате средния интервал от време и да видите дали не изглежда твърде бързо. Обикновено бихте искали контролна точка да се случва не повече от всеки пет минути, а при натоварена система може да се наложи да я увеличите до десет минути или повече, за да имате надежда да се справите. С този пример всеки 3,8 минути вероятно е твърде бърз – това е система, която се нуждае от checkpoint_segments, за да бъде по-висока.
Използването на тази техника за измерване на интервала на контролната точка ви позволява да знаете дали трябва да увеличите параметрите checkpoint_segments и checkpoint_timeout, за да за постигане на тази цел. Можете да изчислите числата ръчно в момента и след като 9.0 се пусне, това е нещо, което можете да обмислите да направите напълно автоматично – стига да нямате нищо против статистиките ви да изчезват всеки път, когато сървърът се рестартира.
Има някои други интересни начини за да анализирам данните, които фоновият редактор ви предоставя в pg_stat_bgwriter, но днес няма да раздам всичките си трикове.