安全的web服务器——使用mysqldump和mysqlbinlog实现MySQL全量与增量备份
Posted chuxinbufu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安全的web服务器——使用mysqldump和mysqlbinlog实现MySQL全量与增量备份相关的知识,希望对你有一定的参考价值。
1.环境
系统是Deepin15.6,数据库的版本号是:
Server version: 5.7.18-1 (Debian)
数据库引擎是:InnoDB。如何查看数据库版本和数据库引擎呢?
终端登录mysql数据库命令行的时候,就可以看见数据库版本。
登录数据库后,使用如下命令:
show engines;
它会显示很多数据库引擎,其中,显示YES的指本数据库支持的引擎,显示default的是本数据库默认的引擎。
也可以用如下命令:
show variables like ‘%storage_engine%‘;
来显示数据库引擎。
2.全量备份
全量备份很简单,备份的命令是:
恢复的命令是在MySQL命令行中执行的,要先手动创建一个数据库,然后再use这个数据库:
mysql> source $DumpFile
3.增量备份
这个操作需要MySQL本身的日志文件支持,登陆mysql,检查log-bin是否开启:
show variables like ‘log_bin‘;
如果如下所示:
mysql> show variables like ‘log_bin‘; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | OFF | +---------------+-------+ 1 row in set (0.00 sec)
显示OFF的话,那就是没有开始日志服务。那么找到MySQL的配置文件,更改配置,这个地方看了网上的很多教程,但是都没有用。大概他们讲的都是centos上的配置步骤吧,而我用的是基于debian的deepin15.6(Ubuntu应该也是适用的)。配置文件的目录是
/etc/mysql/mysql.conf.d/mysqld.cnf
在其中加入这么几项:
然后,在终端中输入:sudo service mysql restart 重启MySQL服务,再登陆上MySQL,执行命令
show variables like ‘log_bin‘;看到如下结果,证明binlog配置成功。
+---------------------------------+--------------------------------+ | Variable_name | Value | +---------------------------------+--------------------------------+ | log_bin | ON | | log_bin_basename | /var/log/mysql/mysql-bin | | log_bin_index | /var/log/mysql/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | +---------------------------------+--------------------------------+ 5 rows in set (0.00 sec)
binlog_format 此参数配置binlog的日志格式,默认为mixed。 max_binlog_size此参数配置binlog的日志最大值,最大和默认值是1GB。 max_binlog_cache_size此参数表示binlog使用最大内存的数。 binlog-do-db=db_name 此参数表示只记录指定数据库的二进制日志。 binlog-ignore-db=db_name此参数表示不记录指定的数据库的二进制日志。 expire_logs_days 此参数表示binlog日志保留的时间,默认单位是天。
关于binlog日志的操作命令:
1.查看所有binlog日志列表 mysql> show master logs; 2.查看master状态,即最后(最新)一个binlog日志的编号名称,及其最后一个操作事件pos结束点(Position)值,这个文件就是当前MySQL在使用的binlog文件。 mysql> show master status; 3.刷新log日志,自此刻开始产生一个新编号的binlog日志文件 mysql> flush logs; 注:每当mysqld服务重启时,会自动执行此命令,刷新binlog日志;在mysqldump备份数据时加 -F 选项也会刷新binlog日志; 4.重置(清空)所有binlog日志 mysql> reset master;
如果想查看binlog日志的具体内容,登录MySQL命令行:
mysql> show binlog events [IN ‘log_name‘] [FROM pos] [LIMIT [offset,] row_count]; 选项解析: IN ‘log_name‘ 指定要查询的binlog文件名(不指定就是第一个binlog文件) FROM pos 指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算) LIMIT [offset,] 偏移量(不指定就是0) row_count 查询总条数(不指定就是所有行)
比如做一下查询,在mysql-bin.000002文件中查询pos在219之后的内容:
mysql> show binlog events in ‘mysql-bin.000002‘ from 219; +------------------+-----+------------+-----------+-------------+----------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+------------+-----------+-------------+----------------------------------------+ | mysql-bin.000002 | 219 | Query | 1 | 298 | BEGIN | | mysql-bin.000002 | 298 | Table_map | 1 | 366 | table_id: 241 (wordpressdb.wp_options) | | mysql-bin.000002 | 366 | Write_rows | 1 | 447 | table_id: 241 flags: STMT_END_F | | mysql-bin.000002 | 447 | Xid | 1 | 478 | COMMIT /* xid=53 */ | +------------------+-----+------------+-----------+-------------+----------------------------------------+ 4 rows in set (0.00 sec)
这样,我们的binlog日志功能算是做好了。
4.恢复数据实战
首先,建立一个数据库,并且插入一些数据:在MySQL程序中输入以下命令:
mysql> create database AAA; Query OK, 1 row affected (0.00 sec) mysql> use AAA; Database changed mysql> create table BBB(id int); Query OK, 0 rows affected (0.04 sec) mysql> insert into BBB (id) values (1); Query OK, 1 row affected (0.00 sec) mysql> insert into BBB (id) values (2); Query OK, 1 row affected (0.01 sec) mysql> insert into BBB (id) values (3); Query OK, 1 row affected (0.01 sec)
此时,数据库AAA中的数据库表BBB中的内容如下所示:
mysql> select * from BBB; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.00 sec)
然后,使用MySQL的全量备份,备份整个AAA数据库:
mysqldump -uroot -p123456 --databases AAA --flush-logs --single-transaction > /home/xu/AAA.sql
然后,我们再对数据库AAA中的数据库表BBB做一些操作:
mysql> insert into BBB (id) values (4); Query OK, 1 row affected (0.01 sec) mysql> update BBB set id=5 where id=3; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0
此时,数据库AAA中的数据库表BBB的内容如下所示:
mysql> select * from BBB; +------+ | id | +------+ | 1 | | 2 | | 5 | | 4 | +------+ 4 rows in set (0.00 sec)
接着,不小心删掉了数据库AAA:
mysql> drop database AAA; Query OK, 1 row affected (0.03 sec)
此时,迅速的查看当前使用的binlog文件:
mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000003 | 818 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
这里,查看这个binlog文件的内容:
mysql> show binlog events in ‘mysql-bin.000003‘; +------------------+-----+----------------+-----------+-------------+-----------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+-----+----------------+-----------+-------------+-----------------------------------------+ | mysql-bin.000003 | 4 | Format_desc | 1 | 123 | Server ver: 5.7.18-1-log, Binlog ver: 4 | | mysql-bin.000003 | 123 | Previous_gtids | 1 | 154 | | | mysql-bin.000003 | 154 | Anonymous_Gtid | 1 | 219 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘ | | mysql-bin.000003 | 219 | Query | 1 | 290 | BEGIN | | mysql-bin.000003 | 290 | Table_map | 1 | 335 | table_id: 254 (AAA.BBB) | | mysql-bin.000003 | 335 | Write_rows | 1 | 375 | table_id: 254 flags: STMT_END_F | | mysql-bin.000003 | 375 | Xid | 1 | 406 | COMMIT /* xid=1777 */ | | mysql-bin.000003 | 406 | Anonymous_Gtid | 1 | 471 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘ | | mysql-bin.000003 | 471 | Query | 1 | 542 | BEGIN | | mysql-bin.000003 | 542 | Table_map | 1 | 587 | table_id: 254 (AAA.BBB) | | mysql-bin.000003 | 587 | Update_rows | 1 | 633 | table_id: 254 flags: STMT_END_F | | mysql-bin.000003 | 633 | Xid | 1 | 664 | COMMIT /* xid=1778 */ | | mysql-bin.000003 | 664 | Anonymous_Gtid | 1 | 729 | SET @@SESSION.GTID_NEXT= ‘ANONYMOUS‘ | | mysql-bin.000003 | 729 | Query | 1 | 818 | drop database AAA | +------------------+-----+----------------+-----------+-------------+-----------------------------------------+ 14 rows in set (0.00 sec)
从中,我们可以看见,最后一个命令正式删除数据的操作。
所以,先恢复全量备份的数据库文件AAA.sql, 在从增量备份文件mysql-bin.000003,恢复文件。因为恢复文件过程中,依然要在binlog中记录,所以首先要刷新binlog文件:
mysql> flush logs; Query OK, 0 rows affected (0.02 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000004 | 154 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
这样,恢复过程中的记录就不会再记录到mysql-bin.000003中,造成死循环了。并且,在恢复过程中,一定要关闭对数据库AAA的操作。
首先,手动创建数据库AAA,然后使用恢复全量文件AAA.sql:
mysql> create database AAA; Query OK, 1 row affected (0.00 sec) mysql> use AAA; Database changed mysql> source /home/xu/AAA.sql Query OK, 0 rows affected (0.00 sec) (…………………………………………………………………………………………) Query OK, 0 rows affected (0.00 sec)
此时,查询数据库,有如下结果:
mysql> select * from BBB; +------+ | id | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.00 sec)
接着,从增量文件mysql-bin.000003中恢复BBB数据库中的其他数据:
恢复语法格式: # mysqlbinlog mysql-bin.0000xx | mysql -u用户名 -p密码 数据库名 常用选项: --start-position=953 起始pos点 --stop-position=1437 结束pos点 --start-datetime="2013-11-29 13:18:54" 起始时间点 --stop-datetime="2013-11-29 13:21:53" 结束时间点 --database=zyyshop 指定只恢复zyyshop数据库(一台主机上往往有多个数据库,只限本地log日志) 不常用选项: -u --user=name Connect to the remote server as username.连接到远程主机的用户名 -p --password[=name] Password to connect to remote server.连接到远程主机的密码 -h --host=name Get the binlog from server.从远程主机上获取binlog日志 --read-from-remote-server Read binary logs from a MySQL server.从某个MySQL服务器上读取binlog日志
所以,这里恢复命令是:
[email protected]:/var/log/mysql# mysqlbinlog --stop-position=729 --database=AAA /var/log/mysql/mysql-bin.000003 | mysql -uroot -p123456 -v AAA
注意,在恢复的时候,一定要注意--stop-position这个命令,不然,很可能会使得drop命令还被执行。
再观察数据库,可以看到数据库恢复成功:
mysql> select * from BBB; +------+ | id | +------+ | 1 | | 2 | | 5 | | 4 | +------+ 4 rows in set (0.00 sec)
5.通过脚本实现定时的备份
全量备份的脚本如下:
#!/bin/bash export LANG=en_US.UTF-8 BakDir=/home/xu/mysql/backup LogFile=/home/xu/mysql/backup/bak.log Date=`date +%Y%m%d%H%M%S` Begin=`date +"%Y年%m月%d日 %H:%M:%S"` cd $BakDir DumpFile=$Date.sql GZDumpFile=$Date.sql.tgz #--databases,指定数据库,所有表格的表结构及其数据 #--flush-logs,产生新的日志文件,binlog文件,这个在后面的增量备份有讲到过 #--delete-master-logs,删掉原来的日志文件,binlog文件 #DumpFile是要备份的目标文件 mysqldump -uroot -p123456 --databases wordpressdb --flush-logs --single-transaction > $DumpFile #tar -czvf $GZDumpFile $DumpFile #rm $DumpFile #只保留过去四周的数据库内容 count=$(ls -l *.sql |wc -l) if [ $count -ge 5 ] then file=$(ls -l *.sql |awk ‘{print $9}‘|awk ‘NR==1‘) rm -f $file fi Last=`date +"%Y年%m月%d日 %H:%M:%S"` echo 开始:$Begin 结束:$Last $GZDumpFile succ >> $LogFile #恢复命令:在MySQL命令行里面使用source命令 mysql> source /home/xu/mysql/backup/20180804104810.sql
然后,通过crontab来设置定时运行:
vi /etc/crontab #每个星期日凌晨3:00执行完全备份脚本 0 3 * * 0 /......../databak.sh >/dev/null 2>&1
使上述定时任务生效:
crontab /etc/crontab
以上是关于安全的web服务器——使用mysqldump和mysqlbinlog实现MySQL全量与增量备份的主要内容,如果未能解决你的问题,请参考以下文章