Загадочная картина: монитор показывает огромную долю времени ожидания, процессор будто завален работой, система ползёт - а накопитель при этом почти не нагружен. По всем приметам узкое место в дисковых операциях, но сам диск спокоен. Парадокс ставит в тупик и сбивает диагностику с пути: ищут перегруженный накопитель, а его нет. На деле высокое время ожидания не всегда означает занятый локальный диск. Оно означает, что процессы чего-то ждут от подсистемы ввода-вывода, и это что-то может лежать вовсе не на местном накопителе.

Доля времени ожидания в показаниях процессора - это время, которое процессор простоял без дела, ожидая завершения операций ввода-вывода. Источников у такого ожидания несколько: медленный диск, но также сетевое хранилище, застрявший в ожидании процесс, нехватка памяти с уходом в подкачку. Разберём, как подтвердить высокое ожидание, как найти виновный процесс через монитор ввода-вывода и состояние процессов, и почему диск порой ни при чём.

Подтверждение высокого времени ожидания и проверка диска

Сначала картину подтверждают обзорными инструментами. Доля времени ожидания видна в мониторе процессов и в обзоре виртуальной памяти - в строке состояния процессора это отдельная доля.

top                # доля ожидания в строке состояния процессора
vmstat 1 5         # колонка wa показывает долю ожидания

Высокая доля ожидания означает, что процессор простаивает в ожидании ввода-вывода. Но прежде чем винить диск, надо проверить, действительно ли он нагружен. Это делает подробная статистика устройств хранения, и в ней есть ключевые колонки.

iostat -xz 2 10    # подробная статистика дисковых устройств

Самая важная колонка тут - загрузка устройства в процентах. Сто процентов означают полностью насыщенный диск, и тогда узкое место действительно в накопителе. Вторая важная колонка - среднее время ожидания операции, которое для быстрых накопителей должно быть малым. Вот здесь и вскрывается парадокс из заголовка: если загрузка устройства низка, а время ожидания высоко - диск не виноват, и искать причину надо в другом месте.

Когда диск действительно насыщен, стоит заглянуть и в его здоровье - деградирующий накопитель или сбойный массив тоже растягивают операции.

sudo smartctl -a /dev/sda    # здоровье накопителя по данным самодиагностики

Монитор ввода-вывода называет процесс, грузящий диск

Когда диск всё же нагружен, виновного ищет специальный монитор - он показывает, какие процессы создают дисковую нагрузку прямо сейчас, подобно тому как обычный монитор показывает нагрузку на процессор. Его обычно нужно установить, и запускают с правами администратора, чтобы видеть все процессы.

sudo iotop -o      # процессы, реально создающие ввод-вывод

Флаг показа только активных оставляет в списке лишь те процессы, что действительно ведут операции ввода-вывода, отсеивая простаивающие. Так среди десятков процессов сразу видно того, кто читает или пишет больше всех. Это прямой путь к виновнику, когда диск загружен.

Если монитор ввода-вывода недоступен, есть обходной путь через файловую систему процессов. У каждого процесса есть файл со статистикой ввода-вывода, где видно, сколько байтов он прочитал и записал на уровне хранилища.

cat /proc/12345/io    # статистика ввода-вывода конкретного процесса

Колонки прочитанных и записанных байтов показывают объём, реально прошедший через подсистему хранения для этого процесса. Сопоставив их у подозреваемых, можно подтвердить, кто создаёт нагрузку, даже без специального монитора.

Состояние процесса выдаёт того, кто застрял в ожидании

Вот ключ к парадоксу ненагруженного диска. Обычный список процессов не показывает нагрузку на ввод-вывод напрямую, но показывает состояние процесса, и одно из состояний прямо указывает на ожидание ввода-вывода. Это состояние непрерываемого сна, помечаемое буквой D. Процесс в нём ждёт завершения операции ввода-вывода и не может быть прерван даже сигналом, пока операция не завершится.

ps aux | awk '$8 ~ /D/'    # процессы в состоянии непрерываемого сна

Эта команда выбирает все процессы, чьё состояние - непрерываемый сон. Именно они чего-то ждут от подсистемы ввода-вывода. И вот тут вскрывается суть парадокса: процесс может застрять в ожидании D, при том что локальный диск почти не нагружен. Куда же он смотрит?

