Метрики процессов во времени: pidstat

Рейтинг: 70.2% · 15 голосов
Подробный курс по диагностике и производительности Linux для админов и DevOps: с чего начать, методология USE, логи (journalctl, dmesg), процессы, CPU, память и OOM, диск и IO (iostat), сеть (ss, tcpdump), системные вызовы и strace, ltrace, perf, флеймграфы, ftrace, eBPF и bpftrace, lsof, мониторинг. Разбор каждого инструмента с чтением вывода.
Ответить
Аватара пользователя
Dmitry_SRE
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Метрики процессов во времени: pidstat

Сообщение Dmitry_SRE »

Оглавление курса (47)
  1. С чего начать диагностику Linux: методология вместо паники
  2. Первые 60 секунд: экспресс-диагностика нагруженного сервера
  3. Методологии диагностики: USE, RED и здравый смысл
  4. Логи systemd через journalctl: где искать причину
  5. Где лежат логи Linux: /var/log, dmesg и rsyslog
  6. Источники правды: load average, /proc и /sys
  7. Процессы Linux: ps, pstree и состояния процессов
  8. Интерактивный мониторинг: top и htop
  9. Метрики процессов во времени: pidstat (вы здесь)
  10. Приоритеты и ограничения: nice, ionice, cgroups
  11. Сигналы и зависшие процессы: kill, и что делать с D-state
  12. Загрузка CPU: user, system, iowait, steal и контекст-свитчи
  13. Диагностика CPU по ядрам: vmstat и mpstat
  14. Профилирование CPU: perf top и поиск пожирателя
  15. Частоты, троттлинг и NUMA: turbostat и numastat
  16. Память Linux: RSS, VSZ, page cache и миф о нехватке памяти
  17. Сколько памяти занято: free, /proc/meminfo и vmstat
  18. Поиск утечек и пожирателей памяти: smem, pmap, smaps
  19. Swap и подкачка: swapon, swappiness, когда своп - это боль
  20. OOM killer: кто и за что убил процесс
  21. Память ядра и slab: slabtop и куда уходит RAM
  22. Подсистема ввода-вывода: путь запроса от приложения до диска
  23. Диагностика диска: iostat и чтение await, %util
  24. Кто грузит диск: iotop и атрибуция io процессам
  25. Файловые системы: df, du, иноды и куда делось место
  26. Глубокая диагностика блочного слоя: blktrace и biolatency
  27. Кеш страниц и грязные данные: dirty pages, fsync, drop_caches
  28. Сетевой стек Linux: путь пакета и где возникают задержки
  29. Сокеты и соединения: ss и netstat
  30. Захват трафика: tcpdump для диагностики сети
  31. Задержки и потери в сети: ping, mtr, диагностика латентности
  32. Сеть как источник проблем: nftables, conntrack, дропы
  33. Что такое системный вызов и зачем его трассировать
  34. strace: трассировка системных вызовов на практике
  35. strace в бою: почему программа висит, падает или тормозит
  36. ltrace: трассировка вызовов библиотек
  37. Накладные расходы трассировки и безопасные альтернативы
  38. perf: универсальный профайлер Linux
  39. Флеймграфы: визуализация профиля производительности
  40. Трассировка ядра: ftrace и trace-cmd
  41. eBPF: революция в наблюдаемости Linux
  42. Инструменты eBPF на практике: BCC и bpftrace
  43. lsof: открытые файлы, дескрипторы, кто держит файл и порт
  44. Разбор кейса: приложение тормозит - пошаговая диагностика
  45. Непрерывный мониторинг: sar, node_exporter, Grafana, Zabbix
  46. Диагностика в контейнерах: cgroups, лимиты, Docker и Kubernetes
  47. Карта инструментов и сквозной разбор инцидента производительности
