MySQL增量备份 - 即时备份和恢复InnoDB和MyIsam数据库

Mysql增量备份是一个完整的增量备份脚本,用于MyISAM和InnodB数据库使用MySQL二进制日志,以便备份过程...

进行增量备份是大型生产数据库的重要要求。 没有安全的增量备份,你不能告诉自己你有一个可靠的生产数据库。 因为您必须拥有足够的数据才能在紧急情况下恢复数据库。 在互联网上进行一些搜索后,我找不到任何可以在混合环境中对MyISAM和InnodB进行完全增量备份的工具,因为应用程序同时使用数据库引擎(也许我不是Google和Internet上的专家搜索者)。 所以我决定写这个,但是为了避免浪费时间和从其他开源解决方案中获益,我更喜欢将这个功能添加到-automysqlbackup脚本中,这是在简单和广泛使用中完全备份的最佳脚本。

机制

我们使用automysqlbackup的Post和Pre功能进行增量备份。 在开始完全备份之前,mysql-backup-pre执行查询以在备份过程中锁定整个数据库,因为我们必须冻结binlog以避免在备份运行时发生任何更改。 备份期间binlog名称和位置可能不会更改。 二进制日志位置在后续增量备份过程中非常重要,将作为开始下一个增量备份的起点。 完成完整备份后,mysql-backup-post将删除数据库锁。

锁定查询: FLUSH表与READ LOCK; 选择睡眠(86400)

查找锁查询: mysql -u [username] -p [pass] -e“show processlist”| grep“SELECT SLEEP(86400)”| awk'{print $ 1}'

要求

  • root权限安装包和更新mysql.conf
  • mysql-community-client包
  • 安装automysqlbackup和mysql-incremental

安装

为您的发行版安装mysql-community-client包。

注意:在MySQL安装后,您必须具有'mysqlshow'命令。

安装automysqlbackup:

download the package from https://sourceforge.net/projects/automysqlbackup/

tar -xzf [PathYouSavedTarFile] -C /tmp/

cd /tmp/

./install.sh

在安装automysqlbackup时,系统会询问automysqlbackup.conf及其二进制文件的路径,您可以保留默认值,而不会发生任何更改。

rm /etc/automysqlbackup/myserver.conf

安装mysql-incremental:从https://sourceforge.net/projects/mysqlincrementalbackup/下载软件包

cd /tmp
wget http://downloads.sourceforge.net/project/mysqlincrementalbackup/mysql-incremental.tar.gz
tar xfz mysql-incremental.tar.gz

cp mysql-incremental /etc/automysqlbackup/

chmod 755 /etc/automysqlbackup/mysql-incremental

cp mysql-backup-post /etc/automysqlbackup/

chmod 755 /etc/automysqlbackup/mysql-backup-post

cp mysql-backup-pre /etc/automysqlbackup/

chmod 755 /etc/automysqlbackup/mysql-backup-pre

更新automysqlbackup.conf:

查找以下参数,取消注释并更改它们:

        CONFIG_mysql_dump_username='Mysql user name. It must has privileges to get Lock'
	CONFIG_mysql_dump_password='Password'
	CONFIG_backup_dir='The backup directory you want to store full and incremental backup'
	CONFIG_db_names=('databaseName1' 'databaseName2' )
	CONFIG_db_month_names=('databaseName1' 'databaseName2' )
	CONFIG_mysql_dump_master_data=2
	CONFIG_prebackup="/etc/automysqlbackup/mysql-backup-pre"
	CONFIG_postbackup="/etc/automysqlbackup/mysql-backup-post"

更新my.cnf:

编辑MySQL配置文件:

nano /etc/mysql/my.cnf

1- BinLog格式

由于STATEMENT格式的一些限制,我的建议是设置基于ROW的格式。 有关详细信息,请参阅此操作中的“疑难解答”一节。 您可以通过执行“ select @@ binlog_format ”查询来检查二进制日志格式的类型。 要修改logbin格式,您必须添加binlog_format = ROW到mysql.conf或my.cnf。

2- binlog_do_db

您必须指定要在二进制日志中具有相关更改的数据库。 请注意,如果您没有指定任何数据库,任何数据库上的任何更改将被记录到二进制日志中。 在这种情况下,如果您选择STATEMENT格式,也许在从增量备份和binlog文件进行还原时,您可能会遇到麻烦。 您可以向此选项添加数据库:

binlog_do_db = DATABASENAME1
binlog_do_db = DATABASENAME2

3到expire_logs_days

要使二进制日志文件更长时间,您可以将此参数增加到更高的值。 我的建议是60天。 所以你必须添加或更改为“ expire_logs_days = 60 ”。

4- log-bin

将存储二进制日志的目录。 在旧的MySQL版本中,mysql-incrementmenetal可能无法找到正确的路径。 因此,如果在执行mysql-incremental之后收到错误信息,则必须更新mysql-incremental脚本并设置二进制日志路径。

5- log_slave_updates

如果要在从属服务器上设置mysql增量备份,则必须启用此选项。 通常,从服务器接收到的从属服务器不会将更新日志记录到自己的二进制日志中。 此选项告诉从属将其SQL线程执行的更新记录到其自己的二进制日志中。 http://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_log-slave-updates

运行automysqlbackup

运行automysqlbackup手动从指定的数据库至少有一个完整的备份。

automysqlbackup

成功执行命令后,请查看/ [BackupDirInAutomysqlbackup] / status / backup_info文件,了解有关日常备份的新增信息。 有关错误的详细信息,请查看/ var / log / Backup_Post_Pre_log 备份文件将存储在/ [BackupDirInAutomysqlbackup] / daily / [DatabaseName] /目录中

运行mysql-incremental

现在运行mysql-incremental ,至少要进行一次小时的备份。

mysql-incremental

如果出现错误,详细信息将记录在文件“ / var / log / Backup_Incremental_Log ”中。 增量备份文件将存储在/ [BackupDirInAutomysqlbackup] / IncrementalBackup /目录中

编辑根crontab

您可以安排mysql-incremental超过一个小时。 您可以从backup_status找到完整备份的总时间,然后根据该值设置准确的计划时间。 当然,mysql增量备份确实有一种机制,可以在启动之前查找任何运行的完整备份,所以不用担心增量备份和完全备份之间的冲突。

crontab -e

5 00 * * * root /usr/local/bin/automysqlbackup
25 *  * * * root  /etc/automysqlbackup/mysql-incremental

恢复数据库

为了恢复到特定时间(即时恢复),首先必须恢复一个完整的每日备份,然后恢复顺序相关的增量备份文件。 要澄清更多,以下是恢复testDB数据库的步骤。 在样本场景中,我们打算在上午2点之前恢复到2015-5-01。 我们将/ backup作为我们的主备份目录和testDB作为目标数据库:

1- mysql -u root -p DatabaseName < /backup/daily/testDB/daily_DatabaseName_2015-05-16_00h05m_Saturday.sql.gz
2- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_00h25m.1
3- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_01h25m.2
4- mysql -u root -p DatabaseNAme < /backup/IncrementalBackup/2015-5-01_Incremental/testDB/testDB_IncrementalBackup_2015-5-01_02h25m.3

重要说明和故障排除

MySQL支持二进制日志的不同格式。 一些Mysql版本使用“基于语句”作为binlog格式,这种类型的binlog确实有一些限制,当我们打算在增量备份过程中使用它时,我们必须密切关注它。 当mysql设置为statement-base格式时,它无法根据数据库进行正确的过滤。 如果设置'USE或'u'来更改数据库,然后更新另一个未包含在binlog-do-db中的数据库,则该语句将被记录在binlog文件中,这是不可取的状态! 并且在基于特定数据库进行还原时会出现一些问题,并且如果您更改为未包含在binlog-do-db中的另一个数据库,并更新binlog-do-db中包含的数据库,则该语句将不会记录到binlog文件。 我们将数据库添加到binlog-do-db的目的是为了基于数据库进行过滤,但是它不能像预期的那样工作。 如果USE或\ u在运行查询之前未执行,则mysqlbinlog无法提取与一个数据库相关的“更新查询”。 下面我们来解释一下这个问题:

databases: 
 - binlog
     - person (table) 
  - binlog2
     - person (table)

 binlog-do-db=binlog2 (it is supposed only change of this database are logged to binlog file)
--------Scenario 1---------
\u binlog2
insert into person (data) values ('17') ---> loged in binlog  *desired state*
insert into binlog.person (data) values ('25'); ---> logged in binlog (target database is 'binlog' ) *undesired state*
--------Scenario 2---------
\u binlog
insert into person (data) values ('17') ---> is not logged in binlog  *desired state*
insert into binlog2.person (data) values ('25'); ---> is not logged in binlog (target database is 'binlog2' ) *undesired state* because the binlog2 database
is begin changed, so we want to have this change,but it will not logged in logbin file
--------Scenario 3---------
if you just connect to database without any USE or \u statement, all of updates on any databases will be logged, but mysqlbinlog can not able to filter
based on specific database, so that is not desirable state for our purpose in incremental backup. Using USE or \u before executing update queries, is very
important. Because mysqlbinlog finds update queries based on USE statement in binlog file.

解决上述问题

1)通过以每个用户只能访问一个数据库进行更新(应用程序用户)和连接到数据库的方式定义数据库上的用户,必须指定数据库的名称。 当然,大多数应用程序确实有一个配置文件,其中设置了数据库的凭据和名称,因此在这种情况下,您将不会对数据库进行交叉访问,并且不会担心使用“\ USE”或“u” “。

2)如果使用基于行的binlog格式,所有上述问题都将消失。 换句话说,基于行的格式是二进制文件的更合适的方法。 https://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html

日志文件

我尝试将所有内容记录在日志文件中,以便您可以在日志中找到足够的信息:

/ var / log / Backup_Post_Pre_log
/ var / log / Backup_Incremental_Log
/[SpecifiedBackupDirInAutomysqlbackup.conf]/status/backup_info

文件“ backup_info ”包含有关备份的详细信息,备份完成时间(时间为Unix时间格式)。 它包含备份启动的时间点的binlog名称和位置,备份的类型,自上次完全备份以来的备份数以及备份的持续时间。

示例backup_info:

1431043501,mysql-bin.000026,120,Daily,2015-05-08,0,24
1431044701,mysql-bin.000026,120,Hourly,2015-05-08,1,1

以下是不同值的描述:

 1th) 1431043501 : indicates the time when the backup has been finished. You can run date --date @1431043501 command on the server the backup has been done to view it in human readable format.
 2th) Mysql-bin.000026 : indicates the binary log name that backup up to this file has been done.
 3th) 120 : indicates the position of binlog  that backup up to this position in binary log has been done.
 4th) Daily/Hourly: indicates type of backup. Daily does mean the full backup by automysqlbackup script and Hourly is done by mysql-incremental script.
 5th) 2015-05-08: The date that backup has been done. This date will be used in creating directory for incremental backup and also as a base for restore hourly backups. In restoring procedure, first a full backup is restored and then sequentially other incremental backup are restored.
 6th) 0 : indicates number of backups from previous full backup. 0 does mean the backup is full and others mean hourly. This number is very important in restoring procedure.
 7th) 24: The backup duration in second.

错误报告

您可以通过https://sourceforge.net/projects/mysqlincrementalbackup报告错误或提供建议和评论。