Как записать позицию двоичного журнала Mysql для master при выполнении mysqldump из slave?

StackOverflow https://stackoverflow.com/questions/1522976

Вопрос

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

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

Пока что мои исследования подвели меня очень БЛИЗКО к достижению этой цели, но, похоже, я не могу придумать автоматизированный способ ее достижения.Вот "почти", которые я обнаружил:

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

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

Это было полезно?

Решение

Следующий сценарий оболочки будет выполняться в cron или periodic, заменяя переменные по мере необходимости (значения по умолчанию написаны для 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

Другие советы

Хотя сценарий Росса находится на правильном пути, @joatis прав, когда говорит остановить ведомое устройство перед проверкой положения главного журнала.Причина в том, что БЛОКИРОВКА ЧТЕНИЯ не сохранит 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

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

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

Мне нужно было придумать способ создания дифференциальных резервных копий с помощью 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. выполните сброс и перезагрузите ведомое устройство.

Просто мысль, но я предполагаю, что вы могли бы добавить строку "ИЗМЕНИТЬ MASTER НА" в файл дампа, и она была бы выполнена, когда вы восстановили / настроили новый slave.

Использование 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

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

(Я опаздываю, я знаю)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top