美文网首页
MySQL复制中的管理技巧

MySQL复制中的管理技巧

作者: 显卡hg | 来源:发表于2017-12-17 23:16 被阅读0次

    复制中断处理

    • 1677错误
      • 第一种将主库改成statement格式
      • 第二种在从库设置slave_type_conversions
    • 从库出现写入数据,把自增ID占用:1062错误
      • 将从库该条数据删除
      • 能确定数据一致也可以跳过该错误
    • 从库上出现少数据,delete,update操作时,找不到相应的记录,出现1032错误
      • delete可以跳过错误
      • update只能补数据,在master的binlog中解析出哪个位置出错了,将这条数据插入,主要是主键个非空列,开启复制sql_thread,查看status
    • 从库gtid值大于主库gtid值
      • 有可能主库被reset了
      • 新回复的从库将auto.cnf也恢复了,binlog还删除了,也有可能会出现这种场景

    复制延迟排查

    • 搞明白当前的数据库在干什么
      • show processlist;
      • show slave status\G定位到sql_thread执行到位置
        • io_tread同步到主库的binlog位置:Master_Log_File;Read_Master_Log_Pos
        • sql_thread重放到对应主库的binlog位置:Relay_Master_Log_File;Exec_Master_Log_Pos
        • Seconds_Behind_Master:这个值是怎么计算的?
          • io_thread.event.timestamp-sql_thread.event.timestamp 单位秒
    • 查看当前的SQL状态
      • 机器负载很高
        • 索引不合理!!!
        • Statement索引不合理,造成同步延迟
          • mysql>pager more
          • mysql>show processlist;
            • 可以直接用select * from information_schema.processlist where 1=1 order by TIME desc limit 10;
            • USER不是sys的,感觉没什么问题的,时间太长快死掉的连接都可以杀掉
          • 在从库上能看到执行的SQL都有问题的!!!
    • 利用perf top 查看MySQL的调度情况
      • perf top -p `pidof mysqld`
      • 利用Google
      • 利用源码定位出问题的地方
    • 延迟现象一
      • Seconds_Behind_Master一直在增大,但Exec_master_log_pos就是卡着不动
      • 解析sql_thread执行的binlog
      • mysqlbinlog -v --base64-output=decode=rows --start-position=xxx mysql-bin.xxxx
      • 去主库上面找
        • Relay_Master_Log_File,Exec_Master_Log_Pos这两个参数定位
      • 在从库上面找
        • Relay_Log_File,Relay_Log_Pos这两个参数
      • 大事务卡的两个原因
        • 真的是大事务等待,一次更新50W行以上,坐等
        • 更新这个表可能没有索引
          • stop slave不了可以mysqladmin -S/mysql3306.sock shutdown
          • 关闭都关闭不了,只能kill -9,从库这么干,主库还是不要这么干
          • 重启mysql,重建索引,之后start slave

    如何避免延迟

    • 从库的配置适当高一点
    • 使用MySQL5.7开启并行复制
    • 表结构设计时,一定要有主键,而且主键要短小
    • 使用新型硬件:PCI-E&SSD类设备
    • 程序端适当的Cache,减少数据库的压力

    复制结构调整Tips

    • 场景
    • 将下图中的机器加内存,并修改buffer pool,业务暂停时间小于1分钟


    • 凌晨读写压力不大的情况下,可以考虑将读写都放在M上
    • 将s1->stop slave;
    • s1,s11,s12,s13全部shutdown,加内存,修改buffer pool
    • 在s1和M上装keepalived,vip先指到M上,之后停掉M,查看vip是否指到s1上
    • 如果是gtid复制,M启动后直接change master指到s1就可以
      • 在将s11,s13,M都指向s12就ok了
    • 如果是传统复制,要经过一下几步
      • 在vip指过去之前在s1上执行show master status;
      • sleep 1;
      • show master status;结果没变化可以将结果保存到一个文件中
      • show master status>/tmp/1.log
      • M启动后change master to指s1就可以
      • 将s11,s13,M指向s12有两种办法
      • 第一种
        • 可以手工制造个错误,使s11,s12,s13,M都停在同一个位置
        • 在s12上执行show master status>/tmp/1.log
        • 在将s11,s13,M都指向s12就ok了
        • 之后再s12上跳过错误或者将错误修复
      • 第二种
        • 将s11,s12,s13,M全部停掉sql_thread
        • 在s1上执行show master status;
        • s11,s12,s13,M执行start slave sql_thread until master_log_file='xxx',master_log_pos=xxx;
        • 使s11,s12,s13,M机器都停在s1执行的show master status节点上
        • 在s12上执行show master status>/tmp/1.log
        • 在将s11,s13,M都指向s12就ok了
    • 将级联复制改成正常的一级复制


    • gtid可以直接change过去
    • 传统复制
      • 在s1上执行stop slave;
      • 在s1上查看show slave status;
      • 在s11上的change master语句,host,port指定到M上
      • master_log_file='Relay_Master_Log_File' #在s1上执行show slave status查看出来的
      • master_log_pos=Exec_Master_Log_Pos #在s1上执行show slave status查看出来的
      • s2,s21同上
      • 将所有的从库开启复制start slave
    • 假设s1机器电源坏了,不能登录,将s11机器挂到M下或者挂到s2下,怎么搞定?
      • gtid可以直接change master过去
      • 传统复制
        • 一种是将s21机器复制一份数据将s11机器还原,挂到s2下
        • 另一种是不需要重新备份
          • 解析s21机器的mysql-binlog,找到最后一个M库的server_id对应的事务,在这个事务上面找到它对应的timestamp,开启中继日志情况下server_id和timestamp具有传递性
          • 解析出timestamp对应的时间,去M机器上面找到对应的mysql-binlog,大概找到这个时间是写入的哪个binlog,可以用ls查看
          • 解析这个binlog,在这个binlog中查找上述的timestamp,找到对应的事务,要和从库上的那个事务语句一样才可以,查看一下从库的这个事物执行完没有(commit还是没commit),如果没执行完就要记录这个事物begin之前的log_pos,执行完了就记录下一个事务开始的log_pos
          • 将上述的binlog和log_pos写入到从库的change master to上面,开启复制,就可以将机器挂到M下面了

    相关文章

      网友评论

          本文标题:MySQL复制中的管理技巧

          本文链接:https://www.haomeiwen.com/subject/liduwxtx.html