Уровень 2.0
Клиентское подключение
В этом разделе рассмотрим, как происходит подключение к серверу баз данных – с локальной машины и по сети, через Unix-сокеты и TCP/IP.
Клиент-серверное взаимодействие
PostgreSQL как и СУБД Pangolin реализует классическую схему клиент-серверного взаимодействия. Когда сервер запускается, происходит следующее:
Сначала запускается головной процесс postmaster. Этот процесс запускает несколько дочерних процессов (процессы экземпляра), поддерживающих базы данных кластера в работоспособном состоянии, и открывает Unix-сокет и несколько сетевых портов, с помощью которых клиенты могут подключаться к серверу. Когда приходит клиент, головной процесс запускает отдельный серверный процесс для его обслуживания.

Процессы экземпляра обмениваются информацией между собой с помощью стандартных средств межпроцессного взаимодействия – IPC (Inter Process Communications). Это могут быть разделяемая память, очереди сообщений. Чтобы увидеть подробности, воспользуйтесь командами man 2 ipc и man ipcs.
Клиент и обслуживающий его серверный процесс взаимодействуют с помощью сетевого протокола прикладного уровня (Application Layer OSI). Этот протокол работает через TCP/IP для сетевых подключений или через Unix-сокеты для локальных. Протокол открытый и допускает различные реализации.
Наиболее простой способ — использовать штатную клиентскую библиотеку libpq с широким набором возможностей.
В любом случае клиент формирует запрос SQL и по сетевому протоколу отправляет его серверу, дожидаясь от него ответа.
Этапы взаимодействия клиента и сервера
Клиент инициирует соединение с сервером, используя специальный сетевой протокол PostgreSQL, основанный на сообщениях. Протокол поддерживает сетевые соединения TCP/IP и локальные Unix-сокеты.
В зависимости от настроек сервер может отклонить соединение либо продолжить его. Если настроена аутентификация, то сервер требует:
- идентификацию клиента — когда клиент сообщает, кто он такой;
- аутентификацию – подтверждение, что это именно он.
При успешной аутентификации дальнейшее обслуживание клиента осуществляет серверный процесс (backend).
Все взаимодействие клиента с экземпляром после успешной аутентификации происходит с серверным процессом, который будет обслуживать клиента в течение всей сессии. Как только сессия прерывается, этот серверный процесс автоматически завершается.
Параметры соединения
Типичное подключение через клиент psql:
[student@ServerName ~]$ psql
psql (15.5)
Type "help" for 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.
Встроенная команда (метакоманда в терминах psql) \conninfo информирует о том, как выполнено соединение. В данном случае — через Unix-сокет в каталоге /tmp.
Сокеты
Сетевые соединения производятся через сокеты:
- Unix-сокеты — файлы особого типа, работают только для локальных соединений;
- Internet-сокеты — привязаны к сетевым интерфейсам.
Посмотрим, какие сокеты открыты на сервере:
[student@ServerName ~]$ sudo -u postgres ss -ln | grep 5432
Где:
ss(socket status) – утилита для просмотра информации о сокетах. Читайте о нем вman ss;-l– показывает только слушающие сокеты;-n– выводит адреса и порты в числовом формате.
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:* [::]:*
А что в выводе?
Значение полей в выводе:
| Поле | Описание |
|---|---|
u_str/tcp | тип сокета (Unix stream или TCP) |
LISTEN | состояние сокета (ожидание подключений) |
0 | количество байт в очереди приема |
290 | максимальная длина очереди ожидания (backlog) |
| адрес сокета | путь к Unix-сокету (/tmp/.s.PGSQL.5432) или IP-порт |
0 0.0.0.0:* | удаленный адрес (для слушающих всегда * – любой) |
Исходя из этого, вот что мы видим:
- Unix-сокет –
/tmp/.s.PGSQL.5432. Он слушает локальные соединения через файл сокета. Число20416– это inode этого файла, по которому его можно идентифицировать в файловой системе. - TCP-сокет IPv4 –
0.0.0.0:5432. Прослушивает все сетевые интерфейсы (адрес0.0.0.0означает любой) на порту 5432. - TCP-сокет IPv6 –
[::]:5432. Аналогичяно для протокола IPv6.
Unix-сокеты — один из способов межпроцессного взаимодействия IPC (в MS Windows не поддерживается). Сокеты — это файлы особого типа. Например:
[student@ServerName ~]$ 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
[student@ServerName ~]$ 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:
[postgres@ServerName ~]$ postgres -C listen_addresses 2> /dev/null
*
[postgres@ServerName ~]$ postgres -C port 2> /dev/null
5432
[postgres@ServerName ~]$ postgres -C unix_socket_directories 2> /dev/null
/tmp
Разбор команд:
postgres– обращение к исполняемому файлу;-C– выводит параметры конфигурации сервера;listen_addresses/-h– сетевые интерфейсы для Internet-сокетов (*– все интерфейсы, по умолчанию прослушивается толькоloopbackинтерфейсlocalhost);port/-p– TCP-порт, который прослушивает сервер (5432);unix_socket_directories/-k– каталог файловой системы, где будет размещен Unix-сокет (/tmp).
Информация о сервере
При старте экземпляра в каталоге PGDATA создается файл postmaster.pid. Ранее головной процесс экземпляра назывался postmaster, поэтому файл унаследовал это имя. Он содержит служебную информацию о работающем процессе:
[student@ServerName ~]$ sudo -u postgres cat $PGDATA/postmaster.pid
819
/pgdata/06/data
1726069733
5432
/tmp
*
786435 0
ready
Содержимое файла от первой строки к последней:
- PID головного процесса;
- Каталог данных кластера;
- Время старта кластера (в секундах с эпохи Unix);
- Порт, прослушиваемый сервером;
- Каталог Unix-сокета;
- Прослушиваемые интерфейсы;
- Идентификатор разделяемой памяти;
- Статус сервера.
Получение информации о сеансе
В открытом сеансе можно получить данные о нем и о сервере с помощью специальных функций:
[postgres@ServerName ~]$ psql -qtU postgres -d student
postgres@student=# SELECT user; -- Имя пользователя в сеансе
postgres
postgres@student=# SELECT current_catalog; -- Имя базы данных, к которой подключились
student
postgres@student=# SELECT inet_server_port (); -- Порт TCP (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
Метакоманда \c выполняет переключение с новыми параметрами (в примере – смена адреса сервера).
Библиотека libpq
Большинство клиентов (включая psql) скомпилировано с библиотекой libpq для работы с СУБД Pangolin:
[postgres@ServerName ~]$ ldd `which psql`
linux-vdso.so.1 (0x00007ffdc5d57000)
libpq.so.5 => /usr/pangolin/lib/libpq.so.5
(0x00007f6792efa000)
...
Что тут видно?
Разбор использованных команд:
which psql– показывает полный путь к исполняемому файлу psql;- обратные кавычки – подставляют результат выполнения команды как аргумент для
ldd; ldd– утилита для вывода зависимостей от динамических библиотек (подробнее можно прочитать в справкеman ldd).
В примере видно, что для работы psql необходима библиотека libpq.so.5, которая реализует протокол взаимодействия с сервером.
libpq предоставляет API для подключения клиента к серверу и реализует разбор параметров строк подключения. Параметры задаются в виде пар ключ-значение, либо в виде URI.
Основные параметры подключения:
host— задает имя узла или путь к Unix-сокету для подключения;hostaddr— имя узла для подключения без разрешения имен (resolve);port— TCP-порт для подключения;dbname— имя БД для подключения;user— устанавливает имя пользователя, подключающегося к базе данных;password— пароль.
Подведем итоги
- Клиент инициирует соединение с сервером, формирует запросы, а сервер их обрабатывает и отвечает клиенту;
- Соединение происходит через Unix-сокет или Internet-сокет. В зависимости от настроек может требоваться аутентификация;
- Для соединения необходимы адрес сервера, порт, имя базы данных и имя пользователя;
- Прослушиваемые сервером сокеты настраиваются и ограничивают круг клиентов, которые могут подключиться.
Самопроверка
Вопрос 1
Какие параметры нужно указать при подключении к серверу? Не рассматриваем случай, когда некоторые утилиты могут брать значения по умолчанию. Если параметры не заданы явно, укажите, что является параметрами подключения в общем случае.
Вопрос 2
Что означает значение параметра listen_addresses = 0.0.0.0 ?
Вопрос 3
Какую информацию о сервере можно получить из файла PGDATA/postmaster.pid?
Вопрос 4
Какой метакомандой psql можно получить информацию о текущем подключении?