Виявлення невідповідності ashift у ZFS: як перевірити існуючі пули

Було корисно?

Ви не помічаєте проблему з ashift, коли пул новий. Все порожнє, бенчмарки виглядають добре, життя прекрасне.
Потім пул заповнюється, затримки зростають, scrub’и тягнуться вічно, і раптом ваш «швидкий» масив SSD поводиться так, ніби надсилає результати з підвалу.

Неприємна частина: ви не можете «виправити» невірний ashift на місці. Завдання — виявлення. Прийняття рішення — також завдання.
Цей посібник про перевірку існуючих пулів, підтвердження наявності невідповідності та вибір найменш болісного шляху вирішення.

Що таке ashift насправді (і чого він не є)

ashift — це розмір одиниці виділення на диску в ZFS, виражений як степінь двійки.
Якщо ashift=12, ZFS виділяє блоки по 212 байтів: 4096 байтів (4K).
Якщо ashift=9, це 512 байтів.

Це не те саме, що «логічний» або «фізичний» розмір сектору, який віддає диск, але це пов’язано.
ZFS обирає ashift під час створення vdev, виходячи з того, що вважає мінімальним розміром сектора пристрою.
Після встановлення воно фактично постійне для цього vdev. Ви можете замінювати диски, розширювати, виконувати resilver — ashift залишається.

Ось операційний переклад:

  • Занадто мале ashift (наприклад, 512B на пристроях з 4K фізичними секторами) спричиняє read-modify-write, посилення записів, стрибки латентності та скраби/ресилвери, що здаються проклятими.
  • Занадто велике ashift (наприклад, 8K або 16K на 4K пристроях) витрачає трохи місця та може підвищувати накладні витрати для дуже дрібних блоків, але зазвичай не створює такого «все горить» профілю.

Чого ashift не є:

  • Воно не те саме, що recordsize або volblocksize. Це логічні розміри верхнього рівня, які використовують файлові системи та zvol’и.
  • Це не налаштування, яке можна «задати пізніше» без перебудови. Якщо якийсь блог стверджує інакше, він продає вам надію.

Ще одне: ashift належить vdev, а не безумовно пулу. Пули містять vdev’и. Vdev’и містять диски.
Більшість пулів створюють послідовний ashift для всіх vdev’ів, але змішані ashift-пули трапляються — часто під час розширень або коли хтось додав «ще один» vdev з іншої епохи.

Цікаві факти та трохи історії

Проблеми зі сховищами повторюються, бо виробники постійно змінюють правила, залишаючи маркетингові назви. Декілька фактів допомагають зрозуміти, навіщо потрібен ashift:

  1. 512-байтні сектора колись були дефолтом. Десятиліття програм припускали 512B блоки. ZFS народився в цьому світі.
  2. «Advanced Format» (4K фізичні сектора) став масовим на початку 2010-х. Багато дисків віддавали 512B логічно для сумісності, тоді як фізично писали 4K.
  3. Деякі пристрої брешуть. USB–SATA мости, деякі RAID-контролери та віртуальні диски історично повідомляли 512B, хоча бекенд — 4K.
  4. ZFS вибрав ashift один раз, бо формат на диску має значення. ZFS дбає про узгодженість і перевірність; зміна границі виділення пізніше була б міграцією формату, а не «налаштуванням».
  5. Ранній інструментарій OpenZFS не завжди явно показував ashift. Ви могли створити пул і виявити невідповідність лише коли продуктивність впала у масштабі.
  6. SSD—блоки стирання та сторінки NAND значно більші за 4K. Навіть при правильному ashift флеш-технології можуть створювати власне посилення записів — неправильний ashift погіршує ситуацію.
  7. 4Kn (нативні 4K логічні сектори) існують. Деякі корпоративні диски віддають 4096 логічних і фізичних; вони поводяться краще, здебільшого тому, що їх важче неправильно виявити.
  8. Деякі гіпервізори «нормалізують» розміри блоків. Ваш гость може бачити 512B, тоді як датастор використовує 4K або більше. ZFS всередині гостя приймає рішення на основі видимого гостьового розміру.

