Learning Platform
Глоссарий Troubleshooting
Урок 11.02 · 22 мин
Начальный
pspgreppkill/procprocess inspectionBSD vs System V

ps: смотрим на процессы

ps (process status) — главный инструмент, чтобы увидеть, что сейчас работает в системе. Это снапшот — выводит состояние процессов на момент запуска и завершается. Если нужно «смотреть как меняется» — это top/htop из следующего урока, а ps — для «отчёт прямо сейчас, в логи положить, проанализировать grep-ом».

У ps есть исторический подвох: два разных синтаксиса флагов — BSD-стиль (без дефиса) и System V-стиль (с дефисом). Они одновременно работают и иногда смешиваются. Разберёмся.


Две вселенные ps: BSD vs System V

В мире UNIX исторически было два семейства: BSD (Berkeley) и System V (AT&T). У них были разные ps с разными флагами. Linux объединил оба варианта в одной утилите, поэтому вы видите такое:

BSD vs System V в ps

Один и тот же тул, два стиля флагов. Можно использовать любой

ps auxBSD-стиль. Флаги без дефиса. a=all users, u=user-oriented format, x=включая процессы без терминала
ps -efSystem V-стиль. Флаги с дефисом. -e=every process, -f=full format
ps -fp 1234SysV: -f full, -p PID. Детально про конкретный процесс
ps -u usernameSysV: процессы конкретного пользователя

Запомните хотя бы один стиль. Большинство DE/DevOps используют ps aux — это идиоматично и встречается в любом туториале с Stack Overflow.

# BSD-стиль: все процессы со всех пользователей, user-oriented
ps aux

# System V-стиль: все процессы, full format
ps -ef

Вывод ps aux:

USER    PID  %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1  0.0  0.1 168528 12384 ?        Ss   May01   0:12 /sbin/init
root    432  0.0  0.0  72340  4992 ?        Ss   May01   0:00 /usr/sbin/sshd
postgres 1300 0.5 2.1 245680 87232 ?        S    May01   8:23 postgres
levo   2500  0.0  0.1  21560  9024 pts/0    Ss   10:15   0:00 -bash
levo   3300  0.2  0.5  84320 22340 pts/0    R+   10:42   0:00 ps aux

Колонки ps aux — что значат

Колонки ps aux

Что показывает каждое поле в стандартном aux-выводе

USERИмя пользователя-владельца процесса. От его имени работает программа
PIDProcess ID. Уникальный номер процесса
%CPUПроцент CPU за всё время жизни процесса. Снапшот на момент запуска ps. Для long-running процессов малоинформативен — лучше top/htop
%MEMПроцент физической памяти (RSS / total RAM × 100). Например 2.1% значит 2.1% всей RAM сервера
VSZVirtual Size. Виртуальная память процесса в КБ. Включает всё: код, данные, mmap-нутые файлы, swap. Обычно намного больше RSS — это нормально
RSSResident Set Size. Физическая память (РЕАЛЬНО используемая в RAM) в КБ. Это то, что реально занято в физической памяти
TTYК какому терминалу привязан процесс. pts/0 — псевдотерминал 0, ? — нет терминала (демон)
STATСостояние: R/S/D/Z/T (из урока 01). Может быть с модификаторами: + foreground, s session leader, l multi-threaded, N low priority
STARTКогда процесс запущен. Если меньше суток — время. Если больше — дата
TIMECPU time, потреблённое процессом за всё время жизни (не wall clock). 8:23 = 8 минут 23 секунды CPU
COMMANDКоманда запуска. По умолчанию обрезается шириной терминала. С -w или --cols показывает полностью
WARNING

Различие VSZ vs RSS — частый вопрос на собеседовании. VSZ (virtual size) включает всё «обещанное» — все mmap, swap, библиотеки. RSS (resident set size) — только реально занятое в физической RAM. Когда нужно понять «сколько процесс ест памяти на самом деле» — смотрите RSS, а не VSZ.


STAT — модификаторы состояния

