Настройка и эксплуатация сервера

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

Учетная запись пользователя QHB

Как и любой серверный процесс, доступный для внешнего мира, QHB рекомендуется запускать под отдельной учетной записью пользователя. Эта учетная запись должна владеть только данными, которыми управляет сервер, и не должна использоваться совместно с другими служебными процессами. (Например, было бы неудачной идеей выбрать пользователя nobody.) В частности, не рекомендуется назначать этого пользователя владельцем исполняемых файлов QHB, потому что скомпрометированный серверный процесс может их изменить.

Для добавления в вашу систему учетной записи пользователя Unix выполните команду useradd или adduser. Часто используется имя пользователя qhb, которое предполагается в этой документации, но при необходимости можно использовать другое имя.



Создание кластера баз данных

Прежде чем что-либо делать, вы должны инициализировать область хранения баз данных на диске. Она называется кластером баз данных. (В стандарте SQL применяется термин кластер каталогов.) Кластер баз данных — это набор баз данных, который управляется одним экземпляром работающего сервера баз данных. После инициализации кластер баз данных будет содержать базу данных с именем qhb, являющуюся базой данных по умолчанию для использования утилитами, пользователями и сторонними приложениями. Сам сервер баз данных не требует существования базы данных qhb, но многие внешние утилиты предполагают, что она существует. Также в каждом кластере во время инициализации создаются еще две базы данных с именами template1 и template0. Как следует из названий, они будут использоваться в качестве шаблонов для баз данных, создаваемых впоследствии, и не должны использоваться для фактической работы. (Информацию о создании новых баз данных в кластере см. в главе Управление базами данных.)

С точки зрения файловой системы, кластер баз данных — это один каталог, в котором будут храниться все данные. Он называется каталогом данных или областью данных. Место хранения данных полностью зависит от пользователя. Какого-то стандартного расположения не существует, хотя популярны такие места, как /var/lib/qhb/data или /u01/qhb/data. Чтобы использовать каталог данных, его нужно инициализировать с помощью программы qhb_bootstrap (или initdb), которая устанавливается с QHB. Расположение файловой системы вашего кластера баз данных указывается с помощью параметра -D, например:

qhb_bootstrap -D /var/lib/qhb/data

или

$ initdb -D /var/lib/qhb/data

Обратите внимание, что вы должны выполнить эту команду при входе в учетную запись пользователя QHB, которая описана в предыдущем разделе.

Совет
В качестве альтернативы параметру -D можно установить переменную среды PGDATA.

Как вариант, команду initdb можно запустить через программу qhb_ctl следующим образом:

$ qhb_ctl -D /var/lib/qhb/data initdb

Этот вариант может быть удобнее, если вы используете qhb_ctl для запуска и остановки сервера (см. раздел Запуск сервера баз данных); таким образом, qhb_ctl будет единственной командой, с помощью которой вы будете управлять экземпляром сервера баз данных.

Команда qhb_bootstrap попытается создать указанный вами каталог, если он еще не существует. Конечно, это не удастся, если у qhb_bootstrap нет прав на запись в родительский каталог. Обычно рекомендуется, чтобы пользователь QHB владел не только каталогом данных, но и его родительским каталогом, поэтому это не должно стать проблемой. Если желаемый родительский каталог тоже не существует, сначала нужно его создать, используя права суперпользователя, если находящийся выше каталог недоступен для записи. Так что процесс может выглядеть так:

root# mkdir /usr/local/qhb
root# chown qhb /usr/local/qhb
root# su qhb
qhb$ qhb_bootstrap -D /var/lib/qhb/data

При работе от root выполняем:

root# mkdir /var/lib/qhb/data
root# chown qhb /var/lib/qhb/data
root# sudo -u qhb /usr/local/qhb/bin/qhb_bootstrap -D /var/lib/qhb/data

Команда qhb_bootstrap не станет запускаться, если каталог данных существует и уже содержит файлы; это предотвращает случайную перезапись существующей установки.

Поскольку каталог данных содержит все данные, хранящиеся в базе данных, важно, чтобы он был защищен от несанкционированного доступа. Поэтому qhb_bootstrap отзывает права доступа у всех, кроме пользователя QHB и, при необходимости, группы. Групповой доступ, если он включен, доступен только для чтения. Это позволяет непривилегированному пользователю из одной группы с владельцем кластера создавать резервную копию данных кластера или выполнять другие операции, для которых требуется только чтение.

Обратите внимание, что включение или выключение группового доступа в существующем кластере требует отключения этого кластера и установки соответствующего режима для всех каталогов и файлов перед перезапуском QHB. В противном случае в каталоге данных может существовать комбинация режимов. Для кластеров, разрешающих доступ только владельцу, подходят режимы 0700 для каталогов и 0600 для файлов. Для кластеров, разрешающих чтение и для группы, подходят режимы 0750 для каталогов и 0640 для файлов.

Однако, хотя содержимое каталога защищено, настройка аутентификации клиента по умолчанию позволяет любому локальному пользователю подключаться к базе данных и даже стать ее суперпользователем. Если вы не доверяете другим локальным пользователям, рекомендуется использовать один из параметров qhb_bootstrap: -W, --pwprompt или --pwfile, чтобы назначить пароль суперпользователю базы данных. Кроме того, укажите -A scram-sha-256, чтобы не использовался trust — режим аутентификации по умолчанию, или измените созданный файл qhb_hba.conf после запуска qhb_bootstrap, но перед первым запуском сервера. (Другие разумные подходы включают использование аутентификации peer или разрешений файловой системы для ограничения соединений. Подробную информацию см. в главе Аутентификация клиентского приложения.)

Также команда qhb_bootstrap инициализирует для кластера баз данных локаль по умолчанию. Обычно она просто берет параметры локали из среды и применяет их к инициализированной базе данных. Можно указать для базы данных и другую локаль; более подробную информацию об этом можно найти в разделе Поддержка языковых стандартов. Порядок сортировки по умолчанию, используемый в конкретном кластере баз данных, устанавливается qhb_bootstrap, и хотя вы можете создавать новые базы данных, используя другой порядок сортировки, но порядок, используемый в базах-шаблонах, которые создает утилита qhb_bootstrap, нельзя изменить без их удаления и пересоздания. Кроме того, использование локалей, отличных от C или POSIX, влияет на производительность. Поэтому важно правильно сделать этот выбор с первого раза.

Команда qhb_bootstrap также устанавливает для кластера баз данных кодировку набора символов по умолчанию. Обычно ее следует выбирать в соответствии с настройками локали. Подробную информацию см. в разделе Поддержка кодировок.

Локали, отличные от C или POSIX, при упорядочении набора символов полагаются на библиотеку сопоставления операционной системы. Это определяет порядок ключей, хранящийся в индексах. По этой причине кластер не может переключиться на несовместимую версию библиотеки, ни посредством восстановления снимка состояния, ни через двоичную потоковую репликацию, другую операционную систему или обновление операционной системы.


Использование добавочных файловых систем

Многие установки создают свои кластеры баз данных не в «корневой» файловой системе (томе) компьютера, а в других томах. Если вы решите сделать это, не рекомендуется пытаться использовать в качестве каталога для хранения данных самый верхний каталог добавочного тома (точку монтирования). Лучше всего будет создать в каталоге точки монтирования каталог, который принадлежит пользователю QHB, а затем уже в нем создать каталог данных. Это позволит избежать проблем с разрешениями, особенно для таких операций, как qhb_upgrade, а также гарантирует чистые ошибки, если добавочный том окажется отключен.


Файловые системы

Как правило, для QHB можно использовать любую файловую систему с семантикой POSIX. Пользователи предпочитают другие файловые системы по разным причинам, включая поддержку поставщиков, производительность и изученность. Опыт показывает, что при прочих равных не следует ожидать значительных изменений в производительности или в поведении просто от переключения файловых систем или незначительных изменений конфигурации файловой системы.

NFS

Для хранения каталога данных QHB можно использовать файловую систему NFS. QHB не подстраивается специально под файловые системы NFS, то есть предполагает, что NFS ведет себя точно так же, как локально подключенные накопители. QHB не использует функциональности, демонстрирующие нестандартное поведение в NFS, например блокировку файлов.

Единственное жесткое требование для использования NFS с QHB — это монтирование файловой системы с использованием параметра hard. С параметром hard процессы могут «зависать» на неопределенное время при возникновении проблем с сетью, поэтому такая конфигурация потребует тщательной настройки мониторинга. Параметр soft будет прерывать системные вызовы в случае проблем с сетью, но QHB не будет повторять системные вызовы, прерванные таким образом, поэтому любое такое прерывание приведет к сообщению об ошибке ввода/вывода.

Нет необходимости использовать параметр монтирования sync. Поведения параметра async вполне достаточно, поскольку QHB вызывает fsync в нужное время для очистки кэшей записи (аналогично тому, как это происходит в локальной файловой системе). Однако настоятельно рекомендуется использовать параметр экспорта sync на сервере NFS в системах, где он существует (в основном, это Linux). В противном случае fsync или ее эквивалент на клиенте NFS не гарантируют того, что данные достигнут постоянного хранилища на сервере, что может привести к повреждению данных, как и выключение параметра fsync. Значения по умолчанию этих параметров монтирования и экспорта различаются у разных поставщиков и версий, поэтому рекомендуется в любом случае проверить и, возможно, указать их явно, чтобы избежать двусмысленности.

В некоторых случаях к внешнему хранилищу можно получить доступ через NFS или протокол более низкого уровня, например iSCSI. В последнем случае хранилище представляется как блочное устройство, и на нем можно создать любую поддерживаемую файловую систему. Такой подход может избавить администратора баз данных от необходимости иметь дело с некоторыми особенностями NFS, но, конечно, тогда сложность управления удаленным хранилищем возникает на других уровнях.