Чому невідповідність ashift шкодить (режими відмов)

Класична невідповідність — ashift=9 на дисках з фізичними секторами 4K. ZFS пише 512B-вирівняні блоки, але диск може оновлювати лише 4K-чанки.
Тому «малий запис» стає:

  1. Зчитати 4K фізичний сектор, що містить 512B ділянку.
  2. Змінити 512B частину в пам’яті.
  3. Записати назад увесь 4K сектор.

Цей цикл read-modify-write збільшує латентність і перетворює ваші IOPS на практичний жарт.

Звичайні прояви в продакшні:

  • Час scrub/resilver стрімко зростає, бо система робить більше IO операцій на логічну кількість даних.
  • Рандомні записи страждають (БД, образи ВМ, робота з дрібними файлами, збірки з великою кількістю метаданих).
  • Використання CPU може зрости, бо IO-шлях робить більше роботи, взаємодія з компресією/дедупом стає гучнішою, а латентність підвищує контекстні переключення.
  • Посилення записів шкодить витривалості SSD — не завжди катастрофічно, але достатньо, щоб гарантійні плани довелося переглядати частіше.

«Але мій пул виглядає нормально.» Звісно. Невідповідність може маскуватися такими факторами:

  • Переважно послідовні записи
  • Велика кількість попадань у ARC
  • Низьке заповнення пулу
  • Навантаження домінують великі блоки (медіа, резервні копії)

Потім ви додаєте ВМ, вмикаєте sync-записи, досягаєте 70% заповнення або починаєте багато оновлень метаданих. Невідповідність перестає бути теоретичною.

Одна операційна цитата (парафраз): Манtra надійності Gene Kranz — «failures are not an option» — добре перекладається: плануйте, що невідповідність реальна, поки не доведете протилежне.

Жарт #1: Якби сховище могло говорити, воно сказало б «воно не повільне, воно просто виражає себе». Потім воно тайм-аутнуло вашу базу.

Швидкий план діагностики

Ви хочете найкоротший шлях від «це виглядає повільно» до «це ashift, або ні». Ось порядок, який економить найбільше часу.

Перш за все: підтвердіть ashift на кожному топ-рівневому vdev

  • Якщо ashift правильний і послідовний — припиняйте його підозрювати і продовжуйте шукати іншу причину.
  • Якщо ashift занадто малий (9 на 4K обладнанні) — вважайте його підозрюваним №1.
  • Якщо ashift змішаний між vdev’ами — очікуйте нерівномірної продуктивності та дивних хвостових латентностей.

По-друге: підтвердіть, що ОС думає про диски (логічний/фізичний)

  • Перевірте розміри секторів через lsblk і blockdev.
  • Шукайте пристрої «512/4096». Саме там народжуються помилки ashift.
  • Не довіряйте USB-містам або RAID-HBA, які віртуалізують сектори без повідомлення.

По-третє: перевірте характерні підписи продуктивності

  • zpool iostat -v для виявлення дрібних записів і високої латентності на рівні vdev
  • iostat -x для високого await і низької пропускної здатності при великому навантаженні
  • zpool status -v для помилок або повільного прогресу resilver/scrub (не доказ, але «запах» проблеми)

По-четверте: перевірте вирівнювання під контрольованим тестом запису

  • Використайте тимчасовий датасет або тестовий хост, якщо можете.
  • Запустіть тест випадкових записів з малими блоками і спостерігайте латентність/IOPS. Невідповідний ashift часто «обривається» на навантаженнях 4K-подібних.

По-п’яте: вирішіть ваш шлях

  • Правильний ashift: зосередьтеся на recordsize, налаштуваннях sync, SLOG, спеціальних vdev’ах, фрагментації та заповненні пулу.
  • Неправильний ashift: припиніть підлаштовуватися. Плануйте міграцію або перебудову.

Практичні завдання: команди, виводи, рішення

Нижче — реальні перевірки, які можна виконати сьогодні. Кожне завдання містить: команду, що означає вивід, і яке рішення з нього випливає.
Використовуйте їх як чекліст, а не як ворожбу.