В колонке STAT иногда видно Ss+, Sl, R<, D<. Первая буква — основное состояние (R/S/D/Z/T), дальше — модификаторы:

+   foreground process group (привязан к терминалу как foreground)
s   session leader (управляет терминальной сессией)
l   multi-threaded (имеет threads)
<   high priority (низкий nice value)
N   low priority (высокий nice value)
L   pages locked in memory (используется mlock)

Например, Ss+ у bash значит: Sleeping, session leader, foreground. Sl у postgres значит: Sleeping, multi-threaded (хотя Postgres использует процессы, не threads — но есть internal threads тоже).


Детально по конкретному PID

# Детали по PID 1234
ps -fp 1234

# Или BSD-стиль
ps u -p 1234

# Конкретные колонки (наш контроль)
ps -p 1234 -o pid,ppid,user,%cpu,%mem,etime,cmd

-o позволяет выбирать колонки. Полезные:

Полезные -o колонки

Кастомизация вывода ps под задачу

pidProcess ID
ppidParent PID
userИмя владельца. Альтернатива uid (числовое)
%cpuPercent CPU usage
%memPercent memory usage
rssRSS в КБ
vszVirtual size в КБ
etimeПрошедшее время с запуска (elapsed time)
timeCPU time
cmdКоманда + аргументы
statSTAT (как выше)
niceNice value (-20 до 19)
ttyТерминал
wchanWhat channel — на каком ядерном вызове спит процесс

Фильтрация и сортировка

# Сортировка по убыванию использования памяти
ps aux --sort=-%mem | head

# Сортировка по убыванию CPU
ps aux --sort=-%cpu | head

# Сортировка по PID (по возрастанию)
ps aux --sort=pid

# Несколько критериев: сначала по user, потом по %mem убывание
ps aux --sort=user,-%mem

Минус в --sort=-%mem — это «по убыванию». Без минуса — по возрастанию.

# Только процессы конкретного пользователя
ps -u postgres

# Только процессы по конкретному терминалу
ps -t pts/0

# Только с конкретным PPID (например, все потомки systemd)
ps --ppid 1 | head

Анатомия процесса: что хранит ядро для каждого процесса

pgrep и pkill — найти/убить по имени

pgrep ищет процессы по имени или паттерну. pkill тоже ищет, но сразу шлёт сигнал.

# PID-ы всех процессов с airflow в имени
pgrep airflow

# То же, но с дополнительной информацией: PID + cmdline
pgrep -af airflow

# Точное совпадение
pgrep -x bash

# Конкретного пользователя
pgrep -u airflow

# Убить (TERM = SIGTERM = 15)
pkill airflow

# Жёстко (SIGKILL = 9)
pkill -9 airflow

# Убить конкретного пользователя
pkill -u airflow -9
WARNING

pkill airflow убьёт все процессы с подстрокой «airflow» в имени, включая ваш vim airflow_dag.py, если кто-то так назвал файл. Перед pkill всегда делайте pgrep -af чтобы увидеть, кого именно убьёте.

DE-сценарий: после деплоя нужно перезапустить Airflow scheduler.

# 1. Сначала посмотри, что найдётся
pgrep -af "airflow scheduler"

# 2. Аккуратно прибей (TERM, не KILL)
pkill -f "airflow scheduler"

# 3. Подожди немного, проверь
sleep 3
pgrep -af "airflow scheduler"  # если ещё работает — sigkill

-f означает «искать по полной командной строке», не только по имени процесса. Это нужно для случаев, когда имя процесса — python, но командная строка — python /opt/airflow/bin/airflow scheduler.


/proc/PID/ — внутренности процесса

Уже видели в уроке 01. Теперь — на практике для DE.

# Куда process пишет stdout (например, Airflow worker)
ls -l /proc/$(pgrep -f "airflow worker")/fd/1

# Текущая рабочая директория процесса
ls -l /proc/$(pgrep -x postgres)/cwd

