7

我目前在 Mysql 从站上运行 mysqldump 来备份我们的数据库。这对于备份我们的数据本身来说效果很好,但我想补充的是与 mysqldump 生成的数据相对应的 master 的二进制日志位置。

这样做将允许我们恢复我们的从属(或设置新的从属),而无需在我们获取主数据库的二进制日志位置的主数据库上执行单独的 mysqldump。我们只需将 mysqldump 生成的数据与我们生成的二进制日志信息结合起来,瞧……重新同步。

到目前为止,我的研究已经让我非常接近能够实现这个目标,但我似乎无法找到一种自动化的方式来实现它。以下是我发现的“几乎”:

  • 如果我们从主数据库运行 mysqldump,我们可以使用 mysqldump 的“--master-data”参数来记录主数据库的二进制位置以及转储数据(我想如果我们开始从我们的奴隶,但这对于我们想要完成的事情来说似乎有点过分了)
  • 如果我们想以非自动化的方式执行此操作,我们可以登录到从站的数据库并运行“STOP SLAVE SQL_THREAD;” 其次是“显示奴隶状态;” (http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html)。但这对我们没有任何好处,除非我们事先知道我们想要从药膏中备份一些东西。
  • 如果我们每年要花 500 美元,我们可以使用 InnoDb 热备份插件并从主数据库运行我们的 mysqldumps。但是我们没有这笔钱,而且我也不想在我们的主数据库上添加任何额外的 I/O。

这似乎是一件很常见的事情,以前一定有人想出来过,希望有人在使用 Stack Overflow?

4

5 回答 5

9

以下 shell 脚本将以 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
于 2009-10-06T01:19:43.763 回答
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已更改。

由于我们检查状态后快速启动备份,因此脚本记录的日志位置可能是准确的。但是,最好按照此处的程序进行操作: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-logs 以进行增量备份或作为额外的安全措施,将 --flush-logs 附加到上面的 $dumpoptions 变量中很有用

于 2010-12-16T01:56:41.917 回答
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. 将文件名、文件名存储在变量中
  4. 转储并重新启动从站。

只是一个想法,但我猜你可以将“CHANGE MASTER TO”行附加到转储文件中,当你恢复/设置新的从属时它会被执行。

于 2009-10-06T21:23:33.923 回答
0

使用 Read_Master_Log_Pos 作为从 master 继续的位置意味着您最终可能会丢失数据。

Read_Master_Log_Pos 变量是从 IO 线程到的主二进制日志文件中的位置。

这里的问题是,即使在停止从属 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
于 2013-02-12T18:12:30.647 回答
0

mysqldump (在 5.6 上)似乎有一个选项 --dump-slave ,当在从属服务器上执行时,它会记录该节点作为从属节点的主服务器的二进制日志坐标。这种转储的意图正是您所描述的。

(我迟到了,我知道)

于 2017-03-14T08:54:56.187 回答