zoukankan      html  css  js  c++  java
  • 10. 主从复制-主从复制(基于GTID)--附加半同步复制

    select * from user into outfile '/tmp/user.csv' fields terminated by ',' optionally enclosed by '"' lines terminated by '
    ';

    ####参数说明
     into outfile '导出的目录和文件名'
     执行导出的目录和文件名

     fields terminated by '字段间分隔符'
     定义字段间的分隔符

     optionally enclosed by '字段包围符'
     定义包围字段的字符(数值型字段无效)

     lines terminated by '行间分隔符'
     定义每行的分隔符

    1.介绍:

      1.搭建主从复制  ***

      2.主从原理熟悉 *****

      3.主从的故障处理 ******

      4.主从延时       ******

      4.主从的特殊架构的配置和使用

      5.主从架构的演变

    2. 主从复制的介绍

      (1)主从复制基于binlog来实现的

      (2)主库发生新的操作,都会记录binlog

      (3)从库取得主库的binlog 进行回放

      (4)主从复制是异步方式进行的

    3.主从复制的前提(搭建主从复制)

      (1)2个或以上的数据库实例

      (2)主库需要要开启二进制日志

      (3)server_id 要不同,要区分不同的节点

      (4)主库需要建立专用的复制用户

      (5)告诉主库,谁是主库,怎么连接? 人为告诉从库一些复制信息(ip ,port , user, 二进制起点位置)

      (6)从库应该开启专门的复制线程,  线程(三个) : Dump_thread    IO_thread     SQL_thread 

    4. 主从复制搭建过程(生产)

      4.1 准备多实例:略

      4.2 主库检查二级制日志是否开启和server_id也要不同

      4.3 主库创建复制用户

        grant  replication  slave on  *.*  to repl@'172.19.94.%' identified by '123';

      4.4 备份主库

         mysqldump -uroot  -p123 -A -R -E  --triggers --single-transaction --master-data=2  --set-gtid-purged=on  >/tmp/full.sql

      4.5 把主库的数据恢复到从库上

          登录从库

          source  /tmp/full.sql ;

          或者:mysql -uroot -p123 -S /data/mysql.sock  </tmp/full.sql

      4.6 开始开启主从复制

        登录从库     

      help  change master to  # 查看帮助信息
              CHANGE MASTER TO
              MASTER_HOST='172.17.94.207',
              MASTER_USER='repl',
              MASTER_PASSWORD='123',
              MASTER_PORT=3307,
              MASTER_LOG_FILE='mysql-bin.000001',
              MASTER_LOG_POS=154,
              MASTER_CONNECT_RETRY=10;
    或者开了GTID后:
        
            change master to 
            master_host='172.17.94.207',
            master_user='repl',
            master_password='123' ,
            MASTER_PORT=3307
          MASTER_AUTO_POSITION=1;

      4.7 开启复制线程

        从库中:执行  start slave;

      4.8 检查主从复制状态

        show slave status;

      4.9 如果有报错

        1 先停掉从库:stop slave

        2. 再重置从库:reset slave all;

    5.主从复制原理

      主库: binlog       (binlog_dump Thread  :主库中所用到的线程)

      从库:relaylog:中继日志       master.info  :主库信息文件        relaylog.info: relaylog 应用信息        (Slave_Io  Thread    Slave_SQL Thread   :这是从库所用到的两个线程)  

      

                   主从复制原理

     过程解释:

    1.从库执行change master to 命令(主库的连接信息+复制的起点)
    2.从库会通过以上信息,记录到master.info 文件
    3.从库执行start slave 命令,立即开启IO_T 和SQL_T
    4.从库IO_T,读取master.info 文件中的信息获取到Ip,PORT,User,Pass,binlog的位置信息
    5.从库IO_T请求连接主库,主库专门提供一个DUMP_T,负责和IO_T交互
    6.IO_T根据binlog的位置信息(mysql-bin.00001,888),请求主库更新binlog
    7.主库通过DUMP_T将最新的binlog,通过网路TP给从库的IO_T
    8 IO_T接受到新的binlog日志,存储到TCP/IP 缓存,立即返回ACK给主库,并更新master.info
    9.IO_T将TCP/IP缓存中数据,转储到磁盘relaylog中
    10.SQL_T读取relay.info 中的信息,获取到上次已经应用过的relaylog的位置信息
    11.sql_T会按照上次的位置点回放最新的relaylog,再次更新relay.info 信息
    12.从库会自动purge应用relay进行定期清理
    补充说明:
    一旦主从复制构建成功,主库当中发生了新的变化,都会通过dump_T发送信号给IO_T,增强了主从复制的实时性。

     这里可以在主机上面查看连接的从机信息(补充)

    root@localhost:(none)>show slave hosts;
    +-----------+------+------+-----------+--------------------------------------+
    | Server_id | Host | Port | Master_id | Slave_UUID                           |
    +-----------+------+------+-----------+--------------------------------------+
    |        57 |      | 3307 |        47 | 9c9c6940-72e0-11eb-b5ab-000c29adaa80 |
    +-----------+------+------+-----------+--------------------------------------+

    这里还应该显示从库的host的ip地址

    6.主从复制监控

    命令:
        show slave statusG;
        
    主库信息
     Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.17.94.207
                      Master_User: repl
                      Master_Port: 3307
                      Connect_Retry: 10
                
             #重点是看这两个信息
                  Master_Log_File: mysql-bin.000001
                  Read_Master_Log_Pos: 628
        
    
    #从库relay应用信息有关的(relay.info)
     Read_Master_Log_Pos: 628
     Relay_Log_File: node03-relay-bin.000002
     Relay_Log_Pos: 794
    Relay_Master_Log_File: mysql-bin.000001
    
    #线程判断是否有故障(排错用到的信息)
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    Last_IO_Errno: 0
    Last_IO_Error: 
    Last_SQL_Errno: 0
    Last_SQL_Error: 
    
    
    #和过滤复制有关的信息
    Replicate_Do_DB: 
    Replicate_Ignore_DB: 
    Replicate_Do_Table: 
    Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
    Replicate_Wild_Ignore_Table: 
    
    
    #从库延时主库的时间(秒)
    Seconds_Behind_Master: 0
    
    
    
    #延时从库(人为) 防止人为的误操作
    SQL_Delay: 0
    SQL_Remaining_Delay: NULL
    
    
    
    #与Gtid复制有关的状态信息     
    Retrieved_Gtid_Set: 
    Executed_Gtid_Set: 
    Auto_Position: 0
    Replicate_Rewrite_DB: 
    Channel_Name: 
    Master_TLS_Version: 

    7 主从复制故障分析

      情况1

        从库:  IO线程故障

        连接主库:connecting

        网络:连接信息错误或者变更了,防火墙,连接数上限了

        如果是以上情况,我们可以尝试一下能否可以使用复制账户在从库连接主库登录

        解决方式:重置主从复制:  stop slave  ;    reset slave all ;   change  master to ...  ;   start slave  ;

         情况2:

        如果是binlog日志没开或者是损坏

        我们需要在配置文件中开启binlog日志,然后在重置一下主库:reset  master  这个命令是重新同步主库的binlog日志的日志位置信息

       情况3:

        如果是SQL线程故障

          有如下原因导致:

            1,版本差异,参数设定不同,比如:数据类型的差异,SQL_MODE影响

            2.   要创建的数据库对象已经存在  这个很常见

            3.   要删除或修改的对象不存在

            4.   DML 语句不符合表定义及约束时

            归根接地的原因都是由于人为操作的失误

          处理方法: 把握一个原则,一切以主库为准进行解决

             如果出现问题,尽量进行反操作

          最稳妥的办法就是重新构建主从

                       方法一:

            stop  slave;

            set global sql_slave_skip_counter=1;  # 将同步指针向移动一个,如果多次不同步,可以重复操作

            start  slave;

         方法二:     

    /etc/my.cnf
        slave-skip-errors = 1032,1062,1007   ###表示跳过这几个错误
        常见错误代码:
        1007:对象已存在
        1032:无法执行DML
        1062:主键冲突,或约束冲突

        上面的方式虽然可以解决问题,但是有时操作是有风险的,最安全的做法是重新构造主从复制

    如果碰到主键冲突:

      这时需要我们采用方式一 来跳过这个错误

    所以为了很大程度的避免SQL线程故障

      (1) 从库设置只读

          read_only:

          super_read_only;

      (2)使用读写分离中间件

          atlas   mycat     proxysql     maxscale 等等

    8 主从延时监控分析

      8.0  主库方面原因

        (1)主库binlog写入不及时     解决: 双一   调参    sync_binlog=1   

        (2) 默认情况下dump_t 是串行传输binlog
          在并发事务量大的时候或大事务,有dump_t是串行工作的,导致传送日志较慢

          如何解决这个问题?
            必须使用GTID,使用Group commit方式,可以支持DUMP_T并行

        (3)主库极其繁忙
          慢查询
          锁等待
          从库太多

      8.1 从库方面原因

        (1)传统复制中
          如果主库开发事务量很大,或者出现大事务
          由于从库是单SQL线程,导致不管传的日志有多少,只能一次执行一个事务

          5.6版本,有了GTID,可以实现多SQL线程,但是只能基于不同库的事务进行回放,(database)
          5.7版本中,有了增强的GTID,增加了seq_no,增加了新型的并发SQL线程模式,logical_clock ,针对事务的并发 MTS技术

        (2)主从硬件差异太大
        (3)主从的参数配置
        (4)从库和主库的索引不一致

    1.主库方面原因的监控
    
    主库:
    -->show  master status G;
    ------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000001 |      628 |              |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    
    从库: 
    -->show slave statusG;
        Master_Log_File: mysql-bin.000001
        Read_Master_Log_Pos: 628
    
    
    2.从库方面的监控
    
    看从库从主库拿了多少
        Master_Log_File: mysql-bin.000001
        Read_Master_Log_Pos: 628
    
    执行了多少
            Relay_Log_File: node03-relay-bin.000002
                    Relay_Log_Pos: 794
      
            Exec_Master_Log_Pos: 628
            Relay_Log_Space: 1002

    ==============================

    进阶:

      8.0 配置延时

    SQL线程延时:数据已经写入relaylog中了,SQL线程"慢点"运行
    一般企业建议3-6小时,具体看公司运维人员对于故障的反应时间
    
    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

      8.1 恢复思路: 

    1主1从,从库延时5分钟,主库误删除1个库
    1. 5分钟之内 侦测到误删除操作
    2. 停从库SQL线程
    3. 截取relaylog
    起点 :停止SQL线程时,relay最后应用位置
    终点:误删除之前的position(GTID)
    4. 恢复截取的日志到从库
    5. 从库身份解除,替代主库工作

      8.3 故障模拟   

    1.主库数据操作
    db01 [(none)]>create database relay charset utf8;
    db01 [(none)]>use relay
    db01 [relay]>create table t1 (id int);
    db01 [relay]>insert into t1 values(1);
    db01 [relay]>drop database relay;

    以下是在从库中操作:
    2、停止SOL线程
      stop slave sql_thread;
    3.找relaylog的截取起点和终点
      起点:
        Relay_Log_FIle : xxxx-relay-bin.xxxxxx
        Relay_log_POS: xxx
    终点:
        show relaylog events in 'xxxx-relya-bin.xxxxxx'
     4.备份sql语句:
        mysqlbinlog --start-position=xxx --stop-position=xxx /data/3307/xxxx-relay-bin.xxxxxx >/tmp/relay.sql

     5.从库恢复relay
        source /tmp/relay.sql
     6.从库身份解除
        stop slave;
        reset slave all;

     ======================================

    9 过滤复制

      主库:

    show master status;
    Binlog_Do_DB
    Binlog_Ignore_DB 

      从库:  

    show slave statusG
    Replicate_Do_DB:    ###针对的是数据库
    Replicate_Ignore_DB: 

      #针对表
      Replicate_Do_Table:
      Replicate_Ignore_Table:

     配置,在从库的配置文件添加需要过滤的数据名或表名

        vi  /data/3308/my.cnf

          replicate_do_db=数据库名

    10. GTID:

       GTID(Global Transaction ID)是对于一个已提交事务的唯一编号,并且是一个全局(主从复制)唯一的编号。  

      它的官方定义如下:
        GTID = source_id :transaction_id
        7E11FA47-31CA-19E1-9E56-C43AA21293967:29
        什么是sever_uuid,和Server-id 区别?
        核心特性: 全局唯一,具备幂等性

       GTID核心参数  

        gtid-mode=on   ####这个是核心参数,启动gtid类型,否则就是普通的复制架构
        enforce-gtid-consistency=true   ####核心参数        ---强制GTID的一致性
        log-slave-updates=1   ####这个只是基于GTID主从复制的参数      --slave更新是否记录日志

        编辑配置文件 

        [mysqld]
        basedir=/data/mysql/
        datadir=/data/mysql/data
        socket=/tmp/mysql.sock
        server_id=51
        port=3306
        secure-file-priv=/tmp    ###这个参数是用于限制load data,select .....outfile, load_file()传到哪个指定的目录下
        autocommit=0
        log_bin=/data/binlog/mysql-bin
        binlog_format=row
        gtid-mode=on
        enforce-gtid-consistency=true
        log-slave-updates=1
        [mysql]
        prompt=db01 [\d]>

    GTID从库误写入操作处理

    查看监控信息:
    Last_SQL_Error: Error 'Can't create database 'oldboy'; database exists' on query. Default database: 'oldboy'. Query: 'create database oldboy'
    
    Retrieved_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-3
    Executed_Gtid_Set:  71bfa52e-4aae-11e9-ab8c-000c293b577e:1-2,
    7ca4a2b7-4aae-11e9-859d-000c298720f6:1
    
    注入空事物的方法:
    
    stop slave;
    set gtid_next='99279e1e-61b7-11e9-a9fc-000c2928f5dd:3';
    begin;commit;
    set gtid_next='AUTOMATIC';
        
    这里的xxxxx:N 也就是你的slave sql thread报错的GTID,或者说是你想要跳过的GTID。
    最好的解决方案:重新构建主从环境

      GTID复制和普通复制的区别

    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;
    
    change master to 
    master_host='10.0.0.51',
    master_user='repl',
    master_password='123' ,
    MASTER_AUTO_POSITION=1;
    start slave;
    
    (0)在主从复制环境中,主库发生过的事务,在全局都是由唯一GTID记录的,更方便Failover
    (1)额外功能参数(3个)
    (2)change master to 的时候不再需要binlog 文件名和position号,MASTER_AUTO_POSITION=1;
    (3)在复制过程中,从库不再依赖master.info文件,而是直接读取最后一个relaylog的 GTID号
    (4) mysqldump备份时,默认会将备份中包含的事务操作,以以下方式
        SET @@GLOBAL.GTID_PURGED='8c49d7ec-7e78-11e8-9638-000c29ca725d:1';
        告诉从库,我的备份中已经有以上事务,你就不用运行了,直接从下一个GTID开始请求binlog就行。

     =================================================

    半同步

      1.1 什么是全同步?

        指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响

       1.2 什么是半同步?

        半同步复制(Semisynchronous replication)
        首先,半同步是5.5版本推出的特性,介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库(详见参数rpl_semi_sync_master_wait_for_slave_count)接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用

       1.3 什么异步复制?

       MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

     

    配置半同步

    加载插件
    主:
    INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    从:
    INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
    查看是否加载成功:
    show plugins;
    启动:
    主:
    SET GLOBAL rpl_semi_sync_master_enabled = 1;
    从:
    SET GLOBAL rpl_semi_sync_slave_enabled = 1;
    重启从库上的IO线程
    STOP SLAVE IO_THREAD;
    START SLAVE IO_THREAD;
    查看是否在运行
    主:
    show status like 'Rpl_semi_sync_master_status';
    从:
    show status like 'Rpl_semi_sync_slave_status';

         

  • 相关阅读:
    dpkg 删除 百度网盘 程序
    ubuntu 安装go
    解决 swap file “*.swp”already exists!问题
    ROS Topic 常用指令
    正交概念
    vim 永久显示行号 & 临时显示行号
    awk、grep、sed
    Keil中使用Astyel进行C语言的格式化
    红黑树学习
    802.11 对于multicast 和 broadcast的处理
  • 原文地址:https://www.cnblogs.com/zmc60/p/13899893.html
Copyright © 2011-2022 走看看