Запуск сервера баз данных

Прежде чем кто-либо сможет получить доступ к базе данных, вы должны запустить сервер баз данных. Программа сервера баз данных называется qhb.

Программа qhb должна знать, где найти файлы базы данных, которые она должна использовать. Это делается с помощью параметра -D*, например:

qhb# qhb -D /var/lib/qhb/data

При запуске от root:

root# sudo -u qhb ./qhb -D /var/lib/qhb/data

При этом сервер продолжит работу на переднем плане. Эта программа должна выполнятся из-под учетной записи пользователя QHB. Без параметра -D сервер попытается использовать каталог данных, заданный в переменной среды PGDATA. Если эта переменная тоже не указана, произойдет сбой.

Обычно лучше запускать qhb в фоновом режиме. Для этого используется обычный синтаксис оболочки Unix:

$ qhb -D /var/lib/qhb/data >logfile 2>&1 &

Важно где-то хранить выходные данные сервера из каналов stdout и stderr, как показано выше. Это поможет при аудите и диагностики проблем. (Более подробно обработка файлов журнала рассматривается в разделе Обслуживание файлов журнала.)

Также программа qhb принимает ряд других параметров командной строки. Подробную информацию см. на справочной странице qhb и в главе Конфигурация сервера.

Этот синтаксис оболочки может быстро стать громоздким. Поэтому для упрощения некоторых задач предоставляется программа-обертка qhb_ctl. Например:

qhb_ctl start -l logfile

запустит сервер в фоновом режиме и поместит вывод в именованный файл журнала. Параметр -D имеет то же значение, что и для qhb. Кроме того, qhb_ctl способна останавливать сервер.

Обычно возникает желание запускать сервер баз данных при загрузке компьютера. Скрипты автозапуска зависят от операционной системы. Некоторые из них распространяются с пакетами QHB. Для установки такого скрипта в систему понадобятся права root.

Различные системы имеют разные соглашения для запуска служебных процессов во время загрузки. Во многих системах имеется файл /etc/rc.local или /etc/rc.d/ rc.local. Другие используют каталоги init.d или rc.d Что бы вы ни делали, сервер должен работать под учетной записью пользователя QHB, а не под root или любым другим пользователем. Поэтому стоит формировать свои команды, используя su qhb -c '...'. Например:

su qhb -c 'qhb_ctl start -D /var/lib/qhb/data -l serverlog'

Вот несколько более конкретных предложений для ряда операционных систем. (В каждом случае вместо указанных нами общих значений обязательно используйте надлежащие каталог установки и имя пользователя.)

  • Для запуска во FreeBSD используйте файл contrib/start-scripts/freebsd в исходном дистрибутиве QHB.

  • В OpenBSD добавьте в файл /etc/rc.local следующие строки:

    if [ -x /usr/local/qhb/bin/qhb_ctl -a -x /usr/local/qhb/bin/qhb ]; then
        su -l qhb -c '/usr/local/qhb/bin/qhb_ctl start -s -l /var/qhb/log -D /var/lib/qhb/data'
     echo -n ' qhb'
    fi
    
  • В системах Linux либо добавьте

    /usr/local/qhb/bin/qhb_ctl start -l logfile -D /var/lib/qhb/data
    

    в /etc/rc.d/rc.local или /etc/rc.local, либо используйте файл contrib/start-scripts/linux в исходном дистрибутиве QHB.

    При использовании systemd можно использовать следующий файл сервисного блока (например в /etc/systemd/system/qhb.service):

    [Unit]
    Description=QHB database server
    Documentation=man:qhb(1)
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    User=qhb
    ExecStart=/usr/local/qhb/bin/qhb -D /var/lib/qhb/data
    ExecReload=/bin/kill -HUP $MAINPID
    KillMode=mixed
    KillSignal=SIGINT
    TimeoutSec=infinity
    
    [Install]
    WantedBy=multi-user.target
    

    Применение Type=notify требует, чтобы сервер был скомпилирован с указанием configure --with-systemd.

    Тщательно продумайте настройку тайм-аута. На данный момент в systemd тайм-аут по умолчанию составляет 90 секунд, и процесс, который не уведомит о готовности в течение этого времени, будет уничтожен. Но у сервера QHB, которому может потребоваться при запуске выполнить восстановление после сбоя, на подготовку может уйти гораздо больше времени. Предлагаемое значение infinity выключает логику тайм-аута.

  • В NetBSD воспользуйтесь скриптами запуска для FreeBSD или для Linux, в зависимости от предпочтений.

  • В Solaris создайте файл с именем /etc/init.d/qhb, содержащий следующую строку:

    su - qhb -c "/usr/local/qhb/bin/qhb_ctl start -l logfile -D /var/lib/qhb/data"
    

Затем создайте символическую ссылку на него в каталоге /etc/rc3.d с именем S99qhb.

Во время работы сервера его идентификатор (PID) хранится в файле qhbmaster.pid в каталоге данных. Это позволяет предотвратить запуск нескольких экземпляров сервера в одном каталоге данных, а также может использоваться для отключения сервера.


Сбои при запуске сервера

Существует несколько распространенных причин, по которым сервер может не запуститься. Проверьте файл журнала сервера или запустите его вручную (без перенаправления стандартного вывода или стандартной ошибки) и посмотрите, какие сообщения об ошибках появляются. Ниже мы рассмотрим некоторые из наиболее распространенных сообщений об ошибках более подробно.

LOG:  could not bind IPv4 address "127.0.0.1": Address already in use
HINT:  Is another qhbmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets
-- ЖУРНАЛ: не удалось присвоить адрес IPv4 "127.0.0.1": Адрес уже используется
-- СОВЕТ: На порту 5432 уже запущен другой процесс qhbmaster? Если нет, подождите несколько секунд и повторите попытку.
-- КРИТИЧНО: не удалось создать сокеты TCP/IP

Обычно это означает именно то, что написано: вы попытались запустить сервер на том же порту, на котором уже работает другой. Однако если сообщение об ошибке в ядре не Address already in use или какой-то его вариант, возможно, это другая проблема. Например, на попытку запустить сервер с зарезервированным номером порта может быть выдано что-то вроде этого:

$ qhb -p 777
LOG:  could not bind IPv4 address "127.0.0.1": Permission denied
HINT:  Is another qhbmaster already running on port 777? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets
-- ЖУРНАЛ: не удалось присвоить адрес IPv4 "127.0.0.1": Отсутствие прав доступа
-- СОВЕТ: На порту 777 уже запущен другой процесс qhbmaster? Если нет, подождите несколько секунд и повторите попытку.
-- КРИТИЧНО: не удалось создать сокеты TCP/IP

Сообщение вроде:

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).
-- КРИТИЧНО: не удалось создать сегмент разделяемой памяти: Недопустимый аргумент
-- ДЕТАЛИЗАЦИЯ: Сбой произошел в системном вызове shmget(key=5440001, size=4011376640, 03600).

вероятно, означает, что предельный размер разделяемой памяти в вашем ядре меньше, чем рабочая область, которую пытается создать QHB (в этом примере 4011376640 байт). Чаще всего это происходит, если вы установили в параметре shared_memory_type значение sysv. В этом случае можно попробовать запустить сервер с меньшим, чем обычно, числом буферов ( shared_buffers) или перенастроить ядро, чтобы увеличить допустимый размер разделяемой памяти. Кроме того, это сообщение может появиться при попытке запустить несколько серверов на одном компьютере, если их общее запрошенное пространство превышает ограничение ядра.

Ошибка вроде:

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).
-- КРИТИЧНО: не удалось создать семафоры: Недостаточно места на устройстве
-- ДЕТАЛИЗАЦИЯ: Сбой произошел в системном вызове semget(5440126, 17, 03600).

не означает, что вам не хватает места на диске. Это означает, что предельное число семафоров System V в вашем ядре меньше, чем число семафоров, которое хочет создать QHB. Как и в случае выше, эту проблему можно обойти, запустив сервер с меньшим количеством разрешенных соединений (max_connections), но в конечном итоге будет необходимо увеличить ограничение ядра.

Подробную информацию о конфигурировании средств IPC в стиле System V см. в подразделе Разделяемая память и семафоры.


Проблемы с подключением клиента

Хотя возможные состояния ошибки на стороне клиента довольно разнообразны и зависят от приложения, некоторые из них могут быть напрямую связаны с тем, как был запущен сервер. Состояния, отличные от указанных ниже, должны быть описаны в документации соответствующего клиентского приложения.

psql: error: connection to server at "server.joe.com" (123.123.123.123), port 5432 failed: Connection refused
        Is the server running on that host and accepting TCP/IP connections?
-- ошибка: не удалось подключиться к серверу "server.joe.com" (123.123.123.123), порт 5432: в подключении отказано
        -- Сервер действительно работает на этом хосте и принимает подключения по TCP/IP?

Это частый сбой «Я не могу найти сервер для взаимодействия». Похоже, здесь была попытка установить связь с TCP/IP. Распространенная ошибка — забыть сконфигурировать сервер так, чтобы разрешить TCP/IP-соединения.

Кроме того, при попытке подключения к локальному серверу с помощью сокета домена Unix вы можете получить:

psql: error: connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
        Is the server running locally and accepting connections on that socket?
-- ошибка: не удалось подключиться к серверу через сокет "/tmp/.s.PGSQL.5432": Такого файла или каталога не существует
        -- Сервер действительно работает локально и принимает подключения через этот сокет?

