三月阳光 发表于 2018-9-28 10:38:01

mysql 系列目录

从binlog恢复数据
  1.MySQL 利用SQL线程对Binlog操作
  2.使用 row 格式 binlog 撤销操作

[*](./binlog_undo -f /data/mysql/log-bin.000004 -p 3958 -o binlog.out)  会扫描 /data/mysql/log-bin.000004 从位置 3958 到末尾的所有事务,倒转其中所有事务顺序和每个事务中的语句顺序,并反向所有的操作,把 WRITE 和 DELETE 反转,把 UPDATE 的前后镜像互换,然后将生成后的 binlog 文件写入 binlog.out 中。之后就可以用 mysqlbinlog 工具来回放这个 binlog 来撤销操作了。
  3.mysqlbinlog flashback 5.6完全使用手册与原理
  (MySQL的flashback功能是由淘宝的彭立勋,在MySQL-5.5.18的基础上开发的。随着binlog格式的变动和类型的增加,基于5.5.18的版本,无法用于目前主流的5.6版本的。因此平民软件将该功能移植到5.6版本上,让相关人员对数据库有更强的掌控能力。)
  反转
  insert:event中包含该行数据的每个字段值,删除即可
  delete:event中包含了删除前,该行数据的所有字段值。将删除的数据,重新插入即可
  update:只需将set和where部分调换,即可完成反转。
  多个event闪回
  如果误操作的事务是由多个event组成的,那么必须将整个事务倒序恢复,即从最后一个event恢复到第一个event。
  限制
  该软件利用binlog中记录了操作前的数据镜像和操作后的数据镜像。有如下限制
  1)      binlog_format=row
  2)      只支持insert、update、delete
  3)      不支持drop 、truncate、alter等ddl语句
  结论
  flashback功能,可以在紧急情况下,避免用户漫长的数据库恢复过程。让高可用提升一个级别。
  4.625某电商网站数据库宕机故障解决实录
  全量恢复后,全备的时间点
  增量binlog恢复
  mysqlbinlog --no-defaultsmysql-bin.000014 mysql-bin.000015 --start-datetime='2014-06-24 02:23:00'>bin.sql
  # less bin.sql
  # mysql eshop_ett100 < bin.sql
  5.binlog2sql
  6.案例 - 误删千万的表
  http://blog.51cto.com/dadaman/1933137
mysql主从不一致的情况
  1.隔离级别
  REPEATABLE-READ Statement
  READ COMMITTED Row
  有个特别要注意的问题,如果 binlog_format 为 MIXED,而且使用的是默认隔离级别REPEATABLE-READ,那么会导致主从数据不一致。
  2.MIXED格式来说,在如下情况的时候,binlog会自动转为ROW格式记录
  揪出MySQL延迟上千秒的元凶
  3.MySQL 【Row】下的 Event_type
  在从上执行 查看在执行到主的哪个position被”卡“住
  show binlog events in 'mysql-bin_3306.000011' from 143808509 limit 10;
  好了,回到这次出现问题的地方。为什么会延迟呢?通过 show binlog events 得到的信息中,看到了大量的Write_rows 状态(50万+),说明刚执行了一个大量的插入操作。想知道是怎么样的sql语句,Row模式不能通过 show binlog events 来看,只能通过mysqlbinlog 去看binlog日志:
  mysqlbinlog -vv --start-position=143808509 mysql-bin_3306.000011 | more
  发现是一个脚本在主上执行了一个 insert into tb select * from ta 的操作引发的。可能会有人问,为什么ROW下会出现这个情况,而STATEMENT下不会,这个问题请具体看:MySQL Binlog 【ROW】和【STATEMENT】选择,里面有详细说明。文章里也给出了建议:
  http://www.cnblogs.com/zhoujinyi/archive/2013/01/15/2836131.html
  set session binlog_format=mixed;
  #!/usr/bin/env python
  import MySQLdb
  conn = MySQLdb.connect(host='localhost',user='root',passwd='123456',db='test',port=3306,charset='utf8')
  query = 'insert into t1 select userid from tb_0513'
  cursor = conn.cursor()
  cursor.execute(&quot;set session binlog_format='mixed'&quot;)
  cursor.execute(query)
  print query
  通过命令 show binlog events in '' from pos limit x 得出:
  Mysql对Binlog的处理是以事件为单位的,每一次DML操作可能会产生多次事件,例如对于innodb存储引擎,会额外产生一条QUERY_EVENT(事务的begin语句)以及XID_EVENT(事务提交)。
  在上面的结果中观察得到一个现象:不管表是MyISAM还是Innodb(支持或则不支持事务),都执行了begin...commit的命令。所以通过events的信息中,要看是否是innodb表需要看 Event_type 是不是用Xid 去提交的,是则为innodb。
  具体row的信息请看这里
  http://www.cnblogs.com/zhoujinyi/archive/2013/05/23/3094978.html
  4.在主库运行 LOAD DATA LOCAL INFILE ,主库和从库时这样同步的
  http://www.colabug.com/910166.html MySQL 复制夯住排查以及原理探讨
  这样的故障,归根结底还是研发写的程序还有优化的余地。大批量的数据插入,这在 MySQL 中是不推荐使用的。我们可以这样:第一,一条 SQL 语句插入多条数据;第二,在事务中进行插入处理;第三,分批插入,在程序中设置 auto_commit 为 0,分批插入完成后,手动 COMMIT;第四,需要使用 LOAD DATA LOCAL INFILE 时,设置 sync_binlog 为 1。
主从不一致恢复
  参考
  (Master_Log_File: mysql-bin.000799
  Relay_Master_Log_File: mysql-bin.000799
  Read_Master_Log_Pos: 31212118
  Exec_Master_Log_Pos: 31212118
  Relay_Log_File: ot21-relay-bin.001722
  Relay_Log_Pos: 31212331
  Relay_Log_Space: 31212624)
  5.6
  end_log_pos 有了它,根据pos值,直接就能找到,找到delete那条数据,反做(变成insert)
  大量插入,LOAD DATA LOCAL INFILE
  那么我们可以试着分析 MySQL 的 binlog,看 Pos 为 594374863 的点发生了什么操作
  /usr/local/mysql/bin/mysqlbinlog --no-defaults -v --start-position=&quot;594374863&quot;
  binlog.000283 > /XXX/binlog.sql
  1.备份时不加 –master-data 参数和 –single-transaction。究其原因,–master-data 禁用 –lock-tables 参数,在和 –single-transaction 一起使用时会禁用 –lock-all-tables
  2.replicate-ignore-table=databaseA.tableA 切走从库的流量
  3.同步完成后,需要把从库配置文件中增加的 replicate-ignore-table 参数注释,并重启 MySQL
  5.7
  1.GTID_SKIP(){
  mysql -u$USER -p$PWD -h$HOST -P$PORT -e &quot;stop slave;set session gtid_next='$GTID:$GTID_START';begin;commit;set session gtid_next=&quot;AUTOMATIC&quot;;start slave;&quot;
  }
  mysqlbinlog mysql-bin.001313|grep -C 10 &quot;end_log_pos 19583512&quot;
  stop slave;
  set @@session.gtid_next='b30dcce8-3395-11e6-902b-0050569d58f6:38435158';
  begin;
  commit;
  set @@session.gtid_next=automatic;
  start slave;

[*]全备份后,指定最新的GTID_END  GTID_PURGE(){
  echo &quot;GTID_UUID:$GTID, GTID_START:$GTID_START, GTID_END=%GTID_END&quot;
  mysql -u$USER -p$PWD -h$HOST -P$PORT -e &quot;stop slave;reset slave;reset master;set global gtid_purged='$GTID:$GTID_START-$GTID_END';CHANGE MASTER TO MASTER_HOST='$REPH', MASTER_PORT=$REPP, MASTER_USER='$REP',MASTER_PASSWORD='$REPPWD', master_auto_position=1;start slave;&quot;
  sleep 1
  mysql -u$USER -p$PWD -h$HOST -P$PORT -e &quot;show slave status\G;&quot;
  }
  GTID_PURGE() 当同步发生大量的错误时,使用flush table with read lock锁住主库,记录GTID的事务编号(最后那个,例如后面示例里面的142787),然后数据同步到从库,在参数中加上UUID(空格)起始事务编号(空格)中止事务编号
  原理:purge掉master log中,同步数据的SCN之前的事务,从同步时间点以后开始读取binlog; 这样做的好处是不用去master操作,清理binlog(手抖清理了其他东西就不好了~)
mysql高级功能
  阿里巴巴的异地双活数据中心DRC
  未来可能的应用

[*]通过解析binlog中的行数据,进行增量数据dump;
[*]结合handlersocket进行replication

页: [1]
查看完整版本: mysql 系列目录