Глава 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.