Перейти к основному содержимому

Глава 03. Клиентское подключение

В этой главе:

  • Клиент - серверное взаимодействие.
  • Этапы взаимодействия клиента и сервера.
  • Параметры соединения.
  • Сокеты.
  • Настройки сервера для сокетов Информация о сервере.
  • Получение информации о сеансе Библиотека libpq.

Клиент - серверное взаимодействие

PostgreSQL реализует классическую схему клиент-серверного взаимодействия. При запуске исполняемого файла postgres он запускает несколько дочерних процессов (процессы экземпляра), выполняющих различные задачи, и открывает Unix сокет и несколько сетевых портов, посредством которых клиенты могут подключаться к серверу.

Процессы экземпляра поддерживают базы данных кластера в работоспособном состоянии, а при появлении запроса клиента на установку соединения запускается индивидуальный серверный процесс для его обслуживания. Процессы экземпляра обмениваются информацией посредством стандартных средств межпроцессного взаимодействия IPC (Inter Process Communications). См. man 2 ipc и man ipcs.

Клиент и серверный процесс, его обслуживающий, взаимодействуют с помощью сетевого протокола прикладного уровня (Application Layer OSI), использующего в качестве транспорта протокол TCP, либо Unix сокет. Протокол открытый и допускает различные реализации. https://www.postgresql.org/docs/15/protocol.html.

Однако, наиболее простой способ - использовать штатную клиентскую библиотеку libpq с широким набором возможностей. https://www.postgresql.org/docs/15/libpq.html.

В любом случае, клиент формирует запрос SQL и по сетевому протоколу отправляет его серверу, дожидаясь от него ответа.

Этапы взаимодействия клиента и сервера

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

Протокол поддерживает сетевые соединения TCP/IP и локальные Unix сокеты.

В зависимости от настроек сервер может отклонить соединение, либо продолжить его. Если настроена аутентификация, то сервер требует:

  • идентификации клиента, когда клиент сообщает, кто он такой;
  • аутентификации, то есть, подтверждения, что это именно он.

При успешной аутентификации дальнейшее обслуживание клиента осуществляет серверный процесс (backend).

После подключения через Unix сокет или посредством TCP сессии, клиент инициирует взаимодействие по прикладному протоколу PostgreSQL. И это еще не значит, что сеанс действительно запустится, так как в большинстве случаев клиент должен пройти процедуру аутентификации, для чего PostgreSQL предоставляет разные возможности, описанные в главе "Авторизация и аутентификация". Так, например, сервер должен проверить аутентичность клиента, а клиент, при использовании сертификатов SSL, может проверить аутентичность самого сервера, исключая его подмену. https://www.postgresql.org/docs/15/client-authentication.html.

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

Параметры соединения

$ psql
psql (15.5)
Введите "help", чтобы получить справку. student=> \conninfo
You are now connected to database "student" as user "student" via socket in
"/tmp" at port "5432".
  • student - База данных, к которой производится соединение.
  • student - Пользователь, зарегистрированный в СУБД.
  • tmp - Адрес или имя сервера, либо путь к Unix сокету.
  • 5432 - TCP порт, по умолчанию 5432 в PostgreSQL. В Pangolin порт TCP по умолчанию - 5433 по соображениям безопасности.

Команда psql запускает интерактивную оболочку стандартного клиента PostgreSQL, подробнее о котором будет рассказано в главе 4. PostgreSQL в виртуальной машине специально настроен так (вплоть до главы 11), что не требуется подтверждения аутентичности пользователя. Поэтому на приглашения ввести пароль, ни каких-либо других процедур аутентификации не производилось. Встроенная команда (метакоманда в терминах psql) \conninfo информирует о том, как выполнено соединение. В данном случае - через Unix сокет в каталоге /tmp.

Сокеты

$ sudo -u postgres ss -ln | grep 5432
u_str LISTEN 0 tcp LISTEN 0 tcp LISTEN 0
290 290 290
/tmp/.s.PGSQL.5432 20416 0.0.0.0:5432 [::]:5432
* 0 0.0.0.0:* [::]:*
$ sudo -u postgres lsof /tmp/.s.PGSQL.5432
COMMAND PID USER FD TYPE
postgres 819 postgres 7u unix 0x000000008828accb 0t0 20416 /tmp/.s.PGSQL.5432 type=STREAM

Сетевые соединения производятся через сокеты:

– Unix сокеты - файлы особого типа, только локальное соединение; – Internet сокеты привязаны к сетевым интерфейсам.

Команда ss выводит состояние сокетов. Команда lsof информирует о процессах, работающих с файлом.

Команда ss (Socket Status) с опцией -l показывает открытые Unix сокеты и порты TCP (или UDP). Опция -n команды ss нужна для вывода информации в числовом виде. Нас интересует порт TCP 5432 - порт по умолчанию для PostgreSQL (в Pangolin по требованиям безопасности обычно используют иной порт TCP). См. man ss.

Unix сокеты - один из способов межпроцессного взаимодействия IPC (в MS Windows не поддерживается). Сокеты - это файлы особого типа. Например:

