Кейс: «Сервер тормозит, но CPU и RAM в норме». В поисках дискового I/O.
Проблема: Один из наших веб-серверов (Ubuntu + Nginx + PostgreSQL) начал отвечать на запросы очень медленно. Стандартные дашборды в Grafana показывали, что загрузка CPU — 20-30%, использование RAM — около 60%. На первый взгляд, всё в порядке.
Симптомы:
top и htop не показывали процессов, которые бы «съедали» процессор.
Время ответа сайта (TTFB) выросло с 200 мс до 2-3 секунд.
Пользователи жаловались на «зависания» при работе с базой данных.
Диагностика: копаем в сторону дисков
Первая гипотеза: если не CPU и не RAM, значит, проблема в дисковой подсистеме (I/O). Процессы могут простаивать в ожидании, пока диск прочитает или запишет данные.
Шаг 1: top и iowait
Запускаем top и смотрим на строку %Cpu(s). Нас интересует параметр wa — iowait. Он показывал значения 40-50%, что аномально много. Это значит, что процессор почти половину времени ждёт ответа от дисков.
Шаг 2: iotop
Устанавливаем iotop (sudo apt install iotop), чтобы увидеть, какой именно процесс создаёт нагрузку на диск.
Bash
Картина прояснилась: процесс postgres постоянно что-то писал на диск с высокой скоростью, а также системный процесс jbd2/sda1-8 (журналирование файловой системы ext4) показывал высокую активность.
Ша-г 3: Анализ работы PostgreSQL
Проверка настроек PostgreSQL показала, что уровень логирования был установлен на statement, то есть каждый SQL-запрос писался в лог-файл. Нагрузка на сайт выросла, и база данных генерировала гигантский объём логов, забивая всю пропускную способность диска.
Решение:
Изменили уровень логирования. В postgresql.conf параметр log_statement был изменён с all на ddl. Теперь логируются только изменения схемы, а не каждый SELECT.
Вынесли логи на отдельный диск. В идеальном мире, логи и данные должны лежать на разных физических дисках, чтобы не конкурировать за I/O.
Оптимизировали checkpoint'ы. Увеличили интервалы между checkpoint'ами, чтобы снизить частоту записи «грязных» буферов на диск.
Вывод:
Когда сервер тормозит, а CPU и RAM свободны, — всегда смотрите на iowait. Это «слепая зона» для многих админов. Умение диагностировать дисковые проблемы с помощью iotop и iostat — ключевой навык для поддержания производительности высоконагруженных систем.
#linux #devops #case #postgresql #performance #debug
Проблема: Один из наших веб-серверов (Ubuntu + Nginx + PostgreSQL) начал отвечать на запросы очень медленно. Стандартные дашборды в Grafana показывали, что загрузка CPU — 20-30%, использование RAM — около 60%. На первый взгляд, всё в порядке.
Симптомы:
top и htop не показывали процессов, которые бы «съедали» процессор.
Время ответа сайта (TTFB) выросло с 200 мс до 2-3 секунд.
Пользователи жаловались на «зависания» при работе с базой данных.
Диагностика: копаем в сторону дисков
Первая гипотеза: если не CPU и не RAM, значит, проблема в дисковой подсистеме (I/O). Процессы могут простаивать в ожидании, пока диск прочитает или запишет данные.
Шаг 1: top и iowait
Запускаем top и смотрим на строку %Cpu(s). Нас интересует параметр wa — iowait. Он показывал значения 40-50%, что аномально много. Это значит, что процессор почти половину времени ждёт ответа от дисков.
Шаг 2: iotop
Устанавливаем iotop (sudo apt install iotop), чтобы увидеть, какой именно процесс создаёт нагрузку на диск.
Bash
sudo iotop
Картина прояснилась: процесс postgres постоянно что-то писал на диск с высокой скоростью, а также системный процесс jbd2/sda1-8 (журналирование файловой системы ext4) показывал высокую активность.
Ша-г 3: Анализ работы PostgreSQL
Проверка настроек PostgreSQL показала, что уровень логирования был установлен на statement, то есть каждый SQL-запрос писался в лог-файл. Нагрузка на сайт выросла, и база данных генерировала гигантский объём логов, забивая всю пропускную способность диска.
Решение:
Изменили уровень логирования. В postgresql.conf параметр log_statement был изменён с all на ddl. Теперь логируются только изменения схемы, а не каждый SELECT.
Вынесли логи на отдельный диск. В идеальном мире, логи и данные должны лежать на разных физических дисках, чтобы не конкурировать за I/O.
Оптимизировали checkpoint'ы. Увеличили интервалы между checkpoint'ами, чтобы снизить частоту записи «грязных» буферов на диск.
Вывод:
Когда сервер тормозит, а CPU и RAM свободны, — всегда смотрите на iowait. Это «слепая зона» для многих админов. Умение диагностировать дисковые проблемы с помощью iotop и iostat — ключевой навык для поддержания производительности высоконагруженных систем.
#linux #devops #case #postgresql #performance #debug
🐘 PostgreSQL: Почему база растет, если я удаляю данные?
Классика: вы удалили миллион строк из таблицы, а место на диске не освободилось. Добро пожаловать в мир MVCC (Multi-Version Concurrency Control).
В Postgres при удалении (DELETE) строка не стирается физически. Она помечается как «мертвая» (dead tuple). Но место всё ещё занято.
❌ Ошибка джуна: Запустить VACUUM FULL. Это освободит место, НО заблокирует таблицу намертво (Access Exclusive Lock). Ваш прод встанет.
✅ Путь Архитектора:
Настройте Autovacuum. Он должен работать агрессивнее, чтобы «мертвецы» не накапливались.
Используйте pg_repack (или pg_squeeze). Это расширение позволяет пересобрать таблицу и вернуть место ОС без блокировок чтения/записи.
Шпаргалка по проверке "вздутия" (Bloat): Вам не нужны сложные скрипты, поставьте pg-bloat-check или используйте запрос:
Если bloat_ratio > 0.2 (20%) — пора звать автовакуум.
#postgresql #database #dba #performance #sql
Классика: вы удалили миллион строк из таблицы, а место на диске не освободилось. Добро пожаловать в мир MVCC (Multi-Version Concurrency Control).
В Postgres при удалении (DELETE) строка не стирается физически. Она помечается как «мертвая» (dead tuple). Но место всё ещё занято.
❌ Ошибка джуна: Запустить VACUUM FULL. Это освободит место, НО заблокирует таблицу намертво (Access Exclusive Lock). Ваш прод встанет.
✅ Путь Архитектора:
Настройте Autovacuum. Он должен работать агрессивнее, чтобы «мертвецы» не накапливались.
Используйте pg_repack (или pg_squeeze). Это расширение позволяет пересобрать таблицу и вернуть место ОС без блокировок чтения/записи.
Шпаргалка по проверке "вздутия" (Bloat): Вам не нужны сложные скрипты, поставьте pg-bloat-check или используйте запрос:
SELECT schemaname, relname, n_dead_tup, n_live_tup,
(n_dead_tup::float / n_live_tup::float) as bloat_ratio
FROM pg_stat_user_tables
WHERE n_dead_tup > 0;
Если bloat_ratio > 0.2 (20%) — пора звать автовакуум.
#postgresql #database #dba #performance #sql
🐧 Linux: Спасаем базу данных от OOM Killer
Бывало такое?
Серверу не хватило памяти, пришел OOM Killer (Out of Memory) и убил... нет, не зависший PHP-скрипт, а твой основной PostgreSQL.
💀 Почему? Потому что БД потребляет больше всего памяти, и для ядра она выглядит как самый "жирный" кандидат на расстрел.
Решение: Настроить oom_score_adj. Это число от -1000 (бессмертный) до +1000 (убить первым).
Как защитить критический процесс: Находим PID процесса (например, postgres):
Запрещаем OOM Killer'у трогать его (ставим -1000):
Как сделать это вечным (в systemd): Добавьте в unit-файл сервиса (systemctl edit postgresql):
Теперь, когда память кончится, Linux убьет веб-сервер, кэш, SSH-сессию, но база данных останется стоять до последнего.
#linux #kernel #oom #postgresql #sysadmin #reliability #systemd 🛡️
Бывало такое?
Серверу не хватило памяти, пришел OOM Killer (Out of Memory) и убил... нет, не зависший PHP-скрипт, а твой основной PostgreSQL.
💀 Почему? Потому что БД потребляет больше всего памяти, и для ядра она выглядит как самый "жирный" кандидат на расстрел.
Решение: Настроить oom_score_adj. Это число от -1000 (бессмертный) до +1000 (убить первым).
Как защитить критический процесс: Находим PID процесса (например, postgres):
pgrep -f postgres | head -1
Запрещаем OOM Killer'у трогать его (ставим -1000):
echo -1000 > /proc/[PID]/oom_score_adj
Как сделать это вечным (в systemd): Добавьте в unit-файл сервиса (systemctl edit postgresql):
[Service]
OOMScoreAdjust=-900
Теперь, когда память кончится, Linux убьет веб-сервер, кэш, SSH-сессию, но база данных останется стоять до последнего.
#linux #kernel #oom #postgresql #sysadmin #reliability #systemd 🛡️
🎓 Собеседование сисадмина. Выпуск #6: Базы данных (Reliability & Scalability)
Привет, коллеги! Сегодня разберем три вопроса, которые проверяют твое понимание того, как данные «живут» на дисках и в сети.
❓ Вопрос 1: «Что такое репликация и в чем разница между Synchronous (Синхронной) и Asynchronous (Асинхронной) репликацией?»
❌ Ответ новичка: «Репликация — это когда данные копируются на другой сервер. Синхронная — это быстро, асинхронная — медленнее».
✅ Ответ инженера:
❓ Вопрос 2: «Что такое индексы в БД, и почему нельзя просто навесить их на каждую колонку таблицы "на всякий случай"?»
❌ Ответ новичка: «Индексы нужны для ускорения поиска. Если их много, то всё будет летать».
✅ Ответ инженера:
❓ Вопрос 3: «Как вы будете делать бэкап базы объемом в 1 ТБ, чтобы не "положить" сервис во время процесса?»
❌ Ответ новичка: «Сделаю
✅ Ответ инженера:
💡 Золотое правило собеса:Если тебя спрашивают про базы, всегда упоминай мониторинг. Фраза «Я обязательно настрою алерты на Replication Lag (задержка репликации) и Disk Space» — это музыка для ушей любого тимлида.
Сохраняйте пост, чтобы не «поплыть», когда база скажет «ой»!
#собеседование_AF #database #mysql #postgresql #replication #backup #sysadmin #devops #admin_future
Привет, коллеги! Сегодня разберем три вопроса, которые проверяют твое понимание того, как данные «живут» на дисках и в сети.
❓ Вопрос 1: «Что такое репликация и в чем разница между Synchronous (Синхронной) и Asynchronous (Асинхронной) репликацией?»
❌ Ответ новичка: «Репликация — это когда данные копируются на другой сервер. Синхронная — это быстро, асинхронная — медленнее».
✅ Ответ инженера:
Репликация — это механизм синхронизации данных между Master (Writer) и Replica (Reader).
* Асинхронная: Мастер записывает данные и тут же подтверждает успех клиенту, не дожидаясь реплики.
* *Плюс:* Максимальная скорость.
* *Минус:* Риск потери данных при падении Мастера (те миллисекунды данных, что не успели улететь на реплику).
* Синхронная: Мастер ждет, пока реплика подтвердит получение данных, и только потом отвечает клиенту.
* *Плюс:* Гарантия сохранности данных.
* *Минус:* Если реплика «залагает» или упадет сеть — встанет и запись на Мастере.
❓ Вопрос 2: «Что такое индексы в БД, и почему нельзя просто навесить их на каждую колонку таблицы "на всякий случай"?»
❌ Ответ новичка: «Индексы нужны для ускорения поиска. Если их много, то всё будет летать».
✅ Ответ инженера:
Индекс — это отдельная структура (обычно B-Tree), которая позволяет не сканировать всю таблицу целиком.
* Проблема: Каждый индекс занимает место на диске. Но главное — любой индекс замедляет запись (INSERT/UPDATE). При каждом изменении данных базе приходится обновлять и все связанные с этой колонкой индексы.
* Вывод: Индексы нужно создавать только на те колонки, по которым реально идет частая фильтрация (WHERE) или сортировка (ORDER BY).
❓ Вопрос 3: «Как вы будете делать бэкап базы объемом в 1 ТБ, чтобы не "положить" сервис во время процесса?»
❌ Ответ новичка: «Сделаю
mysqldump или pg_dump ночью, когда никто не пользуется».✅ Ответ инженера:
Логический бэкап (dump) на терабайтной базе — это плохая идея. Он будет делаться вечно и создаст огромную нагрузку.
* Правильный путь: 1. Снапшоты на уровне ФС/LVM: Замораживаем ФС на секунду, делаем снапшот, размораживаем и спокойно копируем данные.
2. Физический бэкап: Инструменты вроде `pg_backrest` для PostgreSQL или `Percona XtraBackup` для MySQL. Они копируют сами файлы данных «на лету», не блокируя чтение и запись.
3. Бэкап с реплики: Самый надежный способ. Снимаем бэкап с репликационного сервера, чтобы вообще не нагружать основной Master-сервер.
💡 Золотое правило собеса:
Сохраняйте пост, чтобы не «поплыть», когда база скажет «ой»!
#собеседование_AF #database #mysql #postgresql #replication #backup #sysadmin #devops #admin_future
👍1