Как записать двоичный журнал Mysql позиции мастера при выполнении mysqldump от подчиненного - PullRequest
7 голосов
/ 06 октября 2009

В настоящее время я запускаю mysqldump на подчиненном сервере Mysql для резервного копирования нашей базы данных. Это прекрасно работает для резервного копирования самих данных, но я хотел бы дополнить их двоичной лог-позицией мастера, которая соответствует данным, сгенерированным mysqldump.

Выполнение этого позволит нам восстановить нашего ведомого (или настроить новых ведомых) без необходимости выполнения отдельного mysqldump в основной базе данных, где мы получаем двоичную лог-позицию мастера. Мы бы просто взяли данные, сгенерированные mysqldump, объединили их с сгенерированной нами двоичной журнальной информацией и вуаля ... были повторно синхронизированы.

Пока что мои исследования позволили мне очень Близко к достижению этой цели, но я не могу придумать автоматизированный способ ее достижения. Вот «почти все», которые я обнаружил:

  • Если бы мы запускали mysqldump из основной базы данных, мы могли бы использовать параметр "--master-data" с mysqldump для записи двоичной позиции мастера вместе с данными дампа (я предполагаю, что это, вероятно, также сработает, если мы начнем генерировать двоичные журналы от нашего ведомого, но это кажется излишним для того, что мы хотим достичь)
  • Если бы мы хотели сделать это неавтоматизированным способом, мы могли бы войти в базу данных ведомого и запустить «STOP SLAVE SQL_THREAD;» с последующим "SHOW SLAVE STATUS;" (http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html). Но это не принесет нам никакой пользы, если мы заранее не знаем, что хотим что-то подкрепить из мази.
  • Если бы у нас было 500 долларов в год, мы могли бы использовать плагин горячего резервного копирования InnoDb и просто запустить mysqldumps из основной БД. Но у нас нет этих денег, и я не хочу добавлять дополнительные операции ввода-вывода в нашу основную БД.

Это кажется чем-то достаточно распространенным, что кто-то должен был выяснить раньше, надеюсь, что кто-то использует переполнение стека?

Ответы [ 5 ]

8 голосов
/ 06 октября 2009

Следующий скрипт оболочки будет работать в cron или периодическом режиме, при необходимости заменяя переменные (по умолчанию написано для FreeBSD):

# MySQL executable location
mysql=/usr/local/bin/mysql

# MySQLDump location
mysqldump=/usr/local/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases
databases="db1 db2 db3"

# Backup Directory
backupdir=/usr/backups

# Flush and Lock
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'

set `date +'%Y %m %d'`

# Binary Log Positions
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Read_Master_Log_Pos'`

# Write Binlog Info
echo $masterlogfile >> ${backupdir}/info-$1-$2-$3.txt
echo $masterlogpos >> ${backupdir}/info-$1-$2-$3.txt

# Dump all of our databases
echo "Dumping MySQL Databases"
for database in $databases
do
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/${database}-$1-$2-$3.sql.gz
done

# Unlock
$mysql $userpassword -e 'START SLAVE'

echo "Dump Complete!"

exit 0
1 голос
/ 16 декабря 2010

Несмотря на то, что сценарий Росса находится на правильном пути, @joatis прав, когда он говорит остановить подчиненное устройство перед проверкой позиции главного журнала. Причина в том, что READ LOCK не сохранит Read_Master_Log_Pos, полученный с помощью SHOW SLAVE STATUS.

Чтобы убедиться, что это так, войдите в MySQL на своем ведомом устройстве и запустите:

FLUSH TABLES WITH READ LOCK

SHOW SLAVE STATUS \G

Обратите внимание на Read_Master_Log_Pos

Подождите несколько секунд и снова запустите:

SHOW SLAVE STATUS \G

Вы должны заметить, что Read_Master_Log_Pos изменился.