Сервер тормозит, нагрузка высокая, а кто виноват - непонятно. Ты открываешь top, видишь, что что-то ест CPU, что-то лезет на диск, но картинка дёргается, цифры скачут, и через секунду виновник уже спрятался. Знакомо? Проблема в том, что большинство привычных инструментов показывают момент, а не процесс во времени. А нагрузка - штука волнообразная: пик длится полсекунды, ты моргнул и не успел поймать. В этом уроке разберём pidstat - один из самых недооценённых инструментов для атрибуции ресурса конкретному процессу. Это про мониторинг процессов linux честно и по интервалам: не "сколько съел за всё время с запуска", а "сколько он ест прямо сейчас, в секунду". К концу урока ты будешь читать вывод pidstat по колонкам, отличать норму от тревоги и связывать его с iostat и vmstat в единый маршрут расследования.

Почему интервальные метрики честнее моментальных

Давай сразу про главное заблуждение. Команда ps показывает накопленные значения с момента старта процесса. Если база данных работает три недели и за это время сожрала 400 часов CPU - тебе это число ни о чём не говорит про сейчас. Может, она спит. Может, наоборот, душит сервер. ps этого не покажет, потому что усредняет по всей жизни процесса. То же с колонкой %CPU в ps: для большинства реализаций это среднее за всё время жизни процесса (отношение потраченного CPU-времени к возрасту процесса), а не "сейчас".

Представь спидометр и одометр. Одометр (ps) говорит "проехал 200 тысяч км". Спидометр (pidstat 1) говорит "едешь 90 км/ч прямо сейчас". Когда машина тормозит и ты ищешь, кто гонит, тебе нужен спидометр. Интервальная метрика - это разница между двумя снимками счётчиков из /proc, делённая на длину интервала. pidstat читает /proc/[pid]/stat, /proc/[pid]/io, /proc/[pid]/status, делает первый снимок, ждёт интервал, делает второй и печатает скорость. Поэтому первая строка вывода без интервала - это среднее с момента загрузки, а вот строки при pidstat 1 - честная скорость потребления здесь и сейчас.

Именно поэтому в перфоманс-расследованиях интервальные счётчики честнее. Ты задаёшь интервал (например, 1 секунда), и инструмент печатает свежую строку каждую секунду. Виновник всплывает сам.

Изображение

Откуда берётся pidstat linux и базовый запуск

pidstat входит в пакет sysstat - тот самый набор, где живут iostat, mpstat, vmstat и sar. На голой системе его часто нет, ставится так:

Код: Выделить всё

# Debian/Ubuntu/Astra Linux
sudo apt install sysstat

# RHEL/Fedora/RED OS
sudo dnf install sysstat
Актуально на 2026: свежая ветка - sysstat 12.7.x (12.7.7 вышла в начале 2025). В ней починили баг с завышенными %usr и добавили общий для всего пакета вывод в JSON через -o JSON - удобно, когда pidstat скармливается в скрипт или конвейер мониторинга. Версию проверяй так:

Код: Выделить всё

$ pidstat -V
sysstat version 12.7.7
Самый частый запуск - pidstat с интервалом и числом повторов:

Код: Выделить всё

$ pidstat 1 5
Linux 6.8.0-40-generic (web-01)  06/15/2026  _x86_64_  (8 CPU)