Завдання 1: Перелічіть пули і переконайтеся, що дивитесь на потрібний

cr0x@server:~$ zpool list
NAME   SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  21.8T  17.2T  4.60T        -         -    32%    78%  1.00x  ONLINE  -

Значення: У вас один пул, tank, 78% заповнений і помірно фрагментований. Заповненість і фрагментація можуть посилювати проблеми ashift.

Рішення: Якщо пул >80% заповнений, вважайте проблему багатофакторною. Все одно перевірте ashift, але не зупиняйтесь лише на ньому.

Завдання 2: Отримайте схему vdev (потрібна для перевірки ashift по vdev)

cr0x@server:~$ zpool status -P tank
  pool: tank
 state: ONLINE
config:

        NAME                                      STATE     READ WRITE CKSUM
        tank                                      ONLINE       0     0     0
          raidz2-0                                ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C  ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3D  ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3E  ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3F  ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3G  ONLINE       0     0     0
            /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3H  ONLINE       0     0     0

errors: No known data errors

Значення: Один vdev RAIDZ2 з шістьма дисками.

Рішення: Ви перевірите ashift для цього vdev і підтвердите, що всі підлеглі пристрої мають збігаючі характеристики секторів.

Завдання 3: Перевірте ashift через zdb (найпряміший, найменш сподівальний метод)

cr0x@server:~$ sudo zdb -C tank | sed -n '/vdev_tree/,/features_for_read/p'
        vdev_tree:
            type: 'root'
            id: 0
            guid: 12345678901234567890
            children[0]:
                type: 'raidz'
                id: 0
                guid: 11111111111111111111
                nparity: 2
                ashift: 12
                children[0]:
                    type: 'disk'
                    id: 0
                    guid: 22222222222222222222
                    path: '/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C'
                children[1]:
                    type: 'disk'
                    id: 1
                    guid: 33333333333333333333
                    path: '/dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3D'

Значення: ashift: 12 означає виділення 4K. Це зазвичай правильно для сучасних HDD/SSD.

Рішення: Якщо ви бачите ashift: 9 на будь-якому vdev, створеному на 4K фізичних дисках, позначте його для планування міграції.

Завдання 4: Виявлення змішаного ashift між vdev’ами (зазвичай при розширеннях)

cr0x@server:~$ sudo zdb -C tank | grep -E 'children\[[0-9]+\]:|ashift'
            children[0]:
                ashift: 12
            children[1]:
                ashift: 9

Значення: У вас принаймні два топ-рівневі vdev’и з різними значеннями ashift. Це податок на продуктивність і передбачуваність.

Рішення: Вважайте найменший ashift ймовірним винуватцем. Плануйте вивести цей vdev (через міграцію) або перебудувати пул.

Завдання 5: Перевірте, що ОС повідомляє про логічні/фізичні розміри секторів

cr0x@server:~$ lsblk -d -o NAME,MODEL,SIZE,ROTA,LOG-SEC,PHY-SEC /dev/sd[a-f]
NAME MODEL            SIZE ROTA LOG-SEC PHY-SEC
sda  ST12000NM0008  10.9T    1     512    4096
sdb  ST12000NM0008  10.9T    1     512    4096
sdc  ST12000NM0008  10.9T    1     512    4096
sdd  ST12000NM0008  10.9T    1     512    4096
sde  ST12000NM0008  10.9T    1     512    4096
sdf  ST12000NM0008  10.9T    1     512    4096

Значення: Це 512e-диски: 512 логічно, 4096 фізично. Якщо ваш vdev має ashift 9, ви несумісні з фізичним IO.

Рішення: Для 512e за замовчуванням використовуйте ashift=12 для нових vdev’ів. Для існуючих vdev’ів з ashift=9 плануйте міграцію, а не «налаштування».

Завдання 6: Підтвердіть розміри секторів через blockdev (допомагає виявити дивну звітність)

cr0x@server:~$ sudo blockdev --getss /dev/sda
512
cr0x@server:~$ sudo blockdev --getpbsz /dev/sda
4096

