TL;DRСтатия предоставя удобен, бърз и надежден начин за определяне на Linux програми, които записват данни на диска, което помага за идентифициране на голямо или аномално високо натоварване върху дисковата подсистема, както и за оценка на разходите на файловата система. Това е особено актуално за SSD устройства в компютри, EMMC и флаш памет в одноплатни компютри.
В процеса на написването на статията се установи, че записването на няколко килобайта данни в файловата система BTRFS води до записването на 3 мегабайта реални данни на диска.
Въведение
„Ой, глупости, паметните клетки на съвременните SSD устройства ще се повредят след десетки години обикновена употреба, не си струва да се притесняваме за това и още по-малко да прехвърляме swap, виртуални машини и папката с профила на браузъра на HDD“ — типичен отговор на въпрос за надеждността на SSD устройства с гарантирани ≈150 TBW. Ако сметнем колко данни обичайно софтуер може да записва, изглежда, че 10-20 ГБ на ден е вече голямо число, нека да приемем максимум 40 ГБ, много по-вече не може. При такива цифри отговорът е доста разумен — нужно е 10 години, за да се достигнат гарантираните стойности по броя на перезаписванията на клетките, при 40 ГБ записани данни всеки ден.
Обаче, през последните 6 години ползвам вече трети SSD: при първия контролерът се повреди, а вторият започна да прехвърля данни между клетките няколко пъти на ден, което водеше до 30-секундни забавяния при записването.
След 7 месеца употреба на нов SSD реших да проверя количеството записани данни, както ги съобщава самият диск чрез SMART.
19.7 ТБ.
Общо за 7 месеца съм използвал 13% от гарантираното количество записани данни, при положение, че той е настроен в съответствие с препоръките за изравняване на дялове и настройка на файловата система, swap почти не се използва, дисковете на виртуални машини са разположени на HDD!
Това е аномално голямо число, при тези темпове гарантираният TBW ще бъде превишен още преди изтичането на 5-годишния гаранционен срок на диска. И не може моят компютър да записва по 93 гигабайта дневно! Нужно е да проверя колко данни се записват на диска за 10 минути…
Общо:
Написани опашки: 24,712, 2,237MiB
Завършени записи: 25,507, 2,237MiB
Сливане на записи: 58, 5,472KiB
2.2 ГиБ, о-го-го!
Определянето на количеството записани данни на дисково устройство
Ако вашето устройство поддържа S.M.A.R.T. (SSD, EMMC, няколко промишлени MicroSD), то на първо място следва да поискате данни от носителя с програмите smartctl, skdump или mmc (от състава mmc-utils).
Пример на изхода на програмата smartctl
$ sudo smartctl -a /dev/sdb
smartctl 7.0 2019-03-31 r4903 [x86_64-linux-5.3.11-200.fc30.x86_64] (local build)
Copyright (C) 2002-18, Bruce Allen, Christian Franke, www.smartmontools.org
=== НАЧАЛО НА РАЗДЕЛ ПРОДОСТАВЕНА ИНФОРМАЦИЯ ===
Семейство Модели: SSD устройства на базата на Samsung
Модел на Устройството: Samsung SSD 860 EVO mSATA 250GB
Сериен Номер: S41MNC0KA13477K
LU WWN Идентификатор на Устройството: 5 002538 e700fa64b
Версия на Фърмуера: RVT41B6Q
Потребителска Вместимост: 250 059 350 016 байта [250 GB]
Размер на Сектора: 512 байта логически/физически
Скорост на Завъртане: Solid State Device
Форма Фактор: mSATA
Устройството е: В базата данни на smartctl [за подробности използвайте: -P show]
ATA Версия е: ACS-4 T13/BSR INCITS 529 ревизия 5
SATA Версия е: SATA 3.1, 6.0 Gb/s (текуща: 3.0 Gb/s)
Местно Време е: Вт Ное 19 01:48:50 2019 MSK
SMART поддръжка е: Налична - устройството има SMART способности.
SMART поддръжка е: Включена
=== НАЧАЛО НА ЧЕТЕНЕ НА ДАННИТЕ ОТ SMART ===
Резултат от теста за самооценка на общото здраве на SMART: ПРЕМИНАЛ
Общи стойности на SMART:
Статус на офлайн събиране на данни: (0x00) Активността по събиране на офлайн данни
никога не е започвала.
Авто офлайн събиране на данни: Деактивирано.
Статус на изпълнение на самооценка: ( 0) Предишната рутинна самооценка е завършила
без грешки или не е била проведена
рутинна самооценка.
Общо време за завършване на Офлайн
събиране на данни: ( 0) секунди.
Офлайн събиране на данни
възможности: (0x53) SMART изпълнява офлайн незабавно.
Поддържа авто офлайн събиране на данни.
Спира офлайн събиране при нов
команда.
Няма поддръжка за офлайн повърхностно сканиране.
Поддържа самооценка.
Няма поддръжка за самооценка на транспорт.
Поддържа селективна самооценка.
SMART способности: (0x0003) Запазва SMART данни преди да влезе
в режим на пестене на енергия.
Поддържа таймер за автозапазване на SMART.
Възможност за запис на грешки: (0x01) Поддържа запис на грешки.
Поддържа Общоприето Логиране.
Препоръчително време за наблюдение на
кратката рутинна самооценка: ( 2) минути.
Препоръчително време за наблюдение на
разширената рутинна самооценка: ( 85) минути.
Възможности на SCT: (0x003d) Поддържа SCT статус.
Поддържа контрол на възстановяване на грешки SCT.
Поддържа контрол на функции SCT.
Поддържа таблица с данни SCT.
Версия на лог файла за грешки на SMART: 1
Няма записани грешки
Структура на лог файла за самооценка на SMART версия: 1
Не са записани самооценки. [За да стартирате самооценки, използвайте: smartctl -t]
Структура на данните в лог файла за селективна самооценка на SMART версия: 1
СПАН МИНИМАЛЕН_LBA МАКСИМАЛЕН_LBA ТЕКУЩ СТАТУС_НА_ТЕСТА
1 0 0 Не_тества
2 0 0 Не_тества
3 0 0 Не_тества
4 0 0 Не_тества
5 0 0 Не_тества
Флагове за селективно самооценяване (0x0):
След сканиране на избраните области, не чете-сканира останалата част от диска.
Ако селективното самооценяване е в очакване при включване, продължете след 0 минути забавяне.Моят SSD съхранява количеството записани данни в параметъра 241 Total_LBAs_Written, в логически блокове (LBA), а не в байтове. Размерът на логическия блок в моя случай е 512 байта (може да се види в изхода на smartctl, в Sector Size). За да получите байтовете, трябва да умножите стойността на параметъра по 512.
38615215765 × 512 ÷ 1000 ÷ 1000 ÷ 1000 ÷ 1000 = 19,770 TB
38615215765 × 512 ÷ 1024 ÷ 1024 ÷ 1024 ÷ 1024 = 17,981 TiBПрограма skdump на моя SSD се опитва да интерпретира стойността Total_LBAs_Written по свой начин, поради което показва 1296217.695 TB, което очевидно е неправилно.
За да разберем количеството записвана информация на ниво устройство, ще използваме програмата btrace от пакета blktrace. Тя показва както общата статистика за цялото време на работа на програмата, така и отделните процеси и потоци (включително ядра), които са извършвали запис.
Изпълнете следната команда, за да съберете информация за 10 минути, където /dev/sdb е вашият диск:
# btrace -w 600 -a write /dev/sdbТипичен изход от командата
…
8,16 0 3253 50.085433192 0 C WS 125424240 + 64 [0]
8,16 0 3254 50.085550024 0 C WS 193577744 + 64 [0]
8,16 0 3255 50.085685165 0 C WS 197246976 + 64 [0]
8,16 0 3256 50.085936852 0 C WS 125736264 + 128 [0]
8,16 0 3257 50.086060780 0 C WS 96261752 + 64 [0]
8,16 0 3258 50.086195031 0 C WS 94948640 + 64 [0]
8,16 0 3259 50.086327355 0 C WS 124656144 + 64 [0]
8,16 0 3260 50.086843733 15368 C WSM 310218496 + 32 [0]
8,16 0 3261 50.086975238 753 A WSM 310218368 + 32 < (8,20) 291339904
8,16 0 3262 50.086975560 753 Q WSM 310218368 + 32 [dmcrypt_write/2]
8,16 0 3263 50.086977345 753 G WSM 310218368 + 32 [dmcrypt_write/2]
8,16 0 3264 50.086978072 753 I WSM 310218368 + 32 [dmcrypt_write/2]
8,16 0 3265 50.086979159 753 D WSM 310218368 + 32 [dmcrypt_write/2]
8,16 0 3266 50.087055685 0 C WSM 310218368 + 32 [0]
8,16 0 3267 50.087060168 753 A WSM 310218592 + 160 < (8,20) 291340128
8,16 0 3268 50.087060367 753 Q WSM 310218592 + 160 [dmcrypt_write/2]
8,16 0 3269 50.087061242 753 G WSM 310218592 + 160 [dmcrypt_write/2]
8,16 0 3270 50.087061698 753 I WSM 310218592 + 160 [dmcrypt_write/2]
8,16 0 3271 50.087062361 753 D WSM 310218592 + 160 [dmcrypt_write/2]
8,16 0 3272 50.087386179 0 C WSM 310218592 + 160 [0]
8,16 0 3273 50.087436417 15368 A FWS 0 + 0 < (253,1) 0
8,16 0 3274 50.087437471 15368 Q FWS [LS Thread]
8,16 0 3275 50.087440862 15368 G FWS [LS Thread]
8,16 0 3276 50.088300047 0 C WS 0 [0]
8,16 0 3277 50.088470917 753 A WFSM 18882688 + 8 < (8,20) 4224
8,16 0 3278 50.088471091 753 Q WFSM 18882688 + 8 [dmcrypt_write/2]
8,16 0 3279 50.088471688 753 G WFSM 18882688 + 8 [dmcrypt_write/2]
8,16 0 3280 50.088474334 32254 D WSM 18882688 + 8 [kworker/0:2H]
8,16 0 3281 50.088515572 0 C WSM 18882688 + 8 [0]
8,16 0 3282 50.089229069 0 C WSM 18882688 [0]
CPU0 (8,16):
Reads Queued: 0, 0KiB Writes Queued: 345, 25,932KiB
Read Dispatches: 0, 0KiB Write Dispatches: 331, 25,788KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 1,597, 117,112KiB
Read Merges: 0, 0KiB Write Merges: 1, 16KiB
Read depth: 0 Write depth: 177
IO unplugs: 0 Timer unplugs: 0
CPU1 (8,16):
Reads Queued: 0, 0KiB Writes Queued: 502, 39,948KiB
Read Dispatches: 0, 0KiB Write Dispatches: 495, 40,076KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 177
IO unplugs: 0 Timer unplugs: 0
CPU2 (8,16):
Reads Queued: 0, 0KiB Writes Queued: 297, 26,800KiB
Read Dispatches: 0, 0KiB Write Dispatches: 287, 26,800KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 0, 0KiB
Read depth: 0 Write depth: 177
IO unplugs: 0 Timer unplugs: 0
CPU3 (8,16):
Reads Queued: 0, 0KiB Writes Queued: 418, 24,432KiB
Read Dispatches: 0, 0KiB Write Dispatches: 408, 24,448KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 0, 0KiB
Read Merges: 0, 0KiB Write Merges: 2, 272KiB
Read depth: 0 Write depth: 177
IO unplugs: 0 Timer unplugs: 0
Total (8,16):
Reads Queued: 0, 0KiB Writes Queued: 1,562, 117,112KiB
Read Dispatches: 0, 0KiB Write Dispatches: 1,521, 117,112KiB
Reads Requeued: 0 Writes Requeued: 0
Reads Completed: 0, 0KiB Writes Completed: 1,597, 117,112KiB
Read Merges: 0, 0KiB Write Merges: 3, 288KiB
IO unplugs: 0 Timer unplugs: 0
Throughput (R/W): 0KiB/s / 2,338KiB/s
Events (8,16): 9,287 entries
Skips: 0 forward (0 - 0.0%) btrace позволява да се види реалното количество записани данни, но да разберете кои точно програми извършват запис, е трудно от нейния изход.
Определяне на програмите, които извършват запис на носителя
Програма iotop ще покаже процесите, които записват на диска, и размера на записаните данни.
Най-удобният изход осигуряват следните параметри:
# iotop -obPatПримерен изход на програмата
02:55:47 Total DISK READ : 0.00 B/s | Total DISK WRITE : 30.65 K/s
02:55:47 Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TIME PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
b'02:55:47 753 be/4 root 0.00 B 0.00 B 0.00 % 0.04 % [dmcrypt_write/2]'
b'02:55:47 788 be/4 root 72.00 K 18.27 M 0.00 % 0.02 % [btrfs-transacti]'
b'02:55:47 15057 be/4 valdikss 216.00 K 283.05 M 0.00 % 0.01 % firefox'
b'02:55:47 1588 ?dif root 0.00 B 0.00 B 0.00 % 0.00 % Xorg -nolisten tcp -auth /var/run/sddm/{398f030f-9667-4dff-b371-81eaae48dfdf} -background none -noreset -displayfd 18 -seat seat0 vt1'
b'02:55:47 15692 be/4 valdikss 988.00 K 9.41 M 0.00 % 0.00 % python3 /usr/bin/gajim'
b'02:55:47 15730 ?dif valdikss 9.07 M 0.00 B 0.00 % 0.00 % telegram-desktop --'
b'02:55:47 2174 ?dif valdikss 1840.00 K 2.47 M 0.00 % 0.00 % yakuake'
b'02:55:47 19827 be/4 root 16.00 K 896.00 K 0.00 % 0.00 % [kworker/u16:7-events_unbound]'
b'02:55:47 19074 be/4 root 16.00 K 480.00 K 0.00 % 0.00 % [kworker/u16:4-btrfs-endio-write]'
b'02:55:47 19006 be/4 root 16.00 K 1872.00 K 0.00 % 0.00 % [kworker/u16:1-events_unbound]'
b'02:55:47 1429 be/4 root 484.00 K 0.00 B 0.00 % 0.00 % accounts-daemon'
b'02:55:47 15820 be/4 valdikss 312.00 K 0.00 B 0.00 % 0.00 % firefox -contentproc -childID 6 -isForBrowser -prefsLen 7894 -prefMapSize 223880 -parentBuildID 20191022164834 -greomni /usr/lib64/firefox/omni.ja -appomni /usr/lib64/firefox/browser/omni.ja -appdir /usr/lib64/firefox/browser 15057 tab'
b'02:55:47 2125 ?dif valdikss 0.00 B 92.00 K 0.00 % 0.00 % plasmashell'
b'02:55:47 1268 be/3 root 0.00 B 4.00 K 0.00 % 0.00 % auditd'
b'02:55:47 1414 be/4 root 0.00 B 4.00 K 0.00 % 0.00 % sssd_nss --uid 0 --gid 0 --logger=files'
b'02:55:47 15238 be/4 valdikss 0.00 B 4.00 K 0.00 % 0.00 % thunderbird'
b'02:55:47 18605 be/4 root 0.00 B 3.19 M 0.00 % 0.00 % [kworker/u16:0-btrfs-endio-write]'
b'02:55:47 18867 be/4 root 0.00 B 96.00 K 0.00 % 0.00 % [kworker/u16:5-btrfs-endio-meta]'
b'02:55:47 19070 be/4 root 0.00 B 160.00 K 0.00 % 0.00 % [kworker/u16:2-btrfs-freespace-write]'
b'02:55:47 19645 be/4 root 0.00 B 2.17 M 0.00 % 0.00 % [kworker/u16:3-events_unbound]'
b'02:55:47 19982 be/4 root 0.00 B 496.00 K 0.00 % 0.00 % [kworker/u16:6-btrfs-endio-write]'На пръв поглед се наблюдава, че Firefox е записал 283 мегабайта за няколко минути работа на iotop.
Определяне на файловете, в които се извършва запис
Информация за процеса, който натоварва диска — е добра, но пътищата, по които се извършва запис — са още по-добри.
Нека използваме програмата fatrace, която следи промените в файловата система.
# fatrace -f WПримерен изход на програмата
firefox(15057): CW /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/moz-extension+++e5c304fb-af40-498a-9ba8-47eb0416e933^userContextId=4294967295/idb/3647222921wleabcEoxlt-eengsairo.sqlite-wal
firefox(15057): CW /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/moz-extension+++e5c304fb-af40-498a-9ba8-47eb0416e933^userContextId=4294967295/idb/3647222921wleabcEoxlt-eengsairo.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): CW /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/usage-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/usage
firefox(15057): CW /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/usage
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite-wal
firefox(15057): CW /home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/https+++habr.com/ls/data.sqlite-journal
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqlite
firefox(15057): W /home/valdikss/.mozilla/firefox/xyf4vqh2.default/webappsstore.sqliteFatrace не показва броя на записаните данни поради използването на доста прост метод за наблюдение на достъпа до файловете чрез inotify.
От изхода е видно как хабр запазва моята статия в local storage на браузъра, докато я пиша, както и разширението Group Speed Dial, което, как се установи именно с помощта на fatrace, чете данните си на всеки 30 секунди. Именно чете, а не записва: CW Пред файла се казва, че файлът може да се отваря за четене и запис, като същевременно се създава файл, ако той не съществува (извиква се openat с флага O_RDWR|O_CREAT), но не се казва, че в файла действително е записана някаква информация.
За всеки случай, за да се уверим в това, ще използваме strace с филтър за файловите системни повиквания:
strace -yy -e trace=open,openat,close,write -f -p 15057 2>&1 | grep extensionИзход от командата
[pid 20352] openat(AT_FDCWD, "/home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/moz-extension+++e5c304fb-af40-498a-9ba8-47eb0416e933^userContextId=4294967295/idb/3647222921wleabcEoxlt-eengsairo.sqlite", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 153
[pid 20352] read(153, "SQLite format 3 20 22 @ d 23"..., 100) = 100
[pid 20352] read(153, "SQLite format 3 20 22 @ d 23"..., 4096) = 4096
[pid 20352] openat(AT_FDCWD, "/home/valdikss/.mozilla/firefox/xyf4vqh2.default/storage/default/moz-extension+++e5c304fb-af40-498a-9ba8-47eb0416e933^userContextId=4294967295/idb/3647222921wleabcEoxlt-eengsairo.sqlite-wal", O_RDWR|O_CREAT|O_CLOEXEC, 0644) = 166
…
[pid 20352] read(54, " r4304364354354364- 4204!4'414" 250 &"..., 4096) = 4096
[pid 20352] read(54, " 136Pt2262504 O24532016:"16.27 r245306>2461t1q370"..., 4096) = 4096
[pid 20352] close(77) = 0
[pid 20352] close(54) = 0 Няма нито едно повикване write(), което говори за отсъствие на записи в файла.
Определение на разходите за файловата система
Голяма разлика в показанията iotop и btrace ме накара да помисля да тествам файловата система, като ръчно запиша данни в файл и проследя показанията на btrace.
Ако напълно изключим записването на диск, като се стартираме в emergency режим на systemd и ръчно запишем няколко байта данни в съществуващ файл, btrace на SSD с btrfs съобщава за запис 3 мегабайта реални данни. Създателят на файловата система на флашката с размер 8 ГБ записва минимум 264 КиБ при записването на един байт.
За сравнение, записването на два байта в файл на ext4 завършва с запис на 24 килобайта данни на диска.
През 2017 година Jayashree Mohan, Rohan Kadekodi и Vijay Chidambaram , техните резултати за btrfs и ext4 при запис на 4 КБ съответстват на моите.

Заключение и извод
Чрез описаните манипулации беше установено:
- Честото записване на състоянията на заданията от печатащия демон CUPS в /var/cache/cups каждую минуту. Проблема устранена очисткой /var/spool/cups (хотя никаких заданий печати не было);
- Фактът на читене на базата данни на всеки 30 секунди от добавката Group Speed Dial за Firefox;
- Периодичното записване на логове от различни услуги за проследяване на производителността в Fedora, което води до запис на няколко мегабайта данни на btrfs: pmcd.service, pmie.service, pmlogger.service;
- Огромна амплификация при запис на малко количество данни при използване на btrfs.
Извод: не е advisable да се използва btrfs, ако програмите често записват малки количества данни (няколко килобайта), в противен случай това ще се оберне в мегабайти записани данни. Особено актуално за едноплаткови компютри с ОС на MicroSD.
Източник: habr.com