10:21:03      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
10:21:04        0      1187    2.00    1.00    0.00    0.00    3.00     2  rsyslogd
10:21:04     1000     20431   85.00   12.00    0.00    5.00   97.00     4  ffmpeg
Здесь "1 5" значит: интервал 1 секунда, всего 5 отчётов. По умолчанию pidstat показывает только активные задачи (те, у кого статистика изменилась за интервал), поэтому спящие демоны не засоряют вывод. Читаем по колонкам - это и есть ключевой навык:
  • %usr - сколько CPU процесс тратит в пользовательском коде (твоя программа считает).
  • %system - сколько в ядре (системные вызовы, работа с диском и сетью через ядро). Если тут много - процесс долбит ядро сисколлами; стоит глянуть strace или, что в 2026 правильнее по накладным расходам, eBPF-трейсинг.
  • %guest - время внутри виртуальной машины (актуально, когда сам процесс - гипервизор/qemu; на обычном сервере обычно 0).
  • %wait - процесс был готов считать, но ждал очереди на ядро (runqueue). Это не "ждёт диск", а "ждёт процессор". Стабильно ненулевой %wait - признак того, что готовых к счёту задач больше, чем ядер. Это насыщение CPU, а не медленный процесс.
  • %CPU - суммарная загрузка процесса = %usr + %system. Важно: на 8-ядерной машине многопоточный процесс может показать до 800% (по 100% на ядро). Если хочешь, чтобы pidstat нормировал на число ядер (то есть 100% = вся машина), запускай pidstat -u --human или добавляй -I - тогда значение делится на количество CPU.
  • CPU - номер ядра, на котором процесс крутился последним. Если он постоянно скачет - возможна проблема с привязкой к ядрам (CPU affinity) и потерей кэша.
В примере выше всё очевидно: ffmpeg ест 97% и сидит в %usr - значит реально молотит вычисления, а не ждёт. Виновник найден за одну команду. А вот если бы доминировал %system - искать надо было бы в сисколлах, а не в самом алгоритме.

sysstat в деле: ищем виновника по конкретному ресурсу

CPU - только начало. Сила pidstat в том, что им можно резать нагрузку по типу ресурса. Это четыре флага, которые стоит зазубрить.

Дисковый ввод-вывод: кто реально пишет и читает (-d)

Код: Выделить всё

$ sudo pidstat -d 1
10:31:12      UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
10:31:13     1000      8842      0.00  61440.00      0.00      14  postgres
10:31:13      999      9001   2048.00      0.00      0.00       2  clickhouse
kB_rd/s - килобайт в секунду, которые процесс реально вызвал на чтение с диска. kB_wr/s - то же на запись. kB_ccwr/s - килобайты, запись которых на диск была отменена (например, процесс перезаписал или укоротил грязные страницы в pagecache до того, как их сбросили на диск); большое значение тут - это запись, которой по факту не случилось. iodelay - суммарная задержка задачи на блочном вводе-выводе, в тиках ядра; сюда входит ожидание завершения синхронного блочного I/O и подкачки страниц (swapin). Здесь видно, что postgres пишет 60 МБ/с - вот он, источник дисковой нагрузки. iostat скажет тебе "диск загружен на 100%", но не назовёт виновника. А pidstat -d называет по имени. Для доступа к /proc/[pid]/io по чужим процессам нужен root, поэтому -d почти всегда идёт с sudo.

Память и страничные ошибки (-r)

Код: Выделить всё

$ pidstat -r 1
10:35:40      UID       PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
10:35:41     1000     20431    320.00     45.00 2451200  812044   9.80  java
minflt/s - минорные page faults: страница уже есть в физической памяти, ядро просто доформировало маппинг или взяло страницу из кэша. Это дёшево и нормально. majflt/s - мажорные: страницу пришлось грузить с диска (mmap-файл или своп). Вот это тревога. Стабильно высокий majflt/s означает, что процессу не хватает резидентной памяти и он перечитывает страницы с диска или свопится - каждый такой fault это поход на диск, на порядки медленнее обращения к RAM. VSZ - виртуальный размер (сколько адресного пространства зарезервировано, обычно сильно завышено). RSS - резидентная память, реальные физические килобайты в RAM. %MEM - доля RSS от всей физической памяти. Смотри на RSS, %MEM и majflt/s, а не на пугающий VSZ.

Контекстные переключения (-w)

Код: Выделить всё