Значення: Ядро бачить логічний сектор 512B, фізичний 4096B. Узгоджується з виглядом lsblk.

Рішення: Якщо інструменти суперечать (наприклад, 512/512, хоча ви знаєте, що це 4K), вважайте шар пристрою ненадійним і припускайте, що вам мінімум потрібен ashift=12.

Завдання 7: Підтвердіть поведінку IO пулу під реальним навантаженням

cr0x@server:~$ zpool iostat -v tank 1 5
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        17.2T  4.60T    210    980  54.3M  22.1M
  raidz2-0                  17.2T  4.60T    210    980  54.3M  22.1M
    ata-ST12000NM...B3C         -      -     35    165  9.10M  3.80M
    ata-ST12000NM...B3D         -      -     35    165  9.05M  3.75M
    ata-ST12000NM...B3E         -      -     35    165  9.07M  3.78M
    ata-ST12000NM...B3F         -      -     35    165  9.02M  3.76M
    ata-ST12000NM...B3G         -      -     35    160  9.03M  3.70M
    ata-ST12000NM...B3H         -      -      35    160  9.06M  3.72M
--------------------------  -----  -----  -----  -----  -----  -----

Значення: Збалансована стата по дисках свідчить, що vdev поводиться нормально. Це не доводить правильність ashift, але виключає очевидне гальмування одного диска.

Рішення: Якщо по-дискові записи високі при малій пропускній здатності, підозрюйте дрібні записи і посилення — ashift у списку кандидатів поряд із sync-навантаженням та фрагментацією.

Завдання 8: Корелюйте з латентністю на рівні пристрою за допомогою iostat

cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 	12/26/2025 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           6.12    0.00    3.41    8.55    0.00   81.92

Device            r/s     w/s   rkB/s   wkB/s  rrqm/s  wrqm/s  %util  await  r_await  w_await
sda              35.0   160.0  9320.0  3860.0     0.0     2.0   92.0   27.4     9.2     31.1
sdb              35.0   160.0  9300.0  3840.0     0.0     1.0   91.5   26.9     9.0     30.6

Значення: Високе завантаження та підвищений await на записах можуть бути нормою під навантаженням для HDD RAIDZ, але якщо ви бачите екстремальний await при малій пропускній здатності, щось не так.

Рішення: Якщо ви штовхаєте дрібні записи і бачите великий await, перевірте ashift, а також шлях sync (SLOG), налаштування dataset і патерни навантаження.

Завдання 9: Підтвердіть очікування recordsize/volblocksize (не плутайте їх з ashift)

cr0x@server:~$ zfs get -o name,property,value,source recordsize,compression tank
NAME  PROPERTY     VALUE     SOURCE
tank  recordsize   128K      default
tank  compression  lz4       local

Значення: recordsize — 128K. Це типовий вибір для загального призначення. Воно не змінює ashift, але впливає на IO-патерни.

Рішення: Якщо в пулі розміщуються ВМ/БД, можна налаштувати recordsize/volblocksize. Але якщо ashift неправильний, налаштування будуть лише косметикою.

Завдання 10: Перевірте розмір блоку zvol (поширено у віртуалізації)

cr0x@server:~$ zfs get -o name,property,value,source volblocksize tank/vmdata
NAME         PROPERTY      VALUE  SOURCE
tank/vmdata  volblocksize  8K     local

Значення: zvol використовує 8K блоки. Якщо ashift = 9 на 4K фізичних пристроях, 8K може теж бути частково невирівняним у підступний спосіб під час часткових записів.

Рішення: Тримайте volblocksize узгодженим з навантаженням (часто 8K–16K для ВМ/БД), але спершу виправте невідповідність ashift, якщо вона є.

Завдання 11: Перевірте 4Kn vs 512e vs «дивні пристрої» через udev ID

cr0x@server:~$ for d in /dev/disk/by-id/ata-ST12000NM0008-*; do echo "== $d =="; udevadm info --query=property --name="$d" | grep -E 'ID_MODEL=|ID_SERIAL=|ID_BUS='; done
== /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C ==
ID_BUS=ata
ID_MODEL=ST12000NM0008-1JH101
ID_SERIAL=ST12000NM0008-1JH101_ZA1A2B3C

