DBA-主从复制

1、介绍

   依赖于二进制日志的,“实时”备份的一个多节点架构

2、主从复制的前提(搭建主从复制)

   1、至少俩个实例
   2、不同的server_id
   3、主库需要开启二进制日志
   4、主库需要授权一个专用复制用户
   5、主库数据备份
   6、开启专用复制线程

3、搭建主从复制。

   1、准备多实例。   ---->第二章做了
   2、检查server_id
      mysql -S /data/3307/mysql.sock -e "select @@server_id"
      mysql -S /data/3308/mysql.sock -e "select @@server_id"
      mysql -S /data/3309/mysql.sock -e "select @@server_id"
   3、检查主库(3307)的二进制状态
      mysql -S /data/3307/mysql.sock -e "show variables like '%log_bin%'"
   4、主库创建复制用户
      mysql -S /data/3307/mysql.sock
      grant replication slave on *.* to repl@'10.0.0.%' identified by '123'; 创建repl用户并赋予专用的权限。
   5、进行主库数据备份
      mysqldump -S /data/3307/mysql.sock -A --master-data=2 -R -E --triggers --single-transaction >/tmp/full.sql
   6、恢复数据到从库(3308)
      [root@mysql-db01 /data]  mysql -S /data/3308/mysql.sock
       mysql> set sql_log_bin=0;
       mysql> source /tmp/full.sql;
   7、告诉从库一些复制的信息。
      先查看备份的信息:22 -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000004', MASTER_LOG_POS=444;
      然后在MySQL中执行以下数据
      mysql> CHANGE MASTER TO
          ->   MASTER_HOST='10.0.0.51',
          ->   MASTER_USER='repl',
          ->   MASTER_PASSWORD='123',
          ->   MASTER_PORT=3307,
          ->   MASTER_LOG_FILE='mysql-bin.000004',
          ->   MASTER_LOG_POS=444,
          ->   MASTER_CONNECT_RETRY=10;
   8、启动复制线程
      mysql> start slave;
   9、如果 change master to 信息输入错误,咋办?
      mysql> stop slave;
      mysql> reset slave all;
      CHANGE MASTER TO
        MASTER_HOST='10.0.0.51',
        MASTER_USER='repl',
        MASTER_PASSWORD='123',
        MASTER_PORT=3307,
        MASTER_LOG_FILE='mysql-bin.000001',
        MASTER_LOG_POS=444,
        MASTER_CONNECT_RETRY=10;
        mysql> start slave;

4、主从复制工作过程

   1、名词认识
      文件
          主库:binlog
          从库:relay-log 中继日志
               master.info 主库信息文件
               relaylog.info 中继日志应用信息
      线程
          主库:binlog_dump_thread 二进制日志投递线程
                mysql -S /data/3307/mysql.sock -e "show processlist"
          从库:IO_Thread:从库的IO线程:请求和接受binlog
                SQL_Thread:从库的SQL线程:回放日志
   2、工作原理
      1、从库执行change master to语句,会立即将主库信息记录到master.info中;
      2、从库执行start slave语句,会立即生成IO_T和SQL_T;
      3、IO_T读取master.info文件,获取到主库信息。
      4、IO_T连接主库,主库会立即分配一个DUMP_T,进行交互
      5、IO_T根据master.info binlog信息,向主库的DUMP_T请求最新的binlog
      6、主库DUMP_T,经过查询,如果发现有新的,截取并返回给从库的IO_T
      7、从库IO_T会收到binlog,存储在TCP/IP缓存中,并且在网络底层返回ACK
      8、从库IO_T会更新master.info信息,重置binlog位置点信息
      9、从库的IO_T会将binlog,写入到relay-log中
      10、从库SQL_T读取relay-log.info文件,获取上次执行过的位置点
      11、SQL_T按照位置点往下执行relaylog日志
      12、SQL_T执行完成后,重新更新relay-log.info
      13、relaylog有定期自动清理的功能。
      细节:
      主库发生了信息的修改,更新二进制日志完成后,会发送一个信号给DUMP_T,DUMP_T会通知IO_T线程。

5、主从复制监控及故障处理

   1、主从监控
      主库:show processlist;
      从库:show slave status \G
                           
      ----------------------------------------主库的信息---------------------------------------------
                                    Master_Host: 10.0.0.51                   主库的IP
                                    Master_User: repl                        复制用户名
                                    Master_Port: 3307                        主库的端口号
                                  Connect_Retry: 10                          断连之后重试
                                Master_Log_File: mysql-bin.000004            主库获取的binlog的文件名
                            Read_Master_Log_Pos: 444                         已经获取的binlog的位置号

      ----------------------------------------从库的信息---------------------------------------------
                                 Relay_Log_File: mysql-db01-relay-bin.000002 从库已经运行过的relaylog的文件名
                                  Relay_Log_Pos: 320                         从库已经运行过的relaylog的位置点
                          Relay_Master_Log_File: mysql-bin.000004

      -----------------------------------从库复制线程的工作状态---------------------------------------
                               Slave_IO_Running: Yes
                              Slave_SQL_Running: Yes

      --------------------------------------------------------------------------------                  
                                Replicate_Do_DB: 
                            Replicate_Ignore_DB: 
                             Replicate_Do_Table: 
                         Replicate_Ignore_Table: 
                        Replicate_Wild_Do_Table: 
                    Replicate_Wild_Ignore_Table: 

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

      ---------------------------------------从库线程报错的详细信息------------------------------------------
                                  Last_IO_Errno: 0                       IO报错的号码
                                  Last_IO_Error:                         IO报错的具体信息
                                 Last_SQL_Errno: 0                       SQL报错的号码
                                 Last_SQL_Error:                         SQL线程报错的具体原因

      -----------------------------------------------延时从库------------------------------------------
                                      SQL_Delay: 0                       延迟从库设定的时间
                            SQL_Remaining_Delay: NULL                    延迟操作剩余的时间

      ----------------------------------------------GTID复制信息------------------------------------------
                             Retrieved_Gtid_Set:                         接受到的GTID格式
                              Executed_Gtid_Set:                         执行的GTID的个数
      ---------------------------------------------------------------------------------------------------------
   2、主从故障的分析及处理
      1、IO线程故障
         1)、连接主库连接不上
             报错:connecting
             原因:网络不通
                   防火墙
                   IP地址不对
                   port不对
                   用户,密码不对
                   skip_name_resolve
                   连接数上线(151个)
                   
             处理思路:
             查看报错信息:
                          show slave status \G    输出此命令,查看下面几个:
                          Slave_IO_Running: Yes
                          Slave_SQL_Running: Yes
                          Last_IO_Errno: 0
                          Last_IO_Error:
                 分析:
                      [root@mysql-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 'mysql-db01' is not allowed to connect to this MySQL server
                      [root@mysql-db01 ~]  mysql -urepl -p123 -h 10.0.0.52 -P 3307      ------------IP错误
                      mysql: [Warning] Using a password on the command line interface can be insecure.
                      ERROR 2003 (HY000): Can t connect to MySQL server on '10.0.0.52' (113)
                      [root@mysql-db01 ~]  mysql -urepl -p12 -h 10.0.0.51 -P 3307       ------------密码错误
                      mysql: [Warning] Using a password on the command line interface can be insecure.
                      ERROR 1045 (28000): Access denied for user 'repl'@'mysql-db01' (using password: YES)
                      [root@mysql-db01 ~]  mysql -urel -p123 -h 10.0.0.51 -P 3307       ------------用户错误
                      mysql: [Warning] Using a password on the command line interface can be insecure.
                      ERROR 1045 (28000): Access denied for user 'rel'@'mysql-db01' (using password: YES)
                 处理:
                      stop slave;
                      reset slave all;
                      change master to;
                      start slave;
         2)、请求新的binlog
             报错:IO线程变成NO
             原因:日志名报错
                   日志损坏
                   日志不连续
             处理思路:
             日志名报错查看:
                            show slave status \G    输出此命令,查看下面几个:
                            Master_Log_File: mysql-bin.000004
                            Read_Master_Log_Pos: 444
                 处理:和全库备份对比
             日志损坏和不连续:
                 演示:
                      主库:
                           mysql -S /data/3307/mysql.sock
                           mysql> flush logs;
                           mysql> flush logs;
                           mysql> flush logs;
                           mysql> flush logs;
                           mysql> flush logs;
                           mysql> reset master;
                      从库查看报错:
                                   mysql> show slave status \G
                              报错:
                                   Slave_IO_Running: No
                                   Slave_SQL_Running: Yes
                                   Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'could not find next log; the first event 'mysql-bin.000004' at 444, the last event read from '/data/3307/mysql-bin.000009' at 154, the last byte read from '/data/3307/mysql-bin.000009' at 154.'
                        主库创建库:
                                   mysql> create database dd;
                                   mysql> create database dd1;
                                   mysql> create database dd2;
                          从库处理:
                                   mysql> stop slave;
                                   mysql> reset slave all ;
                                   mysql> CHANGE MASTER TO
                                       ->   MASTER_HOST='10.0.0.51',
                                       ->   MASTER_USER='repl',
                                       ->   MASTER_PASSWORD='123',
                                       ->   MASTER_PORT=3307,
                                       ->   MASTER_LOG_FILE='mysql-bin.000001',
                                       ->   MASTER_LOG_POS=154,
                                       ->   MASTER_CONNECT_RETRY=10;
                                   mysql> start slave;
                                   mysql> show slave status \G
         3)、写relaylog
         4)、更新master.info
         5)、server_id重复
      2、SQL线程故障
         原因一:
                读relay-log.info
                读relay-log,并执行日志
                更新relay-log.info
                以上文件损坏,最好是重新构建主从
         原因二:
                为什么一条SQL语句执行不成功
                1)、主从数据库版本差异较大
                2)、主从数据库配置参数不一致(例如:sql_mode等)
                3)、想要创建的对象已经存在
                4)、想要删除或修改的对象不存在
                5)、主键冲突
                6)、DML语句不符合表定义及约束时
                归根结底是在从库写入了
         方法一:
                 stop slave; 
                 set global sql_slave_skip_counter = 1;
                 
                 /etc/my.cnf
                 slave-skip-errors = 1032,1062,1007
                
         方法二:万全的解决 
                 设置从库只读,防止写入
                 使用中间件做成读写分离的架构

6、主从延时原因分析:

   从库延时主库的时间:
   Seconds_Behind_Master:0   从库延时主库的时间(秒为单位)
   1、主库方面:
      1)、日志写入不及时
      2)、sync_binlog=1;
      3)、主库并发业务较高
        "分布式架构"
      4)、从库太多
      5)、级联主从
      对于Classic Replication:
      主库是有能力并发运行事务的,但是在Dump_T在传输日志的时候,是以事件为单元传输日志的,
      所有到时事务的传输工作时串行方式的,这时在主库TPS很高时,会产生比较大的主从延时。
      怎么处理:从5.6开始加入了GTID,在复制时,可以将原来串行的传输模式变成并行的。
                除了GTID支持,还需要双一保证。
       group commit。
   2、从库方面:
      Classic Replication
      SQL    线程只有一个,所有说只能串行执行relay的事务。
      怎么解决?
      多加几个SQL线程
      在5.6中出现database级别的多线程SQL
      只能针对不同库下的事务,才能并发
      在5.7版本加入了MTS才真正实现了事务级别的并发线程SQL

7、延时从库

   1、数据损坏
      1)、物理损坏
      2)、逻辑损坏
      对于传统的主从复制,比较擅长处理物理损坏
   2、设计理念   
      对SQL线程进行延时设置
   3、延时多久合适?
      3-6个小时   
   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
   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;
         发现问题:
                  1、停止SQL线程,停止主库业务
                  2、模拟SQL手工恢复relaylog到drop之前的位置点
                  3、截取relaylog日志,找到起点(relay-log.info)和终点(drop操作)
                  4、恢复截取的日志,验证数据可用性。
         开始处理:
                  1、 关闭SQL线程
                      mysql> stop slave sql_thread;
                  2、 找到起点和终点
                      Relay_Log_File: mysql-db01-relay-bin.000002           名字
                      Relay_Log_Pos: 479                                    起点
                      show relaylog events in 'mysql-db01-relay-bin.000002';
                      | mysql-db01-relay-bin.000002 | 1151 | Query          |         7 |        1710 | drop database delay   
                  3、 截取日志
                      mysqlbinlog --start-position=479 --stop-position=1151 /data/3308/data/mysql-db01-relay-bin.000002 >/tmp/relay.sql
                  4、 恢复
                      mysql -S /data/3308/mysql.sock 
                      set sql_log_bin=0;
                      source /tmp/relay.sql

你可能感兴趣的:(DBA-主从复制)