$ pidstat -w 1
10:40:02      UID       PID   cswch/s nvcswch/s  Command
10:40:03     1000      8842    150.00      3.00  postgres
10:40:03     1000     31002      5.00  9500.00   busy-loop
cswch/s - добровольные переключения: процесс сам уступил ядро, потому что чего-то ждёт (блокировка, ввод-вывод, сон). nvcswch/s - недобровольные: ядро силой отняло CPU, потому что вышел квант времени, а в очереди стоят другие готовые задачи. Огромный nvcswch/s (как у busy-loop выше) - классический симптом перегрузки по CPU: готовых задач больше, чем ядер, и планировщик постоянно их тасует, тратя такты на сами переключения. Много cswch/s - процесс часто блокируется на чём-то внешнем (нормально для I/O-bound сервисов вроде БД, но если внезапно вырос - ищи новую блокировку или контеншн на локах).

Потоки и конкретный PID

Флаг -t разворачивает процесс на потоки (TID), -p сужает до одного PID (или -p ALL - все задачи, включая спящие):

Код: Выделить всё

$ pidstat -t -p 20431 1
$ pidstat -d -p 8842 1
-t незаменим, когда жирный многопоточный процесс (JVM, nginx, postgres) ест CPU, а ты хочешь понять, какой именно поток виноват: pidstat покажет строку TGID (процесс целиком) и под ней строки TID с прочерком в TGID - это отдельные потоки.

Полезные фильтры (актуально на 2026)
  • -C "имя" - оставить только процессы, чьё имя команды совпадает с регуляркой: pidstat -C "postgres|nginx" 1.
  • -G "имя" - то же, но матчит по полному имени процесса.
  • -l - печатать полную командную строку с аргументами (отличить десяток одноимённых воркеров).
  • --human - человекочитаемые размеры (1.2M вместо 1258291).
  • -e program args - запустить программу и сразу мерить именно её; требует ненулевого интервала: pidstat -e -r 1 ./myapp.
Типичные грабли и заблуждения
  • Запуск без интервала. Просто pidstat покажет средние с момента загрузки - то есть бесполезную "историю". Всегда давай интервал: pidstat 1.
  • Путаница %wait и iodelay. %wait - это ожидание процессора (стоял в runqueue), а не диска. Ждёшь диск - смотри iodelay в -d.
  • Испуг от VSZ. Виртуальный размер в гигабайтах - норма для JVM и Go (резервируют адресное пространство впрок). Реальное потребление - это RSS.
  • majflt/s высокий, а swap пуст. Это не обязательно своп. Мажорные faults бывают и без свопа: процесс читает большой mmap-нутый файл (например, JVM подгружает классы/jar после деплоя, или БД маппит файлы данных) и страницы вытесняются из pagecache под давлением памяти. Смотри связку: pidstat -r (majflt/s) плюс free -m (сколько buff/cache) плюс vmstat 1 (колонки si/so - своп, bi - чтение блоков). Если si/so по нулям, а bi скачет - дело в pagecache и mmap, а не в свопе.
  • Забыл sudo для -d. Без root чисел по дисковому io по чужим процессам не увидишь.
  • Только pidstat без контекста. pidstat говорит, КТО ест ресурс. Чтобы понять, НАСЫЩЕН ли сам ресурс, нужна связка: vmstat 1 (общая картина CPU/память/swap/runqueue), iostat -x 1 (загрузка дисков, %util, await, aqu-sz). Сначала vmstat/iostat показывают, ЧТО узкое место, потом pidstat - КТО конкретно его создаёт.
  • Где pidstat упирается в потолок. pidstat выдаёт агрегаты по процессу за интервал. Если нужно знать, на КАКОМ именно сисколле или функции залипает процесс, или ловить короткоживущие процессы, которые pidstat не успевает заметить, - в 2026 это территория eBPF: bpftrace и bcc-инструменты (execsnoop для коротких процессов, biosnoop/biolatency для дисковых задержек, offcputime для анализа времени вне CPU). Они зрелые, работают на ядрах 5.x и новее и почти вытеснили strace/старый perf для точечной диагностики из-за низких накладных расходов. pidstat остаётся первым, быстрым шагом; eBPF - вторым, прицельным.