$ sudo find /tmp -type s -iname '*sql*' -ls 2>/dev/null
265667 0 srwxrwxrwx 1 postgres postgres 0 окт 18
13:24 /tmp/.s.PGSQL.5432
$ sudo lsof /tmp/.s.PGSQL.5432 2>/dev/null
COMMAND PID USER FD TYPE DEVICE SIZE/OFF
NODE NAME
postgres 116380 postgres 7u unix 0x0000000045d05bdc 0t0
1560935 /tmp/.s.PGSQL.5432 type=STREAM

В каталоге /tmp есть файл .s.PGSQL.5432 - Unix сокет, что показывает команда find, которая нашла все Unix сокеты в /tmp, в имени которых есть подстрока sql с игнорированием регистра. Командой lsof подтверждено, что файл открыт процессом postgres. См. man find, man lsof.

Настройки сервера для сокетов

$ postgres -C listen_addresses 2> /dev/null *
$ postgres -C port 2> /dev/null
5432
$ postgres -C unix_socket_directories 2> /dev/null /tmp
  • -h - указывает адреса сетевых интерфейсов для Internet сокетов, параметр listen_addresses (* - все адреса).
  • -p - прослушиваемый порт, параметр port.
  • -k - каталог для Unix сокетов, параметр unix_socket_directories.
  • В примере опция -C выводит значения параметров конфигурации.

Исполняемый файл postgres с машинным кодом PostgreSQL имеет опцию -C, позволяющую выводить параметры конфигурации сервера. В примере на слайде показано, что параметр настройки listent_addresses указывает прослушивать все имеющиеся сетевые интерфейсы (по умолчанию прослушивается только loopback интерфейс localhost). Настройка post показывает порт TCP - 5432. Параметр unix_socket_directories задает каталог файловой системы, где будет размещен Unix сокет. См. man postgres.https://www.postgresql.org/docs/15/app-postgres.html.

Информация о сервере

$ sudo -u postgres cat $PGDATA/postmaster.pid
819 //PID головного процесса
/pgdata/06/data // Каталог данных
1726069733 // Время запуска
5432 // Порт
/tmp
*
786435 0
ready

При старте экземпляра создается файл postmaster.pid. Ранее главный процесс экземпляра назывался postmaster, поэтому файл унаследовал это имя.

Содержимое файла (с первой строки к последней):

  • PID головного процесса;
  • каталог данных кластера;
  • время старта кластера;
  • порт, прослушиваемый сервером; каталог Unix сокета; прослушиваемые интерфейсы; идентификатор разделяемой памяти; статус сервера. https://www.postgresql.org/docs/15/storage-file-layout.html.

Получение информации о сеансе

$ psql -qtU postgres -d student
postgres@student=# SELECT user; -- Пользователь в сеансе
postgres
postgres@student=# SELECT current_catalog; -- База данных, к которой подключились
student
postgres@student=# SELECT inet_server_port (); -- NULL через Unix сокет
postgres@student=# \c - - localhost
postgres@student=# SELECT inet_server_port (); -- Подключение через Internet сокет
5432
postgres@student=# SELECT inet_server_addr (); -- Адрес сервера IPv6 ::1
postgres@student=# \c - - 127.0.0.1
postgres@student=# SELECT inet_server_addr (); -- Адрес сервера IPv4
127.0.0.1

Открыв сеанс можно получить данные о нем и о сервере с помощью специальных функций:

  • user - имя пользователя в сеансе;
  • current_catalog - название БД, к которой выполнено подключение в данном сеансе;
  • inet_server_port() - порт TCP;
  • inet_server_addr() - IP адрес сервера.

https://www.postgresql.org/docs/15/functions-info.html.

Библиотека libpq

Стандартная библиотека libpq реализует протокол PostgreSQL. Имеет средства разбора строки подключения. В строке подключения параметры задаются в виде пар ключ-значение, либо в виде URI.

Основные параметры:

  • host задает имя узла или путь к Unix сокету для подключения;
  • hostaddr - имя узла для подключения без разрешения имен (resolve);
  • port - TCP порт для подключения;
  • dbname - имя БД для подключения;
  • user устанавливает имя пользователя, подключающегося к БД;
  • password - пароль.

Стандартная библиотека, реализующая API для подключения клиента к серверу. Большинство клиентов скомпилировано с этой библиотекой для работы с PostgreSQL. Например:

[postgres@p620 ~]$ ldd `which psql`
linux-vdso.so.1 (0x00007ffdc5d57000)
libpq.so.5 => /usr/pangolin/lib/libpq.so.5
(0x00007f6792efa000)
...

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

  • host - имя узла или путь к Unix сокету для подключения;
  • hostaddr - имя узла для подключения без разрешения имен (resolve);
  • port - TCP порт для подключения;
  • dbname - имя БД для подключения;
  • user - имя пользователя, подключающегося к БД;
  • password - пароль.

https://www.postgresql.org/docs/15/libpq.html.

Итоги

  • Клиент инициирует соединение с сервером, формирует запросы, а сервер их обрабатывает и отвечает клиенту.
  • Соединение через Unix или Internet сокет, в зависимости от настроек требуется аутентификация.
  • Для соединения необходимы адрес сервера, порт, имя БД и имя пользователя.
  • Прослушиваемые сервером сокеты настраиваются и ограничивают круг клиентов, которые могут подключиться.
  • Имеются средства для получения информации о сервере и сеансе.
  • Стандартная библиотека libpq реализует клиент - серверный протокол PostgreSQL.