nav-img
Evolution

Запись данных в произвольный участок тома

Произвольные данные могут быть записаны в любой подходящий диапазон в границах тома. Это действие выполняется с помощью операции write.

До начала загрузки данных в том убедитесь, что:

  • Северы метаданных и чанков (MDS и CS) запущены и работают.

  • Файл /etc/storage/mds_list.yml существует и содержит корректную информацию о серверах метаданных кластера.

  • Нужный том присутствует в системе и диапазон для записи данных не выходит за его границы.

Для организации безопасного совместного доступа к данным утилита sbdctl устанавливает на целевом томе эксклюзивную блокировку (exclusive lease). При этом параллельная работа любых других клиентов с этим томом невозможна. В случае, если другой клиент уже установил блокировку на целевом томе, то операция завершается с ошибкой (при условии, что не указана опция --revoke-lease).

Использование sbdctl write:

  1. Аналогично import текущая реализация write гарантирует только изоляцию от других клиентов. Но атомарность и консистентность записи при этом уже не гарантируются, т.к. в случае ошибки данные могут быть записаны лишь частично. Откатить такую операцию записи не получится. При этом данные на целевом томе могут стать логически неконсистентными с точки зрения других клиентов. В таком случае операцию можно запустить повторно с такими же данными (при возможности).

  2. Операция write записывает входные данные без преобразования или интерпретации их формата, поэтому шестнадцатеричный дамп или образ в формате sbd не подходит для записи с помощью sbdctl write.

  3. В отличие от import операция write пишет длинные последовательности нулевых байт «как есть». При использовании sbdctl версий ниже, чем 1.4 (т.е. 1.2.xx, 1.3.xx) соответствующие диапазоны на целевом томе не помечаются как неиспользуемые с помощью операции unmap блочного устройства. Для записи образов тома в формате raw лучше использовать sbdctl import.

  4. В sbdctl версии 1.4.xх и более новых используется оптимизация записи данных на уровне клиентской библиотеки. Вместо записи выравненной последовательности нулевых байт весь соответствующий диапазон целевого вольюма помечается как неиспользуемый с помощью операции unmap, непосредственной записи данных не происходит. Требуемое значение выравнивания равно slice size * stripe depth, при этом длина и смещение начала последовательности нулевых байт должны быть кратно этому значению. Значение slice size для целевого тома можно узнать с помощью команды storage volume list, при этом нулевое значение в соответствующем столбце соответствует значению по умолчанию (256 Кб). Значение stripe depth — это первая цифра в схеме кодирования данных тома (например, 4 для кодировки 4+2/1).

Операция sbdctl write:

sbdctl write --volume-id <volume_id> [--file-from <input_file> | --stdin] <other options>

Обязательные параметры:

  • --volume-id volume_id или -v volume_id — задает идентификатор тома в виде 64-битного числа в шестнадцатеричной системе счисления. Префикс 0x, характерный для такой записи чисел, можно не указывать.

  • --file-from input_file или -f input_file — задает путь к файлу, из которого утилита будет читать данные для записи.

  • или же: --stdin — читать данные для записи из стандартного потока ввода (stdin). При этом нельзя использовать оператор перенаправления ввода из обычного файла (<file и — для этого нужно использовать –input file). Допустимо использовать перенаправление вывода другой программы на вход sbdctl, например, с помощью оператора конвейеризации ввода-вывода.

Необязательные параметры:

  • --offset arg или -o arg — задает смещение в целевом томе, начиная с которого sbdctl write будет записывать данные, в виде 64-битного целого числа в шестнадцатеричной системе счисления. Префикс 0x, характерный для такой записи чисел, можно не указывать. Значение по умолчанию — 0, т.е. данные записываются начиная с начала тома. Смещение не должно выходить за границы целевого тома. На данный момент нет возможности задать смещение во входном файле.

  • --write-size size или -s size — задает максимальный размер данных, которые будут записаны, или 0, если требуется записать все входные данные (поведение по умолчанию). Работа этой опции отличается для обычных файлов (для которых размер заранее известен) и для специальных файлов (stdin, FIFO-файлы, символьные устройства, сокеты). Подробнее в таблице ниже.

  • --batch-size N — задает ограничение на блоков, которое записывается за один вызов клиентской библиотеки блочного устройства. По умолчанию записывается не более, чем 1024 блока. Допустимые значения — от 1 до 16384, при увеличении этого значения может потребоваться увеличивать соответствующий тайм-аут с помощью опции --tout.

  • --show-stats — выводит в стандартный поток ошибок (stderr) подробную статистику выполнения операции после ее окончания. Опция крайне важна для диагностики медленной работы sbdctl write.

  • --stats-json и --format-json — вывод статистики в формате JSON.

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

