工作生活

走向DBA之主从复制(监控及故障处理)

2019-06-30  本文已影响0人  国王12

52为主库,51,53为从库

查看主库(52)线程

db02 [(none)]>show processlist;
+----+------+-----------------+------+------------------+------+---------------------------------------------------------------+------------------+
| Id | User | Host            | db   | Command          | Time | State                                                         | Info             |
+----+------+-----------------+------+------------------+------+---------------------------------------------------------------+------------------+
|  3 | repl | 10.0.0.53:19273 | NULL | Binlog Dump GTID | 2225 | Master has sent all binlog to slave; waiting for more updates | NULL             |
| 63 | root | localhost       | NULL | Query            |    0 | starting                                                      | show processlist |
| 65 | repl | 10.0.0.51:8447  | NULL | Binlog Dump      |  466 | Master has sent all binlog to slave; waiting for more updates | NULL             |
+----+------+-----------------+------+------------------+------+---------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
#从库Command列出现binlog dump为正常

查看从库状态(拿从库51举例):

db01 [(none)]>show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.0.0.52                             主库IP
                  Master_User: repl                                  复制用户名(连接主库的用户)
                  Master_Port: 3306                                  主库的端口
                Connect_Retry: 10                                    断链之后重试次数
              Master_Log_File: mysql-bin.000004                     已经获取到binlog的文件名
          Read_Master_Log_Pos: 827                                  已经获取到的binlog位置号
               Relay_Log_File: db01-relay-bin.000004                从库已经运行过的relaylog的文件名
                Relay_Log_Pos: 472                                  从库已经运行过的relay的位置号
        Relay_Master_Log_File: mysql-bin.000004                     主库当前最新binlog文件名
             Slave_IO_Running: Yes                                  从库IO线程状态
            Slave_SQL_Running: Yes                                  从库SQL线程状态
                         省略若干行
#看到Slave_IO_Running,Slave_SQL_Running状态为yes,即代表主从状态正常

一、IO线程故障:

分析:IO线程干了啥:

1.连接主库
2.请求新的binlog
3.写relaylog
4.更新master.info

IO线程故障具体解决:

1.连接主库连接不上  :
状态:
Slave_IO_Running: Connecting

原因:
网络不通
防火墙
IP不对
port不对   端口
用户,密码不对
链接数上限
skip_name_resolve

处理思路:
手动连接测试,看看是哪一块出的问题,修改change master to 信息即可

举例:
[root@db01 ~] mysql -urepl -p123 -h 10.0.0.51 -P 3308   --->端口问题
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1130 (HY000): Host 'db01' is not allowed to connect to this MySQL server

解决(51从库操作):
mysql> stop slave;         停止主从复制
mysql> reset slave all;    关闭主从复制
重新录入连接主库的信息
mysql> CHANGE MASTER TO    
  MASTER_HOST='10.0.0.52',
  MASTER_USER='repl',
  MASTER_PASSWORD='123456',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='mysql-bin.000004',
  MASTER_LOG_POS=194,
  MASTER_CONNECT_RETRY=10;
注意:binlog文件名和position号可在主库使用show master status \G查看
还需要把数据差补上
mysql> start slave;   启动主从
状态:
IO线程NO
Slave_IO_Running: NO

原因:
从库信息
日志名不对  
Master_Log_File: mysql-bin.000001     已经获取得到binlog的文件名
Read_Master_Log_Pos: 444              已经获取得到binlog的位置号
 把这些号和备份信息的号对比,看看对不对
 
日志损坏   
比如:主库 reset master; 就是主库清空日志了,从001开始了,日志号对不上了从库比主库日志还新呢
解决:
关闭从库的主从状态,重新开启,修改change master
stop slave;
reset slave all ;
mysql> CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=675,
MASTER_CONNECT_RETRY=10;

 mysql> start slave;
 注意,既然主库日志从1开始了,那么position号要从154开始同步,因为154之前是默认开头,不用同步

日志不连续

server_id  重复 解决:重亲录入,方法在上边

二、SQL线程故障

分析:SQL线程都干啥了?

读relay-log.info
读delay-log,并执行日志
更新relay-log.info

以上文件损坏,最好是重新构建主从
为什么一条SQL语句执行不成功?
1.主从数据库版本差异较大
2.主从数据库配置参数不一致(如:sql_mode等)
3.想要创建的对象已经存在
4.想要删除或修改的对象不存在
5.主键冲突
6.DML语句不符合表定义约束

从库被操作了

解决:万能方法:

设置从库只读,防止写入。
做成多谢分离结构

三、主从延时原因分析

(被动)从库延时主库的时间:
Seconds_Behind_Master: 0        从库延时主库的时间(秒为单位)

3.1主库方面造成主从延时:

1.语句执行之后,日志写入不及时       
       sync_binlog=1;  即表示语句已提交,立即刷写磁盘,5.6版本以后
2.主库并发业务较高
      硬件升级
      分布式架构
3.从库太多
      不要太多从库
4.对于传统的复制,(Classic Replication),主库是有能力并发运行事务的,但是
在Dump_T在传输日志的时候,是以事件为单元传输日志的,所以导致事务的传输工作是串
行方式的,这时在主库TPS很高时,会产生比较大的主从延时 
     处理:从5.6卡开始加入了GTID,在复制时,可以将原来串行的传输模式变成并行的。
     除了GTID的支持,还需要双一来保证
     这种工作模式叫做  group commit
     在同一时刻并发的事务,可以一起传输。

3.2从库方面造成主从延时

对于传统的复制,(Classic Replication)
SQL线程只有一个,所以只能串行执行relay的事务

解决:多加几个SQL线程
在5.6中出现了多线程SQL(只能针对不同库下才能并发)基于databases级别的多线程SQL
到5.7中加入了MTS,才真正实现了事务级别的并发SQL线程

四、延时从库(手工配置的)

4.1数据损坏的原因:

物理损坏
       磁盘坏了,服务器炸了等等
逻辑损坏
       drop,内部删除了
对于传统的主从复制,比较擅长处理物理损坏,不擅长逻辑损坏。

4.2设计理念:

对SQL线程进行延时(该传日志传日志,该收日志收日志,晚点执行就行了)

4.3延时多久合适?

一般:3-6小时,主要还是根据当从发现删除操作到运维人原反应解决的时间。

4.4如何设置延时?(从库设置)

mysql>stop slave;                            关闭主从
mysql>CHANGE MASTER TO MASTER_DELAY = 300;   设置延时间
mysql>start slave;                           启动主从
mysql> show slave status \G                  查看状态

SQL_Delay: 300                              延时三百秒
SQL_Remaining_Delay: NULL                   还有多久执行

4.5如何使用延时从库?

4.5.1故障模拟:

mysql -S /data/3307/mysql.sock
create database delay charset utf8mb4;
use delay;
create table t1(id int);
insert into t1 values(1),(2),(3);
commit;
drop database delay;
commit;

4.5.2发现了drop

思路:
1.停止SQL线程,停止主从业务
2.模拟SQL手工恢复relaylog到drop之前的位置点
3.截取relaylog日志(找到起点和终点)
    起点:relay-log.info记录了上次SQL线程最后执行的位置点
    终点:drop操作前
4.恢复截取日志,验证数据可用性。

4.5.3处理:

1.停从库的SQL线程
    mysql> stop slave sql_thread;   
2. 查起点和终点 mysql> show slave status \G
Relay_Log_File: mysql52-relay-bin.000002   停线程时文件名
 Relay_Log_Pos: 320                         postion号名
 000002文件320为起点

show relaylog events in 'mysql52-relay-bin.000002';    找终点(drop前)

4.5.4截取日志

mysqlbinlog --start-position=320 --stop-position=992 /data/3308/data/mysql52-relay-bin.000002>/tmp/relay.sql
起点和终点都找到了,进行备份

4.5.5恢复数据

mysql -S /data/3308/mysql.sock
mysql> set sql_log_bin=0;
mysql> source /tmp/relay.sql;
mysql> set sql_lob_bin=1;

4.5.6将从库替换为主库,对外服务

stop slave;       停止主从
reset slave all;   关闭主从
将业务引向这台服务器

4.5.7补偿原主库数据和新主库保持一致并重新构建主从

上课的解决方法:
把从库多出来的那个库删掉
stop slave;          停掉主从
reset slave all;      关闭主从
mysql> show master status;     查看主库的position号和日志文件名

CHANGE MASTER TO
  MASTER_HOST='10.0.0.51',
  MASTER_USER='repl',
  MASTER_PASSWORD='123456',
  MASTER_PORT=3307,
  MASTER_LOG_FILE='mysql-bin.000009',
  MASTER_LOG_POS=154,
  MASTER_CONNECT_RETRY=10;            信息修改够重新建立主从
mysql> start slave;                 启动主从

五、过滤复制

应用场景:

把某一项业务或某一个或多个库的数据复制在一台服务器上时,需要过滤复制

从主库设置(了解)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000009 |      154 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
binlog_do_db                 白名单
binlog_ignore_db             黑名单
写到配置文件即可

从从库下手(常用)

是在SQL线程进行回放日志时,进行控制日志,即日志该接收接收,当SQL线程执行时进行过滤,匹配则执行,不匹配则不执行
show slave status \G
Replicate_Do_DB:              库级别的白名单
Replicate_Ignore_DB:          库级别的黑名单

Replicate_Do_Table:           表级别的白名单
Replicate_Ignore_Table:       表级别的黑名单

Replicate_Wild_Do_Table:          
Replicate_Wild_Ignore_Table: 

举例:

只需要复制xyz库的数据到从库
解决:
只需要把replicate_do_db=xyz 写到从库的my.cnf
若果想过滤多个库,那么在配置文件写多行即可。如:
replicate_do_db=xyz
replicate_do_db=abc
replicate_do_db=jqx
然后重启即可
查看:
show slave status \G
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: xyz

六、半同步复制

略。。。

上一篇下一篇

猜你喜欢

热点阅读