2009-10-05 3 views
7

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

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

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

  • Если мы бежали туздЫшпр из основной базы данных, мы могли бы использовать параметр «--master-данные» с туздЫшпром войти двоичное положение хозяина вместе с dump data (я предполагаю, что это, вероятно, также сработает, если мы начнем генерировать бинарные журналы из нашего подчиненного устройства, но это похоже на излишний уровень для того, что мы хотим достичь)
  • Если бы мы хотели сделать это неавтоматизированным способом, мы могли бы войдите в базу данных подчиненного и запустите «STOP SLAVE SQL_THREAD;» а затем «ПОКАЗАТЬ СОПУТСТВУЮЩИЙ СТАТУС»; (http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html). Но это не принесет нам никакой пользы, если мы заранее не узнаем, что хотим вернуть что-то из бальзака.
  • Если бы у нас было $ 500/year to blow, мы могли бы использовать плагин HotOp InnoDb и просто запускать наши mysqldumps из основного DB. Но у нас нет этих денег, и я вообще не хочу добавлять какие-либо дополнительные входы/выходы в нашу основную БД.

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

ответ

8

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

Yup, это похоже на мой второй сценарий, выше. Если верить документам Mysql, вы можете получить двоичное положение мастера из подчиненного устройства, остановив подчиненный поток и показывая статус подчиненного. Это не требует блокировки мастера. Но я надеюсь найти автоматическое решение, которое автоматически сохранит позицию журнала в процессе выполнения нашей повседневной резервной копии. – wbharding

+0

Эй, совершенно забыл, что статус мастера можно получить от раба! Приветствия для напоминания. Я добавил информацию в shellscript, который выполняет ежедневные резервные копии, поэтому мы должны иметь информацию о двоичном журнале, записанную сейчас вместе с резервными копиями. Я добавлю информацию к моему ответу, будет применима только в том случае, если вы используете систему * nix, но я уверен, что если вы работаете в системе Windows, у вас есть свой собственный способ сделать это:) –

+0

OP действительно не хочет делать LOCK TABLES WITH READ LOCK на хозяине. И никто, действительно, тоже. – MarkR

0

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

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

  1. подключения к MySQL и "стоп-ведомый"
  2. выполнить SHOW SLAVE STATUS
  3. магазин имя_файла, file_pos в переменных
  4. самосвала и перезапустить раба.

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

1

Хотя сценарий Росса находится на правильном пути, @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 изменился.

Поскольку резервное копирование инициируется быстро после проверки состояния, позиция журнала, записанная сценарием, может быть точной. Тем не менее, его prefereable вместо того, чтобы следовать процедуре здесь: 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-журналы в $ dumpoptions variable выше

0

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

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

Проблема в том, что даже в течение небольшого промежутка времени между остановкой подчиненного потока SQL и возвратом Read_Master_Log_Pos поток IO может получить больше данных от мастера, который не был применен потоком 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

туздЫшпр (на 5,6), кажется, есть возможность --dump-рабыню, который при выполнении на рабу записи двоичных журналов со-ords из мастер, что узел был подчиненным. Цель такого дампа - именно то, что вы описываете.

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