Значення: Диски — прямі ATA-пристрої, не за USB. Добре: менше брехні про сектори.

Рішення: Якщо бачите USB або незвичні шляхи транспорту для продакшн-пулів, вважайте звітність секторів підозрілою і будьте консервативними (ashift=12 або 13 для нових пулів).

Завдання 12: Підтвердіть, що ZFS використовує нативні шляхи, а не застарілі імена пристроїв

cr0x@server:~$ zpool status -P tank | grep /dev/sd

Значення: Немає шляхів /dev/sdX у конфігурації (добре). Використання by-id шляхів зменшує операційні помилки при заміні дисків.

Рішення: Якщо ваш пул використовує /dev/sdX, виправте це під час наступного вікна обслуговування (export/import з by-id) перед будь-якими ризикованими операціями, як-от міграції.

Завдання 13: Перевірте ashift на рівні листа (корисно, коли vdev_tree довгий)

cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-ST12000NM0008-1JH101_ZA1A2B3C | grep -i ashift
    ashift: 12

Значення: Мітка листового пристрою вказує ashift 12 для vdev, до якого він належить. Це швидка перевірка, коли не хочете дампити всю конфігурацію.

Рішення: Якщо мітка показує ashift: 9 і фізичний сектор пристрою 4096, ви підтвердили невідповідність. Починайте планувати перебудову/міграцію.

Завдання 14: Заміряйте підпис синхронного запису з малими блоками (не здогадуйтеся)

cr0x@server:~$ sudo zfs create -o sync=always -o recordsize=16K tank/ashift-test
cr0x@server:~$ dd if=/dev/zero of=/tank/ashift-test/blob bs=4K count=250000 oflag=dsync status=progress
1024000000 bytes (1.0 GB, 954 MiB) copied, 54 s, 19.0 MB/s
cr0x@server:~$ sync

Значення: Цей грубий тест змушує поведінку sync. 4K блоки плюс sync швидко виявляють проблеми вирівнювання і латентності.

Рішення: Якщо пропускна здатність падає і латентність різко зростає, хоча апаратне забезпечення має працювати краще, перевірте ashift і також SLOG/PLP. Не «оптимізуйте», поки не з’ясуєте, яке саме вузьке місце.

Три корпоративні історії: що пішло не так і що нас врятувало

Міні-історія 1: Інцидент через неправильне припущення

Команда успадкувала платформу з ZFS, яка «працювала роками». Вона також була побудована в епоху, коли половина дисків у постачанні були 512e,
і частина інструментів досі сприймала розмір сектора як дрібницю.

На чергуванні почали надходити алерти: стрибки латентності IO у ВМ, зростання черг сховища та періодичні таймаути додатків.
Першим припущенням команди було, що «нове навантаження шумніше», бо з’явився новий мікросервіс. Вони обмежували орендарів, крутнули налаштування планувальника IO і перемістили кілька ВМ. Симптоми змінювалися, але проблема залишалася.

Потім запустився scrub. Він зайшов у робочий час, як завжди, і ставав повільнішим з місяця в місяць. Цього разу це спричинило каскад:
латентність зросла, таймаути збільшилися, пішли хвилі повторних спроб, і система моніторингу почала частіше дзвонити.

Насправді корінь був болісно нудним: один топ-рівневий vdev мав ashift=9 з моменту створення пулу,
тоді як диски під ним були фізично 4K. Це «працювало», коли пул був майже порожнім і коли навантаження було переважно послідовним.
Через роки це стало податком на кожен рандомний запис і оновлення метаданих.

Виправлення не було хитрим. Воно було дорогим: побудувати новий пул з ashift=12, мігрувати датасети, перевести орендарів і вивести старі vdev’и з експлуатації.
Урок запам’ятався, бо боляче: не припускайте, що попередники вибрали правильний ashift, навіть якщо система стара і «нормальна».

