SSD ломается незаметно. Сначала всё работает штатно, потом накопитель замирает при записи, а однажды система перестаёт его видеть. Хорошая новость в том, что контроллер задолго до этого честно фиксирует износ ячеек памяти в служебных счётчиках S.M.A.R.T., и прочитать их можно прямо из консоли. Ниже рассказано, какие атрибуты выдают приближающийся отказ, как настроить smartmontools и как собрать скрипт уведомлений для администратора.

Тихая деградация SSD и первые признаки скорого отказа накопителя

Жёсткий диск обычно предупреждает звуком: пощёлкивание, треск, затяжной скрежет. SSD молчит почти до конца. Ячейки NAND-памяти выдерживают ограниченное число циклов записи и стирания, у массовой TLC-памяти это порядка 600-1000 циклов. Ресурс накопителя производитель задаёт в терабайтах записи, параметр TBW, у ходовых моделей на 240-500 ГБ это обычно 150-300 ТБ. Пока ресурс не выработан, диск выглядит безупречным, потому что контроллер размазывает запись по всем чипам и прячет сбои в запасных блоках сверх номинального объёма. Механизм выравнивания износа старит ячейки равномерно, и лишь на нулевом запасе блоков накопитель перестаёт маскировать проблемы.

Первые тревожные знаки появляются в счётчиках, а не в ощущениях: растёт число переназначенных блоков, копятся неисправимые ошибки чтения, ползут вверх задержки ответа. Финал часто выглядит внезапным: файловая система падает в режим только для чтения, крупные файлы пишутся с ошибками, сервер грузится через раз. Регулярный взгляд на S.M.A.R.T. переводит поломку из внезапности в плановую замену, а для взгляда достаточно пары команд раз в месяц.

Установка smartmontools и первая проверка диска из консоли

Пакет smartmontools есть в репозиториях всех распространённых дистрибутивов:

sudo apt-get install smartmontools    # Debian, Ubuntu, Mint
sudo dnf install smartmontools        # Fedora, RHEL, AlmaLinux
sudo pacman -S smartmontools          # Arch

Утилита командной строки называется smartctl. Сначала стоит найти накопители и убедиться, что S.M.A.R.T. включён:

sudo smartctl --scan
sudo smartctl -i /dev/sda

Ключ --scan выводит список устройств с указанием шины, например "/dev/sda -d sat". Ключ -i показывает модель, прошивку, серийный номер и строку "SMART support is: Enabled". Если там значится "Disabled", поддержка включается командой sudo smartctl -s on /dev/sda. Быстрая оценка здоровья делается так:

sudo smartctl -H /dev/sda

Ответ "PASSED" означает лишь то, что контроллер пока не видит собственной неисправности: заводские пороги расставлены с запасом, а настоящая картина износа живёт в таблице атрибутов. Диск за USB-переходником опрашивается с явным ключом шины, например sudo smartctl -H -d sat /dev/sdb. Для NVMe указывается путь /dev/nvme0, а синтаксис остаётся прежним.

Чтение таблицы атрибутов smartctl и расшифровка колонок

Полная таблица вызывается ключом -A, а ключ -a выдаёт всё сразу: общий вердикт, таблицу, журнал ошибок. Пример для SATA-диска Samsung 870 EVO, строки сокращены:

ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       0
  9 Power_On_Hours          0x0032   095   095   000    Old_age   Always       -       9842
177 Wear_Leveling_Count     0x0013   093   093   000    Pre-fail  Always       -       118
179 Used_Rsvd_Blk_Cnt_Tot   0x0013   100   100   010    Pre-fail  Always       -       12
187 Uncorrectable_Error_Cnt 0x0032   100   100   000    Old_age   Always       -       0
199 UDMA_CRC_Error_Count    0x003a   100   100   000    Old_age   Always       -       3
241 Total_LBAs_Written      0x0032   099   099   000    Old_age   Always       -       119321344

Колонка VALUE содержит нормализованное значение, у большинства производителей 100 означает новый накопитель, и цифра тает по мере износа. WORST хранит худшее значение за всю жизнь диска. THRESH это заводской порог, при достижении которого атрибут объявляется неисправным, тогда в колонке WHEN_FAILED вспыхивает FAILING_NOW, а общее заключение меняется на PRE-FAIL. RAW_VALUE содержит настоящий счётчик, и именно к нему стоит присматриваться. По цифрам из примера читается биография диска: 9842 часа наработки это примерно 1,1 года непрерывной работы, а 3 ошибки CRC на шине намекают на проверку кабеля.

С сырыми значениями есть математическая ловушка. Атрибут 241 Total_LBAs_Written со значением 119321344 секторов превращается в объём записи простым умножением на 512 байт, выходит около 61 ГБ за всю жизнь. Но у части прошивок Western Digital сырые единицы атрибута 241 отличаются от секторов, поэтому цифру перепроверяют по разделу Device Statistics из вывода -x.