Если сервер действительно работает, проверьте, что указываемый клиентом путь сокета (здесь /tmp) соответствует значению параметра unix_socket_directories на сервере.

В сообщении об ошибке подключения всегда выводится адрес сервера или путь сокета, что помогает проверить, действительно ли клиент пытается подключиться по нужному адресу. Если в действительности там не указано сервера, обычно выдается сообщение об ошибке от ядра Connection refused или No such file or directory, как показано выше. (Важно понимать, Connection refused в данном контексте не означает, что сервер получил ваш запрос на подключение и отверг его. В этом случае было бы выдано другое сообщение, показанное в разделе Проблемы аутентификации.) Другие сообщения об ошибках, например Connection timed out (Тайм-аут подключения), могут указывать на более фундаментальные проблемы, например на отсутствие возможности сетевого соединения или блокировку подключения брандмауэром.



Управление ресурсами ядра

Иногда QHB может исчерпывать ряд ресурсов операционной системы до предела, особенно при запуске в одной системе нескольких копий сервера или в очень больших дистрибутивах. В этом разделе описываются ресурсы ядра, используемые QHB, и шаги, которые можно предпринять для решения проблем, связанных с исчерпанием ресурсов ядра.

Разделяемая память и семафоры

QHB требует, чтобы операционная система предоставляла средства межпроцессного взаимодействия (inter-process communication, IPC), в частности, разделяемую память и семафоры. Дочерние системы Unix обычно предоставляют средства IPC в стиле «System V», в стиле «POSIX» или и те, и другие.

По умолчанию QHB резервирует очень малый объем разделяемой памяти System V и гораздо больший объем анонимной разделяемой памяти mmap. Как вариант, возможно использование одной крупной области разделяемой памяти System V (см. shared_memory_type). Кроме того, при запуске сервера создается значительное число семафоров, которые могут быть в стиле System V либо POSIX. В настоящее время семафоры POSIX используются в системах Linux и FreeBSD, тогда как на других платформах используются семафоры System V.

Средства IPC в стиле System V обычно ограничены лимитами резервирования на уровне системы. Когда QHB превышает один из таких лимитов, сервер отказывается запускаться и должен выдать информативное сообщение об ошибке, описывающее проблему и что с ней делать. (См. также подраздел Сбои при запуске сервера.) Соответствующие параметры ядра в разных системах называются единообразно (с ними можно ознакомиться в Таблице 1), однако методы их настройки различаются. Ниже даны предложения для некоторых платформ.

Таблица 1. Параметры IPC в стиле System V

ИмяОписаниеЗначения, необходимые для запуска одного экземпляра QHB
SHMMAXМаксимальный размер сегмента разделяемой памяти (в байтах)как минимум 1 КБ, но обычно значение по умолчанию гораздо больше
SHMMINМинимальный размер сегмента разделяемой памяти (в байтах)1
SHMALLОбщий объем доступной разделяемой памяти (в байтах или страницах)если в байтах, то же, что и SHMMAX; если в страницах, то ceil(SHMMAX/PAGE_SIZE) плюс место для других приложений
SHMSEGМаксимальное число сегментов разделяемой памяти на процесснужен только один сегмент, но значение по умолчанию гораздо больше
SHMMNIМаксимальное число сегментов разделяемой памяти на всю системукак SHMSEG плюс место для других приложений
SEMMNIМинимальное число идентификаторов семафоров (т. е. их наборов)как минимум ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) плюс место для других приложений
SEMMNSМаксимальное число семафоров на всю системуceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17 плюс место для других приложений
SEMMSLМаксимальное число семафоров в наборекак минимум 17
SEMMAPЧисло записей в карте семафорасм. текст ниже
SEMVMXМаксимальное значение семафоракак минимум 1000 (по умолчанию обычно 32767; не меняйте его без необходимости)

QHB запрашивает несколько байтов разделяемой памяти System V (обычно 48 байт на 64-битных платформах) для каждой копии сервера. В большинстве современных операционных систем такой объем резервируется с легкостью. Однако если запустить много копий сервера или явно настроить сервер для использования больших объемов разделяемой памяти System V (см. shared_memory_type и dynamic_shared_memory_type), может понадобиться увеличить значение SHMALL, задающее общий объем разделяемой памяти System V для всей системы. Обратите внимание, что во многих системах SHMALL измеряется в страницах, а не в байтах.

Менее вероятны проблемы с минимальным размером сегментов разделяемой памяти (SHMMIN), который для QHB не должен превышать примерно 32 байт (обычно это всего 1 байт). Максимальное число сегментов на всю систему (SHMMNI) или на процесс (SHMSEG) обычно не вызывают проблем, если только в вашей системе они не равны нулю.

Когда QHB использует семафоры System V, она применяет по одному семафору на каждое разрешенное подключение (max_connections), каждый разрешенный рабочий процесс автовакуума (autovacuum_max_workers) и каждый разрешенный фоновый процесс (max_worker_processes), в наборах по 16. В каждом таком наборе также имеется 17-й семафор, содержащий «магическое число» для обнаружения коллизий с наборами семафоров, используемыми другими приложениями. Максимальное число семафоров в системе задается параметром SEMMNS, который, следовательно, должен быть равен как минимум сумме max_connections, autovacuum_max_workers, max_wal_senders и max_worker_processes плюс один дополнительный семафор на каждые 16 разрешенных подключений и рабочих процессов (см. формулу в Таблице 1). Параметр SEMMNI определяет предельное число наборов семафоров, которые могут одновременно существовать в системе. Таким образом, этот параметр должен быть равен как минимум ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16). В качестве временного решения проблемы можно уменьшить число разрешенных подключений, но обычно это вызывает нелогичные сообщения «No space left on device» (На устройстве не осталось места) от функции semget.

В некоторых случаях может также возникнуть необходимость увеличить SEMMAP как минимум до уровня SEMMNS. Если в системе есть этот параметр (во многих системах его нет), он определяет размер карты ресурсов семафоров, в которой для каждого непрерывного блока доступных семафоров требуется отдельная запись. Когда набор семафоров освобождается, эта запись либо добавляется к соседней с освобожденным блоком существующей записи, либо регистрируется как новая запись в карте. Если карта переполняется, освобождаемые семафоры теряются (до перезагрузки). Фрагментация пространства семафоров со временем может привести к снижению числа доступных семафоров.

Другие параметры, связанные с «уничтожением семафоров», например SEMMNU и SEMUME, на работу QHB не влияют.

При использовании семафоров в стиле POSIX число необходимых семафоров такое же, как для System V, то есть по одному семафору на каждое разрешенное подключение (max_connections), каждый разрешенный рабочий процесс автоовакуума (autovacuum_max_workers) и каждый разрешенный фоновый процесс (max_worker_processes). На платформах, где предпочитается этот вариант, отсутствует конкретный лимит ядра на число семафоров POSIX.

AIX

Для таких параметров, как SHMMAX, нет необходимости в каком-то особом конфигурировании, поскольку система, по-видимому, настроена так, что позволяет использовать всю память в качестве разделяемой. Конфигурация такого рода обычно используется и для других баз данных, например для DB/2.

Однако может понадобиться изменить глобальную информацию ulimit в /etc/ security/limits, поскольку стандартные жесткие ограничения на размер (fsize) и число (nofiles) файлов могут быть слишком маленькими.

FreeBSD

Стандартные настройки разделяемой памяти обычно вполне приемлемы, если вы не установите в shared_memory_type значение sysv. Семафоры System V на этой платформе не используются.

Стандартные настойки IPC можно изменить с помощью интерфейсов sysctl или loader. Используя sysctl, можно установить следующие параметры:

# sysctl kern.ipc.shmall=32768
# sysctl kern.ipc.shmmax=134217728

Чтобы эти настройки сохранялись после перезагрузки, измените /etc/sysctl.conf.

Если вы установили в shared_memory_type значение sysv, вам также может понадобиться настроить ядро так, чтобы блокировать разделяемую память System V в ОЗУ и не дать ей выгружаться в пространство подкачки. Этого можно добиться, используя в sysctl параметр kern.ipc.shm_use_phys.

При запуске сервера в «камере» FreeBSD, следует установить в его параметре sysvshm значение new, чтобы у сервера было собственное отдельное пространство имен разделяемой памяти System V. (До версии 11.0 во FreeBSD требовалось разрешать общий доступ из камер к пространству имен IPC хоста и принимать меры во избежание коллизий.)

NetBSD

Стандартные настройки разделяемой памяти обычно вполне приемлемы, если вы не установите в shared_memory_type значение sysv. Как правило, стоит увеличить kern.ipc.semmni и kern.ipc.semmns, поскольку их значения по умолчанию в NetBSD чересчур малы.

Параметры IPC можно скорректировать с помощью sysctl, например:

# sysctl -w kern.ipc.semmni=100

Чтобы эти настройки сохранялись после перезагрузки, измените /etc/sysctl.conf.

Если вы установили в shared_memory_type значение sysv, вам также может понадобиться настроить ядро так, чтобы блокировать разделяемую память System V в ОЗУ и не дать ей выгружаться в пространство подкачки. Этого можно добиться, используя в sysctl параметр kern.ipc.shm_use_phys.

OpenBSD

Стандартные настройки разделяемой памяти обычно вполне приемлемы, если вы не установите в shared_memory_type значение sysv. Как правило, стоит увеличить kern.ipc.semmni и kern.ipc.semmns, поскольку их значения по умолчанию в OpenBSD чересчур малы.

Параметры IPC можно скорректировать с помощью sysctl, например:

