MySQL ZFS Backup v2

Обновил и расширил функциональность своего скрипта, осуществляющего бэкап базы данных MySQL с помощью ZFS снапшотов.

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

db# ./mysql_zfs_backup.sh -u mysqluser -p mysqlpass -d rpool/mysql -d ssd/mysql
Replication is running: 0 seconds master delay
Snapshots will be rotated for ZFS datasets: rpool/mysql ssd/mysql
Done

Конфигурация по-умолчанию читается из файла mysql_zfs_backup.conf:

mysql_user='mysqluser'
mysql_pass='mysqlpass'
zfs_datasets='rpool/mysql ssd/mysql'
quiet='0'

И, кстати:

db# /bin/sh -c 'time -h ./mysql_zfs_backup.sh'
Replication is running: 0 seconds master delay
Snapshots will be rotated for ZFS datasets: rpool/mysql
Done
        3.09s real              0.02s user              0.00s sys
db# du -h -c /var/db/mysql | grep total
 79G    total

Файлы: сам скрипт, пример конфига.

Сдох SSD

Внезапно сдох 128 гиговый ссд диск STT FTM28GX25H 1916. Проработал недели три в качестве log/l2arc для zfs пула.

ahcich0: Timeout on slot 31
ahcich0: Timeout on slot 31
ahcich0: Timeout on slot 31
ahcich0: Timeout on slot 31
(ada0:ahcich0:0:0:0): lost device

Похерился пул вместе с данными. Благо бэкапный мастер под боком был. Мораль — используйте для лог девайсов зеркало!

Тюнинг ZFS, MySQL и InnoDB

Тюнинг MySQL и InnoDB

InnoDB начинает работать с файлами данных и логами напрямую, не используя буферы файловой системы.
Позволяет избежать двойной буферизации при работе с файлами данных и логов.

innodb_flush_method = O_DIRECT

Механизм буфера двойной записи (doublewrite) используется в InnoDB для того, чтобы удостовериться, что измененные страницы были записаны в файл данных. Этот механизм позволяет избежать потери данных при внезапном отключении сервера. Поскольку у ZFS есть свой механизм обеспечения целостности данных, буфер двойной записи можно отключить:

skip-innodb_doublewrite

Запись в файлы данных InnoDB должна осуществляться блоками по 16Кб, что соответствует размеру страницы, используемом в этом движке. Поскольку размер блока записи по-умолчанию составляет 128Кб, файлы данных нужно вынести на отдельную файловую систему.

innodb_data_home_dir=/var/db/mysql/ibdata
# zfs create data/mysql/ibdata
# zfs set recordsize=16K data/mysql/ibdata
# mv /var/db/mysql/ibdata1 /var/db/mysql/ibdata/

Тюнинг ZFS

База данных осуществляет чтение в произвольном порядке, который нельзя предсказать.
Отключение префетча позволяет избежать ненужных операций чтения. Добавим в /boot/loader.conf строку

vfs.zfs.prefetch_disable=1

ZFS кэширует данные в ARC, используя свободную оперативную память. Поскольку страницы InnoDB уже кэшируются в буфер пуле, отключим кэширование файлов данных InnoDB:

# zfs set primarycache=metadata data/mysql/ibdata

См. также: MySQL на ZFS под FreeBSD: подготовка

Бэкапим MySQL на ZFS

Кстати, бэкапиться с ZFS на слейвах очень и очень просто:

#!/bin/sh
user='mysqlbackup';
pass='superpass';
/usr/local/bin/mysql -u $user -p$pass -e 'STOP SLAVE; FLUSH LOGS; FLUSH TABLES WITH READ LOCK; \
SYSTEM zfs destroy -r data/mysql@yesterday; \
SYSTEM zfs rename -r data/mysql@today @yesterday; \
SYSTEM zfs snapshot -r data/mysql@today; \
UNLOCK TABLES; START SLAVE;'

Скрипт выполняется примерно за секунду на 30 гиговой базе.

Про zvol

ZFS предоставляет интерфейс zvol, который позволяет обращаться к разделам как к блочным устройствам, используя путь /dev/zvol/zpoolname/volume. Как показала практика, объекты типа filesystem адресовать нельзя.

# uname -r
8.0-RELEASE-p2
# zfs list
NAME         USED  AVAIL  REFER  MOUNTPOINT
system      1.16G   269G  1.16G  legacy
tank         177K  1.43T  30.4K  none
tank/video  28.8K  1.43T  28.8K  none
# mount
system on / (zfs, local)
devfs on /dev (devfs, local, multilabel)
# zfs get type tank/video
NAME        PROPERTY  VALUE       SOURCE
tank/video  type      filesystem  -
# ls -la /dev/zvol
ls: /dev/zvol: No such file or directory

Однако если создать volume с четко заданным размером, то его можно будет использовать как блочное устройство.

# zfs create -V 100m tank/test
# ls -l /dev/zvol/tank
total 0
crw-r-----  1 root  operator    0, 116 Jan 12 13:21 test

Клонирование ZFS на другой пул

Цель: сделать копию файловой системы и развернуть ее на другом пуле ZFS.
Решение проще пареной репы:

zfs create backup/root
zfs snapshot tank/root@now
zfs send tank/root@now | zfs receive -F backup/root
zfs rollback backup/root@now
zfs destroy tank/root@now
zfs destroy backup/root@now

Optimizing MySQL Performance with ZFS

Наткнулся в интернетах на интереснейшую презентацию с The 2009 MySQL Conference & Expo. Умные мужчины из Sun Microsystems в течении почти часа рассказывают о тонкостях использования MySQL на ZFS.

MySQL на ZFS под FreeBSD: подготовка

Итак, что есть на руках:

# uname -rm
8.0-RELEASE amd64
# atacontrol list
ATA channel 2:
    Master:  ad4 ST3500320NS/SN06 SATA revision 1.x
    Slave:       no device present
ATA channel 3:
    Master:  ad6 ST3500320NS/SN06 SATA revision 1.x
    Slave:       no device present
# zpool status
  pool: tank
 state: ONLINE
 scrub: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          mirror    ONLINE       0     0     0
            ad4s1d  ONLINE       0     0     0
            ad6s1d  ONLINE       0     0     0

errors: No known data errors

Имеем мы 64 битную FreeBSD 8-й ветки, релиз которой состоялся совсем недавно Операционная система установлена на ZFS зеркале из двух SATA жестких дисков. FreeBSD ZFS Tuning Guide рекомендует именно такие версии софта для наиболее стабильной работы. Для начала создадим в уже имеющемся ZFS пуле с названием tank файловые системы, которые мы будем использовать для хранения данных Не забыв при этом остановить сервер MySQL и сделать бэкап директории с данными.
Читать далее MySQL на ZFS под FreeBSD: подготовка