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

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

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

  • 如果我们从主数据库运行 mysqldump,我们可以使用 mysqldump 的“--master-data”参数来记录主数据库的二进制位置以及转储数据(我想如果我们开始从以下位置生成二进制日志,这也可能有效)我们的奴隶,但这对于我们想要实现的目标来说似乎有点矫枉过正)
  • 如果我们想以非自动化的方式执行此操作,我们可以登录从属数据库并运行“停止从属SQL_THREAD;”;其次是“显示奴隶状态”; ((http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html)。但这不会给我们带来任何好处,除非我们事先知道我们想要从药膏中备份一些东西。
  • 如果我们每年有 500 美元的预算,我们可以使用 InnoDb 热备份插件,然后从主数据库运行 mysqldump。但我们没有那么多钱,而且我也不想在我们的主数据库上添加任何额外的 I/O。

这看起来很常见,之前肯定有人已经弄清楚了,希望有人正在使用 Stack Overflow?

有帮助吗?

解决方案

以下 shell 脚本将在 cron 或 period 中运行,根据需要替换变量(默认值是为 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

其他提示

尽管 Ross 的脚本是正确的,但@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-logs 以进行增量备份或作为额外的安全措施,则将 --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_name、file_pos 存储在变量中
  4. 转储并重新启动从站。

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

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

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

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

(我知道我迟到了)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top