• Mysql主从复制


    主从复制:MySQL5.6开始主从复制有两种方式:基于日志(binlog);基于GTID(全局事务标示符);

    1》基于日志(binlog)主从复制原理:

        Mysql的Replication是一个异步复制的过程,从一个Mysql instace(我们称成之为:Master)复制另外一个Mysqlinstance(我们称为slave),在Master与 slave     之间实现整个复制的过程是由三个线程来完成的,其中两个线程(sql线程和IO线程)在Slave端,另外一个线程(IO线程0在Master端.)要实MysqlReplication
       首先必须打开Master端的Binary Log(就是打开bin-log功能)否则无法实现,整个的复制过程实际上就是Slave从Master端获取binlog日志然后再slave端顺序执    行日志中所有的记录及各种操作;

      Mysql复制基本过程如下:
        1> Slave上面的IO线程连接上Master,并且请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
        2>Master接收到来自Slave的IO线程请求后,通过负责复制的IO线程根据请求的信息指定日志指定位置后的日志信息,返回给Slave端的IO线程,返回的信                   息当中除了日志所有包含的信息外,还包括本次返回信息在Master段的Binary log(二进制)文件名称以及Binary log(二进制)的位置.
        3>Slave的IO 线程接收到master返回的信息后,将接收到的日志内容一次写入slave端的Relay log中继日志文件,(mysql-relay-bin.xx)的最末端,并且将                     读取到的Master端的bin-log的文件和位置记录,纪录到 master-info文件当中,以方便下一次读取的时候能够清楚的告诉Master 我需要从某个bin-lo
                       g的哪个位置开始往后的日志内容,请发给我;
        4>Slave的SQL线程检测到Relay Log中心增加了内容后,会马上解析Master 二进制日志文件中的内容执行里面的Query语句;

                    

    2》主从环境

       Master IP: 192.168.1。106
         Slave IP: 192.168.1。110
            在Master和Slave上安装Mysql
    3》
    Master(主)操作

        # : vim /etc/my.cnf
        #log_slave_updates 注释掉这行
        server-id=1 将id号改为1
        #mysql –uroot –p –h localhost
        mysql>grant replication slave on *.* to 'admin'@'192.168.1.106' identified by '123456'; #给13slave进行授权复制
        mysql>flush tables with read lock;
        mysql>show master status;

                     

                    mysql>unlock tables;

    4》Slave(从)操作

      #:vim /etc/my.cnf
      server-id=2 #将server_id改为2
      #mysql –uroot –p –h localhost
      mysql>stop slave;
      mysql>change master to
      master_host='192.168.100.160',
      master_user='admin',
      master_password='123456',
      master_log_file='masterlog.000001',
      master_log_pos=120;
      mysql>start slave;
      mysql>show slave statusG;

               排错:
        如果show slave statusG;报错是因为没有找到正确的端口号,则可以在这个直接添加定义
        master_port=3306,

      检查从服务器复制功能状态:  排错:
        如果show slave statusG;报错是因为没有找到正确的端口号,则可以在这个直接添加定义
        master_port=3306,

      检查从服务器复制功能状态:

               

                          注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。

    5》测试数据同步

      1>在Master创建一个库表插入一条数据
        #mysql –uroot –p –h localhost
        Mysql->create database zytest;
        Mysql->create table aa(
        User_id int,
        User_name varchar(10));
        Mysql->inster into aa values(‘11’,’alvin’);

      2>在从上查看同步情况
        #mysql –uroot –p –h localhost
        Mysql->show slave statusG;
        Mysql->show databases;

    6》常见故障解决

      1>一般的异常只需要跳过一步即可恢复
            模拟故障,创建主从复制之前.在主上创建一个CC库,在开启主从复制,从的IO都是为YES后,在主上创建一个gongda库,看看从库是否同步成功?
         如果成功,接下来模拟故障.在主上将CC删除掉.在从看slave状态是不是就开始报错了??
      解决方法如下:
        > stop slave;
        >SET GLOBAL sql_slave_skip_counter = 1; 遇到错误直接跳过,继续恢复
        > start slave;

      2>断电导致主从不能同步时,通主库的最后一个bin-log日志进行恢复
        在主库服务器上,mysqlbinlog mysql-bin.xxxx > binxxxx.txt
                  tail -n 100000 binxxxx.txt > tail-binxxxx.txt
                vim tail-binxxxx.txt 打开tail-binxxxx.txt文件找到最后一个postion值
        然后在从库上,change host to 相应正确的值
                >stop slave;
                >change master to master_host='ip', master_user='username', master_password='password',
                master_log_file='mysql-bin.xxxx', master_log_pos=xxxx;
                >start slave;
                >show slave statusG;

            3>主键冲突、表已存在等错误代码如1062,1032,1060等,可以在mysql主配置文件指定
        略过此类异常并继续下条sql同步,这样也可以避免很多主从同步的异常中断
        [mysqld]
        slave-skip-errors = 1062,1032,1060

     ======================常见错误场景描述以及解决方法
    GTID复制模式手动跳过复制错误

      1.场景描述:
        A 服务器(Master)
        B 服务器(Slave)
      在A 服务器上创建一个库叫做aatest
      在B 服务器上查看是否同步,

      2.错误场景描述开始:
        在B 服务器(Slave)将aatest删除掉.
        在A 服务器(Master)将aatest删除掉
      在个时候到B服务器使用show slave statusG;发现SQL 线程阻塞.

        3.开始尝试恢复,使用binlog的跳过方式,尝试跳过恢复(并未得到解决,但是给出了提示)    

                  当备库复制出错时,传统的跳过错误的方法是设置sql_slave_skip_counter,然后再START SLAVE。但如果打开了GTID,就会设置失败:

        mysql> set global sql_slave_skip_counter = 1;
        ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each                transaction that you want to skip, generate an empty transaction with the same GTID as the transaction
       提示的错误信息告诉我们,可以通过生成一个空事务来跳过错误的事务。
            我们手动产生一个备库复制错误:
       Last_SQL_Error: Error ‘Unknown table ‘test.t1” on query. Default database: ‘test’. Query: ‘DROP TABLE `t1` /* generated by server */’
           查看binlog中,该DDL对应的GTID为7a07cd08-ac1b-11e2-9fcf-0010184e9e08:1131

     4.通过GTID的方式跳过事务,得到解决。

      4.1、步骤1:
        在备库上执行:
        mysql>show slave statusG; 查看一下
        Master_Log_File: mysql-bin.000003 这里得到A 服务器(Master)的binlog日志文件

      4.2、步骤2:
      在主库上执行:
        # mysqlbinlog mysql-bin.000003
      找到drop database aatest这个语句动作的上下文,
      我们可以看到有两个SET @@SESSION.GTID_NEXT。

              (1)第一个是drop database aatest之上的:SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:31
         (2)第二个是drop database aatest之下的:SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32
                << 我们将第2个SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32 复制一下>>
        #160817 1:08:06 server id 1 end_log_pos 5484 CRC32 0x963858ea GTID [commit=yes]

        SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:31'/*!*/;
        # at 5484
        #160817 1:08:06 server id 1 end_log_pos 5565 CRC32 0x96ff64da Query thread_id=44exec_time=0 error_code=0

        SET TIMESTAMP=1471367286/*!*/;
        drop database aatest
        /*!*/;
        # at 5565
        #160817 1:08:22 server id 1 end_log_pos 5613 CRC32 0x14d35459 GTID [commit=yes]
        SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32'/*!*/;

         4.3、步骤3:
        在备库上执行:
        mysql> select @@GTID_NEXT 先查询GTID_NEXT 的值
        mysql> STOP SLAVE; 先停止掉SLAVE
        Query OK, 0 rows affected (0.00 sec)
        mysql> SET @@SESSION.GTID_NEXT= '59ebdf10-63c8-11e6-9d86-000c2916dc3f:32‘;将步骤2复制的粘贴运行,
        Query OK, 0 rows affected (0.00 sec)
        mysql> BEGIN; COMMIT; 给一个空的事务,然后在提交。
        Query OK, 0 rows affected (0.00 sec)
        Query OK, 0 rows affected (0.00 sec)
        mysql> SET SESSION GTID_NEXT = AUTOMATIC; 重新设置自动提交事务GTID。
        Query OK, 0 rows affected (0.00 sec)

        mysql> START SLAVE;
        再查看show slave status,就会发现错误事务已经被跳过了。这种方法的原理很简单,空事务产生的GTID加入到GTID_EXECUTED中,这相当于告诉                备库,这个GTID对应的事务已经处理了;

  • 相关阅读:
    Python 生成器相关知识
    openpyxl 模块学习记录
    Python 装饰器相关知识
    Python 闭包的相关知识
    Python 内置函数简单介绍
    Git提交的本地仓库在什么位置
    支付宝公钥,私钥加密解密问题
    字符转义
    pyhton 模拟浏览器实现
    大小端模式 大端存储 小端存储
  • 原文地址:https://www.cnblogs.com/xiaocheche/p/7616193.html
Copyright © 2020-2023  润新知