>

Mysql主从复制

- 编辑:金沙国际平台登录 -

Mysql主从复制

刚管理完“挖矿”事件,在做最终三个MySQL NBU备份的时候,发掘从库不平时,好奇的是怎么主从状态极其未有报告急察方呢?先不管这么多了,管理了那么些主题素材再完善告急内容。

主从复制:MySQL5.6方始主从复制有三种方式:基于日志(binlog卡塔尔国;基于GTID(全局职业标示符卡塔 尔(阿拉伯语:قطر‎;

意气风发、错误音讯

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

从库show slave status G见到的错误音讯如下:

    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端顺序执    行日志中具备的记录及各样操作;

Slave_IO_Running: No
Slave_SQL_Running: Yes
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the first event 'mysql-bin.000081' at 480141113, the last event read from './mysql-bin.000081' at 4, the last byte read from './mysql-bin.000081' at 4.'

  Mysql复制基本进程如下:
    1> Slave上边的IO线程连接上Master,而且呼吁从钦定日志文件的钦定地点(或许从最牵头的日志)之后的日志内容;
    2>Master接纳到来自Slave的IO线程须要后,通过承受复制的IO线程依据供给的音讯内定日志内定地方后的日记音信,再次来到给Slave端的IO线程,重返的信                   息个中除了日志全部包括的消息外,还包涵这次再次回到音讯在Master段的Binary log(二进制)文件名称以至Binary log(二进制卡塔 尔(英语:State of Qatar)的地点.
    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语句;**

二、错误原因

                图片 1

那边见到从库的io_thread已经甘休,错误编号是1236,具体是由于读取主库的binlog日志地方(the first event 'mysql-bin.000081' at 480141113, the last event read from './mysql-bin.000081' at 4卡塔 尔(英语:State of Qatar)不对诱致基本失败建设构造战败。

2》主干意况

三、技术方案

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

1.反省从库状态甚至读取、试行的binlog音讯

    # : 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> show slave status G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: xx.xx.xx.xx
                  Master_User: username
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000081
          Read_Master_Log_Pos: 480141113
               Relay_Log_File: mysql9017-relay-bin.000163
                Relay_Log_Pos: 480141259
        Relay_Master_Log_File: mysql-bin.000081
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 480141113
              Relay_Log_Space: 480141462
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from impossible position; the first event 'mysql-bin.000081' at 480141113, the last event read from './mysql-bin.000081' at 4, the last byte read from './mysql-bin.000081' at 4.'
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 17
1 row in set (0.00 sec)

                 图片 2

2.查看主库的binlog内容

                mysql>unlock tables;

[backup]# mysqlbinlog  mysql-bin.000081 >mysql-bin.log

4》Slave(从)操作

图片 3

  #: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;

看样子主库binlog日志mysql-bin.000081最大的pos为480140557,但从库要读取的是'mysql-bin.000081' at 480141113,明显从库要读的pos值比主库本人存在的pos值大,招致读取不到,进而战败。

***           排错:
    如果show slave statusG;报错是因为尚未找到科学的端口号,则足以在这里个平素助长定义
    master_port=3306,

可经过上面语句查看binlog的pos信息和日志内容
mysql> show binlog events in  'mysql-bin.000081' from 480140557 limit 10;       
Empty set (0.04 sec)
3.改造从库的协作地方,完结数据再次联合

  检查从服务器复制功能状态:  排错:
    如果show slave statusG;报错是因为没有找到科学的端口号,则能够在此个一贯助长定义
    master_port=3306,

 主库:

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

mysqlbinlog  mysql-bin.000082  |more

           图片 4

从库:

                      注:Slave_IO及Slave_SQL进度必需不奇怪运作,即YES状态,不然都是指鹿为马的景色(如:此中一个NO均属不当)。

change master to master_host='xx.xx.xx.xx',master_user='username',master_port=3306,master_password='password',master_log_file='mysql-bin.000082',master_log_pos=4;

5》测量试验数据同步

start slave;

***  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’);

show slave status G

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

主干同步寻常

6》多如牛毛故障解决

图片 5

***  1>经常的特别只必要跳过一步就能够复苏
        模拟故障,创立主从复制以前.在主上创立贰个CC库,在开启主从复制,从的IO都以为YES后,在主上创制二个gongda库,看看从库是不是同步成功?
     假如成功,接下去模拟故障.在主上将CC删除掉.在从看slave状态是还是不是就从头报错了??
  消除方法如下:
    > stop slave;
    >SET GLOBAL sql_slave_skip_counter = 1; 境遇错误直接跳过,继续上涨
    > start slave;

4.主库参数改正

  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;***

 引致那个原因非常的大程度上是由于宗意在一块儿的进程中,主库万分断电,引致内部存款和储蓄器数据传输到从库但没有提交到binlog日志,即主库 sync_binlog设置大概不不奇怪,在主库检查参数设置:

        3>主键冲突、表已存在等错误代码如1062,1032,1060等,能够在mysql主配置文件钦命
    略过此类十分并世袭下条sql同步,那样也足以免止过多为主同步的至极中断
    [mysqld]
    slave-skip-errors = 1062,1032,1060

mysql> show global variables like '%sync_binlog%';                       
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 0     |
+---------------+-------+
1 row in set (0.00 sec)

*** ======================平淡无奇错误场景描述以致缓慢解决格局
GTID复制情势手动跳过复制错误

果真其值是 0,不主动同步binlog cache的数据到磁盘,而依靠操作系统自身不许时把文件内容 flush 到磁盘。设为 1 最安全,在种种语句或作业后同盟一回 binary log,纵然在崩溃时也最多有失一个口舌或业务的日志,但就此也最慢。这里安装为0,断电的情形下促成binlog cache数据错过未有写入主库的binlog,但binlog新闻已联合至从库。这种场馆轻易变成基本数据不一致等,所以固然恢复生机基本数据后,依然要透过着力数据比较校验数据的生龙活虎致性。

  1.现象描述:
    A 服务器(Master)
    B 服务器(Slave)
  在A 服务器上开创多个库叫做aatest
  在B 服务器上查看是或不是同步,

mysql> set global sync_binlog=1;
Query OK, 0 rows affected (0.00 sec)

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

改动配置文件my.cnf设置sync_binlog=1

    3.起来尝试苏醒,使用binlog的跳过方式,尝试跳过大张旗鼓(并未有得到解决,但是付出了升迁)**    **

5.主从数额校验

*              当备库复制出错开上下班时间,传统的跳过错误的办法是安装sql_slave_skip_counter,然后再START SLAVE。*但即使打开了GTID,就能够设置战败:**

 pt-table-checksum h=master_ipaddr,u=username,p='password',P=mysql_port --nocheck-binlog-format --recursion-method=hosts

***    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***

pt-table-checksum h=master_ipaddr,u=username,p='password',P=mysql_port --nocheck-binlog-format --recursion-method=hosts  
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
08-03T17:49:29      0      0      595       1       0   0.186 user.hole

*** *4.经过GTID的主意跳过业务,得到解决。**

里头--recursion-method有几种艺术查看从库音信,这里运用的是hosts形式,必要在从库参与如下参数,方可在主库实施show slave hosts查看从库的音讯

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

report_host=slave_ip

  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
            << 我们将第三个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]

report_port=slave_port

    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

METHOD       USES
===========  =============================================
processlist  SHOW PROCESSLIST
hosts        SHOW SLAVE HOSTS
cluster      SHOW STATUS LIKE 'wsrep_incoming_addresses'
dsn=DSN      DSNs from a table
none         Do not find slaves

    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'/*!*/;

 


6.innodb_flush_log_at_trx_commit参数扩大

**     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)

innodb_flush_log_at_trx_commit 参数指定了 InnoDB 在事务提交后的日志写入频率。这么说其实并不严谨,且看其不同取值的意义和表现。

    当 innodb_flush_log_at_trx_commit 取值为 0 的时候,log buffer 会 每秒写入到日志文件并刷写(flush)到磁盘。但每次事务提交不会有任何影响,也就是 log buffer 的刷写操作和事务提交操作没有关系。在这种情况下,MySQL性能最好,但如果 mysqld 进程崩溃,通常会导致最后 1s 的日志丢失。
    当取值为 1 时,每次事务提交时,log buffer 会被写入到日志文件并刷写到磁盘。这也是默认值。这是最安全的配置,但由于每次事务都需要进行磁盘I/O,所以也最慢。
    当取值为 2 时,每次事务提交会写入日志文件,但并不会立即刷写到磁盘,日志文件会每秒刷写一次到磁盘。这时如果 mysqld 进程崩溃,由于日志已经写入到系统缓存,所以并不会丢失数据;在操作系统崩溃的情况下,通常会导致最后 1s 的日志丢失。

    mysql> START SLAVE;
    再查看show slave status,就能开采错误事务已经被跳过了。这种艺术的原理相当粗略,空事务产生的GTID加入到GTID_EXECUTED中,这一定于告诉                备库,那几个GTID对应的事务已经管理了;**

 

本文由 数据库发布,转载请注明来源:Mysql主从复制