Поскольку резервное копирование начинается быстро после того, как мы проверим состояние, позиция журнала, записанная сценарием, может быть точной. Тем не менее, предпочтительнее вместо этого следовать процедуре здесь: http://dev.mysql.com/doc/refman/5.0/en/replication-solutions-backups-mysqldump.html

И запустить STOP SLAVE SQL_THREAD; вместо FLUSH TABLES WITH READ LOCK на время резервного копирования.

Когда закончите, снова начните репликацию с START SLAVE

Также, если вы хотите сделать резервную копию бинарных журналов для инкрементных резервных копий или в качестве дополнительной меры безопасности, полезно добавить --flush-logs к переменной $ dumpoptions выше

0 голосов
/ 14 марта 2017

mysqldump (на 5.6), кажется, имеет опцию --dump-slave, которая при выполнении на ведомом устройстве записывает двоичные журнальные коды ведущего устройства, узлом которого был ведомый. Цель такого дампа - именно то, что вы описываете.

(я опоздал, я знаю)

0 голосов
/ 12 февраля 2013

Использование Read_Master_Log_Pos в качестве позиции для продолжения от мастера означает, что вы можете получить недостающие данные.

Переменная Read_Master_Log_Pos - это позиция в главном двоичном файле журнала, до которой доходит подчиненный поток ввода-вывода.

Проблема здесь в том, что даже в течение небольшого промежутка времени между остановкой подчиненного потока SQL и получением Read_Master_Log_Pos поток ввода-вывода мог получить больше данных от мастера, которые не были применены остановленным потоком SQL.

Это приводит к тому, что Read_Master_Log_Pos опережает данные, возвращаемые в mysqldump, оставляя пробел в данных при импорте и продолжении на другом ведомом устройстве.

Правильное значение, используемое на ведомом устройстве, - это Exec_Master_Log_Pos, то есть позиция в главном двоичном файле журнала, которую последний исполняющий поток SQL выполнял, что означает отсутствие пропуска данных между mysqldump и Exec_Master_Log_Pos.

Используя скрипт Росса выше, правильное использование будет:

# MySQL executable location
mysql=/usr/bin/mysql

# MySQLDump executable location
mysqldump=/usr/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases to dump
databases="db1 db2 db3"

# Backup Directory
# You need to create this dir
backupdir=~/mysqldump


# Stop slave sql thread

echo -n "Stopping slave SQL_THREAD... "
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'
echo "Done."

set `date +'%Y %m %d'`

# Get Binary Log Positions

echo "Logging master status..."
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Exec_Master_Log_Pos'`

# Write log Info

echo $masterlogfile
echo $masterlogpos
echo $masterlogfile >> ${backupdir}/$1-$2-$3_info.txt
echo $masterlogpos >> ${backupdir}/$1-$2-$3_info.txt

# Dump the databases

echo "Dumping MySQL Databases..."
for database in $databases
do
echo -n "$database... "
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/$1-$2-$3_${database}.sql.gz
echo "Done."
done

# Start slave again

echo -n "Starting slave... "
$mysql $userpassword -e 'START SLAVE'
echo "Done."

echo "All complete!"

exit 0
0 голосов
/ 07 октября 2009

Ваш второй вариант выглядит как правильный трек.

Мне пришлось придумать способ создания дифференциальных резервных копий с помощью mysqldump. В итоге я написал скрипт, который выбрал базы данных для резервного копирования и затем выполнил mysqldump. Не могли бы вы создать скрипт, который выполнил шаги, указанные в http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_master-data, и вызвать его из задания cron?

  1. подключиться к mysql и "остановить ведомого"
  2. выполнить ПОКАЗАТЬ СТАТУС РАБЫ
  3. сохранить имя_файла, file_pos в переменных
  4. сбросьте и перезапустите подчиненное устройство.

Просто мысль, но я предполагаю, что вы можете добавить строку "CHANGE MASTER TO" в файл дампа, и она будет выполнена, когда вы восстановите / настроите нового ведомого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...