Міні-історія 2: Оптимізація, що обернулася проти

Інший центр вирішив «стандартизувати продуктивність», створюючи нові пули з більшим ashift, бо «більші блоки — швидші».
Хтось вибрав ashift=13 (8K) для всього, включно з малопомітними БД і CI з великою кількістю метаданих.

Спочатку все виглядало нормально. Великі послідовні записи були в порядку, графіки простору не лякали.
Потім помітили, що деякі навантаження на zvol поводяться дивно: дрібні оновлення створювали більше фонового шуму, снапшоти росли швидше, і команда почала скаржитися на «накладні витрати ZFS».

Повернення назад полягав не в тому, що ashift=13 завжди поганий. Проблема в тому, що вони застосували його універсально, не підбираючи під пристрої та навантаження.
На 4K SSD 8K-виділення підсилювало внутрішнє посилення для певних патернів і витрачало місце на дрібні блоки й метадані.
Також вони погіршили компресійні/дедуп-ефекти в крайових випадках.

План відновлення був знову прозаїчним: зберегти ashift=13 там, де це мало сенс (деякі масиви та спеціальні випадки),
і повернутися до ashift=12 як до дефолту. Документували рішення і вимагали обґрунтування для відхилень.
«Стандартизація продуктивності» перетворилася на стандартну практику: не вибирайте ashift за відчуттями.

Жарт #2: Ніщо так не кричить «оптимізація в ентерпрайзі», як методично зробити гірше.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

В одному регульованому середовищі ZFS використовувався для архівів логів і бекапів ВМ. Нічого цікавого. Команда мала чекліст змін, який включав:
записувати розміри секторів, фіксувати запланований ashift і зберігати вивід zdb -C під час створення пулу.
Це було нудно, тому інженери скаржилися — тихо, по-професійному.

Через роки оновлення сховища ввело нову прошивку HBA і нову партію дисків. Планували розширення пулу:
додати ще один RAIDZ vdev. Під час передпольотних перевірок інженер порівняв звіти секторів нових дисків з старими.
Новий шлях (через інший шафовий слот) показував 512 логічних і 512 фізичних, хоча модель диска мала бути 4K фізичною.

Оскільки команда мала нудні артефакти з попередніх збірок, вони помітили невідповідність ще до додавання vdev.
Вони перемістили диски в інший слот шаси, отримали коректну звітність 512/4096 і продовжили з ashift=12.
Ніякого змішаного ashift-пулу, жодного повільного краху, жодних «загадкових» scrub’ів.

Перемога полягала не тільки в уникненні помилки; вона полягала в уникненні повільної помилки, що проявилася б через місяці, коли ніхто не згадає зміни.
Документація не зробила їх швидшими. Вона зробила їх менш здивованими. Ось у чому суть.

Поширені помилки: симптом → корінна причина → виправлення

Цей розділ навмисно конкретний. «Перевірте ваше обладнання» — це не виправлення; це відкладання справ із кращою поставою.

1) Scrub’и повільні, але диски виглядають здоровими

  • Симптоми: Прогрес scrub повільний; zpool status не показує помилок; IO виглядає зайнятим, але пропускна здатність невражаюча.
  • Корінна причина: ashift=9 на 4K фізичних дисках, що спричиняє додаткові IO операції (особливо помітно на метаданих і дрібних блоках).
  • Виправлення: Підтвердіть через zdb -C. Якщо є невідповідність, плануйте міграцію/перебудову пулу з ashift=12. Не намагайтеся «налаштувати» швидкість scrub навколо неправильного ashift.

2) Рандомні записи жахливі; послідовні — нормальні

  • Симптоми: ВМ скаржаться; fsync бази даних має високу латентність; резервні копії пишуться нормально.
  • Корінна причина: Невирівняні малі записи; часто невідповідність ashift, іноді sync-навантаження без правильного SLOG, іноді обидва.
  • Виправлення: Спочатку перевірте ashift і розміри секторів. Якщо ashift правильний, оцініть налаштування sync і SLOG (та захист від втрати живлення, якщо SSD-based).