По порогам тоже есть тонкость. У атрибута Wear_Leveling_Count в примере THRESH равен нулю, то есть формально износ не признаётся неисправностью ни при каком VALUE. Поэтому деградацию отслеживают вручную или скриптом: VALUE 80 означает израсходованную примерно пятую часть ресурса, 50 говорит о выработанной половине, а 20 и ниже переводит замену накопителя из теории в практический план.

Ключевые атрибуты износа ячеек и пороги для тревоги

Главный показатель, атрибут 5 Reallocated_Sector_Ct, считает блоки, от которых контроллер уже отказался и заменил запасными. Любое значение выше нуля заслуживает внимания, а устойчивый рост за короткие интервалы это прогноз близкого отказа. Атрибут 179 Used_Rsvd_Blk_Cnt_Tot показывает, сколько запасных блоков уже израсходовано, 181 Program_Fail_Cnt_Total и 182 Erase_Fail_Count_Total считают неудачные записи и стирания, их рост выдаёт деградацию ячеек. Атрибут 187 Uncorrectable_Error_Cnt хранит счётчик неисправимых ошибок чтения, любое ненулевое значение означает потерю данных в конкретном секторе, это уже не прогноз, а констатация. Атрибут 199 UDMA_CRC_Error_Count растёт при ошибках шины SATA, чаще всего виноваты кабель или переходник, но сам накопитель тоже стоит проверить. Температура живёт в атрибуте 194, комфортно до 60 градусов, длительная жара ускоряет старение ячеек и электроники.

Остаток ресурса разные производители прячут в разных местах. У Intel это атрибут 233 Media_Wearout_Indicator, он стартует со 100 и к исчерпанию номинального ресурса доходит до 1. У Kingston и SanDisk есть 231 SSD_Life_Left с остатком ресурса в процентах. У Crucial и Micron используется 202 Percent_Lifetime_Remain, где в сыром значении лежит израсходованный процент. На Samsung ориентироваться удобнее по нормализованному VALUE атрибута 177 Wear_Leveling_Count, сырые данные там упакованы из нескольких счётчиков стирания сразу.

NVMe-накопители таблицу атрибутов ATA не используют, контроллер отдаёт готовые поля:

sudo smartctl -a /dev/nvme0
SMART overall-health self-assessment test result: PASSED

Critical Warning:                   0x00
Temperature:                        41 Celsius
Available Spare:                    100%
Available Spare Threshold:          10%
Percentage Used:                    3%
Data Units Written:                 11,843,050 [6.06 TB]
Power On Hours:                     9,842
Unsafe Shutdowns:                   27
Media and Data Integrity Errors:    0

Percentage Used показывает долю выработанного ресурса, значение 100 означает, что номинальный TBW исчерпан и накопитель живёт в сверхурочном режиме. Available Spare это остаток запасных блоков в процентах, при падении ниже порога из соседней строки контроллер выставляет биты в Critical Warning. Media and Data Integrity Errors становится ненулевым при сбоях записи данных, это поле наравне с Available Spare самое честное в отчёте. Data Units Written переводится в терабайты простым умножением, одна единица равна 512000 байтам, поэтому 11843050 единиц это 6,06 ТБ записи. Unsafe Shutdowns копит внезапные отключения питания и сам по себе не приговор, но в паре с ошибками целостности уже настораживает. Для скриптов удобнее машиночитаемый JSON:

sudo smartctl -j -a /dev/nvme0 | jq '.nvme_smart_health_information_log.percentage_used'

Расширенная статистика и самотестирование накопителя

Ключ -x показывает всё, что отдаёт прошивка, включая журнал Device Statistics, где строка Logical Sectors Written умножением на 512 байт переводится в честный объём записи за жизнь. Цифра пригодится и для контроля гарантийного ресурса, и для прикидки остатка, а попутно сверяются спорные единицы атрибута 241.

Самопроверки запускаются вручную:

sudo smartctl -c /dev/sda            # расчётное время каждого теста
sudo smartctl -t short /dev/sda
sudo smartctl -t long /dev/sda
sudo smartctl -l selftest /dev/sda   # журнал с результатами

Короткий тест на SSD занимает пару минут, расширенный от пяти минут до получаса, ключ -c назовёт точные цифры для конкретной модели. Во время проверки диском можно пользоваться, хотя производительность падает, а вот ключ -C полностью блокирует устройство, на боевом сервере это критично. Итоговая строка "Completed without error" это норма, запись "Completed: read failure" вместе с адресом LBA прямо называет сбойный сектор, после чего данные с накопителя переносятся на новое место безотлагательно.

Настройка фоновой службы smartd и письма администратору

Запускать команды руками раз в месяц можно, но память коварна. Служба smartd из того же пакета сама опрашивает накопители каждые полчаса и пишет всё в системный журнал. Её поведение задаётся в файле /etc/smartd.conf, а стандартная строка собирается из нескольких понятных частей:

  1. DEVICESCAN находит все подключённые накопители и применяет к каждому последующие директивы;
  2. -a включает полный контроль, здоровье, журнал ошибок, результаты самотестов и температуру;
  3. -n standby,q пропускает опрос уснувшего диска, чтобы не будить его лишний раз;
  4. -W 4,45,55 задаёт температурные рамки, при 45 градусах приходит предупреждение, при 55 уже тревога;
  5. -m Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. назначает получателя писем, а -M daily повторяет сообщение не чаще одного раза в сутки.
