PostgreSQL имеет множество конфигураций. Внесение изменений в эти конфигурации иногда может привести к проблемам или даже остановить запуск сервера.
Кроме того, конфигурация может быть изменена, но еще не применена. Это может легко привести к тому, что мы изменим конфигурацию, перезагрузим или перезапустим сервер, а затем столкнемся с проблемой, не связанной с нашим изменением.
Но хорошей новостью является то, что PostgreSQL предоставил инфраструктуру для проверки наличия ошибки в конфигурации, чтобы ее можно было исправить до перезагрузки или перезапуска сервера.
Способы корректировки конфигураций PostgreSQL
- Редактирование файлов конфигурации
- Использование
ALTER SYSTEM
Проверка наличия ошибок в конфигурации
Приведенный ниже SQL-запрос можно использовать для проверки ошибок в конфигурации
SELECT name, sourcefile, sourceline, setting, error FROM pg_catalog.pg_file_settings WHERE error IS NOT NULL;
name | sourcefile | sourceline | setting | error
------+---------------------------------------------------+------------+---------+--------------------------------------
test | /usr/local/etc/postgresql/14/main/postgresql.conf | 2 | test | unrecognized configuration parameter
(1 row)
Time: 2.354 ms
Давайте попробуем перезагрузить сервер. Мы получим эту информацию в LOG:
2022-07-22 16:00:53.190 CEST [4317] LOG: received SIGHUP, reloading configuration files
2022-07-22 16:00:53.190 CEST [4317] LOG: unrecognized configuration parameter "test" in file "/usr/local/etc/postgresql/14/main/postgresql.conf" line 2
2022-07-22 16:00:53.191 CEST [4317] LOG: configuration file "/usr/local/etc/postgresql/14/main/postgresql.conf" contains errors; no changes were applied
Попробуем перезапустить сервер. Мы получаем следующую ошибку, и сервер не может быть запущен.
2022-07-22 14:03:45.281 GMT [4940] LOG: unrecognized configuration parameter "test" in file "/usr/local/etc/postgresql/14/main/postgresql.conf" line 2
2022-07-22 14:03:45.282 GMT [4940] FATAL: configuration file "/usr/local/etc/postgresql/14/main/postgresql.conf" contains errors
pg_ctl: could not start server
Examine the log output.
Проблемы могут быть быстро устранены, поскольку мы можем проверить состояние конфигурации перед перезагрузкой или перезапуском.
Чтобы избежать неожиданностей, это также можно внедрить в систему управления конфигурацией.
Проверка наличия ожидающей перезагрузки и ожидающего перезапуска
Перед внесением изменений в конфигурацию целесообразно подтвердить текущее состояние сервера. Это гарантирует, что мы начинаем работу в чистом состоянии и помогает предотвратить каскадные проблемы.
Рассмотрим сценарий, в котором один из DBA в вашей команде изменил random page cost
, но изменение еще не вступило в силу. Вы вносите изменения и перезагружаете или перезапускаете сервер. Через несколько дней ваши запросы стали выполняться плохо. Вас расспросили о внесенной корректировке и даже попросили отменить ее, но облегчения так и не последовало.
Расследование таких проблем может быть утомительным и отнимать много времени; лучше перестраховаться, чем потом жалеть.
Мы можем легко проверить наличие ожидающей перезагрузки и перезапуска с помощью этого SQL-запроса:
WITH current_settings AS (
SELECT
name,
CASE
WHEN unit IN ('kB', '8kB', 'MB') THEN pg_catalog.pg_size_pretty(pg_catalog.pg_size_bytes(setting || unit))
WHEN unit = 'B' THEN pg_catalog.pg_size_pretty(pg_catalog.pg_size_bytes(setting))
-- extract seconds from config with units s and min
WHEN unit IN ('s', 'min') THEN floor(extract(epoch from (setting || unit)::interval))::text
-- extract milliseconds from config with unit ms
WHEN unit = 'ms' THEN floor(extract(epoch from (setting || unit)::interval) * 1000)::text
ELSE setting || ' ' || coalesce(unit, '')
END AS current_setting,
unit,
context
FROM pg_catalog.pg_settings
),
file_settings AS (
SELECT
row_number() OVER (PARTITION BY pf.name ORDER BY pf.seqno DESC) AS rn,
pf.name,
CASE
WHEN cs.unit IN ('kB', '8kB', 'MB') THEN pg_catalog.pg_size_pretty(pg_catalog.pg_size_bytes(case when not pf.setting ~ '^-?d*.?d+[a-zA-Z]+$' then pf.setting || cs.unit else pf.setting end))
WHEN cs.unit = 'B' THEN pg_catalog.pg_size_pretty(pg_catalog.pg_size_bytes(case when not pf.setting ~ '^-?d*.?d+B$' and not pf.setting ~ '^-?d*.?d+[a-zA-Z]+$' then pf.setting || 'bytes' when pf.setting ~ '^-?d+B$' then replace(pf.setting, 'B', 'bytes') else pf.setting end))
-- extract seconds from config with units s and min
WHEN cs.unit IN ('s', 'min') THEN floor(extract(epoch from (case when not pf.setting ~ '^-?d*.?d+[a-zA-Z]+$' then pf.setting || cs.unit else pf.setting end)::interval))::text
-- extract milliseconds from config with unit ms
WHEN unit = 'ms' THEN floor(extract(epoch from (case when not pf.setting ~ '^-?d*.?d+[a-zA-Z]+$' then pf.setting || cs.unit else pf.setting end)::interval) * 1000)::text
ELSE setting || ' ' || coalesce(unit, '')
END AS file_setting,
pf.sourcefile,
pf.sourceline,
pf.error
FROM current_settings AS cs
JOIN pg_catalog.pg_file_settings AS pf ON pf.name = cs.name
)
SELECT
cs.name,
cs.current_setting,
fs.file_setting AS pending_setting,
cs.context,
fs.sourcefile,
fs.sourceline,
fs.error,
CASE
WHEN cs.current_setting != fs.file_setting AND cs.context != 'postmaster' THEN true::text
ELSE 'N/A'
END AS pending_reload,
CASE
WHEN cs.current_setting != fs.file_setting AND cs.context = 'postmaster' THEN true::text
ELSE 'N/A'
END AS pending_restart
FROM current_settings AS cs
JOIN file_settings AS fs ON cs.name = fs.name
WHERE fs.rn = 1
AND cs.current_setting != fs.file_setting
ORDER BY pending_reload DESC;
Пример вывода:
name | current_setting | pending_setting | context | sourcefile | sourceline | error | pending_reload | pending_restart
---------------------+-----------------+-----------------+------------+------------------------------------------------------------+------------+--------+----------------+-----------------
archive_command | (disabled) | /bin/true | sighup | /usr/local/var/lib/postgresql/14/main/postgresql.auto.conf | 28 | <null> | true | N/A
autovacuum_work_mem | 10 MB | 1024 kB | sighup | /usr/local/var/lib/postgresql/14/main/postgresql.auto.conf | 20 | <null> | true | N/A
max_wal_size | 1024 MB | 10 GB | sighup | /usr/local/var/lib/postgresql/14/main/postgresql.auto.conf | 26 | <null> | true | N/A
archive_mode | off | on | postmaster | /usr/local/var/lib/postgresql/14/main/postgresql.auto.conf | 27 | <null> | N/A | true
shared_buffers | 160 MB | 1024 MB | postmaster | /usr/local/var/lib/postgresql/14/main/postgresql.auto.conf | 25 | <null> | N/A | true
(5 rows)
Time: 8.198 ms
Чтобы избежать неожиданностей, это также может быть реализовано в системе управления конфигурацией.