前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL执行binlog的两种方法

MySQL执行binlog的两种方法

作者头像
用户1148526
发布2019-05-25 19:38:50
2.5K0
发布2019-05-25 19:38:50
举报
文章被收录于专栏:Hadoop数据仓库Hadoop数据仓库

维护mysql的时候,总会遇到数据库恢复的例子。如果把备份集恢复出来相对比较简单。然而如果遇到恢复到时间点的例子,把一个MySQL实例恢复出来之后,需要执行binlog做增量恢复。 常见的办法是用mysqlbinlog解析binlog,将解析出来的内容重定向到mysql命令行执行。在MySQL手册中也是推荐使用mysqlbinlog工具来实现指定时间点的数据恢复。事实上,这是一个经常“让人郁闷”的办法。更好的办法是,使用MySQL内部复制线程中的SQL Thread来做恢复。

这里先把两种方法的优缺点列出,在通过实验比较两者的性能。

mysqlbinlog方法 优点:

  • 方法简单,无需配置和重启MySQL实例。
  • 有start-datetime、stop-datetime等参数,方便基于时间点的恢复

缺点:

  • 错误处理困难。
  • 不好设置断点。
  • 性能差,只能单线程执行,而且mysqlbinlog解析再通过管道执行,有比较高的性能开销。

SQL Thread方法 优点:

  • 可以随时stop slave,调整一些参数,再start slave。
  • 可以选择忽略一些slave执行报错。
  • 如果mysql版本支持多线程复制,可以使用设置slave_parallel_workers参数启用多个SQL Thread,这么做性能更好。

缺点:

  • 需要修改master.info、hostname-relay-log.info等文件,需要重启实例才会生效。
  • 因为只有UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos子句,基于时间点的恢复时,需要手工把datetime转成pos。

先表明我的观点:在binlog较小时,可以使用mysqlbinlog,否则建议使用MySQL自身复制来恢复binlog。下面是详细实验步骤。 一、环境 Linux 2.6.32 MySQL 5.6.14 xtrabackup 2.2.3 二、前期准备 1. 用xtrabackup做一个全库备份,并应用日志以备库恢复

代码语言:javascript
复制
innobackupex --user=wxy --password=123456 --port=3306 --socket=/tmp/mysql.sock /home/mysql/backup  
innobackupex --apply-log /home/mysql/backup/2015-07-01_09-04-12/  

2. 产生100万条数据和100个binlog文件

代码语言:javascript
复制
-- 建立测试表  
create table t1 (    
    a int not null primary key    
) engine=innodb;    
  
-- 建立生成数据和binlog文件的存储过程  
delimiter $$    
create procedure pCreateNums(cnt int)    
begin    
    declare s int default 1;            
    while s<=cnt do    
        insert into t1 values(s);            
        if mod(s,10000)=0 then           
           commit;  
           flush logs;  
        end if;  
        set s=s+1;  
    end while;    
    commit;  
end $$    
  
-- 执行调用存储过程  
delimiter ;    
call pCreateNums(1000000);     
  
-- 查询验证  
select count(*),min(a),max(a) from t1;  
show binary logs; 

3. 备份binlog文件

代码语言:javascript
复制
cp /usr/local/mysql/data/mysql-bin.* /home/mysql/binlog_bak  
# 删除mysql-bin.index文件  
rm -f /home/mysql/binlog_bak/mysql-bin.index  

4. 用xtrabackup还原备份的数据库