3) Один vdev «відчувається повільнішим» після розширення

  • Симптоми: Після додавання vdev розподіл латентності погіршився; продуктивність стала непередбачуваною.
  • Корінна причина: Змішаний ashift між vdev’ами або новий vdev за шаром пристрою, що повідомляє інші розміри секторів.
  • Виправлення: Перевірте zdb -C для кожного топ-рівневого vdev. Якщо змішано, розгляньте міграцію «гарячих» датасетів з повільного vdev або перебудову.

4) Ви замінили диски і очікували, що ashift зміниться

  • Симптоми: «Ми перейшли на 4Kn диски; чому zdb все ще показує ashift=9?»
  • Корінна причина: Ashift встановлюється під час створення vdev і не змінюється замінами/ресилверами.
  • Виправлення: Перебудуйте/мігруйте на новий vdev/пул, створений з потрібним ashift.

5) Бенчмарки не відтворюють продакшн-болю

  • Симптоми: fio на порожньому пулі виглядає добре; реальні навантаження буксують, коли пул зайнятий.
  • Корінна причина: Бенчмарк не відтворює розмір IO, синхронні семантики, конкурентність або заповненість пулу; невідповідність ashift посилює дрібні випадкові IO під навантаженням.
  • Виправлення: Тестуйте з 4K/8K випадковими записами, реалістичними sync-налаштуваннями і кількома потоками. Підтвердіть ashift перед тим, як довіряти будь-яким висновкам з бенчмарку.

6) USB/JBOD-шасі дають «випадкову» поведінку продуктивності

  • Симптоми: Розміри секторів виглядають непослідовними; ashift вибір різниться для ідентичних дисків; продуктивність змінюється після перепідключення/перезавантаження.
  • Корінна причина: Прошивка мосту бреше або змінює повідомлювані характеристики; ZFS фіксує ashift на основі того, що воно побачило при створенні.
  • Виправлення: Уникайте USB-містів для серйозних ZFS-пулів. Якщо це неминуче, зафіксуйте ashift під час створення через zpool create -o ashift=12 і одразу перевірте через zdb -C.

Чеклісти / покроковий план

Чекліст A: «Чи маю я зараз невідповідність ashift?»

  1. Визначте пул і vdev’и: zpool status -P.
  2. Здампіть конфіг і знайдіть ashift: sudo zdb -C poolname.
  3. Занотуйте ashift для кожного топ-рівневого vdev (mirror/raidz/draid/special).
  4. Перевірте розміри секторів кожного листового диска: lsblk -d -o NAME,LOG-SEC,PHY-SEC.
  5. Якщо якийсь vdev має ashift менший за фізичний розмір сектора, у вас є важлива невідповідність.
  6. Якщо ashift змішаний, у вас є невідповідність, яка вдарить по продуктивності нерівномірно.

Чекліст B: «Чи дійсно ashift є вузьким місцем?»

  1. Підтвердіть розмір IO навантаження та поведінку sync (ВМ і бази даних часто означають малі випадкові + синхронні патерни).
  2. Під час навантаження запустіть zpool iostat -v 1 і iostat -x 1 поруч.
  3. Шукайте високі ops/s з низькою пропускною здатністю і високою латентністю — класичний підпис посиленого дрібного IO.
  4. Якщо ashift правильний, перевірте:
    • заповненість/фрагментацію пулу (zpool list FRAG/CAP)
    • властивості датасетів (sync, recordsize, volblocksize)
    • тиск на спеціальні vdev’и для метаданих (якщо використовуються)
    • конструкцію SLOG (якщо домінують sync-навантаження)

Чекліст C: «План міграції/перебудови, коли ashift неправильний»

  1. Не сперечайтеся з фізикою. Прийміть рішення перебудувати/перемістити, а не намагатися обійти.
  2. Підготуйте нове сховище (новий пул або нові vdev’и) з явним -o ashift=12 (або виправданим більшим значенням).
  3. Негайно перевірте новий ashift через sudo zdb -C і задокументуйте його.
  4. Реплікутйте датасети:
    • zfs snapshot
    • zfs send | zfs receive
    • або використайте наявні інструменти реплікації
  5. Поступово переключайте навантаження; вимірюйте латентність і швидкість scrub’ів.
  6. Виводьте старий пул/vdev лише після того, як у вас:
    • підтверджені відновлення
    • перевірений scrub на новому пулі
    • перевірена продуктивність під піковим навантаженням