# sysctl kern.seminfo.semmni=100

Чтобы эти настройки сохранялись после перезагрузки, измените /etc/sysctl.conf.

HP-UX

Настройки по умолчанию, как правило, удовлетворяют нормальным установкам.

Параметры IPC можно установить в менеджере системного администрирования (System Administration Manager, SAM) в разделе Kernel Configuration (конфигурация ядра) \→ Configurable Parameters (конфигурируемые параметры). По окончании настройки выберите операцию Create A New Kernel (создать новое ядро).

Linux

Стандартные настройки разделяемой памяти обычно вполне приемлемы, если вы не установите в shared_memory_type значение sysv, и даже тогда их нужно будет увеличить только для старых версий ядер, которые поставлялись с маленькими значениями параметров по умолчанию. Семафоры System V на этой платформе не используются.

Параметры размера разделяемой памяти можно изменить с помощью интерфейса sysctl. Например, чтобы разрешить объем 16 ГБ, выполните:

$ sysctl -w kernel.shmmax=17179869184
$ sysctl -w kernel.shmall=4194304

Чтобы эти настройки сохранялись после перезагрузки, измените /etc/sysctl.conf.

macOS

Стандартные настройки разделяемой памяти и семафоров обычно вполне приемлемы, если вы не установите в shared_memory_type значение sysv.

Для конфигурирования разделяемой памяти в macOS рекомендуется создать файл с именем /etc/sysctl.conf, содержащий присваивания переменных, например:

kern.sysv.shmmax=4194304
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=1024

Обратите внимания, что в некоторых версиях macOS в /etc/sysctl.conf нужно установить все пять параметров разделяемой памяти, иначе их значения будут игнорироваться.

Значение SHMMAX должно быть кратно 4096.

На этой платформе SHMALL измеряется в страницах размером 4 КБ.

Все параметры, кроме SHMMNI, можно изменить на ходу с помощью sysctl. Но все равно лучше устанавливать желаемые значения через /etc/sysctl.conf, чтобы они сохранялись после перезагрузки.

Solaris
illumos

Стандартные настройки разделяемой памяти и семафоров обычно вполне приемлемы для большинства приложений QHB. По умолчанию Solaris устанавливает в SHMMAX четверть объема системного ОЗУ. Для дополнительной корректировки этого параметра воспользуйтесь параметром проекта, связанного с пользователем qhb. Например, выполните от имени root следующую команду:

projadd -c "QHB DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U qhb -G qhb user.qhb

Эта команда добавляет проект user.qhb и задает максимальный объем разделяемой памяти для пользователя qhb, равный 8 ГБ; это изменение вступает в силу при следующем входе этого пользователя или при перезапуске QHB (не при перезагрузке конфигурации). При этом подразумевается, что QHB выполняется пользователем qhb в группе qhb. Перезапуск сервера не требуется.

Для серверов баз данных, к которым будет производиться большое число подключений, рекомендуется изменить следующие параметры ядра:

project.max-shm-ids=(priv,32768,deny)
project.max-sem-ids=(priv,4096,deny)
project.max-msg-ids=(priv,4096,deny)

Кроме того, если QHB работает внутри зоны, может потребоваться также увеличить лимиты на использование ресурсов зоны. Дополнительную информацию о projects и prctl см. в «Главе 2: Проекты и задачи» Руководства системного администратора.


RemoveIPC в systemd

Если используется systemd, следует позаботиться о том, чтобы ресурсы IPC (включая разделяемую память) не удалялись преждевременно операционной системой. Это особенно актуально при установке QHB из исходного кода. Пользователей дистрибутивных пакетов QHB это касается меньше, поскольку тогда пользователь qhb обычно создается как системный пользователь.

Параметр RemoveIPC в logind.conf определяет, будут ли объекты IPC удаляться, когда пользователь полностью выходит из системы. Исключение составляют системные пользователи. В обычной поставке systemd этот параметр по умолчанию включен, но в некоторых дистрибутивах операционных систем он по умолчанию выключен.

Обычный наблюдаемый эффект при включении этого параметра заключается в том, то объекты разделяемой памяти, используемые для параллельного выполнения запросов, удаляются в совершенно случайном порядке, приводя к появлению ошибок и предупреждений при попытке открыть и удалить их, например:

WARNING:  could not remove shared memory segment "/PostgreSQL.1450751626": No such file or directory
-- ПРЕДУПРЕЖДЕНИЕ:  не удалось удалить сегмент разделяемой памяти "/QHB.1450751626": Нет такого файла или каталога

Различные типы объектов IPC (разделяемая память/семафоры, System V/POSIX) обрабатываются в systemd немного по-разному, поэтому можно наблюдать ситуации, когда некоторые ресурсы IPC не удаляются так, как другие. Но полагаться на эти незначительные отличия не стоит.

Событие «выход пользователя из системы» может произойти при выполнении работы по обслуживанию или вручную, когда администратор входит под именем qhb или делает что-то подобное, поэтому в целом это довольно трудно предотвратить.

Что такое «системный пользователь», определяется во время компиляции systemd на основе значения параметра SYS_UID_MAX в /etc/login.defs.

Скрипты упаковывания и развертывания должны позаботиться о создании пользователя qhb как системного пользователя, используя команды useradd -r, adduser --system или равнозначные им.

Как вариант, если аккаунт пользователя был создан неправильно или его нельзя изменить, рекомендуется установить

RemoveIPC=no

в /etc/systemd/logind.conf или ином подходящем файле конфигурации.

ВНИМАНИЕ!
Необходимо выполнить хотя бы одно из этих действий, иначе сервер QHB будет крайне нестабильным.


Лимиты ресурсов

Unix-подобные операционные системы накладывают различные виды ограничений ресурсов, которые могут повлиять на работу вашего сервера QHB. Особую важность представляют ограничения на число процессов для пользователя, число открытых файлов и доступный объем памяти для каждого процесса. Каждый из них имеет «жесткий» и «мягкий» лимит. Реальное значение имеет мягкий лимит, но пользователь может изменить его значение вплоть до жесткого. Жесткий лимит может изменить только пользователь root. За настройку этих параметров отвечает системный вызов setrlimit. Для управления лимитами ресурсов из командной строки используется встроенная команда оболочки ulimit (в оболочках Bourne) или limit (csh). В дочерних системах BSD различными ограничениями ресурсов, устанавливаемыми во время входа в систему, управляет файл /etc/login.conf. Подробную информацию см. в документации операционной системы. К значимым параметрам относятся maxproc, openfiles и datasize. Например:

default:\
...
        :datasize-cur=256M:\
        :maxproc-cur=256:\
        :openfiles-cur=256:\
...

(Здесь -cur обозначает мягкий лимит. Чтобы установить жесткий лимит, нужно вместо него добавить суффикс -max.)

Также ядра могут иметь общесистемные лимиты некоторых ресурсов.

  • В Linux максимальное число открытых файлов, которые поддержит ядро, определяется параметром fs.file-max. Этот лимит можно изменить с помощью команды sysctl -w fs.file-max=N. Чтобы эта настройка сохранялась после перезагрузки, нужно добавить присваивание в файл /etc/sysctl.conf. Максимальное число файлов на процесс фиксируется во время компиляции ядра; дополнительную информацию см. в /usr/src/linux/Documentation/proc.txt.

Сервер QHB использует по одному процессу на подключение, поэтому в дополнение к тем процессам, которые нужны для остальной системы, вы должны предоставить как минимум столько процессов, сколько имеется разрешенных подключений. Обычно в этом нет проблемы, но если вы запускаете на одном компьютере несколько серверов, лимит может быть достигнут.

В качестве производственного максимума открытых файлов зачастую устанавливают «социально-ориентированные» значения, позволяющие нескольким пользователям сосуществовать на одном компьютере и при этом не задействовать недопустимый процент системных ресурсов. Если вы запускаете по несколько серверов на компьютер, возможно, именно это вам и нужно, но на выделенных серверах может возникнуть необходимость увеличить этот лимит.

С другой стороны, некоторые системы позволяют отдельным процессам открывать очень много файлов; если это делают несколько процессов, то они с легкостью могут превысить общесистемный лимит. Если вы обнаружите подобное и не захотите менять общесистемный лимит, можно ограничить использование открытых файлов, установив параметр конфигурации QHB max_files_per_process.

Еще одним ограничением ядра, имеющим значение при поддержке большого числа клиентских подключений, является максимальная длина очереди подключений к сокету. Если число запросов на подключение за очень короткий промежуток времени превышает этот предел, некоторые из них могут быть отклонены прежде, чем qhbmaster сможет их обработать, и такие клиенты получат бесполезное сообщение об ошибке подключения вроде «Resource temporarily unavailable» (Ресурс временно недоступен) или «Connection refused» (В подключении отказано). Предел длины очереди на многих платформах по умолчанию составляет 128. Чтобы его повысить, настройте соответствующий параметры ядра посредством sysctl, а затем перезапустите qhbmaster. Этот параметр называется net.core.somaxconn в Linux, kern.ipc.soacceptqueue в последних версиях FreeBSD и kern.ipc.somaxconn в macOS и других вариантах BSD.


Избыточное выделение памяти в Linux

В Linux поведение виртуальной памяти по умолчанию не оптимально для QHB. Из-за того, что ядро выделяет избыточный объем памяти, оно может уничтожить qhbmaster (управляющий серверный процесс) QHB, если потребность в памяти процесса QHB или другого процесса приведет к исчерпанию виртуальной памяти в системе.

Если это происходит, вы увидите примерно такое сообщение ядра (где именно искать подобное сообщение, можно узнать в документации вашей системы):