# Все переменные окружения (например, AIRFLOW__CORE__*)
cat /proc/$(pgrep -x scheduler)/environ | tr '\0' '\n' | grep AIRFLOW

# Memory usage детально
cat /proc/$(pgrep -x postgres)/status | grep -E "VmRSS|VmSize|Threads"

# Открытые сетевые сокеты
ls -l /proc/$(pgrep -x postgres)/fd/ | grep socket

DE-сценарии

1. «Кто-то жрёт всю память на сервере»

# Топ-10 по памяти
ps aux --sort=-%mem | head

# Если занят суммарно много — посмотри по группам процессов
ps -eo rss,user,cmd --sort=-rss | awk '{a[$2]+=$1} END {for (u in a) print a[u], u}' | sort -rn | head

2. «Когда был запущен Airflow scheduler?»

# etime — прошедшее время с запуска
ps -p $(pgrep -x airflow-scheduler) -o pid,etime,start,cmd

# Или дата старта в полном формате
ps -p $(pgrep -x airflow-scheduler) -o lstart,pid,cmd

3. «Сколько worker-ов Airflow сейчас работает?»

pgrep -c -f "airflow worker"
# Просто число

4. «Что висит в D (uninterruptible) — потенциальный disk issue»

ps aux | awk '$8 ~ /D/ {print}'

Если их много — проблема с диском, NFS или iSCSI mount.

5. «Есть ли зомби?»

ps aux | awk '$8 ~ /Z/'
# Если есть — нужно идти по PPID и чинить родителя

ps + grep — частая ошибка

Классика:

ps aux | grep airflow

В вывод попадёт сам процесс grep airflow — он же содержит «airflow» в команде! Чтобы исключить:

# Способ 1: квадратные скобки — grep не матчит сам себя
ps aux | grep '[a]irflow'

# Способ 2: ещё один grep
ps aux | grep airflow | grep -v grep

# Способ 3 (лучший): pgrep
pgrep -af airflow

[a]irflow — регулярка, которая в результирующих строках выводит «airflow», но в самой регулярке стоит [a]irflow. Соответственно grep сам себя не находит. Старый трюк, но работает.


Попробуй сам

# 1. Топ-5 процессов по памяти
ps aux --sort=-%mem | head -6

# 2. Топ-5 процессов по CPU
ps aux --sort=-%cpu | head -6

# 3. Все процессы под твоим пользователем
ps -u $USER -o pid,etime,cmd

# 4. Запусти sleep и посмотри его внутренности
sleep 300 &
SPID=$!
ls -l /proc/$SPID/cwd
ls -l /proc/$SPID/fd/
cat /proc/$SPID/status | head -20
# Прибей
kill $SPID

# 5. Сколько процессов в системе всего
ps -e --no-headers | wc -l

# 6. Сколько из них спят
ps -eo stat --no-headers | awk '$1 ~ /^S/' | wc -l

Cross-link: про сортировку текста — модуль 7. Про awk-обработку вывода ps — модуль 8. Про top/htop (live мониторинг) — следующий урок 03.


Проверка знанийKnowledge check
В чём разница между VSZ и RSS в выводе ps aux, и почему смотрят на RSS, а не на VSZ, когда оценивают потребление памяти процессом?
ОтветAnswer
VSZ (Virtual Size) — это виртуальная память процесса: всё «обещанное» ядром адресное пространство, включая код программы, данные, mmap-нутые файлы (даже не загруженные с диска), swap, библиотеки. Эта цифра может быть огромной — например, JVM запросто показывает VSZ в десятки ГБ. Но это не значит что столько РЕАЛЬНО занято в RAM. RSS (Resident Set Size) — это физическая память, которую процесс реально занимает в RAM прямо сейчас. Это «honestly взятая» память. Когда нужно понять, ест ли процесс много памяти и не пора ли его убивать — смотрят на RSS. VSZ — это в основном теоретический верхний предел, не реальное потребление.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 5. Чем `ps aux` и `ps -ef` отличаются друг от друга?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 5