DEVICESCAN -a -n standby,q -W 4,45,55 -m Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript. -M daily

Дальше служба включается штатным способом, а конфигурация проверяется прогоном одной итерации:

sudo systemctl enable --now smartd
sudo smartd -q onecheck
sudo journalctl -u smartd -f

В журнале мелькают строки вида "Device: /dev/sda, SMART Usage Attribute: 5 Reallocated_Sector_Ct changed from 100 to 99", так служба сообщает об изменениях нормализованных значений. Для проверки почтового канала временно добавляется директива -M test, при следующем старте smartd пришлёт тестовое письмо. Письма отправляет любой почтовый транспорт, например postfix или компактный msmtp, плюс пакет mailutils с утилитой mail. Если почта не нужна, вместо -m указывается -M exec с путём к собственному скрипту, он получает в переменных окружения SMARTD_DEVICE, SMARTD_FAILTYPE, SMARTD_MESSAGE и SMARTD_SUBJECT и сам решает, куда доставить сигнал, в почту, в систему мониторинга или в чат оповещений.

Привычным к графике пригодится приложение "Диски" в GNOME: выбрать накопитель слева, открыть меню с тремя линиями и нажать пункт "Данные S.M.A.R.T.", на домашней машине этого достаточно, на сервере всё равно рулит консоль.

Скрипт с проверкой SSD и отправкой уведомления администратору

smartd следит за заводскими порогами, а собственные лимиты удобнее держать в отдельном скрипте. Ниже готовый пример для /usr/local/bin/ssd-check.sh: он обходит все диски, различает SATA и NVMe, сравнивает счётчики с порогами и отправляет письмо через mail, а событие пишет в журнал.

#!/bin/bash
# Проверка износа SSD и уведомление администратора
MAIL_TO="Адрес электронной почты защищен от спам-ботов. Для просмотра адреса в браузере должен быть включен Javascript."
LIMIT_REALLOC=10
LIMIT_LIFE=20
LIMIT_PERCENT=80

send_alert() {
    echo "$1" | mail -s "Тревога SSD на $(hostname)" "$MAIL_TO"
    logger -t ssd-check "$1"
}

for DISK in $(smartctl --scan | awk '{print $1}'); do
    if smartctl -i "$DISK" 2>/dev/null | grep -q "NVMe"; then
        PERCENT=$(smartctl -a "$DISK" | awk '/Percentage Used:/ {gsub("%",""); print $3}')
        MEDIA=$(smartctl -a "$DISK" | awk '/Media and Data Integrity Errors:/ {print $6}')
        if [ -n "$MEDIA" ] && [ "$MEDIA" -gt 0 ]; then
            send_alert "Диск $DISK фиксирует ошибки целостности, счётчик $MEDIA"
        fi
        if [ -n "$PERCENT" ] && [ "$PERCENT" -ge "$LIMIT_PERCENT" ]; then
            send_alert "Диск $DISK израсходовал $PERCENT процентов ресурса ячеек"
        fi
    else
        REALLOC=$(smartctl -A "$DISK" | awk '$1==5 {print $10}')
        LIFE=$(smartctl -A "$DISK" | awk '$1==231 {print $4}')
        CRC=$(smartctl -A "$DISK" | awk '$1==199 {print $10}')
        if [ -n "$REALLOC" ] && [ "$REALLOC" -ge "$LIMIT_REALLOC" ]; then
            send_alert "Диск $DISK переназначил $REALLOC блоков, счётчик растёт"
        fi
        if [ -n "$LIFE" ] && [ "$LIFE" -le "$LIMIT_LIFE" ]; then
            send_alert "Ресурс ячеек диска $DISK на исходе, осталось $LIFE процентов"
        fi
        if [ "$CRC" -gt 0 ] 2>/dev/null; then
            send_alert "На диске $DISK вырос счётчик ошибок шины, проверьте кабель"
        fi
    fi
done

Скрипту нужны права на исполнение и запись в расписание:

sudo chmod +x /usr/local/bin/ssd-check.sh
sudo crontab -e

В crontab root добавляется строка для ежедневной проверки в восемь утра:

0 8 * * * /usr/local/bin/ssd-check.sh

Тот же скрипт вешается и на smartd через -M exec, служба передаст ему контекст в переменных окружения, и дублирование тут работает как страховка: пороги у службы свои, лимиты у скрипта свои.

Счётчики S.M.A.R.T. не дают дату поломки в календаре, зато честно показывают остаток ресурса и первые сбои. Полезная привычка выглядит так: рост атрибута 5 означает еженедельный контроль, VALUE износа ниже 80 означает ежесуточные проверки и план замены, а неисправимые ошибки или падение Available Spare ниже порога означают, что копировать данные нужно сегодня. Замена накопителя по плану стоит копейки по сравнению с внезапной остановкой сервиса в самый неподходящий час.