Out of Memory: Killed process 12345 (qhb).
-- Недостаточно памяти: уничтожен процесс 12345 (qhb).

Это указывает на то, что процесс qhb был уничтожен из-за нехватки памяти. Хотя существующие подключения к базе данных продолжат функционировать нормально, новые подключения приниматься не будут. Для восстановления работы сервера понадобится перезапустить QHB.

Один из способов избежать этой проблемы — запускать QHB на машине, где вы можете быть уверены, что другие процессы не исчерпают ее память. При дефиците памяти помочь решить эту проблему может увеличение объема пространства подкачки операционной системы, поскольку OOM killer (out-of-memory killer, уничтожитель процессов при нехватке памяти) вызывается, только когда заканчивается и физическая память, и место в пространстве подкачки.

Если память заканчивается из-за самой QHB, этой проблемы можно избежать, изменив конфигурацию сервера. В некоторых случаях может помочь уменьшение параметров конфигурации, связанных с памятью, в частности shared_buffers, work_mem и hash_mem_multiplier. В других случаях проблема может возникать из-за того, что разрешено слишком много подключений к самому серверу баз данных. Зачастую лучшим выходом будет снизить значение max_connections и вместо этого воспользоваться внешней программой для организации пула подключений.

«Избыточное выделение» памяти можно предотвратить, изменив поведение ядра. Хотя эта настройка и не отключит вызов OOM killer полностью, она значительно снизит вероятность этого, тем самым сделав поведение системы более стабильным. Для этого нужно выбрать режим строгого выделения памяти посредством sysctl:

sysctl -w vm.overcommit_memory=2

или поместить соответствующую запись в /etc/sysctl.conf. Возможно, вам также понадобится изменить связанный параметр vm.overcommit_ratio. Подробную информацию см. в файле документации ядра.

Другой подход, который можно применить как с изменением параметра vm.overcommit_memory, так и без него, заключается в установке для свойства корректировка коэффициента OOM процесса qhbmaster значения -1000; это гарантирует, что данный процесс не станет целью OOM killer. Проще всего это сделать, выполнив

echo -1000 > /proc/self/oom_score_adj

в скрипте запуска qhbmaster непосредственно перед тем, как его запустить. Обратите внимание, что это нужно делать от root, иначе команда не подействует; так что проще всего это сделать в скрипте запуска, принадлежащем root. Если вы делаете это, вам также необходимо перед вызовом qhbmaster установить в скрипте запуска следующие переменные среды:

export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
export PG_OOM_ADJUST_VALUE=0

С этими параметрами дочерние процессы qhbmaster будут запускаться с обычной, нулевой корректировкой коэффициента OOM, так что при необходимости OOM killer все равно сможет их уничтожать. Если вы хотите, чтобы дочерние процессы выполнялись с другой корректировкой коэффициента OOM, можно задать для PG_OOM_ADJUST_VALUE другое значение. (Кроме того, PG_OOM_ADJUST_VALUE можно вообще опустить, и в этом случае по умолчанию подразумевается ноль.) Если вы не установите PG_OOM_ADJUST_FILE, дочерние процессы будут выполняться с той же корректировкой коэффициента OOM, что и qhbmaster, что неразумно, поскольку основная цель всего этого — сделать так, чтобы настройки давали qhbmaster преимущество.


Огромные страницы в Linux

Использование огромных страниц снижает издержки при работе с большими непрерывными блоками памяти, как это делает QHB, в частности, когда задействует большие значения shared_buffers. Чтобы воспользоваться такой функциональностью в QHB, вами нужно сконфигурировать ядро с параметрами CONFIG_HUGETLBFS=y и CONFIG_HUGETLB_PAGE=y. Кроме того, вам потребуется сконфигурировать операционную систему, чтобы та могла предоставлять достаточно огромных страниц желаемого размера. Для оценки требуемого числа огромных страниц воспользуйтесь командой qhb, чтобы узнать значение параметра shared_memory_size_in_huge_pages. Обратите внимание, что для просмотра этого параметра, вычисляемого во время выполнения, сервер необходимо остановить. Это может выглядеть примерно так:

$ qhb -D $PGDATA -C shared_memory_size_in_huge_pages
3170
$ grep ^Hugepagesize /proc/meminfo
Hugepagesize:       2048 kB
$ ls /sys/kernel/mm/hugepages
hugepages-1048576kB  hugepages-2048kB

В этом примере стандартный размер составляет 2 МБ, но в huge_page_size можно явно задать 2 МБ или 1 ГБ, чтобы подогнать число страниц, вычисленное в shared_memory_size_in_huge_pages. Хотя в этом примере нам понадобится не менее 3170 огромных страниц, большее значение было бы оправдано, если бы другим программам на этой машине тоже были нужны огромные страницы. Это значение можно задать так:

# sysctl -w vm.nr_hugepages=3170

Не забудьте добавить эту настройку в /etc/sysctl.conf, чтобы она действовала и после перезагрузки. Если размер огромных страниц отличается от стандартного, его можно изменить следующим образом:

# echo 3170 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Кроме того, эти настройки можно задать во время загрузки операционной системы, используя параметры ядра, например hugepagesz=2M hugepages=3170.

Иногда ядро не может сразу выделить желаемое количество огромных страниц из-за фрагментации, поэтому может потребоваться повторить эту команду или перезагрузить систему. (Сразу после перезагрузки большая часть памяти компьютера должна стать доступной для преобразования в огромные страницы.) Для проверки ситуации с размещением огромных страниц заданного размера воспользуйтесь:

$ cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages

Также может понадобиться дать пользователю операционной системы сервера баз данных разрешение на использование огромных страниц, добавив его группу в vm.hugetlb_shm_group с помощью sysctl и/или дав разрешение на блокировку памяти, выполнив ulimit -l.

По умолчанию QHB использует огромные страницы стандартного системного размера, когда это возможно, а в противном случае возвращается к использованию обычных страниц. Чтобы заставить ее пользоваться огромными страницами, можно установить для huge_pages значение on в qhb.conf. Обратите внимание, что с этим значением QHB не сможет запуститься, если доступно недостаточно огромных страниц.

Подробное описание механизма огромных страниц в Linux см. в документации ядра.



Завершение работы сервера

Есть несколько способов отключить сервер баз данных. С точки зрения внутренней структуры все они сводятся к передаче различных сигналов управляющему процессу qhb:

  • SIGTERM
    Это режим умного отключения. После получения сигнала SIGTERM сервер запрещает новые подключения, но позволяет существующим сеансам нормально завершить свою работу. Сервер отключается только после завершения всех сеансов. Если сервер находится в состоянии восстановления, то при запросе умного отключения восстановление и потоковая репликация будут остановлены только после завершения всех обычных сеансов.

  • SIGINT
    Это режим быстрого отключения. Сервер запрещает новые подключения и отправляет всем существующим серверным процессам сигнал SIGTERM, заставляя их прервать свои текущие транзакции и быстро завершить работу. Затем он ожидает завершения всех серверных процессов и наконец отключается сам.

  • SIGQUIT
    Это режим немедленного отключения. Сервер отправит сигнал SIGQUIT всем дочерним процессам и будет ждать их завершения. Если они не прекратятся в течение 5 секунд, им будут отправлены сигналы SIGKILL. Управляющий процесс сервера завершается сразу же после завершения всех дочерних процессов, без выполнения обычной процедуры завершения работы базы данных. Это приведет к выполнению процесса восстановления (путем воспроизведения журнала WAL) при следующем запуске. Этот режим отключения рекомендуется использовать только в чрезвычайных ситуациях.

Программа qhb_ctl предоставляет удобный интерфейс для отправки этих сигналов для завершение работы сервера. Кроме того, сигнал можно отправить напрямую командой kill. PID процесса qhb можно найти с помощью программы ps или в файле qhbmaster.pid в каталоге данных. Например, для быстрого отключения можно написать следующее:

$ kill -INT `head -1 /var/lib/qhb/data/qhbmaster.pid`

ВАЖНО!
Лучше не использовать SIGKILL для отключения сервера, так как в этом случае сервер не освободит разделяемую память и семафоры. Кроме того, SIGKILL уничтожает процесс qhb, не позволяя ему передать сигнал своим подпроцессам, поэтому может потребоваться уничтожить вручную и отдельные подпроцессы.

Чтобы завершить отдельный сеанс, при этом не завершая другие сеансы, используйте pg_terminate_backend() (см. таблицу Функции для передачи сигналов серверу) или отправьте сигнал SIGTERM дочернему процессу, связанному с этим сеансом.



Обновление кластера QHB

В этом разделе рассказывается о том, как обновить данные вашей базы данных с одной версии QHB на другую.

Текущие номера версий QHB состоят из номеров основной и дополнительной версий, при этом основная версия образуется группой из первых двух цифр номера версии. Например, в версии 1.4.1 группа 1.4 обозначает основную версию а третья цифра (1) — дополнительную, то есть это первый дополнительный релиз основного релиза 1.4.

В дополнительных релизах никогда не меняется внутренний формат хранения, и они всегда совместимы с предыдущими или последующими дополнительными релизами одного номера основной версии. Например, версия 1.4.1 совместима с версией 1.4.0 и 1.4.2. Для обновления до совместимых версий достаточно просто заменить исполняемые файлы при отключенном сервера и перезапустить его. Обновления дополнительных версий настолько просты, что при этом не затрагивается каталог данных.

При обновлении основных релизов QHB внутренний формат хранения данных может измениться, тем самым усложняя процедуру обновления. Традиционным способом переноса данных в новую основную версию является выгрузка базы данных из старой версии и загрузка ее в новую, хотя это может занять много времени. Более быстрый способ — воспользоваться приложением qhb_upgrade. Также доступны способы с использованием репликации, как описано ниже.

Кроме того, новые основные версии обычно приносят какие-то видимые пользователю несовместимости, поэтому может потребоваться внести изменения в приложения. Все подобные изменения перечисляются в замечаниях к релизу. Хотя вы можете перейти с одной основной версии на другую, не обновляя QHB до промежуточных версий, вам следует обязательно прочитать замечания к каждому пропускаемому релизу.

Осторожные пользователи могут пожелать протестировать свои клиентские приложения на новой версии, прежде чем полностью на нее перейти, поэтому часто имеет смысл установить одновременно старую и новую версии. При тестировании обновления основной версии QHB изучите следующие категории возможных изменений:

Администрирование
Инструменты, доступные администраторам для мониторинга и управления сервером, часто меняются и совершенствуются в каждом основном релизе.

SQL
Обычно сюда входят новые возможности команд SQL, а не изменения в их поведении, если только это специально не указывается в замечаниях к релизу.

API библиотек
Обычно в библиотеки типа libpq только добавляются новые функциональные возможности, опять же, если иное не указывается в замечаниях к релизу.

Системные каталоги
Изменения в системных каталогах обычно влияют только на инструменты управления базами данных.

API сервера для кода на C/RUST
Сюда входят изменения в API серверных функций, которые написаны на языках программирования C/RUST. Подобные изменения влияют на код, обращающийся к серверным функциям глубоко внутри сервера.


Обновление данных посредством qhb_dumpall

Один из методов обновления состоит в выгрузке данных из одной основной версии QHB и загрузке их в другую — для этого необходимо использовать инструмент логического копирования вроде qhb_dumpall; методы резервного копирования на уровне файловой системы не подойдут. (На самом сервере существуют проверки, не дающие использовать каталог данных с несовместимой версией QHB, поэтому попытка запустить с этим каталогом неправильную версию сервера не причинит большого вреда.)

Рекомендуется использовать программы qhb_dump и qhb_dumpall из новой версии QHB, чтобы воспользоваться улучшениями, которые могли в них появиться.

В этих инструкциях предполагается, что ваша существующая установка находится в каталоге /usr/local/qhb, а область данных — в каталоге /var/lib/qhb/data. Подставляйте собственные пути надлежащим образом.

  1. При запуске резервного копирования убедитесь в том, что в базе данных не выполняются изменения. Это не повлияет на целостность копии, но измененные данные в нее, разумеется, не попадут. При необходимости отредактируйте разрешения в файле /var/lib/qhb/data/qhb_hba.conf (или подобном), чтобы запретить доступ к серверу всем, кроме себя. Дополнительную информацию по управлению доступом см. в главе Аутентификация клиентского приложения.

    Чтобы получить резервную копию вашей установки базы данных, введите:

    qhb_dumpall > выходной_файл
    

    Для создания резервной копии можно воспользоваться командой qhb_dumpall из версии, которая у вас запущена в данный момент; подробную информацию см. в подразделе Использование qhb_dumpall. Однако для наилучшего результата попробуйте выполнить qhb_dumpall из новой версии, поскольку в эту версию могут входить исправления ошибок и усовершенствования, которые отсутствуют в предыдущих. Хотя этот совет может показаться абсурдным, поскольку вы еще не установили новую версию, рекомендуем ему последовать, если вы планируете установить новую версию параллельно старой. В этом случае вы можете выполнить установку как обычно, а потом перенести данные. Это также сократит время простоя.

  2. Остановите старый сервер:

    qhb_ctl stop
    

    В системах, где QHB запускается при загрузке, вероятно, должен быть файл запуска, с котором можно добиться того же самого. Например, в системе Red Hat Linux может сработать следующее:

    /etc/rc.d/init.d/qhb stop
    

    Подробнее запуск и остановка сервера описаны в разделах Запуск сервера баз данных и Завершение работы сервера выше.

  3. При восстановлении из резервной копии переименуйте или удалите старый каталог установки, если его имя не привязано к версии. Лучше переименовать каталог, чем уничтожить, на случай, если возникнут проблемы и понадобится его восстановить. Учтите, что этот каталог может занимать на диске много места. Чтобы переименовать каталог, воспользуйтесь следующей командой:

    mv /usr/local/qhb /usr/local/qhb.old
    

    (Обязательно переносите этот каталог как единое целое, чтобы относительные пути в нем не изменились.)

  4. Установите новую версию QHB, как описано в главе Установка.

  5. При необходимости создайте новый кластер баз данных. Помните, что эти команды следует выполнять, войдя в систему под аккаунтом специального пользователя базы данных (что вы уже сделали, если проводите обновление).

    /usr/local/qhb/bin/qhb_bootstrap -D /var/lib/qhb/data
    
  6. Восстановите изменения, внесенные в предыдущие версии qhb_hba.conf и qhb.conf.

  7. Запустите сервер баз данных, тоже из-под аккаунта специального пользователя базы данных:

    /usr/local/qhb/bin/qhb -D /var/lib/qhb/data
    
  8. Наконец, восстановите данные из резервной копии:

    /usr/local/qhb/bin/psql -d qhb -f выходной_файл
    

    используя новый psql.

Минимизировать время простоя сервера можно, установив новый сервер в другой каталог и запустив старый и новый сервера параллельно, но с разными портами. Затем можно выполнить, например, следующее:

qhb_dumpall -p 5432 | psql -d qhb -p 5433

чтобы перенести данные.


Обновление данных посредством qhb_upgrade

Модуль qhb_upgrade позволяет переносить установку с одной основной версии QHB на другую прямо на месте. Обновления могут занять всего несколько минут, особенно в режиме --link. Для него требуются шаги, похожие на описанные выше действия для qhb_dumpall, например, запустить/остановить сервер, выполнить qhb_bootstrap (или initdb). Все необходимые шаги описаны в документации по qhb_upgrade.


Обновление данных посредством репликации

Для создания резервного сервера с обновленной версией QHB также можно использовать методы логической репликации. Это возможно, поскольку логическая репликация поддерживается между разными основными версиями QHB. Резервный сервер может находиться на том же или на другом компьютере. Как только он синхронизируется с основным сервером (где запущена старая версия QHB), вы можете поменять их местами и сделать резервный сервер основным, а старый экземпляр баз данных просто отключить. При таком переключении простой сервера во время обновления длится всего несколько секунд.

Этот метод обновления можно осуществить, используя как встроенные средства логической репликации, так и внешние системы логической репликации, например pglogical, Slony, Londiste и Bucardo.



Предотвращение имитации сервера

Во время работы сервера пользователь-злоумышленник не может подменить нормальный сервер баз данных. Однако когда сервер отключен, локальный пользователь может его имитировать, запустив свой собственный. Поддельный сервер может читать пароли и запросы клиентов, но не может вернуть никаких данных, поскольку каталог PGDATA все равно будет защищен благодаря своим запретам на чтение. Такая имитация возможна, потому что любой пользователь может запустить сервер баз данных; клиент не способен выявить поддельный сервер, если его специально не настроить.

Один из способов предотвратить имитацию локальных подключений (local) состоит в использовании каталога сокетов домена Unix (unix_socket_directories), в который разрешено писать только доверенному локальному пользователю. Это не даст пользователю-злоумышленнику создать в этом каталоге свой файл сокета. Если вас беспокоит, что некоторые приложения все еще могут обращаться к файлу сокета в /tmp и тем самым остаются уязвимыми к подмене, создайте при загрузке операционной системы символическую ссылку /tmp/.s.QHB.5432, указывающую на перемещенный файл сокета. Возможно, вам также понадобится изменить скрипт очистки /tmp, чтобы он не удалял эту ссылку.

Другой вариант для подключений local — использование клиентами параметра requirepeer, чтобы указать имя нужного владельца серверного процесса, подключенного к сокету.

Для предотвращения имитаций TCP-соединений либо используйте SSL-сертификаты и позаботьтесь, чтобы клиенты проверяли сертификат сервера, либо применяйте шифрование GSSAPI (или пользуйтесь и тем, и другим для отдельных подключений).

Для предотвращения имитаций соединения с SSL сервер должен быть настроен так, чтобы принимать только подключения hostssl (раздел Файл qhb_hba.conf) и иметь ключ и файлы сертификатов SSL (раздел Защита TCP/IP-соединений посредством SSL). TCP-клиент должен подключаться к серверу с параметром sslmode=verify-ca или sslmode=verify-full и иметь соответствующий установленный файл корневого сертификата (подраздел Проверка сертификатов сервера на стороне клиента).

Для предотвращения имитаций соединения с GSSAPI сервер должен быть настроен так, чтобы принимать только подключения hostgssenc (раздел Файл qhb_hba.conf) и использовать для них аутентификацию gss. TCP-клиент должен подключаться к серверу с параметром gssencmode=require.



Варианты шифрования

QHB предлагает шифрование на разных уровнях и обеспечивает гибкость в защите данных от раскрытия при краже сервера баз данных, из-за недобросовестных администраторов или в незащищенных сетях. Шифрование также может понадобиться для защиты конфиденциальных данных, например медицинских записей или финансовых транзакций.

Шифрование паролей

Пароли пользователей базы данных хранятся в виде хешей (алгоритм шифрования определяется параметром password_encryption), поэтому администратор не может определить, какой именно пароль принадлежит конкретному пользователю. Если для аутентификации клиента используется шифрование SCRAM или MD5, незашифрованный пароль никогда не присутствует на сервере, даже временно, потому что клиент шифрует его, перед тем как передать по сети. Предпочтительно использовать SCRAM, поскольку это стандарт, принятый в Интернете, и он более безопасен, чем специфический для QHB протокол аутентификации MD5.

Шифрование заданных столбцов

Модуль pgcrypto позволяет хранить зашифрованными определенные поля. Это полезно, если конфиденциальными являются только некоторые данные. Клиент предоставляет ключ дешифрования, и данные дешифруются на сервере, а затем передаются клиенту.

Дешифрованные данные и ключ дешифрования присутствуют на сервере в течение короткого времени, пока происходит дешифрование и обмен данными между клиентом и сервером. Именно в этот момент данные и ключи могут быть перехвачены тем, кто имеет полный доступ к серверу баз данных, например системным администратором.

Шифрование раздела данных

Шифрование хранилища можно осуществить на уровне файловой системы или на уровне блоков. Механизмы шифрования файловых систем в Linux — eCryptfs и EncFS, во FreeBSD — PEFS. Механизмы шифрования на уровне блоков или всего диска в Linux — dm-crypt + LUKS, во FreeBSD — модули GEOM (geli и gbde). Эту функциональность поддерживают и многие другие операционные системы.

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

Шифрование данных при передаче по сети

SSL-соединения шифруют все данные, передаваемые по сети: пароль, запросы и возвращаемые данные. Файл qhb_hba.conf позволяет администраторам указать, какие хосты могут использовать незашифрованные соединения (host), а каким требуются соединения, зашифрованные SSL (hostssl). Кроме того, клиенты могут указать, что они подключаются к серверам только через SSL.

Соединения, зашифрованные GSSAPI, шифруют все данные, передаваемые по сети, включая запросы и возвращаемые данные. (Пароли по сети не передаются.) Файл qhb_hba.conf позволяет администраторам указать, какие хосты могут использовать незашифрованные соединения (host), а каким требуются соединения, зашифрованные GSSAPI (hostgssenc). Кроме того, клиенты могут указать, что они подключаются к серверам только через соединения, зашифрованные GSSAPI (gssencmode=require).

Для шифрования передаваемых данных также можно использовать Stunnel или SSH.

Аутентификация хоста SSL

Клиент и сервер могут предоставлять друг другу SSL-сертификаты. Это требует некоторой дополнительной настройки с каждой стороны, но обеспечивает более надежную проверку идентификационных данных, чем простое использование паролей. Такая проверка не позволяет компьютеру имитировать сервер достаточно долго, чтобы прочитать отправленный клиентом пароль. Также она помогает предотвратить атаки с применением технологии «незаконный посредник», когда компьютер между клиентом и сервером имитирует сервер и считывает и передает все данные между клиентом и настоящим сервером.

Шифрование на стороне клиента

Если системный администратор серверной станции не является доверенным, клиенту необходимо шифровать данные; в этом случае на сервере баз данных незашифрованные данные никогда не появятся. Данные шифруются на стороне клиента, прежде чем передаются серверу, а полученные из базы данных результаты клиенту перед использованием требуется дешифровать.



Защита TCP/IP-соединений посредством SSL

В QHB имеется встроенная поддержка использования SSL-соединений для шифрования передаваемых между клиентом и сервером данных, что повышает их защиту. Для этого необходимо, чтобы в системах клиента и сервера был установлен OpenSSL и чтобы при сборке в QHB была включена поддержка SSL (см. главу Установка).

Термины SSL и TLS часто используются взаимозаменяемо для обозначения защищенного зашифрованного соединения по протоколу TLS. Протоколы SSL являются предшественниками протоколов TLS, поэтому термин SSL по-прежнему используется для зашифрованных соединений, хотя сами протоколы SSL уже не поддерживаются. В QHB термины SSL и TLS тоже используются взаимозаменяемо.


Базовая настройка

После компиляции поддержки SSL сервер QHB можно запустить с поддержкой зашифрованных соединений по протоколам TLS, установив для параметра ssl в файле qhb.conf значение on. Этот сервер будет принимать как обычные, так и SSL-соединения в одном порту TCP и будет согласовывать использование SSL с каждым подключающимся клиентом. По умолчанию клиент выбирает режим подключения сам; о том, как настроить сервер, чтобы он требовал использования SSL для всех или некоторых подключений, рассказывается в разделе Файл qhb_hba.conf.

Для запуска сервера в режиме SSL уже должны существовать файлы, содержащие сертификат сервера и закрытый ключ. По умолчанию ожидается, что эти файлы будут называться server.crt и server.key соответственно и находиться в каталоге данных сервера, но с помощью параметров конфигурации ssl_cert_file и ssl_key_file для них можно задать и другие имена и расположения.

В системах Unix в разрешениях для server.key должен быть прописан запрет на любой доступ группы и всех остальных; это ограничение устанавливается командой chmod 0600 server.key. Либо же этот файл может принадлежать пользователю root, а группа будет иметь доступ на чтение (то есть маска разрешений 0640). Такая настройка предназначена для установок, в которых файлами сертификата и ключа управляет операционная система. В этом случае пользователь, от имени которого запускается сервер QHB, должен быть членом группы, имеющей доступ к этим файлам.

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

Если закрытый ключ защищен парольной фразой, сервер запросит эту фразу и не запустится, пока та не будет введена. По умолчанию использование парольной фразы лишает возможности изменить конфигурацию SSL без перезагрузки сервера, однако, включив параметр ssl_passphrase_command_supports_reload, это можно сделать.

Первым сертификатом в server.crt должен быть сертификат сервера, поскольку он должен соответствовать закрытому ключу сервера. В этот файл также можно добавить сертификаты «промежуточных» центров сертификации. Это избавляет от необходимости хранить промежуточные сертификаты на стороне клиентов при условии, что корневой и промежуточные сертификаты были созданы с расширениями v3_ca. (При этом в основном ограничении сертификата CA устанавливается значение true.) Кроме того, это упрощает работу с промежуточными сертификатами с истекающим сроком действия.

Добавлять корневой сертификат в server.crt нет необходимости. Вместо этого клиенты должны иметь этот сертификат в цепочке сертификатов сервера.


Конфигурация OpenSSL

QHB читает общесистемный файл конфигурации OpenSSL. По умолчанию этот файл называется openssl.cnf и находится в каталоге, который выводится командой openssl version -d. Это можно переопределить, задав в переменной среды OPENSSL_CONF желаемое имя и расположение файла конфигурации.

OpenSSL поддерживает широкий выбор шифров и алгоритмов аутентификации разной степени защищенности. Хотя список шифров можно указать в файле конфигурации OpenSSL, можно задать отдельные шифры для использования конкретно сервером баз данных, изменив параметр ssl_ciphers в qhb.conf.

Примечание
Издержки аутентификации, связанные с шифрованием, можно исключить, используя шифры NULL-SHA или NULL-MD5. Однако незаконный компьютер-посредник сможет читать и передавать трафик между клиентом и сервером. Кроме того, издержки на шифрование минимальны по сравнению с издержками самой аутентификации. По этим причинам использовать шифры NULL не рекомендуется.


Использование клиентских сертификатов

Чтобы обязать клиента предоставлять доверенный сертификат, поместите сертификаты корневых центров сертификации (Certification authority, CA), которым вы доверяете, в файл в каталоге данных, задайте в параметре ssl_ca_file в qhb.conf имя этого файла и добавьте параметр аутентификации clientcert=verify-ca или clientcert=verify-full в соответствующую строку (или строки) hostssl в qhb_hba.conf. После этого в процессе установления SSL-соединения у клиента будет запрашиваться сертификат. (Как настроить сертификаты на стороне клиента, описывается в разделе Поддержка SSL.)

Для записи hostssl с указанием clientcert=verify-ca сервер будет проверять, подписан ли сертификат клиента одним из доверенных центров сертификации. Если указано clientcert=verify-full, сервер будет не только проверять цепочку сертификатов, но и сличать имя пользователя или его сопоставление с общим именем (cn, Common Name) в предоставленном сертификате. Обратите внимание, что при использовании метода аутентификации cert цепочка сертификатов проверяется всегда (см. раздел Аутентификация по сертификату).

Промежуточные сертификаты, образующие цепочку до существующих корневых сертификатов, при желании можно также включить в файл ssl_ca_file, чтобы не хранить их на стороне клиентов (при условии, что корневой и промежуточные сертификаты были созданы с расширениями v3_ca). Если установлен параметр ssl_crl_file или ssl_crl_dir, также проверяются записи в списке отозванных сертификатов (Certificate Revocation List, CRL).

Параметр аутентификации clientcert доступен для всех методов аутентификации, но только в строках qhb_hba.conf типа hostssl. Когда clientcert не задан, сервер проверяет сертификат клиента по своему файлу CA, только если этот сертификат предоставлен, а список CA сконфигурирован.

Существует два способа потребовать от пользователей предоставления сертификатов при входе в систему.

Первый способ заключается в использовании метода аутентификации cert для записей hostssl в qhb_hba.conf, с тем чтобы сам сертификат использовался и для аутентификации, и для защиты SSL-соединения. Подробную информацию см. в разделе Аутентификация по сертификату. (Задавать явно какие-либо значения clientcert при использовании метода аутентификации cert необязательно.) В этом случает предоставленное в сертификате cn сверяется с именем пользователя или применяемым сопоставлением.

Второй способ сочетает использование любого метода аутентификации для записей hostssl с проверкой сертификатов клиента, задаваемой установкой в параметре аутентификации clientcert значения verify-ca или verify-full. Первое значение требует только проверки сертификата, тогда как при втором также проверяется, что cn в сертификате соответствует имени пользователя или применяемому сопоставлению.


Файлы, используемые SSL-сервером

В Таблице 2 кратко описаны файлы, относящиеся к настройке SSL на сервере. (Приведены стандартные имена файлов. В конкретных конфигурациях они могут отличаться.)

Таблица 2. Файлы, используемые SSL-сервером

ФайлСодержимоеНазначение
ssl_cert_file
($PGDATA/server.crt)
сертификат сервераотправляется клиенту для идентификации сервера
ssl_key_file
($PGDATA/server.key)
закрытый ключ сервераподтверждает, что сертификат сервера был отправлен его владельцем; не свидетельствует о том, что этому владельцу можно доверять
ssl_ca_fileдоверенные центры сертификациипроверяет, подписан ли сертификат клиента доверенным центром сертификации
ssl_crl_fileсертификаты, отозванные центрами сертификациисертификата клиента не должно быть в этом списке

Сервер читает эти файлы при запуске или при перезагрузке конфигурации. Если в этих файлах ошибка обнаруживается при запуске сервера, сервер откажется запускаться. Но если ошибка обнаруживается при перезагрузке конфигурации, эти файлы игнорируются и продолжает использоваться старая конфигурация SSL. Во всех таких случаях ошибка протоколируется в журнал сервера.


Создание сертификатов

Чтобы создать для сервера простой самоподписанный сертификат, действующий 365 дней, воспользуйтесь следующей командой OpenSSL, заменив хостбд.вашдомен.com именем хоста сервера:

openssl req -new -x509 -days 365 -nodes -text -out server.crt \
  -keyout server.key -subj "/CN=хостбд.вашдомен.com"

Затем выполните:

chmod og-rwx server.key

так как сервер не примет этот файл, если разрешения будут менее строгими, чем указанные. Более подробную информацию о том, как создать собственный закрытый ключ и сертификат, см. в документации OpenSSL.

Хотя самоподписанный сертификат можно использовать при тестировании, в условиях промышленной эксплуатации следует использовать сертификат, подписанный центром сертификации (CA) (обычно это корневой CA уровня предприятия).

Чтобы создать сертификат сервера, подлинность которого смогут проверять клиенты, сначала создайте запрос на подпись сертификата (certificate signing request, CSR) и файлы открытого/закрытого ключа:

openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=корень.вашдомен.com"
chmod og-rwx root.key

Затем подпишите запрос ключом, чтобы создать корневой центр сертификации (используя стандартное расположение файла конфигурации OpenSSL в Linux):

openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

Наконец, создайте сертификат сервера, подписанный новым корневым центром сертификации:

openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=хостбд.вашдомен.com"
chmod og-rwx server.key

openssl x509 -req -in server.csr -text -days 365 \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out server.crt

Файлы server.crt и server.key должны храниться на сервере, а файл root.crt — на клиенте, чтобы клиент мог убедиться, что листовой сертификат был подписан доверенным корневым сертификатом. Файл root.key должен храниться на локальной машине, чтобы его можно было использовать для создания сертификатов в будущем.

Также можно создать цепочку доверия, включающую промежуточные сертификаты:

# корневой сертификат
openssl req -new -nodes -text -out root.csr \
  -keyout root.key -subj "/CN=корень.вашдомен.com"
chmod og-rwx root.key
openssl x509 -req -in root.csr -text -days 3650 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -signkey root.key -out root.crt

# промежуточный сертификат
openssl req -new -nodes -text -out intermediate.csr \
  -keyout intermediate.key -subj "/CN=промежуток.вашдомен.com"
chmod og-rwx intermediate.key
openssl x509 -req -in intermediate.csr -text -days 1825 \
  -extfile /etc/ssl/openssl.cnf -extensions v3_ca \
  -CA root.crt -CAkey root.key -CAcreateserial \
  -out intermediate.crt

# листовой сертификат
openssl req -new -nodes -text -out server.csr \
  -keyout server.key -subj "/CN=хостбд.вашдомен.com"
chmod og-rwx server.key
openssl x509 -req -in server.csr -text -days 365 \
  -CA intermediate.crt -CAkey intermediate.key -CAcreateserial \
  -out server.crt

Файлы server.crt и intermediate.crt следует объединить в комплект файлов сертификатов и хранить на сервере. Файл server.key тоже должен храниться на сервере. Файл root.crt должен храниться на клиенте, чтобы клиент мог убедиться, что листовой сертификат был подписан цепочкой сертификатов, ведущей к доверенному корневому сертификату. Файлы root.key и intermediate.key должны храниться на локальной машине, чтобы их можно было использовать для создания сертификатов в будущем.



Защита TCP/IP-соединений посредством шифрования GSSAPI

В QHB также имеется встроенная поддержка применения GSSAPI для шифрования передаваемых между клиентом и сервером данных, что повышает их защиту. Для поддержки необходимо, чтобы как на клиенте, так и на сервере была установлена реализация GSSAPI (например, MIT Kerberos) и чтобы эта поддержка была включена в QHB при сборке (см. главу Установка).

Сервер QHB будет принимать как как обычные, так и зашифрованные GSSAPI соединения в одном порту TCP и будет согласовывать использование GSSAPI для шифрования (и аутентификации) с каждым подключающимся клиентом. По умолчанию клиент выбирает режим подключения сам (это означает, что злоумышленник может от него отказаться); о том, как настроить сервер, чтобы он требовал использования GSSAPI для всех или некоторых подключений, рассказывается в разделе Файл qhb_hba.conf.

При использовании GSSAPI для шифрования его часто применяют также и для аутентификации, поскольку нижележащий механизм в любом случае будет проверять подлинность клиента и сервера (в соответствии с реализацией GSSAPI). Но это необязательно; для проведения дополнительной проверки можно выбрать любой другой метод аутентификации, поддерживаемый QHB.

Кроме конфигурации поведения при согласовании другой настройки для шифрования GSSAPI не требуется, не считая тех, которые необходимы для аутентификации GSSAPI. (Подробную информацию о том, как это настроить, см. в разделе Аутентификация GSSAPI.)



Защита TCP/IP-соединений посредством туннелей SSH

Для шифрования сетевых соединений между клиентом и сервером QHB можно использовать SSH. Сделанное должным образом, оно обеспечивает надлежащую защиту сетевых соединений даже для клиентов, не поддерживающих SSL.

Сначала убедитесь, что на компьютере с сервером QHB нормально работает сервер SSH и что вы можете подключиться к нему с помощью ssh под именем какого-нибудь пользователя; затем вы сможете установить защищенный туннель к этому удаленному серверу. Защищенный туннель прослушивает локальный порт и перенаправляет весь трафик в порт удаленного компьютера. Трафик, отправляемый в удаленный порт, может поступить на его адрес localhost или, при желании, на другой привязанный адрес; при этом он не будет выглядеть как поступивший с вашего компьютера. Следующая команда создает защищенный туннель между клиентским компьютером и удаленным компьютером foo.com:

ssh -L 63333:localhost:5432 joe@foo.com

Первое число в аргументе -L, 63333, — это локальный номер порта туннеля; это может быть любой незанятый порт. (IANA резервирует порты с 49152 по 65535 для частного использования.) Имя или IP-адрес после этого — удаленный привязанный адрес, к которому вы подключаетесь; здесь это localhost (это значение по умолчанию). Третье число, 5432, — удаленная сторона туннеля, например номер порта, который использует ваш сервер баз данных. Чтобы подключиться к данному серверу с помощью этого туннеля, вы подключаетесь к порту 63333 на локальном компьютере:

psql -h localhost -p 63333 qhb

Тогда для сервера баз данных это будет выглядеть так, как будто вы пользователь joe на хосте foo.com, подключающийся к привязанному адресу localhost, и он будет применять ту процедуру аутентификации, которая была установлена для подключений этого пользователя к этому привязанному адресу. Обратите внимание, что сервер не будет считать такое соединение зашифрованным SSL, поскольку на самом деле трафик между сервером SSH и сервером QHB не зашифрован. Это не должно представлять какой-то дополнительной угрозы безопасности, так как эти серверы находятся на одном компьютере.

Чтобы настроенный туннель работал, вам должно быть разрешено подключаться к компьютеру посредством ssh под именем joe@foo.com аналогично тому, как если бы вы пытались использовать ssh для создания сеанса работы с терминалом.

Кроме того, вы можете настроить перенаправление портов следующим образом:

ssh -L 63333:foo.com:5432 joe@foo.com

но тогда сервер баз данных увидит подключение как приходящее на его привязанный адрес foo.com, который не прослушивается вследствие установки по умолчанию listen_addresses = 'localhost'. Обычно это не то, что вам нужно.

Если вам нужно «перескочить» к серверу баз данных через некоторый регистрационный хост, возможная настройка может выглядеть примерно так:

ssh -L 63333:db.foo.com:5432 joe@shell.foo.com

Обратите внимание, что в этом случае трафик между shell.foo.com и db.foo.com не будет зашифрован туннелем SSH. SSH предлагает довольно много вариантов конфигурации, где ограничения сети организованы разными способами. Подробную информацию см. в документации SSH.

Совет
Существует еще несколько приложений, которые могут создавать безопасные туннели, используя процедуру, схожую по сути с описанной выше.



Улучшенная безопасность. Очистка памяти

QHB предоставляет возможность перед удалением данных выполнить соответствующую очистку памяти, то есть выполнить перезапись этих данных нулевыми байтами. Управление данными возможностями осуществляется с помощью соответствующих конфигурационных параметров в файле конфигурации qhb.conf (подробную информацию см. в подразделе Очистка памяти с повышенной безопасностью).