Чистое изменение конфигураций PostgreSQL

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
Войти в полноэкранный режим Выход из полноэкранного режима

Чтобы избежать неожиданностей, это также может быть реализовано в системе управления конфигурацией.

Оцените статью
devanswers.ru
Добавить комментарий