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

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

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

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

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

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

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

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

qhb_bootstrap -D /usr/local/qhb/data

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

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

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

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

Если работаем от root используем:

root# mkdir /usr/local/qhb/data
root# chown qhb /usr/local/qhb
root# sudo -u qhb ./qhb_bootstrap -D /usr/local/qhb/data

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

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

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

Однако, хотя содержимое каталога является безопасным, настройка аутентификации клиента по умолчанию позволяет любому локальному пользователю подключаться к базе данных и даже стать суперпользователем базы данных. Если вы не доверяете другим локальным пользователям, мы рекомендуем использовать один из параметров qhb_bootstrap -W, --pwprompt или --pwfile, чтобы назначить пароль суперпользователю базы данных. Кроме того, укажите пароль -A md5 или -A password чтобы режим проверки подлинности по умолчанию не использовался; или измените созданный файл qhb_hba.conf после запуска qhb_bootstrap, но перед первым запуском сервера. Другие разумные подходы включают использование peer аутентификации или разрешений файловой системы для ограничения соединений.

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

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

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

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

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

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

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

NFS

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

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

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

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

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

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

qhb# qhb -D /usr/local/qhb/data
root# sudo -u qhb ./qhb -D /usr/local/qhb/data

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

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

$ qhb -D /usr/local/qhb/data >logfile 2>&1 &

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

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

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

qhb_ctl start -l logfile

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

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

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

su qhb -c 'qhb_ctl start -D /usr/local/qhb/data -l serverlog'

Вот еще несколько предложений для запуска :

  • добавьте в /etc/rc.d/rc.local или /etc/rc.local
/usr/local/qhb/bin/qhb_ctl start -l logfile -D /usr/local/qhb/data
  • или используйте файл contrib/start-scripts/linux в исходном дистрибутиве QHB.

  • при использовании systemd вы можете использовать следующий файл для systemd (например, в /etc/systemd/system/qhb.service):

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

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

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

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

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

LOG:  could not bind IPv4 address "127.0.0.1": Address already in use
HINT:  Is another postmaster already running on port 5432? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

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

$ qhb -p 777
LOG:  could not bind IPv4 address "127.0.0.1": Permission denied
HINT:  Is another postmaster already running on port 777? If not, wait a few seconds and retry.
FATAL:  could not create any TCP/IP sockets

Сообщение :

FATAL:  could not create shared memory segment: Invalid argument
DETAIL:  Failed system call was shmget(key=5440001, size=4011376640, 03600).

вероятно, означает, что ограничение вашего ядра на размер разделяемой памяти меньше, чем рабочая область, которую пытается создать QHB (4011376640 байт в этом примере). Или это может означать, что в вашем ядре вообще не настроена поддержка разделяемой памяти System V. В качестве временного решения можно попробовать запустить сервер с меньшим, чем обычно, числом буферов ( shared_buffers). В конечном итоге необходимо перенастроить ядро ОС, чтобы увеличить допустимый размер разделяемой памяти. Это сообщение также может появиться при попытке запустить несколько серверов на одном компьютере, если их общее запрошенное пространство превышает ограничение ядра.

Ошибка :

FATAL:  could not create semaphores: No space left on device
DETAIL:  Failed system call was semget(5440126, 17, 03600).

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

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

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

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

qsql: could not connect to server: Connection refused
        Is the server running on host "server.joe.com" and accepting
        TCP/IP connections on port 5432?

Это общая ошибка «Я не могу найти сервер для связи». Выглядит как ошибка при попытке установить связь TCP/IP. Распространенная ошибка - забыть включить настройки сервера для разрешения соединений по TCP/IP.

В качестве альтернативы, при попытке соединения с локальным сервером с использованием доменных сокетов Unix вы получите:

qsql: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/tmp/.s.PGSQL.5432"?

Последняя строка полезна для проверки того, что клиент пытается подключиться в нужное место. Если на самом деле не работает ни один сервер, сообщение об ошибке в ядре обычно будет либо « onnection refused либо No such file or directory, важно понимать, что в этом контексте Connection refused в соединении, не означает, что сервер получил ваш запрос на соединение и отклонил его. В этом случае будет выдано другое сообщение, которое указывают на более фундаментальные проблемы, такие как отсутствие сетевого подключения.

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

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

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

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

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

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

$ kill -INT `head -1 /usr/local/qhb/data/qhbmaster.pid`

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

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