Мини-лаба: повтори руками прямо сейчас
  • Поставь sysstat, если его нет, и проверь версию: pidstat -V.
  • Запусти pidstat 1 5 и просто посмотри на живые строки %CPU, %usr, %system.
  • В соседнем терминале создай нагрузку на CPU: yes > /dev/null & - и поймай этот процесс в pidstat по %usr и %CPU (он будет около 100%). Потом убей: kill %1.
  • Создай дисковую запись: dd if=/dev/zero of=/tmp/test bs=1M count=2000 oflag=direct - и поймай dd в sudo pidstat -d 1 по kB_wr/s. Удали /tmp/test.
  • Запусти pidstat -w 1 и сравни cswch/s у спокойного процесса (rsyslogd) и nvcswch/s у нагрузочного yes.
  • Возьми любой многопоточный процесс (например pidof java) и разверни его на потоки: pidstat -t -p <PID> 1 - найди самый горячий TID.
Контрольные вопросы
  • Чем интервальная метрика pidstat 1 принципиально честнее, чем колонка %CPU в ps по тому же процессу?
  • Процесс показывает majflt/s = 200 и растущий, RSS большой, но swap пустой по free. О какой проблеме это говорит и какими ещё командами ты это подтвердишь?
  • В чём разница между cswch/s и nvcswch/s, и какой из них растёт при нехватке ядер?
  • Диск загружен на 100% по iostat -x. Какой командой pidstat ты найдёшь конкретного виновника и что в её выводе значит iodelay?
Что запомнить

pidstat из пакета sysstat - твой главный инструмент атрибуции ресурса процессу во времени. Всегда запускай с интервалом: первая строка без интервала - бесполезное среднее с загрузки. Четыре рабочих режима: без флага - CPU (%usr, %system, %wait, %CPU), -d - диск (kB_rd/s, kB_wr/s, iodelay), -r - память и page faults (majflt/s, RSS), -w - контекстные переключения (cswch/s, nvcswch/s). Добавь -t для потоков и -C/-l для фильтрации. Читай не команды, а их колонки: цифры без интерпретации бесполезны. Помни маршрут: vmstat/iostat говорят, что перегружено, pidstat - кто это сделал, а eBPF (bpftrace, bcc) - почему именно, на уровне сисколлов и функций. Это и есть честный мониторинг процессов linux в 2026 году.
👍4 ❤️ 🔥1 😄 🤔
Аватара пользователя
scala_guru
Сообщения: 1
Зарегистрирован: 13 май 2026, 09:06

Re: Метрики процессов во времени: pidstat

Сообщение scala_guru »

Спасибо, наконец дошло почему ps врёт - реально как одометр против спидометра. Всегда думал что %CPU в ps это сейчас, а оно среднее за всё время оказывается.
👍 ❤️1 🔥 😄 🤔
Аватара пользователя
joshwood
Сообщения: 1
Зарегистрирован: 14 май 2026, 18:24

Re: Метрики процессов во времени: pidstat

Сообщение joshwood »

Про majflt/s при пустом swap прям в точку, у меня java после деплоя так и делает - оказалось mmap классов из jar выбивается из pagecache, а не своп. vmstat si/so по нулям подтвердил.
👍3 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Интерактивный мониторинг: top и htop
Следующая глава →
Приоритеты и ограничения: nice, ionice, cgroups

Все главы курса «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Поделиться темой: ✈ Telegram VK
Похожие запросы: perf top как найти что грузит процессорчто такое системный вызов и зачем трассироватькак посмотреть процессы в linux и убить зависшийчто такое load average в linux и какое значение нормальноепервые шаги мониторинга сервера linux для новичкаМониторинг и метрики nginx

Вернуться в «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость