1.1Kпросмотров
30 декабря 2025 г.
stats📷 ФотоScore: 1.2K
Part 2: Simple / Extended Protocol Тут будут краткие выдержки из статьи, которая, на мой взгляд, максимально понятно раскрывает плюсы и минусы использования обоих протоколов с учетом всех обновлений. Вообще поддерживаются несколько протоколов передачи запросов (если можно там выразиться), которые в основном разделяются на Simple и Extended. Simple Protocol отправляет весь запрос одной raw строкой, где драйвер в одном проходе выполняет все этапы - parse, analyze, plan и execute. Этот подход прост и не требует хранения состояния, но плохо подходит для повторяющихся запросов: каждый вызов заново проходит полный цикл разбора и планирования. Extended Protocol разбивает выполнение запроса на отдельные шаги — Parse, Bind и Execute. Это позволяет переиспользовать уже разобранные и спланированные запросы, снижая нагрузку на сервер (в том числе за счет prepared statements, о которых говорила ранее, как благодаря им избегаем повторного парсинга и планирования при повторяющихся вызовах). Кроме того, Extended Protocol поддерживает binary формат передачи данных для параметров и результатов, что уменьшает сетевой трафик и расходы на сериализацию, что особенно заметно на типах UUID, TIMESTAMP, INT, BIGINT, BOOLEAN, BYTEA. Например, UUID в текстовом виде занимает 36 байт, тогда как в бинарном - всего 16. Для TIMESTAMP разница ещё больше: 29 байт против 8. В статье есть пример с таблицей на 100к строк, где результат показал профит почти в 2 раза от передачи по сети запросов в через Extended Protocol (binary) против Simple протокола. То есть передаем почти в два раза меньше данных, не меняя запроса и аргументы. По умолчанию pgx использует QueryExecModeCacheStatement протокол, который полностью поддерживает возможности Extended Protocol, включая binary format, но еще кеширует метадату на уровне pgx. poolConfig.ConnConfig.DefaultQueryExecMode = pgx.QueryExecModeCacheStatement Выводы + инвалидация кеша в случае отмены запроса Об успешности этой пары PGBouncer + pgx + QueryExecModeCacheStatement написали и в комментах к issue 791 Но отметили важный нюанс: работу с таймаутами. Отмена запросы через context.WithTimeout может приводить к некорректному разрыву соединений с PgBouncer. И чтобы вовремя инвалидировать кэш prepared statements при отмене запросы, в prod-конфигурациях рекомендуют ставить statement_timeout на стороне PGBouncer специально небольшим, а клиентский timeout из контекстам наоборот сильно выше. Как только попробуем в январе перейти на такую сборку, расскажу о результатах) А пока хочу поздравить всех с наступающим Новым годом, пусть он будет полон вдохновения, идей и интересных проектов🎄✨