代码语言:javascript
复制
service mysql stop  
rm -rf /usr/local/mysql/data/*  
innobackupex --copy-back /home/mysql/backup/2015-07-01_09-04-12/  

三、用mysqlbinlog执行binlog进行完全恢复

代码语言:javascript
复制
# 启动MySQL服务  
service mysql start  
# 查看需要恢复的起始binlog文件名和位置  
more /home/mysql/backup/2015-07-01_09-04-12/xtrabackup_binlog_info  
cd /home/mysql/binlog_bak  
# 在mysqlbinlog命令中应用xtrabackup_binlog_info中的文件名及其后面产生的所有binlog文件,start-position为xtrabackup_binlog_info中的pos  
mysqlbinlog $(ls -l | awk '{print $9}') --start-position=120 | mysql -u wxy -p123456
代码语言:javascript
复制
-- 执行时间:4分24秒  
-- 查询验证  
select count(*),min(a),max(a) from t1;  

四、用SQL Thread执行binlog(把binlog作为relay-log来执行)进行完全恢复

代码语言:javascript
复制
# 因为缺省情况下,slave应用完relay log就会将relay log文件删除,所以先做一个额外的备份,以免失败的情况丢失binlog  
# 此步骤不是必须的,但强烈建议做  
cp /home/mysql/binlog_bak/* /home/mysql/binlog_bak2  
  
# 编辑my.cnf文件,添加或修改以下参数  
vi /etc/my.cnf  
# relay_log指定到binlog的备份目录  
relay_log = /home/mysql/binlog_bak/mysql-bin  
# 手动启动slave  
skip_slave_start = 1  
# 修改server_id,这步很重要,因为MySQL复制不会应用自身示例产生的SQL  
server_id = 2  
# 生成master.info文件,写入如下内容。这里的内容需要符合规则即可,无需实际内容。  
# 实际上这步只是让MySQL实例启动时认为自己是slave而不是master。  
# 如果没有此文件,start slave sql_thread时会报以下错误  
# ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO  
cat > /usr/local/mysql/data/master.info <<EOF  
23  
dummy.binlog  
4  
dummy.host  
repl  
repl  
3306  
60  
0  
  
  
  
  
  
  
  
  
  
  
0  
1800.000  
  
  
0  
  
  
86400  
  
  
  
  
0  
EOF  
  
# 查看需要恢复的起始文件名和位置  
more /home/mysql/backup/2015-07-01_09-04-12/xtrabackup_binlog_info  
# 生成$DATADIR/relay-log.info文件,第二行改成xtrabackup_binlog_info里的binlog文件名,第三行改成xtrabackup_binlog_info里的pos  
# relay-log.info文件内容规则依赖于MySQL版本,如果内容格式错误,会报以下错误  
# [ERROR] Slave SQL: Slave failed to initialize relay log info structure from the repository, Error_code: 1872  
cat > /usr/local/mysql/data/relay-log.info <<EOF  
7  
/home/mysql/binlog_bak/mysql-bin.000001  
120  
dummy-binlog.1  
0  
0  
0  
1  
1  
EOF  
  
# 在binlog的备份目录生成relay-log-index文件,文件名依赖前面配置的relay_log参数,这里为mysql-bin.index  
# 文件里包含需要执行的所有binlog文件(带绝对路径)  
ls -l /home/mysql/binlog_bak/* | awk '{print $9}' > /home/mysql/binlog_bak/mysql-bin.index  
  
# 启动MySQL服务  
service mysql start
代码语言:javascript
复制
-- 启动SQL Thread线程  
start slave sql_thread;  
-- 通过多次执行show slave status命令查看SQL Thread的执行情况  
show slave status\G  
  
-- 执行时间:35秒  
-- 查询验证  
select count(*),min(a),max(a) from t1; 
代码语言:javascript
复制
-- 删除slave  
stop slave;  
reset slave all;  
代码语言:javascript
复制
# 复员my.cnf配置  
service mysql stop  
vi /etc/my.cnf  
# relay_log = /home/mysql/binlog_bak/mysql-bin  
# skip_slave_start = 1  
server_id = 1  
service mysql start  

五、关于指定时间点的不完全恢复 如果需要执行指定时间点的不完全恢复,mysqlbinlog方法可以直接指定stop-datetime参数。而start slave sql_thread命令只有UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos子句。这时有两种处理方法:

  1. 将除最后一个需要不完全恢复的binlog以外,使用SQL Thread方法,最后一个使用mysqlbinlog方法。
  2. 手工把datetime转成pos,使用SQL Thread方法。下面是一个例子根据datetime找pos的例子

先将binlog日志转换成txt:

代码语言:javascript
复制
mysqlbinlog --start-date="2011-02-27 13:10:12" --stop-date="2011-02-27 13:47:21" jbms_binlog.000002 > temp/002.txt 

功能是将时间段内的日志文件转换成txt,注意binlog和temp文件夹是同一目录下。 查看生成的txt文件,获取编辑位置和时间等数据,然后通过命令:

代码语言:javascript
复制
mysqlbinlog --stop-position="98" jbms_binlog.000002 | mysql -uroot -proot 

即可恢复位置为“98”处操作的数据,其中stop也可以换成start。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年12月27日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档