53.1. Обзор#

53.1. Обзор

53.1. Обзор #

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

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

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

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

Нормальная работа имеет дополнительные подпротоколы для специальных операций, таких как COPY.

Возможно сжатие данных протокола для уменьшения трафика и ускорения взаимодействия клиента и сервера. Сжатие особенно полезно для импорта/экспорта данных в/из базы данных с использованием команды COPY и для репликации (как физической, так и логической). Сжатие также может сократить время ответа сервера для запросов, возвращающих большое количество данных (например, JSON, BLOB, текст и т. д.). В настоящее время поддерживаются две библиотеки: zlib (по умолчанию) и lz4 (если Postgres был настроен с опцией --with-lz4).

53.1.1. Обзор передачи сообщений #

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

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

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

53.1.2. Обзор расширенного запроса #

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

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

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

53.1.3. Форматы и коды форматирования #

Данные определенного типа могут передаваться в любом из нескольких различных форматов. Начиная с Tantor SE7.4, поддерживаются только форматы "текст" и "бинарный", но протокол предусматривает возможность для будущих расширений. Желаемый формат для любого значения указывается с помощью кода формата. Клиенты могут указывать код формата для каждого передаваемого параметра и для каждого столбца результата запроса. Текст имеет код формата ноль, бинарный имеет код формата один, и все остальные коды формата зарезервированы для будущего определения.

Текстовое представление значений - это любые строки, создаваемые и принимаемые функциями преобразования ввода/вывода для конкретного типа данных. В передаваемом представлении нет завершающего нулевого символа; фронтенд должен добавить его к полученным значениям, если хочет обрабатывать их как строки на языке C. (Кстати, текстовый формат не позволяет вставлять нулевые символы).

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