company_banner

Тонкое резервирование файловых систем Linux. Как создавать рабочие копии трехтерабайтной СУБД MySQL за 20 секунд


    Меня зовут Юрий, я руководитель группы системного администрирования в Ситимобил. Сегодня поделюсь опытом работы с технологией тонкого резервирования (thin provisioning) файловых систем Linux и расскажу, как ее можно применять в технологических CI/CD-процессах компании. Мы разберем ситуацию, когда для автоматического тестирования кода при доставке его в production нам как можно быстрее необходимы копии БД MySQL, максимально приближенные к «боевой» версии, доступные на чтение и на запись.


    Введение: зачем давать вредные советы?


    Логичный вопрос, ведь есть отработанные механизмы миграций схем БД в тестовые среды. Зачем вообще доводить основную нешардированную СУБД до таких объемов? Да и для тестирования нужны не все данные. Постараюсь объяснить.


    Примерно год назад на фоне активного роста нашего агрегатора такси (за 2018 год выросли по завершенным поездкам примерно в 15 раз), выросли объемы данных, нагрузка на серверы, частота выкаток. Мы оказались в следующей ситуации:


    • Основная БД MySQL увеличилась примерно до 1000 таблиц общим объемом в 2,5 Тб, и продолжала расти.
    • Не было возможности быстро зашардироваться и разнести базу. Это не позволял старый подход «пишу в базу что хочу и как хочу», куча JOIN’ов и внутренних зависимостей таблиц.
    • Не было механизма миграций схемы БД в тестовые окружения.
    • Не было автоматического тестирования кода при выкатке в эксплуатацию.

    Последнюю проблему хотелось решить максимально быстро. Были уже написаны тесты Postman для проверки основного PHP-монолита, но не хватало актуальной базы данных. При этом мы не могли создавать ночью реплику, делать ее мастером и отдавать на растерзание днем: очень большое количество выкаток и изменений, в том числе в данных и схеме БД, сделали бы стенд неработоспособным уже к середине дня. Да и ограничивать выкатки всего лишь рабочим днем было бы неэффективно.


    Тем не менее, задача была выполнена: первый рабочий стенд мы получили уже через две недели. За прошедший год он претерпел много изменений и продолжает использоваться.


    Далее я подробно опишу все шаги и этапы развития нашего решения. Вы убедитесь, что этот метод заслуживает право на существование.


    Что такое «тонкое резервирование»?
    Это аппаратная или программная технология (другое название — sparse volumes), позволяющая выделять большее количество требуемого ресурса, чем есть в наличии. При этом выделяемый объем должен соответствовать критериям just-enough (столько, сколько нужно) и just-in-time (за необходимое время). В основном тонкое резервирование применяется в различных СХД, чтобы предоставлять дисковое пространство в необходимых объемах, превышающих фактически доступные. Технология поддерживается различными файловыми системами, например, LVM2, ZFS, BTRFS. Она широко используется в гипервизорах виртуализации. Нам тонкое резервирование позволяло быстро создать из снапшотов основного раздела с данными столько копий этого раздела, сколько нам нужно (data-директория СУБД MySQL).


    Первый стенд, технология Thin LVM


    Эту главу можно ещё назвать «Как сделать максимально быстрые снапшоты больших объемов данных с помощью Thin LVM, уменьшив стабильность файловой системы и СУБД MySQL до неприличных показателей».


    Поскольку мы уже использовали LVM для построения основных разделов ОС, то решили начать именно с нее. Для начала нам потребовалась отдельная физическая машина — реплика нашей основной базы MySQL, на которой мы могли бы по запросу создавать снапшот реплики и поднимать его рядом отдельным экземпляром MySQL. На время тестирования мы разрешили применять на этом экземпляре изменяющие операции, и по завершении тестов благополучно его удаляли. Конфигурация сервера была такой:


    • 2 x Intel Silver 4114 (10x2,2 ГГц HT)
    • 8 x 32 ГБ DDR4
    • 8 x 1920 ГБ Intel SSD в RAID-контроллер Adaptec в RAID-10

    На тему выбора между RAID-контроллером и программным RAID MD можно писать отдельную статью. Скажу лишь, что наш выбор повлияли два фактора:


    • Во времена постановки задачи мы все СУБД ставили на RAID-контроллеры, поэтому можно сказать, что так сложилось исторически.
    • Различие в производительности на синтетических тестах файловой системы и тестах с различными операциями в MySQL было минимальным.

    Мы разделили получившийся RAID-10: сделали единый Volume Group (VG) на весь объем (с накладными расходами примерно 6,7 Гб) и создали логический раздел (Logical Volume, LV) под систему на 50 Гб. В обычной ситуации все остальное место мы определяем под раздел c MySQL. Но нам нужно было тонкое резервирование, поэтому сначала мы создали так называемый pool, внутри которого создали раздел под /var/lib/mysql на 3,5 Тб (исходя из предполагаемых объемов БД):


    lvcreate -l 100%FREE -T vga/thin
    lvcreate -V 3.5T -T vga/thin -n mysql

    Отформатировали раздел в ext4, примонтировали его, записали реплику и получили исходный стенд. Затем сделали обвязку в виде API, который должен создавать снапшоты, поднимать экземпляр БД MySQL на заданном порте и удалять созданный экземпляр. Поскольку при этом используются исключительно системные вызовы, в качестве языка написания скриптов мы выбрали обычный bash, а в качестве провязки API HTTP → bash развернули open source-решение goexpose, написанное на Go.


    Когда-нибудь мы выложим наши bash-скрипты в open source, а пока я просто опишу основной алгоритм:


    Создание основного снапшота snapmain:


    1. Останавливаем основную реплику.
    2. Ставим блокировку на операции со снапшотом snapmain.
    3. Создаем новый снапшот snapmain.
    4. Запускаем MySQL и убираем блокировку.

    Создание БД на произвольном порте из snapmain:


    1. Ставим блокировку на конкретный экземпляр БД (порт).
    2. Проверяем наличие блокировки создания основного снапшота. Если она есть, то ждем и перепроверяем каждые 5 секунд.
    3. Проверяем, есть ли старый LV-раздел экземпляра.
      3.1 Если есть, то останавливаем с помощью kill -9 экземпляр MySQL и удаляем LV-раздел.
    4. Создаем из snapmain новый экземпляр.
    5. Готовим и монтируем директории для этого экземпляра.
    6. Убираем признаки слэйва (файлы) и запускаем экземпляр MySQL.
    7. Делаем из него мастер.
    8. Убираем блокировку.

    Удаление БД на произвольном порте:


    1. Ставим блокировку на конкретный экземпляр БД (порт).
    2. Убиваем экземпляр MySQL с помощью kill -9.
    3. Отмонтируем директории.
    4. Удаляем LV-раздел и снимаем блокировку.

    Пример команд для клонирования разделов нового экземпляра БД:


    lvcreate -n stage_3307 -s vga/snapmain
    lvchange -ay -K vga/stage_3307
    mount -o noatime,nodiratime,data=writeback /dev/mapper/vga-stage_3307 /mnt/stage_3307

    Теперь расскажу про основную проблему, с которой мы столкнулись при использовании тонкого резервирования. Мы уперлись в производительность SSD-дисков. Произошло это из-за особенностей Thin LVM: она в своей основе оперирует на уровне устройства низкоуровневыми чанками размером по умолчанию в 4 Мб. Как это выглядело:


    1. Создаем снапшот из основного раздела /var/lib/mysql.
    2. Запускаем репликацию, чтобы догнать мастера.
    3. Любое изменение в таблицах реплики заставляет сохранять старые, неизмененные чанки данных в разделе снапшота.
    4. Любое изменение в поднятом тестовом экземпляре заставляет сохранять старые, неизмененные чанки данных в разделе склонированного снапшота для этого экземпляра.
    5. Получаем загруженность операций ввода-вывода в 100% на устройство, замедление любых операций и постепенное отставание реплики.
    6. К концу рабочего дня получаем отставший на несколько часов стенд.

    Как мы с этим боролись, чтобы получить более вменяемый результат (основные моменты):


    RAID-контроллер:


    • Выключили по умолчанию все виды кэширования.
    • Выставили writeback (при попадании данных в буфер запись завершается прежде, чем выполняется фактическое сохранение на диск).

    Файловая система:


    • В точке монтирования /var/lib/mysql прописали noatime,nodiratime,data=writeback
    • Выключили журналирование ext4 с помощью tune2fs.

    MySQL:


    • Прописали innodb_flush_method = O_DSYNC (увеличили скорость записи, снизив тем самым надежность).
    • Отключили журналирование, логи нам не нужны.
    • Прописали innodb_buffer_pool_size = 4G (чем меньше размер пула InnoDB, тем быстрее погаснет MySQL при остановке, и тем быстрее мы создадим снапшот).

    Это далеко не полный список, особенно по MySQL. Впрочем, остальные изменения минорны и зачастую применимы не всегда и не точно. Например, в попытке разгрузить диски мы даже унесли innodb_parallel_doublewrite_path в /dev/shm, что в некоторых случаях при старте некорректно завершенного экземпляра экономило нам до 5 секунд.


    Почему мы останавливаем MySQL перед тем, как делать снапшот? Ведь мы можем снять его с работающей реплики. Все верно, вот только новый экземпляр БД на этом снапшоте будет по умолчанию считаться поврежденным и потребует полного сканирования при запуске. Останавливать реплику определенно быстрее, хоть это в итоге и является самой длительной операцией во всем процессе.


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


    Из других недостатков стоит отметить практическую невозможность мониторинга пула Thin LVM: помимо системных стандартных функций iostat, понять, например, какой элемент пула сейчас производит наибольшую нагрузку на файловую систему невозможно.


    Отдельно стоит отметить один большой недостаток, связанный с описанной выше оптимизацией: мы получили YOLO-стенд. Примерно раз в один-два месяца ext4 не выдерживала подобных надругательств над собой и безвозвратно ломалась, требуя переформатирования и перезаливки реплики. Выиграв в скорости, мы безнадежно угробили стабильность.


    За какими метриками стоит следить в процессе эксплуатации Thin LVM:


    • Thin pool data %
    • Thin pool metadata %

    Если закончившееся место под данные наш стенд переживет (достаточно почистить диски), то закончившееся место под метаданные приведет к полному краху пула и необходимости его пересоздания с нуля.


    Файловая система внутри пула со временем очень сильно фрагментируется. Рекомендую раз в сутки запускать по крону команду fstrim -v /var/lib/mysql.


    Промежуточные итоги:


    • Технология легко применима, как и сам LVM, и не требует особой квалификации инженера.
    • Она хорошо подойдет для БД небольшого размера и не слишком нагруженных. Чем меньше БД, тем меньше чанков перемещается по файловой системе внутри пула, и тем ниже нагрузка на диски.
    • Для нашей задачи мы стали искать иные решения, о чем и пойдет речь в следующем разделе.

    Второй стенд, технология ZFS


    Когда-то давно я имел дело с файловой системой ZFS, но тогда достоверно хорошо ZFS работала на своем родном семействе ОС Solaris. Существовала портированная на FreeBSD версия с достаточно хорошим уровнем реализации. Был также недоделанный порт на Linux, который мало кто применял. Из-за структуры хранения данных B-tree (кстати, такая же структура хранения и у InnoDB MySQL) ZFS плохо себя показывала на инсталляциях с очень большим количеством файлов. Всё это в совокупности с необходимостью учить матчасть перед использованием надолго вычеркнуло из моей практики эту файловую систему. Появились ext4 и xfs, которые превратились в стандарт. Но учитывая, что под нашу задачу ZFS более чем подходит, да и Linux-версия, судя по отзывам, выросла во вполне вменяемый продукт (хоть и не на полной поддержке, из-за чего поставить систему на ZFS полностью с нуля можно только при помощи различных шаманств), мы решили её попробовать.


    По понятным причинам стенд выбрали аналогичной конфигурации (за исключением RAID-контроллера). Установили восемь SSD-дисков по 1920 Гб. Не было желания писать свой сетевой образ для заливки сервера на голую ZFS, поэтому мы откусили от всех дисков по 50 Гб и сделали на них MD RAID-10 под систему. Оставшиеся 1950 Гб на каждом диске объединили в ZFS-аналог RAID-10:


    zpool create zpool mirror /dev/sda2 /dev/sdb2 mirror /dev/sdc2 /dev/sdd2 mirror /dev/sde2 /dev/sdf2 mirror /dev/sdg2 /dev/sdh2

    Сделали разделы под MySQL:


    zfs create zpool/mysql
    zfs set compression=gzip zpool/mysql
    zfs set recordsize=128k zpool/mysql
    zfs set atime=off zpool/mysql
    zfs create zpool/mysql/data
    zfs set recordsize=16k zpool/mysql/data
    zfs set primarycache=metadata zpool/mysql/data
    zfs set mountpoint=/var/lib/mysql zpool/mysql/data

    Обратите внимание, что мы включили штатное сжатие данных gzip. Процессорных ресурсов у нас на сервере много и они не полностью используются В результате 3 Тб нашей БД превратились в 1,6 Тб, и поскольку слабым звеном, как и в прошлом случае, является максимальная производительность дисков, то чем меньше данных — тем лучше, мы с самого начала получаем отличный бонус от ZFS! В час пик на полной нагрузке на поддержание работы gzip уходит до 4 ядер, но нам и не жалко.


    Дальше внедрение пошло быстрее. Под копирку перенесли c LVM-стенда настройки реплики MySQL. Пришлось потратить некоторое время на переписывание скриптов на команды ZFS, но в целом алгоритмы остались прежними. Пример создания снапшота:


    zfs set snapdir=visible zpool/mysql/data
    zfs create zpool/stage_3307
    zfs clone zpool/mysql/data@snapmain zpool/stage_3307/data
    zfs set mountpoint=/mnt/stage_3307 zpool/stage_3307/data

    Из дополнительного тюнинга: вынесли в память ZFS-разделы с метаданными и логами l2arc и zil. Для нашей задачи, как оказалось в дальнейшем, это было избыточно, но пока что мы оставили эту оптимизацию, поменять при случае несложно. Из негативных эффектов — приходится после перезагрузки сервера пересоздавать соответствующие области памяти. Данные при этом не теряются. Вырезка zpool status:


    logs
          /dev/shm/zil_slog.img  ONLINE       0     0     0
    cache
          /dev/shm/l2arc.img     ONLINE       0     0     0

    В такой конфигурации мы начали тестировать стенд и получили прекрасные результаты: с двумя одновременно работающими экземплярами БД (и активной основной репликой) на снапшотах мы получили загруженность дисков на 50-60 %.


    Мы избавились от нашей основной проблемы, что видно на графике отставания репликации (сравните с предыдущим графиком в разделе Thin LVM):


    Помимо и благодаря этому мы сильно ускорились во всех операциях: полное создание снапшота с остановкой и запуском реплики занимает до 40 секунд, развёртывание из снапшота нового экземпляра MySQL занимает до 20 секунд. Что более чем устраивает как нас, так и наши тесты программного кода.


    Промежуточные итоги:


    • Результаты полностью удовлетворили нашу потребность в получении копии боевой БД для тестирования кода.
    • Технология требует вхождения: нужно понимать, что такое ZFS и как с ней работать.
    • Мы не проверяли текущий статус работы ZFS с большим количеством (от 1 млн) маленьких файлов. Но предполагаем, что проблема сохраняется, поэтому я не стал бы рекомендовать эту файловую систему для каких-либо файловых хранилищ.

    Что дальше?


    В рамках стенда делать больше ничего, результат нас устраивает. Возможно, в дальнейшем добавим в настройку репликации стенда исключения таблиц, не нужных для тестирования, это еще больше сократит объем БД. Мы не тестировали систему BTRFS и ее реализацию технологии тонкого резервирования. Впрочем, такой задачи уже не стоит, поскольку основная цель достигнута. В целом, конечно же, хочется уйти от вышеописанного подхода — реализовать рабочие миграции БД в тестовую среду, создать отдельный тестовый контур БД, заняться шардированием основной базы. Многое из этого мы уже воплощаем в жизнь, о чем обязательно расскажем в будущих статьях.


    Итоги


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


    • Thin LVM — на небольших БД и когда не хочется или нет времени изучать ZFS.
    • ZFS — если есть опыт работы с ней или возможность потратить время на изучение в любых ситуациях.

    На более высоком уровне представления эта статья — не просто сравнение технологии двух файловых систем. Основная идея, которую я хотел бы передать и закрепить, заключается в том, что не стоит бояться мыслить нестандартно в ситуациях, критичных для бизнеса, и брать только готовые рецепты. Когда-то мы могли всем техническим департаментом покачать головой и сказать, что задача создания трехтерабайтных копий БД меньше чем за минуту невыполнима, и нам не нужны рискованные технологии, давайте сделаем как надо. Это было возможно, но мы потеряли бы примерно полгода-год и много поездок клиентов (поездки — наш основной бизнес-показатель) без тестов и во время внедрения. Поступив нестандартно, мы потеряли не так много времени на внедрение, получили опыт в новых и забытых старых технологиях, и предоставили тестирование именно в тот момент, когда мы в нем очень нуждались. Несомненно, это положительно сказалось на всех наших показателях. Выбор всегда за вами, а мы со своей стороны продолжим рассказывать в нашем блоге про интересные текущие и будущие достижения.

    Comments 55

      0
      Если (когда?) вы дадите разработчикам возможность создавать шард под себя и писать/тестить на нём какие-то фичи, что весьма удобно, когда хватает места, то столкнётесь с небольшой проблемой: разработчик показывает бизнесу новые фичи, бизнес говорит «отлично, внедряем!» и не понимает, что хоть шард прода и прод почти одинаковы — нельзя взять и запушить все изменения напрямую.
        0

        почему нельзя?

          +1
          Потому что пуши даже от 3 разработчиков, которые создали свои шарды и что-то поменяли на прод, могут сломать большую часть прода: нужно хотя бы собрать все изменения и оттестить их — функциональное, интеграционное, регресс-тестирование.
          К примеру, 1 добавляет новый функционал, который стартует при вставке в таблицу по ттриггеру on after insert. И второй разработчик сделает что-то с этим триггером — в результате могут быть чудные баги и гонка обновлений: какой alter trigger придёт позже — тот и будет работать, со всеми сопутствующими фичами.
          Хотя, всё зависит от ценности системы и стоимости downtime: знаю компанию, которая свежее UI выкатывает сразу в прод, там же и тестит.
          Запросы тестировщиков на получение тестового контура упираются в «а вам зачем?»
            0

            Не на тот уровень написал ответ https://habr.com/ru/company/citymobil/blog/492172/#comment_21385216

              0
              Разные изменения от двух разработчиков могут сломать друг друга почти всегда. От наличия копии базы с прода это не зависит — и других способов много.

              >Запросы тестировщиков на получение тестового контура упираются в «а вам зачем?»
              Не, ну вопрос-то вполне резонный. Скажем, наш тестовый контур, чтобы полностью реализовать сценарий (лишь один из множества других), имеющий место в проме, должен включать минимум два оракла и хадуп, и это не считая остальных «мелочей». Понятно что это денег стоит — за железки и за работу, и на этом пытаются экономить (обычно за счет надежности, конечно же).
                0
                Значит, для вашей компании упавший пром (+время его даунтайма) выходит дешевле, чем несколько серверов на тестовый контур + оракловые лицензии.
                Или руководители не считали, сколько будет стоить такое падение + простой + недополученная прибыль.
                Или надеются на авось и вообще, «выжпрофессионалы, почему всё упало?!»
                  0
                  > упавший пром
                  Все-таки, пониженная надежность не синоним нулевой надежности. С какого это он вдруг непременно будет падать?

                  А в остальном да, конечно же это нужно считать, что дешевле обойдется.
                    0
                    Ну ладно, не весь пром может упасть, а кусок основного функционала — но от этого-то не легче?
                    Слышал историю, как в одном банке под давлением менеджмента запушили недотестированный функционал на прод, отвалились транзакции по кредитным картам.
                    После этого такие поставки строго запретили, потому что у зама генерального в поездке не получилось расплатиться кредиткой своего же банка, после была феерия.
          0

          Ну так это вопрос пересечения изменений по коду, какая база особо нет разницы. Ну и реально кажется редким случаем — два разработчика одновременно пилят один и тот же кусок кода и не знают об этом. У нас продуктовые команды, где люди общаются, ну и есть лид. Если и случилось такое, то мерж конфликт с мастером уже намекает перепроверить результат. Ну и функциональные тесты как вишенка. Т.е. все стандартно и не вижу, что может поменяться от наличия/ отсутствия снепшотов базы

            +3

            На свежих linux ядрах можно использовать новую фичу — reflinks. На хабре были небольшие заметки, можно поискать.
            Схема останется примерно той же, только упростится (в случае с lvm) — вместо шаманства со снапшотами и всем этим адовым LVM-зоопарком, после остановки реплики делаем
            cp -a --reflink=always /var/lib/mysql /var/lib/mysql-snapshot1/
            и всё — имеем рабочую copy-on-write копию. Помимо упрощения процесса — такой метод не требует наличия отдельно зарезервированного места в lvm пуле для хранения изменений относительно снапшота, которое непонятно как заранее определить.


            Я по такой схеме делаю бэкапы мускуля, постгреса, монги: имею кучу снапшотов, снятых через интервал 10-30 минут за последние несколько суток, и раз в сутки утягиваю актуальный снапшот в холодное хранилище (там уже рефлинки "разломаются", конечно, тк ФС меняется).
            Вотъ. Имею сказать — весьма неплохо работает. Базы от 10 до 350 гигов.


            А вообще, zfs рулит, конечно =)

              0
              новую фичу — reflinks

              На ext4?

                0

                xfs, как я понимаю?

                  0

                  Да, XFS.
                  Как дела у ext не знаю, давно не слежу за ними и не использовал.

                0
                Да, у нас основная production fs это ext4, не поддерживающия COW, да и основное LTS ядро у нас пока без поддержки reflinks. Интересно было бы посмотреть не просто холодные снапшоты а именно под нагрузкой в 2-3 активных снапшота на одном сервере — возможно cо временем проведем такие эксперименты на xfs на свежем ядре.
                  0

                  вангую, что у вас основная ос — дебиан или убунту. Так ?

                    0
                    Ubuntu
                0

                del

                  0
                  А может знаете способ как можно в MySQL быстро скопировать базу в другую (с другим именем) на этом же сервере? Все очевидные варианты (типа создать пустую базу, скопировать в неё файлы) перепробовал — не работает. Percona xtrabackup аналогично не позволяет такое провернуть. Единственное что работает — дамп и заливка, но это дико долго.
                    +1
                    Раздел в xfs, созданый с опцией reflink. Или раздел с btrfs. Копирование в пределах одной ФС, через cp --reflink=auto, займёт секунды.
                      0

                      mongodb на 400 гигов, SSD, reflink копирование занимает 2 — 2:30 минуты.

                        0

                        А сколько файлов копируется?

                          0

                          Imho, здесь важно не количество файлов, а их размер, тк для reflink нужно прописать дополнительные данные для каждого блока.
                          Но я всё же проверил вашу гипотезу. До этого было ~ 600 файлов, тк на реплике были включены диагностики, которые плодили лишние файлы. Отключил диагностику, почистил, теперь осталось 60 файлов.
                          Время reflink копирования не изменилось.

                          0
                          Файловая система какая: xfs, btrfs или APFS?
                          И сколько по времени занимает обычное копирование?

                          Я подозреваю, что у вас XFS. Что касается BTRFS — в ней эта операция c аналогичным объёмом данных на HDD занимает около 10 секунд.

                          Для XFS для reflink нужно создавать раздел заново со специальными ключами, может в этом дело.
                            0

                            XFS. Конечно, ФС была создана с фичей reflink.
                            На BTRFS делать подобное смысла мало, там есть нормальные снапшоты. Но в проде я btr использовать боюсь.

                              0
                              Но в проде я btr использовать боюсь.

                              Synology в своих NAS не боится (смотри ниже ссылку). В конце-концов, опасения верные, но тогда и Убунту пользоваться стремно — у вас же наверняка не куплена поддержка от вендора ?

                                +1

                                Ну у синолоджи свои данные и мнение, а у меня свое. Такое бывает.
                                Я вполне представляю себе расклад по фс, с их + и — , нет смысла стращать меня громкими именами :) Тем паче, что ковырял я синолоджи изнутри, неонки там нет.
                                Убунту на серверах я не использую, хотя попытки были. На десктопе — в целом норм, терпимо.

                          0
                          Тут дело не в скорости копирования даже — MySQL вот так напрямую не позволяет скопировать базу (для innodb по крайней мере), потому как кроме копирования файлов в директории базы нужно ещё модифицировать ibdata
                            0

                            так реплика же

                              0

                              Не понял причём тут реплика. Мне нужно быстро скопировать базу в пределах одного сервера MySQL.

                                0

                                Ну как, реплика позволяет корректно и без простоя потушить инстанс СУБД, сделать снапшот и вернуть реплику в работу. По идее журнарлирование БД должно позволять снимать снапшот прямо с рабочего процесса, и в случае восстановления сделать необходимый откат незавершенных транзакций… Но через реплику как-то спокойнее. =) Ибо были серьезные баги у того же постгреса с вызовом sync, плюс, даже если мы получили ответ, что sync прошел это еще не гарантия того, что данные в самом деле легли на пластины/записались в ячейки. Слишком много там слоёв стало.

                            +1
                            Копирование в пределах одной ФС, через cp --reflink=auto, займёт секунды.

                            В случае btrfs можно же снимок тома делать — это даже не секунды, а мгновенно.

                          –1
                          Процесс БД, как я понимаю, не остонавливали,
                            0
                            Останавливали — это указано в статье — иначе получаем длительный check на старте MySQL на снапшоте из-за некорректного завершения.
                              0

                              Разве это допустимо в продакшне?

                                0
                                Нет — но это и не продакшн — в статье описана stage-среда основанная на реплике от мастер продакшн базы, но которая (реплика) не участвует в бизнес процессах. Поэтому тут важнее не сама остановка, а скорость при остановке и запуске для того чтобы реплика как можно быстрее восстанавливала отставание от мастера.
                            +6

                            Имеем на проде несколько баз PostgreSQL на ZFS. Основная весит более 20Тб. Используется для бэкапов. Да и сами БД на SSD под zfs работают здорово.
                            Есть немного рекоммендаций по тюнингу ZFS:


                            1. Сжатие лучше использовать LZ4 т.к. gzip в разы медленнее. Возможно даже гна порядок медленнее. Под LZ4 база так же жмётся с коэффициентом около 2, а оверхеда на сжатие по сравнению с записью без сжатия вообще не удалось заметить. Т.к. у zfs скорость сжатия на одно ядро подходит к 1Гб/сек.
                            2. Размер блока оптимальный по производительности оказался 128кб, хотя у Постгре блоки в базе по 8кб это оказалось лучше для arc-кэша.Так же более крупные блоки лучше жмутся, опять же, снижая нагрузку на диски.
                            3. Удивило создание вами l2arc на рамдиске. Это намного хуже, чем отдать эту память тому же arc-кэшу. Более того, если у вас вся база уже лежит на ссд от l2arc нет пользы т.к. это нужно для гибридных решений, где есть небольшой, шустрый ссд под кэш, а памяти уже не хватает. У вас же происходит по сути дубляж одних и тех же данных в arc и l2arc.
                            4. Zil slog можно не делать, достаточно прописать для датасета zfs асинхроную запись всегда и режим throughput. Это позволит возвращаться из прерывания записи не дожидаясь фактической записи данных на диск. При внезапном отключении питания потеряются только данные в памяти, на целостность ФС это не влияет.
                            5. Чисто постгресовая вещь, не знаю, есть ли аналог в MySQL — можно отключить full page writes в xlog БД т.к ZFS гарантирует целостность и атомарность записанных блоков.
                              0

                              В п.1 опечатался. Имел в виду, что у LZ4 скорость упаковки/распаковки под 1Гб на ядро. С телефона писал, извините! )

                                0
                                Размер блока оптимальный по производительности оказался 128кб,

                                зависит от данных в бд, стоит тестить


                                Zil slog можно не делать, достаточно прописать для датасета zfs асинхроную запись всегда и режим throughput.

                                Только если готовы потерять последние секунды записи, на кластерах может быть больно.


                                Добавлю ещё, что на линуксе, если вам не нужна 100%-ная совместимость пула с другими ОС, стоит выставлять xattr=sa, будет экономия нескольких iops на каждое изменение и чтение метаданных файлов.

                                  0

                                  Это реплика же. То что потеряется это несколько секунд обычно, дореплицируется заново, накатив логи с мастера. На мастере это было бы критично, конечно в службе такси, у нас же первичная инфа хранится в логах и мы можем повторно залить хоть всю базу, но это очень больно на 20 Тб будет )
                                  Про xattr согласен, тоже устанавливаем. Но на бд профита не заметил.

                                    0

                                    Про 128кб блок, не совсем от данных в бд зависит. Больше от устройства ZFS. На каждый блок в кэше arc и l2arc идёт оверхед на хранение метаданных. Плюс сексканы и вакуумы делаются дольше собирая блоки по 8кб из рандомных мест.
                                    Но конечно тестов под конкретный профиль использовпния БД никто не отменял. Я когда замерял, остановился на 128. На 8кб был огромный оверхед в l2arc в гибридных ssd + hdd инстансах.

                                      0
                                      Вы правы про оверхед ZFS на каждый блок, но я имел в виду тесты на данных именно про оверхед чтения всех 128к для получения 8-16к из них, и аналогично read-modify-write такого блока. Если запись-чтение происходит очень малыми блоками и не последовательно, то этот оверхед может быть больше, чем вы сэкономили в zfs на большом блоке.
                                    0
                                    Спасибо за подробный экспертный комментарий!
                                    п.1 однозначно попробуем
                                    п.2-3 делали по рекомендациям Perconа из вот этой статьи — при замере l2arc в shm особого прироста или регресса не заметил, но решили оставить исходя из рекомендаций.
                                    п.4 попробуем
                                      0

                                      L2arc — выгрузка редко используемого кеша l1arc (в озу) на диск.


                                      Slog — запись zil (журнала синхронной записи до формирования txg) на отдельный быстрый носитель. Если он вам не нужен и вы готовы потерять синхронную запись за последние секунды — просто поставьте sync=disabled на датасет.


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

                                        0

                                        В статье использовали gzip для сжатия. Возможно более мелкий блок позволил лучше распараллелить сжатие и в целом жать меньше при мелких записях/чтении. LZ4 же не является бутылочным горлышком даже при рандомных чтениях по 128кб. Да еще в последних версиях ZFS по дефолту вкючено сжатие и в кэше arc. Если там тот же gzip будет, как у датасета, то это вообще грустно будет по скорости.

                                      +1
                                      Но предполагаем, что проблема сохраняется, поэтому я не стал бы рекомендовать эту файловую систему для каких-либо файловых хранилищ.

                                      То-то внутри коммерческих хранилок ZFS внутри. Ну, или btrfs.

                                        0

                                        В каких?

                                          +1

                                          Во всех на базе zfs и btrfs.


                                          А по серьёзному — zfs для больших хранилок и делался. Nexenta, nutanix files, oracle zfssa, это только из головы.


                                          Не скажу за опыты автора, но с большим количеством файлов она справляется лучше других фс. Для примера на тестах zfs хранит мету о файлах минимум в 2 раза эффективнее по месту, чем ext4.

                                            0

                                            Ну большие серьезные коммерческие хранилки это все же netapp, emc, а там вроде как свои решения, покруче zfs.
                                            zfs это для бедных, хотя лучше ничего нет, это да. С ext сравнивать смешно :)

                                              +1

                                              Synology рассматриваем? или это так — поиграться?
                                              Ну, у них btrfs, о чем они радостно рассказывают — https://www.synology.com/ru-ru/dsm/Btrfs

                                        0

                                        А как получить то же самое, но с анонимизацией некоторых данных (данных клиентов) в БД?

                                          0
                                          При небольшом объеме подобных данных можно делать сразу после старта реплики на снапшоте обфускацию приватных данных скриптом — но это пока только в планах, и реализация конечная пока не продумана, возможно есть лучше решения.
                                          0

                                          Разве FLUSH TABLES WITH READ LOCK; в mysql не хватает для консистентных снапшотов, зачем его полностью тушить?

                                            0
                                            Пробовали, но к сожалению нет — все равно при старте прогоняет recheck всех данных. (Percona 5.7)
                                              0
                                              Давно не лазил в эту часть мускуля, но думал, что он только вычитывает бинлоги. У перконы есть возможность читать только первый и последний бинлог если включить одну настройку. Вы же про бинлоги?
                                                0
                                                Цитируя O'Reilly High Performance MySQL:
                                                InnoDB’s background threads continue to work even if you’ve locked all tables, so it
                                                is probably still writing to its files even as you take the snapshot. Also, because InnoDB
                                                hasn’t performed its shutdown sequence, the snapshot’s InnoDB files will look the way
                                                these files would have looked if the server had lost power unexpectedly.

                                          Only users with full accounts can post comments. Log in, please.