Самый частый ответ - сетевое хранилище. Процесс, читающий или пишущий на сетевую файловую систему, висит в состоянии непрерываемого сна, ожидая ответа по сети, а вовсе не от местного накопителя. Местный диск при этом спокоен, потому что данные идут не через него. Высокая доля времени ожидания при ненагруженном диске - классический признак того, что ожидание упирается в сеть, а не в накопитель.

Стоит осторожно толковать само наличие процесса в состоянии непрерываемого сна. Кратковременное пребывание в нём нормально - любой процесс, ведущий ввод-вывод, мелькает в этом состоянии. Тревожен процесс, застрявший в нём надолго и постоянно: это уже либо тяжёлая нагрузка, либо застревание из-за неполадки драйвера или недоступного сетевого ресурса.

Затяжное застревание в состоянии D сигнализирует о неполадке

Когда процесс намертво залип в состоянии непрерываемого сна и не выходит из него, это нередко признак серьёзной ошибки - чаще всего на уровне драйвера устройства или недоступного хранилища. Такой процесс невозможно завершить даже принудительным сигналом, потому что ядро ждёт завершения операции ввода-вывода, которое может не наступить никогда, если устройство сбоит или сетевой ресурс пропал.

Диагностика тут идёт от того, с чем процесс пытается работать. Если застревание связано с определённым устройством или сетевым ресурсом, причину ищут именно там - в драйвере этого устройства или в доступности этого ресурса. Чтобы понять, что именно делает зависший процесс, помогает трассировка его системных вызовов, показывающая, на какой операции он встал.

strace -e trace=read,write,open -c -p 12345    # на чём застрял процесс

Для более глубокого разбора дисковых операций на уровне блочного устройства применяют трассировку блочного слоя - она показывает размер, длительность и задержку каждой операции ввода-вывода и помогает понять, не молотит ли диск вхолостую перемещениями головок. Но в случае ненагруженного диска при высоком ожидании первым подозреваемым остаётся сеть или зависший на недоступном ресурсе процесс.

Понижение приоритета и память как ещё одна причина

Когда виновный процесс найден и его нагрузка на ввод-вывод не критична, ему можно понизить приоритет ввода-вывода, чтобы он не мешал важным задачам. Это делает отдельная команда управления приоритетом ввода-вывода, переводящая процесс в простаивающий класс.

ionice -c 3 -p 12345    # перевести процесс в простаивающий класс ввода-вывода

Стоит держать в уме и ещё одну скрытую причину высокого ожидания, не связанную напрямую ни с диском, ни с сетью, - нехватку памяти. Когда оперативки не хватает, система вытесняет данные в область подкачки на диске, и процессы ждут этих операций, что выглядит как высокое время ожидания. Проверить это помогает наблюдение за обменом с подкачкой в обзоре виртуальной памяти - устойчивый ненулевой обмен указывает, что корень не в обычных дисковых операциях, а в давлении на память.

Что складывается в методику

Картина выстраивается в чёткую методику. Высокую долю времени ожидания подтверждают обзорными инструментами, затем проверяют диск подробной статистикой. Ключевая развилка - загрузка устройства: высока она при высоком ожидании, значит, диск действительно узкое место, и виновный процесс ищут монитором ввода-вывода или через файл статистики процесса. А вот низкая загрузка диска при высоком ожидании - сигнал, что диск ни при чём.

В этом случае на сцену выходит состояние процессов: процессы в состоянии непрерываемого сна чего-то ждут от ввода-вывода, и при ненагруженном диске это почти всегда сеть или зависший на недоступном ресурсе процесс. Затяжное застревание выдаёт неполадку драйвера или хранилища, а трассировка системных вызовов показывает, на чём именно процесс встал. И нельзя забывать про память как скрытую причину ожидания через подкачку.

Главная мысль: высокое время ожидания - это не приговор диску, а указание на ожидание ввода-вывода вообще. Парадокс ненагруженного диска при высоком ожидании разрешается просто, стоит вспомнить, что ждать можно не только местный накопитель, но и сеть. Стоит освоить связку из проверки загрузки диска и поиска процессов в состоянии непрерываемого сна, и расследование перестаёт топтаться вокруг спокойного накопителя - оно находит истинный источник ожидания, будь то сетевое хранилище, зависший процесс или давление на память.