Опция --write-size для различных типов входных файлов работает по-разному. Рассмотрим ситуацию, когда sbdctl write записывает в том размером volume_size начиная со смещения offset. Описание поведения sbdctl write:

Поведение sbdctl write

Входной файл

Значение опции write-size

Выполняющееся условие

Сколько данных записывает

Поведение sbdctl Write

Любой

Любое

offset ≥ volume_size

Н/д

Выдаст ошибку, не пытаясь записать данные.

Обычный файл (regular file) размером file_size

0

offset + file_size ≤ volume_size

file_size

Попытается записать все данные из файла.

Обычный файл (regular file) размером file_size

0

offset + file_size > volume_size

Н/д

Выдаст ошибку, не пытаясь записать данные.

Обычный файл (regular file) размером file_size

write_size (ненулевое)

offset + min(file_size, write_size) ≤ volume_size

min(file_size, write_size)

Попытается записать min(file_size, write_size) байт с начала входного файла.

Обычный файл (regular file) размером file_size

write_size (ненулевое)

offset + min(file_size, write_size) > volume_size

Н/д

Выдаст ошибку, не пытаясь записать данные.

Специальный файл символьного устройства (/dev/random, /dev/zero и т.п.)

0

≤ volume_size — offset

Попытается записать данные из специального файла, но не больше, чем volume_size — offset. Это сделано для того, чтобы можно было заполнить том нулевыми или случайными данными.

Специальный файл прочих типов (FIFO, в т.ч. при использовании неименованных каналов, а так же сокеты).

0

Столько, сколько прочитает.

Будет читать данные из специального файла до достижения его конца, и пытаться записать их, но при выходе за границы тома выдаст ошибку. Предполагается, что объем записываемых данных контролируется другим процессом, пишущим в FIFO или сокет.

Специальный файл любого типа.

write_size (ненулевое)

offset + write_size ≤ volume_size

≤ write_size

Попытается записать данные из специального файла, но не больше, чем write_size.

Специальный файл любого типа.

write_size (ненулевое)

offset + write_size > volume_size

н/д

Выдаст ошибку, не пытаясь записать данные.

Примеры использования

Запись всех данных из файла input.dat в целевой том начиная с его начала:

sbdctl write --volume-id 0x670adb3d59bff77e --file-from input.dat

Запись первых 8 мегабайт данных из файла input.dat по смещению с показом статистики:

sbdctl write -v 0x670adb3d59bff77e -f input.dat --write-size=8M --offset 0x2A800000 --show-stats

Запись данных, введенных с клавиатуры терминала, по смещению:

sbdctl write -v 0x670adb3d59bff77e -o 0x4A315BF2 --stdin --show-stats

Далее необходимо ввести нужные данные и нажать комбинацию Ctrl-D, соответствующую окончанию ввода. Это сочетание может меняться в зависимости от используемого терминала, на некоторых требуется нажать дважды. При вводе с терминала индикатор прогресса операции не показывается.

Запись случайных данных во второй гигабайт тома:

sbdctl write -v 0x670adb3d59bff77e --offset 0x40000000 --write-size 1G --file-from /dev/random

Запись данных, прочитанных с вывода другой программы (cat) по смещению:

cat input.dat | sbdctl write -v 0x670adb3d59bff77e -o 0x2A800000 --stdin

Копирование данные с одного тома размером 2 Гб на другой том такого же размера без сохранения их на локальном диске:

sbdctl read -v 0x3e05ee41f7badd6c -s 2G -f bin --stdout | sbdctl write -v 0x670adb3d59bff77e --stdin

Аналогичным образом, комбинируя различные опции sbdctl read и sbdctl write, можно копировать данные между различными участками разных томов.