Аналитика Telegram-канала
Подписчики
288
Охват за 24 ч
68
ER за 24 ч
23,61%
Публикаций
137

Динамика подписчиков

7 дней 30 дней 6 месяцев Больше
27 окт30 окт2 ноя
Показаны последние 7 дней Больше истории →

Охваты публикаций

27.1028.1029.1030.1001.1101.11
21
Средний охват
65
Лучший результат
Показаны 6 публикаций — последние в канале Больше статистики →

Упоминания

6
Упоминаний
0
Из них репостов
5
Каналов
Все упоминания

Последние посты

3 из 137 2 из 137
Фото
🐘 Как устроено подключение к PostgreSQL: что происходит внутри БД? Продолжаем изучать PostgreSQL под капотом. В прошлом посте разобрали путь SQL-запроса от приложения до выполнения. Теперь посмотрим, что происходит ещё раньше — как устанавливается соединение и кто обслуживает клиента. Коротко: PostgreSQL использует архитектуру process-per-connection. Для каждого прямого клиентского подключения создаётся отдельный backend process, который обслуживает SQL-запросы на протяжении всей сессии. 1. Установка соединения Допустим, приложение подключается к PostgreSQL: app → postgres:5432 Сначала устанавливается TCP-соединение или используется Unix socket для локального подключения. При необходимости согласовывается TLS. Главный процесс PostgreSQL — postmaster — принимает новое подключение и создаёт отдельный backend process. Получается: Client A → Backend PID 1001 Client B → Backend PID 1002 Client C → Backend PID 1003 Важный момент: PostgreSQL создаёт отдельный процесс на соединение, а не на каждый SQL-запрос. 2. Authentication — проверка доступа Клиент передаёт параметры подключения, включая имя пользователя и базу данных. PostgreSQL обращается к: pg_hba.conf Этот файл определяет, какие подключения разрешены и какой метод аутентификации использовать. Например: host all app_user 10.0.0.0/8 scram-sha-256 В данном случае для подходящего подключения используется SCRAM-SHA-256. PostgreSQL поддерживает и другие методы: сертификаты, LDAP, GSSAPI и т.д. После успешной аутентификации и необходимых проверок доступа сессия становится готовой к работе. 3. Session — что хранится в соединении После подключения создаётся контекст сессии. С ним связаны: • текущая роль и параметры сессии • search_path • временные таблицы • prepared statements • состояние транзакции • session-level advisory locks Например, приложение выполняет: SET search_path TO app; Эта настройка будет действовать в рамках соответствующей сессии. Именно поэтому повторное использование соединений через connection pool требует аккуратного управления session state. 4. Backend Process — кто выполняет SQL Теперь клиент отправляет: SELECT * FROM users WHERE id = 42; Запрос получает backend process, закреплённый за соединением. Он выполняет: Parse → Plan → Execute → Result При этом backend взаимодействует с общими структурами PostgreSQL: Shared Buffers WAL Buffers Lock Manager Хотя процессы отдельные, они используют shared memory и механизмы синхронизации. После выполнения запроса backend не исчезает, а ожидает следующую команду от клиента. 5. Где возможен production-инцидент? Представим, что приложение перезапустили и одновременно поднялись 20 replicas. Каждая создаёт пул: pool size = 20 Получаем потенциально: 20 × 20 = 400 connections Но PostgreSQL ограничивает количество подключений через: max_connections Если доступные слоты закончились, новые клиенты начнут получать ошибки подключения. А большое количество backend processes дополнительно расходует память и ресурсы CPU. Именно поэтому больше соединений не всегда означает больше производительности. Для ограничения количества подключений часто используют PgBouncer. 6. Как диагностировать Посмотреть соединения можно через: pg_stat_activity Например: SELECT pid, usename, application_name, state, wait_event_type, wait_event FROM pg_stat_activity; Особенно интересны состояния: • active — выполняется запрос • idle — соединение ожидает команду • idle in transaction — транзакция открыта, но запрос сейчас не выполняется Последнее состояние особенно опасно: длительные транзакции могут удерживать блокировки и мешать очистке старых версий строк через VACUUM. 📌 Вывод: подключение к PostgreSQL — это не просто открытый TCP-сокет. Connection → Authentication → Backend Process → Session → SQL Каждое прямое соединение получает собственный backend process и контекст сессии. Поэтому при проблемах с PostgreSQL важно анализировать не только медленные SQL-запросы, но и количество соединений, состояние сессий и поведение connection pool. #postgresql #database #architecture #production
ещё
5 1 1 ноя, 21:05
Фото
🗄 Что происходит, когда приложение отправляет SQL-запрос? Коллеги, Kubernetes мы уже достаточно подробно разобрали, поэтому предлагаю перейти к следующей большой теме — внутреннему устройству баз данных. Также важно понять, нравятся ли вам посты про БД или нет. Прошу дать обратную связь :) Начнём с PostgreSQL. Разберём полный путь SQL-запроса, а в следующих постах будем постепенно углубляться в отдельные механизмы: индексы, планировщик, MVCC, WAL, блокировки и работу с памятью. Коротко: когда приложение отправляет SQL-запрос, PostgreSQL не начинает сразу читать данные с диска. Сначала запрос проходит несколько этапов: разбор, проверку, оптимизацию, выполнение и только затем возвращает результат. 1. Connection — подключение к БД Допустим, приложение выполняет: SELECT * FROM users WHERE id = 42; Сначала необходимо соединение с PostgreSQL. Обычно приложение использует connection pool, чтобы не создавать новое TCP-соединение для каждого запроса. Упрощённо: Application → TCP :5432 → PostgreSQL В классической архитектуре PostgreSQL подключение обслуживает отдельный backend process. Он получает SQL-запрос и начинает его обработку. 2. Parser — разбор SQL PostgreSQL получает текст запроса и проверяет его синтаксис. Например: SELECT * FORM users; Здесь ошибка, потому что написано FORM вместо FROM. Если синтаксис корректный, Parser формирует дерево разбора. Далее выполняется семантический анализ: • существует ли таблица • существуют ли указанные столбцы • корректны ли типы данных • есть ли необходимые права доступа Также PostgreSQL может преобразовать запрос через Rewrite System, например при обращении к View. 3. Planner — выбор плана выполнения Теперь PostgreSQL должен решить, как именно получить данные. Допустим, таблица users содержит миллион строк. Есть несколько вариантов: Seq Scan → прочитать таблицу Index Scan → использовать индекс Planner оценивает возможные планы с учётом статистики, количества строк, стоимости I/O и CPU. Выбирается план с наименьшей оценочной стоимостью. Причём наличие индекса не гарантирует его использование! Иногда последовательное чтение таблицы оказывается выгоднее. Для подготовленных запросов план может использоваться повторно. 4. Executor — выполнение запроса После выбора плана начинается выполнение. Например, Planner выбрал: Index Scan using users_pkey Executor обращается к индексу, находит нужную запись и получает данные. Но это не обязательно означает чтение с физического диска. PostgreSQL использует: Shared Buffers Если нужная страница уже находится в памяти: Cache Hit → читаем из RAM Если её нет: Cache Miss → чтение через ОС При этом данные могут оказаться в файловом кэше Linux, поэтому физический I/O тоже не гарантирован. Здесь же PostgreSQL учитывает MVCC, чтобы определить, какие версии строк видны текущей транзакции. 5. Возврат результата Executor формирует строки результата, PostgreSQL передаёт их клиенту через сетевой протокол. Получаем: PostgreSQL → Application → Client На этом обработка SELECT завершается. Для INSERT, UPDATE и DELETE путь сложнее: появляются изменения страниц, WAL, блокировки и другие механизмы. Где может возникнуть production-инцидент? Представим, запрос раньше выполнялся за: 15 ms А после увеличения таблицы стал выполняться за: 4 seconds Причина может быть не в CPU или диске. Например, Planner из-за неактуальной статистики неверно оценил количество строк и выбрал неэффективный план. Вместо: Index Scan получили: Seq Scan Теперь PostgreSQL обрабатывает гораздо больше данных. Для диагностики используем: EXPLAIN (ANALYZE, BUFFERS) Он показывает фактический план выполнения, время операций и статистику обращения к буферам. Важно: ANALYZE действительно выполняет запрос. 📌 Вывод: выполнение SQL — это целая цепочка: Connection → Parser → Analyzer / Rewriter → Planner → Executor → Buffers / Storage → Result Медленный запрос не всегда означает медленный диск. Проблема может находиться в соединениях, планировании, чтении данных, блокировках или передаче результата. #postgresql #database #architecture #production
ещё
65 3 11 1 ноя, 00:03
Фото
💾 Как устроена файловая система Docker-контейнера? Продолжаем изучать контейнеры под капотом. Теперь посмотрим, откуда внутри контейнера берутся файлы, куда записываются изменения и почему запись нескольких байт иногда приводит к копированию целого файла. Коротко: Docker использует слои образа и отдельный writable layer для каждого контейнера. В распространённой реализации на базе OverlayFS работает механизм Copy-on-Write (CoW) — копирование при записи. 1. Из чего состоит Docker Image Допустим, собираем образ: FROM ubuntu:24.04 RUN apt-get update && apt-get install -y nginx COPY nginx.conf /etc/nginx/nginx.conf При сборке формируются слои файловой системы. Упрощённо: Layer 1 → Ubuntu Layer 2 → Nginx Layer 3 → nginx.conf Эти слои неизменяемые — read-only. Когда Docker запускает контейнер, поверх них создаётся дополнительный слой: Writable Layer (RW) Получается: Writable Layer ← изменения Image Layer 3 (RO) Image Layer 2 (RO) Image Layer 1 (RO) Контейнер видит всё как одну файловую систему. 2. Как работает OverlayFS В Linux для этого часто используется OverlayFS. У него есть три важных понятия: • lowerdir — нижние read-only слои образа • upperdir — верхний writable layer контейнера • merged — объединённое представление файловой системы Когда приложение читает: /etc/nginx/nginx.conf OverlayFS ищет файл в верхнем слое, а если его там нет — в нижних. Приложение при этом не знает, в каком именно слое лежит файл. 3. Что такое Copy-on-Write Теперь самое интересное. Допустим, в образе есть файл размером: 1 GB Приложение открыло его и хочет изменить всего несколько байт. Но нижние слои образа изменять нельзя. Поэтому OverlayFS выполняет: lowerdir → copy_up → upperdir То есть при первой записи файл копируется в writable layer, после чего изменяется уже его копия. Важный нюанс: классический OverlayFS выполняет copy_up на уровне файла, а не отдельных блоков. Поэтому изменение нескольких байт в большом файле может привести к копированию всего файла. Последующие записи выполняются уже в верхнем слое без повторного полного copy_up. 4. Где здесь production-инцидент? Представим приложение, в образ которого положили большой файл данных. После запуска оно изменяет небольшой участок этого файла. Внезапно наблюдаем: • увеличение дискового I/O • рост занятого пространства на ноде • задержки при первой записи • увеличение writable layer контейнера Причина может быть не в объёме новых данных, а в copy_up большого файла из image layer. Особенно неприятно, если несколько контейнеров одновременно начинают изменять такие файлы. Каждый контейнер имеет собственный writable layer, поэтому копирование выполняется отдельно. 5. Чем Volume отличается от writable layer Допустим, приложение пишет данные в: /var/lib/postgresql/data Без отдельного mount данные попадут в writable layer контейнера. При удалении контейнера этот слой исчезнет. Теперь подключаем Docker Volume: postgres-data:/var/lib/postgresql/data Данные записываются в подключённый volume, минуя writable layer для этого пути. Получаем: Writable Layer: • принадлежит конкретному контейнеру • удаляется вместе с ним • использует механизм слоёв файловой системы Volume: • существует независимо от контейнера • сохраняет данные после его удаления • подходит для постоянных и интенсивно изменяемых данных Важно: обычный docker restart не удаляет writable layer. Данные исчезают именно при удалении и пересоздании контейнера без переноса данных. 📌 Вывод: контейнер не получает полноценную копию Docker Image при запуске. Он использует общие read-only слои и собственный writable layer. Read → чтение из существующих слоёв Write → copy_up при необходимости Volume → запись вне writable layer Поэтому для баз данных, persistent storage и write-intensive workloads обычно лучше использовать volumes, а не хранить изменяемые данные непосредственно в файловой системе контейнера. И если приложение неожиданно создаёт большую дисковую нагрузку при небольших изменениях файлов — стоит проверить, не столкнулись ли вы с Copy-on-Write. #docker #linux #containers #architecture #production
ещё
18 6 3 30 окт, 21:09
Больше постов

Продолжить анализ этого канала

  • История роста подписчиков
  • Просмотры и охваты публикаций
  • Кто упоминает канал и кого упоминает он
  • Похожие каналы и подбор для рекламы
Открыть аналитику
Демо до 14 дней