FAQ

1) Чи можу я змінити ashift на існуючому vdev або пулі?

Ні, на місці — не можна. Ashift закладено в тому, як блоки розподілені на диску. Практичне виправлення — створити новий vdev/пул з правильним ashift і мігрувати дані.

2) Де надійно побачити ashift для існуючого пулу?

Використовуйте sudo zdb -C poolname і шукайте ashift: N під кожним топ-рівневим vdev у vdev_tree.
zpool get не покаже ashift надійно, бо це не властивість пулу в тому ж сенсі.

3) Якщо мої диски 512e (512 логіч / 4096 фізич), який ashift бажаний?

Зазвичай ashift=12. Це вирівнює виділення ZFS по межах 4K і уникатиме read-modify-write на диску.

4) Чи кращий ashift=13 за ashift=12?

Не автоматично. Він може мати сенс для деяких масивів і специфіки флешу, але також збільшує мінімальний розмір виділення.
За замовчуванням вибирайте 12, якщо немає конкретної причини і тестів під навантаженням.

5) Я замінив усі диски на 4Kn. Чому ashift не оновився?

Тому що ashift визначається при створенні vdev, а не при заміні дисків. Замінені диски успадковують існуючий ashift vdev.

6) Якщо ashift неправильний, чому ZFS цього не помітив?

ZFS використовує повідомлені пристроєм характеристики під час створення. Якщо шар пристрою повідомив 512B (навіть неправдиво), ZFS в це повірив.
ZFS скептично ставиться до корупції, але не до чесності виробників.

7) Які найнадійніші перевірки розміру сектора в Linux?

lsblk -o LOG-SEC,PHY-SEC і blockdev --getss/--getpbsz. Якщо вони не погоджуються або виглядають підозріло за мостами/контролерами, вважайте це попередженням.

8) Чи можуть у одному пулі існувати змішані ashift vdev’и?

Так. Часто трапляється після розширень або додавання vdev’ів з різного обладнання. Це може працювати, але ускладнює продуктивність і передбачуваність.

9) Чи «виправляє» recordsize/volblocksize невідповідність ashift?

Ні. Вони впливають на IO-патерни і можуть зменшити біль у деяких випадках, але не змінюють розмір виділення на диску для існуючих vdev’ів.

10) Яка найбезпечніша операційна реакція після підтвердження ashift=9 на 4K фізичних дисках?

Плануйте міграцію/перебудову. Тримайте пул стабільним, уникайте «геройських» налаштувань і заплануйте контрольований перехід на правильно створений пул.

Висновок: наступні практичні кроки

Виявлення невідповідності ashift — це не академічне вправляння. Це різниця між «цей пул старий, але нормальний» і «цей пул тихо краде наш бюджет латентності».
Якщо підозрюєте невідповідність — не сперечайтеся, вимірюйте.

Практичні кроки:

  1. Запустіть sudo zdb -C і зафіксуйте ashift для кожного vdev.
  2. Підтвердіть розміри секторів дисків за допомогою lsblk і blockdev.
  3. Якщо знайдете ashift=9 на 4K фізичних пристроях, припиніть підлаштовуватися і почніть планувати перебудову/міграцію.
  4. Якщо ashift коректний, рухайтеся далі: перевірте поведінку sync, заповненість пулу, фрагментацію та розміри IO навантаження.
  5. Додайте одну нудну практику у майбутньому: зберігайте вивід zdb -C під час створення пулу разом із записом змін.
← Попередня
Коли референс кращий за кастом: міф, який іноді справджується
Наступна →
Debian 13: «Device busy» при umount — як миттєво знайти утримувача (схема lsof/fuser)

Залишити коментар