zoukankan      html  css  js  c++  java
  • 主从复制

    mysql主从复制(异步复制)

    配置主从的条件

    1.一台带有数据的主库
    2.一台崭新的从库,或者初始化之后的
    
    #初始化
    cd /usr/local/mysql/scripts/ && rm -rf ../data && ./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
    

    1.主库操作

    1.主库配置server_id
    2.主库开启binlog
    3.主库授权连接的用户
    4.查看binlog信息(之后不能再有刷新binlog的操作) -------------
    5.导出数据(mysqldump)
    mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
    
    #查看binlog信息之后,不能再有刷新binlog的操作
    #主从数据的同步,是为了创建或删除的某些时候不报错
    #主从配置的过程中,可以写入数据,因为change master to的时候已经记录了那个位置点,所以同步的时候只需要指定那个位置点就好,那么这样从库就可以同步到主库的所有的数据了
    

    2.从库操作

    1.从库配置server_id(从库不需要配置binlog,因为只配置主从复制的话,从库不会写入binlog,写入中继日志)
    2.确认主库授权的用户可以连接从库(ssh)
    3.导入主库数据
    4.配置主库信息(change master to)(连接,会自动同步位置点之后的数据)
    5.开启slave(IO线程 dump线程)
    
    
    #从库不需要开启binlog,因为从库从主库获取的binlog存放到了中继日志(relay-log),中继日志就相当于从库的binlog
    #当数据量很大的时候,主从复制不是实时的情况将会很突出(中继日志里面的SQL语句SQL线程执行)
    #主从复制实际上是异步复制
    

    3.主从复制原理

    1)图解

    UqHM90.md.jpg

    2)文字描述

    1.主库配置server_id和开启binlog
    	[mysqld]
    	server_id=1
    	log_bin=/usr/local/mysql/data/mysql-bin
    2.主库授权从库连接的用户
    	grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
    3.主库查看binlog信息,与服务器信息
    	show master status;
    3.5 主库导出所有数据(不会记录在SQL)
    mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
    head -22 /tmp/full.sql | tail -1
    	
    4.从库配置跟主库'不一致'server_id,没有binlog不能show master status;
    	[mysqld]
    	server_id=2
    5.配置主从,通过change master to指定'从库主库的信息':ip、用户、密码、端口、binlog位置点(b不加引号)、binlog名字(#端口 位置点不能加引号)
    change master to
    master_host='172.16.1.53',
    master_user='rep',
    master_port=3306,
    master_password='123',
    master_log_file='mysql-bin.000003',
    master_log_pos=120;
    6.从库开启IO线程(连接主库)和sql线程(获取主库信息)
    start slave;
    7.从库连接主库以后,'IO线程'会向主库的'dump线程'发起询问,询问是否有新数据
    8.dump线程被询问,去'查找新数据',并将新数据'返回给IO线程'
    9.'IO线程'拿到数据先写入'TCP缓存')(三次握手,四次挥手)
    10.'TCP缓存'将数据写入'中继日志relay-log',并返回给IO线程一个'ACK'
    11.'IO线程'收到ACK会记录当前位置点到'master.info'
    12.'sql线程'会读取relay-log,'执行'从主库获取的sql语句
    13.执行完以后将执行到的'位置点,记录'到relay-log.info
    
    #binlog中的位置点放到中继日志relay-log中,位置点数值会发生变化(但是之间的数据不变)
    #主从用户的授权必须是*.*
    grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
    #使用过滤复制,可以使从库只同步主库的某一个库,因此一个从库可以同步不同的主库
    #主从复制,从库会同步主库位置点之后的数据变化(之前的并不会同步)
    

    4.主从中涉及到的文件或者线程

    1)主库

    1.binlog:主库执行的sql语句
    2.dump线程:'对比'binlog是否更新,'获取'新的binlog
    

    2)从库

    1.IO线程:连接主库,询问新数据,'dump线程'获取新数据
    2.SQL线程:'执行'从主库拿来的sql语句
    3.relay-log:中继日志,'记录'从主库拿过来的binlog
    4.master.info:'记录'主库binlog信息,会随着同步进行更新
    5.relay-log.info:'记录'sql线程执行到了哪里,下次从哪里开始'执行'
    

    主从复制的搭建

    1.主库操作

    1)配置

    [root@db03 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=1
    log_bin=/service/mysql/data/mysql-bin
    
    [root@db03 ~]# /etc/init.d/mysqld restart
    

    2)授权一个用户

    mysql> grant replication slave on *.* to rep@'172.16.1.%' identified by '123';
    Query OK, 0 rows affected (0.03 sec)
    

    3)查看binlog信息

    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000003 |      326 |   只同步           |  不同步                |                   |
    自己去找binlog,然后同步
    1 row in set (0.00 sec)
    

    4)导出所有数据

    [root@db03 data]# mysqldump -uroot -p -A --master-data=2 --single-transaction > /tmp/full.sql
    
    [root@db03 data]# scp /tmp/full.sql 172.16.1.52:/tmp/
    

    2.从库操作

    1)配置

    [root@db02 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    
    [root@db02 ~]# /etc/init.d/mysqld start
    

    2)验证主库用户

    [root@db02 ~]# mysql -urep -p -h172.16.1.52
    

    3)同步数据

    [root@db02 ~]# mysql -uroot -p123 < /tmp/full.sql
    

    4)配置主从

    change master to
    master_host='172.16.1.52',
    master_user='rep',
    master_password='123',
    master_log_file='mysql-bin.000018',
    master_log_pos=120;
    
    

    5)开启线程

    mysql> start slave;
    Query OK, 0 rows affected (0.04 sec)
    

    6)查看主从

    mysql> show slave statusG
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                
    #如果IO线程和SQL线程都为no,那么就是slave没有开启
    

    主从数据库出错

    1)IO线程出错

    mysql> show slave statusG
                 Slave_IO_Running: No
                Slave_SQL_Running: Yes
                
    mysql> show slave statusG
                 Slave_IO_Running: Connecting
                Slave_SQL_Running: Yes
                
    #排查思路
    1.网络
    	[root@db02 ~]# ping 172.16.1.53
    2.端口
    	[root@db02 ~]# telnet 172.16.1.53 3306
    3.防火墙(Connecting)
    4.主从授权的用户错误
    5.反向解析
    	skip-name-resolve
    6.UUID或server_id相同
    

    2)SQL线程出错

    mysql> show slave statusG
                 Slave_IO_Running: Yes
                Slave_SQL_Running: No
    
    #原因:
    1.主库有的数据,从库没有
    2.从库有的数据,主库没有
    总而言之就是主从才能够数据不一致,create drop insert 导致SQL线程断开连接
    
    #处理方式一:自欺欺人
    1.临时停止同步
    mysql> stop slave;
    2.将同步指针向下移动一个(需要重复操作,断一次跳一次)
    mysql> set global sql_slave_skip_counter=1;
    3.开启同步
    mysql> start slave;
    
    #处理方式二:掩耳盗铃
    1.编辑配置文件
    [root@db01 ~]# vim /etc/my.cnf
    #在[mysqld]标签下添加以下参数
    slave-skip-errors=1032,1062,1007
    
    #处理方式三:正解
    重新同步数据,重新做主从(重新获取binlog位置点即可)
    
    # mysql主从复制的意义就是主库和从库数据的一致,如果配置好主从之后,主从数据还不一致,那么主从就失去意义了
    


    一、主从复制(步骤)(异步复制)

    1.主库操作

    1.配置server_id,开启binlog
    2.主库授权用户
    grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
    3.查看binlog信息
    mysql> show master status;
    4.导出数据库数据
    [root@db03 mysql]# mysqldump -uroot -p -A -R --triggers --master-data=2 --single-transaction > /tmp/full.sql
    
    #主库不要change自己,不然要 stop slave;reset slave;
    

    2.从库操作

    1.配置server_id
    2.配置主从
    change master to
    master_host='172.16.1.52',
    master_user='rep',
    master_password='123',
    master_log_file='mysql-bin.000003',
    master_log_pos=120;
    Query OK, 0 rows affected, 2 warnings (2.94 sec)
    3.导入数据
    mysql> source /tmp/full.sql;
    4.开启线程
    start slave;
    5.查看
    
    

    UqHM90.md.jpg

    二、延时复制

    延时从库只做'备份',不提供任何对外服务
    #即便不配置主库延时配置,从库SQL线程执行的SQL语句在大数据的情况下,'来不及'执行,仍然会有延迟
    
    #解决主库从库延时复制
    1.读写分离,多做几个从库,那个快读哪个
    2.拆库拆表
    3.基于GTID的主从复制,开启多个SQL线程
    

    1.配置延时复制(已经有主从)

    1.停止主从
    mysql> stop slave;
    Query OK, 0 rows affected (0.03 sec)
    
    2.配置延时时间(reset slave all;)
    change master to
    master_delay=180;
    
    master_host='172.16.1.52',
    master_user='rep',
    master_password='123',
    master_log_file='mysql-bin.000018',
    master_log_pos=120,
    
    3.开启主从
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.16.1.52 #被用于连接主服务器的当前ip
                      Master_User: rep		#被用于连接主服务器的当前用户
                      Master_Port: 3306
                    Connect_Retry: 60	#–master-connect-retry选项的当前值
                    
                  Master_Log_File: mysql-bin.000001 #I/O线程当前正在读取的主服务器二进制日志文件的名称
              Read_Master_Log_Pos: 468 --------------------
    #在当前的主服务器二进制日志中,I/O线程已经读取的位置。
              
                   Relay_Log_File: db03-relay-bin.000002	#中继日志
                    Relay_Log_Pos: 283	--------------------		
    #中继日志位置点
    #在主服务器的二进制日志中的(Relay_Master_Log_File, Exec_Master_Log_Pos)对应于在中继日志中的(Relay_Log_File,Relay_Log_Pos)。
            Relay_Master_Log_File: mysql-bin.000001	#主库binlog
            
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                
                  Replicate_Do_DB: 	
    #使用–replicate-do-db和–replicate-ignore-db选项指定的数据库清单。(过滤库复制白名单)
              Replicate_Ignore_DB: (过滤库复制黑名单)
              
               Replicate_Do_Table: 
    #使用–replicate-do-table,–replicate-ignore-table,–replicate-wild-do-table和–replicate-wild-ignore_table选项指定的表清单。
           Replicate_Ignore_Table:  #(过滤表复制白名单)
          Replicate_Wild_Do_Table:  #(过滤表复制黑名单,支持正则)
      Replicate_Wild_Ignore_Table: 
      
                       Last_Errno: 0 #主从数据不一致导致的错误消息数
                       Last_Error: 
                       
                     Skip_Counter: 0  
    #最近被使用的用于SQL_SLAVE_SKIP_COUNTER的值
              Exec_Master_Log_Pos: 468 -------------------------
    #来自主服务器的二进制日志的由SQL线程执行的上一个时间的位置
                  Relay_Log_Space: 455  
    #所有原有的中继日志结合起来的总大小
                  
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
    Until_Condition具有以下值:
    o 如果没有指定'UNTIL'子句,则没有值
    o 如果从属服务器正在读取,直到达到主服务器的二进制日志的'给定位置'为止,则值为Master
    o 如果从属服务器正在读取,直到达到其中继日志的'给定位置'为止,则值为Relay
    Until_Log_File和Until_Log_Pos用于指示日志文件名和位置值。日志文件名和位置值定义了'SQL线程在哪个点中止执行'。
                    
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
    #这些字段显示了被从属服务器使用的参数。这些参数用于连接主服务器。
    Master_SSL_Allowed具有以下值:
    o 如果允许对主服务器进行SSL连接,则值为Yes
    o 如果不允许对主服务器进行SSL连接,则值为No
    o 如果允许SSL连接,但是从属服务器没有让SSL支持被启用,则值为Ignored。
    与SSL有关的字段的值对应于–master-ca,–master-capath,–master-cert,–master-cipher和–master-key选项的值
                   
            Seconds_Behind_Master: 0 
    #本字段测量从属服务器SQL线程和从属服务器I/O线程之间的时间差距,单位以秒计
    ##延时的SQL语句距离在从库执行的已过去时间
            
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
      
                 Master_Server_Id: 1 #主
                      Master_UUID: ebc5b10d-cf5f-11ea-b071-000c299d6beb
                 Master_Info_File: /service/mysql-5.6.46-linux-glibc2.12-x86_64/data/master.info
                 #master_info_file
                        SQL_Delay: 180
                        #sql线程延时180秒
              SQL_Remaining_Delay: NULL
              #延时的SQL语句距离在从库执行的剩余时间(xx秒后执行)
          Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
               Master_Retry_Count: 86400
                      Master_Bind: 
          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 
                Executed_Gtid_Set: 
                    Auto_Position: 0
                    
    #延时复制中,延时的SQL语句保存在只能中继日志
    [root@db03 data]# ll
    total 110668
    -rw-rw---- 1 mysql mysql       56 Jul 27 00:49 auto.cnf
    -rw-rw---- 1 mysql mysql    37295 Jul 27 01:27 db03.err
    -rw-rw---- 1 mysql mysql        5 Jul 27 01:17 db03.pid
    -rw-rw---- 1 mysql mysql      172 Jul 27 01:27 db03-relay-bin.000001
    -rw-rw---- 1 mysql mysql      374 Jul 27 02:04 db03-relay-bin.000002
    -rw-rw---- 1 mysql mysql       48 Jul 27 01:27 db03-relay-bin.index
    #延时复制的作用是:做备份,MHA
    #当发现主从数据不一致的时候,stop slave;同步主库数据,重新做主从
    #同步主库数据,最好重新mysqldump 一下,以免漏数据(别人刷新了binlog)
    #reset slave;刷新从库binlog(清空)
    #如果没有做主从复制,可以关闭主库的binlog来达到’避免binlog内脏数据的记录‘,
    
    

    2.配置延时复制(没有主从)

    1.搭建出一台mysql
    同步数据mysqldump
    2.配置主从
    mysql> change master to
        -> master_host='172.16.1.51',
        -> master_user='rep',
        -> master_password='123',
        -> master_log_file='mysql-bin.000001',
        -> master_log_pos=424,
        
        -> master_delay=180;
    3.开启线程
    mysql> start slave;
    
    #可以自由选择主库位置点
    

    3.关闭延时从库

    mysql> stop slave;
    mysql> change master to master_delay=0;
    mysql> start slave;
    

    4.注意:

    #如果做了主从,就不能关闭主库的binlog了,因为主库执行的drop在中级日志中已经记录,从库早晚都会执行(删库),
    	所以把主库的binlog'一直开启',这样从库的中继日志就可以通过主库的恢复来恢复,'但是从库的slave要关闭'(实际上从库还是会执行主库执行错的语句,只不过又执行了重建语句)
    	如果'关闭'了主库的binlog,那么从库将不能恢复,主从数据不一致,主从复制失败
    
    #binlog一致开启就好
    
    

    UqHM90.md.jpg

    实例

    #思考问题:
    总数据量级500G,正常备份去恢复需要1.5-2小时
    1)配置延时3600秒
    mysql>CHANGE MASTER TO MASTER_DELAY = 3600;
    
    2)主库
    drop database db;
    
    3)怎么利用延时从库,恢复数据?
    提示:
    1、从库relaylog存放在datadir目录下
    2、mysqlbinlog 可以截取relaylog内容(#relaylog就是binlog)
    3、show relay log events in 'db01-relay-bin.000001'; (#看drop之前)
    
    
    #处理的思路:
    1)停止SQL线程(#防止从库执行drop语句损坏'备份'数据)
    mysql> stop slave sql_thread;
    
    2)截取relaylog到误删除之前点
    relay-log.info 获取到上次运行到的位置点,作为'恢复起点'
    分析relay-log的文件内容,获取到'误删除之前'position
    
    #实例
    1)关闭延时
    mysql -S /data/3308/mysql.sock
    mysql> stop slave;
    mysql> CHANGE MASTER TO MASTER_DELAY = 0;
    mysql> start slave;
    
    2)模拟数据
    mysql -S /data/3307/mysql.sock
    source  /root/world.sql
    use world;
    create table c1 select * from city;		#创建且复制数据
    create table c2 select * from city;
    
    3)开启从库延时5分钟
    mysql -S /data/3308/mysql.sock
    show slave status G
    stop slave;
    CHANGE MASTER TO MASTER_DELAY = 300;	#延时同步
    start slave;
    mysql -S /data/3307/mysql.sock
    use world;
    create table c3 select * from city;		#模拟延时同步后数据的写入
    create table c4 select * from city;
    
    4)破坏,模拟删库故障。(以下步骤在5分钟内操作完成。)
    mysql -S /data/3307/mysql.sock
    drop database world;
    
    5)从库,关闭SQL线程
    mysql -S /data/3308/mysql.sock
    stop slave sql_thread;  #只关闭SQL线程
    
    6)截取relay-log
    #备份起点:
    cd /data/3308/data/
    cat relay-log.info
    ./db01-relay-bin.000002	
    283
    #终点:(drop之前)
    mysql -S /data/3308/mysql.sock
    show relaylog events in 'db01-relay-bin.000002'
    db01-relay-bin.000002 | 268047 
    
    mysqlbinlog --start-position=283  --stop-position=268047 /data/3308/data/db01-relay-bin.000002 >/tmp/relay.sql 
    
    #可以通过relay.sql恢复从库到drop之前,恢复了之后,也可以通过Mysqldump -d导出指定库的SQL语句,再导入到主库,主库恢复
    1)取消从库身份
    mysql> stop io_thread;
    mysql> reset slave all;
    
    2)恢复数据
    mysql> set sql_log_bin=0;
    mysql> source /tmp/relay.sql
    mysql> use world
    mysql> show tables;
    
    
    

    三、半同步复制(实时同步)

    UqHM90.md.jpg

    1.半同步复制概念

    从'MYSQL5.5'开始,支持半自动复制。
    之前版本的MySQL Replication都是'异步'(asynchronous)的,(dump线程和IO线程之间没有延迟,IO 线程和SQL线程在'大量访问'的时候即便不配置延时复制,仍然会有'延迟')
    
    主库在执行完一些事务后,是'不会管'备库的进度的。
    如果备库不幸落后,而更不幸的是主库此时又出现Crash(例如宕机),
    这时'备库中的数据就是不完整的'。简而言之,在主库发生故障的时候,我们无法使用备库来继续提供数据一致的服务了。
    '半同步复制'(Semi synchronous Replication)则一定程度上保证提交的事务已经传给了至少一个备库。出发点是保证主从数据一致性问题,安全的考虑。
    
    5.5 出现概念,但是不建议使用,性能太差(#IO线程阻止主库SQL语句的执行)
    5.6 出现group commit 组提交功能,来提升开启半同步复制的性能
    5.7 更加完善了,在group commit基础上出现了MGR(#主库高可用)
    5.7 的增强半同步复制的新特性:after commit; after sync;
    
    #缺点:
    1.性能差,影响主库效率
    2.半同步复制,有一个超时时间(IO线程等待SQL线程时间),超过这个时间'恢复主从复制'
    3.当数据量很大的时候,SQL线程的语句还没有执行的话,会组织主库数据的写入
    4.#小的访问量可以做半同步复制
    
    #半同步复制是在主从复制的基础上做的
    

    2.配置半同步

    1)主库操作

    #登录数据库
    [root@db01 ~]# mysql -uroot -p123
    #查看是否有动态支持
    mysql> show global variables like 'have_dynamic_loading';
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | have_dynamic_loading | YES   |
    +----------------------+-------+
    #安装自带插件
    mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME'semisync_master.so';
    #启动插件(临时开启)
    mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
    #设置超时
    mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000;
    
    #修改配置文件,在[mysqld]标签下添加如下内容(不用重启库)
    [root@db01 ~]# vim /etc/my.cnf
    [mysqld]
    rpl_semi_sync_master_enabled=1
    rpl_semi_sync_master_timeout=1000
    
    检查安装:
    mysql> show variables like'rpl%';
    +------------------------------------+----------+
    | Variable_name                      | Value    |
    +------------------------------------+----------+
    | rpl_semi_sync_master_enabled       | ON       |	#
    | rpl_semi_sync_master_timeout       | 10000    |
    | rpl_semi_sync_master_trace_level   | 32       |
    | rpl_semi_sync_master_wait_no_slave | ON       |	#
    | rpl_stop_slave_timeout             | 31536000 |	#停止主从的时间
    +------------------------------------+----------+
    mysql> show global status like 'rpl_semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 0     | #有几个客户端
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | ON    |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     | #
    
    #数据库自带的未安装的插件(.so)
    [root@db02 ~]# ll /service/mysql/lib/plugin/
    total 3484
    -rwxr-xr-x 1 7161 31415  16581 Sep 27  2019 adt_null.so
    -rwxr-xr-x 1 7161 31415 426219 Sep 27  2019 semisync_master.so  #
    -rwxr-xr-x 1 7161 31415 249327 Sep 27  2019 semisync_slave.so   #
    -rwxr-xr-x 1 7161 31415  14173 Sep 27  2019 test_udf_services.so
    -rwxr-xr-x 1 7161 31415  99629 Sep 27  2019 udf_example.so
    -rwxr-xr-x 1 7161 31415 193667 Sep 27  2019 validate_password.so
    

    2)从库操作

    #登录数据库
    [root@mysql-db02 ~]# mysql -uroot -p123
    #安装slave半同步插件
    mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME'semisync_slave.so';
    #启动插件
    mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
    #重启io线程使其生效
    stop slave io_thread;
    start slave io_thread;
    #编辑配置文件(不需要重启数据库),在[mysqld]标签下添加如下内容
    [root@mysql-db02 ~]# vim /etc/my.cnf
    [mysqld]
    rpl_semi_sync_slave_enabled =1
    #查看是否生效
    mysql> show global status like 'rpl_semi%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | ON    |
    +----------------------------+-------+
    
    #
    mysql> create database sssss;
    Query OK, 1 row affected (0.01 sec)
    
    mysql>  show global status like 'rpl_semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 1     |  #主库半同步复制有几个客户端
    | Rpl_semi_sync_master_net_avg_wait_time     | 1812  |
    | Rpl_semi_sync_master_net_wait_time         | 1812  |
    | Rpl_semi_sync_master_net_waits             | 1     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | ON    | #主库是否开启半同步
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 2273  |
    | Rpl_semi_sync_master_tx_wait_time          | 2273  |
    | Rpl_semi_sync_master_tx_waits              | 1     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 1     | #从库执行半同步的SQL语句
    +--------------------------------------------+-------+
    

    3)额外参数

    rpl_semi_sync_master_timeout=milliseconds(#默认)
    设置此参数值(ms),为了防止半同步复制在没有收到确认的情况下发生堵塞,如果Master在超时之前没有收到任何确认,将恢复到正常的异步复制,并继续执行没有半同步的复制操作。
    
    rpl_semi_sync_master_wait_no_slave={ON|OFF}
    如果'一个事务被提交',但Master'没有任何Slave的连接',这时不可能将事务发送到其它地方保护起来。默认情况下,'Master会在时间限制范围内继续等待Slave的连接',并'确认'该事务已经被正确的写到磁盘上。
    可以使用此参数选项关闭这种行为,在这种情况下,如果没有Slave连接,Master就会恢复到异步复制。
    
    #企业架构
    
    1.开发环境	
    	2台
    2.测试环境 (沙盒环境一般游戏公司做)
    	2台
    	测试并发等
    	部署环境与生产一样
    3.灰度发布(不删档内测)
    4.生产环境
    	20台机子
    	
    #除了开发环境,别的环境都需要运维维护
    

    四、过滤复制

    1.过滤复制的方式

    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000002 |      305 |   白名单      |    黑名单        |                   |
    +------------------+----------+--------------+------------------+-------------------+
    

    1)白名单

    #从库
    只过滤库
    replicate-do-db=test
    只过滤库下表
    replicate-do-table=test.t1
    只过滤库下以t开头的表
    replicate-wild-do-table=test.t*
    #主库
    binlog-do-db=test
    binlog-do-table=test.t1
    binlog-wild-do-table=test.t*
    

    2)黑名单

    #从库
    replicate-ignore-db=test
    replicate-ignore-table=test.t1
    replicate-wild-ignore-table=test.t*
    #主库
    binlog-ignore-db=test
    binlog-ignore-table=test.t1
    binlog-wild-ignore-table=test.t*
    

    2.从库配置过滤复制

    1)主库创建两个库

    create database wzry;
    create database lol;
    
    #过滤复制只在配置了之后才会'过滤'并复制该库以后的内容
    #不管是主从复制,延时复制,半同步复制,过滤复制,都要先同步数据,再做主从复制
    

    2)第一台从库配置

    [root@db02 data]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    replicate-do-db=wzry
    
    [root@db02 data]# systemctl restart mysqld
    
    #查看主从状态
    mysql> show slave statusG
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: wzry  #从库配置文件中指定要同步的库
    

    3)配置第二台从库

    [root@db03 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    replicate-do-db=lol
    
    [root@db03 ~]# systemctl restart mysqld
    
    #查看主从状态
    mysql> show slave statusG
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: lol #从库要同步主库的库
    

    4)验证过滤复制

    #1.主库操作
    use wzry
    create table cikexintiao(id int);
    use lol
    create table fuleierzhuode(id int);
    
    #第一台从库查看
    mysql> use wzry
    mysql> show tables;
    +----------------+
    | Tables_in_wzry |
    +----------------+
    | cikexintiao    |
    +----------------+
    mysql> use lol
    mysql> show tables;
    
    #第二台从库查看
    mysql> use wzry
    mysql> show tables;
    mysql> use lol
    mysql> show tables;
    +---------------+
    | Tables_in_lol |
    +---------------+
    | fuleierzhuode |
    +---------------+
    
    

    3.配置过滤多个库

    1)方法一:

    [root@db02 data]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    replicate-do-db=wzry,lol
    

    2)方法二:

    [root@db02 data]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    replicate-do-db=wzry
    replicate-do-db=lol
    
    

    4.过滤复制配置在主库

    1.配置(#只过滤)
    [root@db01 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=1
    log_bin=/usr/local/mysql/data/mysql-bin
    binlog-do-db=wzry
    
    2.查看主库状态
    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000003 |      120 | wzry         |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    
    3.在主库的wzry库和lol库添加数据
    
    4.从库查看数据,只能看到wzry库的数据
    

    5.过滤复制总结

    #配置在从库时
    1.配置白名单:IO线程将主库的数据拿到了relay-log,但是sql线程'只执行白名单配置'的数据库相关语句
    1.配置黑名单:IO线程将主库的数据拿到了relay-log,但是sql线程'只不执行黑名单配置'的数据库相关语句
    
    #配置在主库时
    1.配置白名单:binlog'只记录'白名单相关的sql语句
    2.配置黑名单:binlog'只不记录'黑名单相关的sql语句
    
    #所以过滤复制一般配置在从库,因为如果配置在了主库,那么binlog将部分记录
    

    五、基于GTID的主从复制

    1.什么是GTID

    1.'全局事务标识符'
    2.组成:UUID + TID    #数据库的id+事务的id(依次递增)
    	   f03a53e0-cd46-11ea-a2c4-000c292c767e:1
    #UUID
    [root@db02 ~]# cat /service/mysql/data/auto.cnf 
    [auto]
    server-uuid=ebc5b10d-cf5f-11ea-b071-000c299d6beb
    
    #停止主从
    stop slave;
    reset slave all;
    

    2.GTID主从复制的优点

    1.GTID同步时开启'多个SQL线程','每一个库'同步时开启'一个线程'
    2.binlog在'rows模式下',binlog内容比'寻常'的主从更加简洁
    3.GTID主从复制会记录主从信息,'不需要手动配置binlog和位置点'
    

    3.GTID主从复制的缺点

    1.备份时更加麻烦,需要额外加一个参数 --set-gtid=on
    2.主从复制出现错误,没有办法跳过错误(#不能跳过就不能跳过吧)
    

    4.搭建GTID主从复制

    1)配置三台数据库

    #配置第一台主库
    [root@db01 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=1
    log_bin=/usr/local/mysql/data/mysql-bin
    
    #配置第一台从库
    [root@db02 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    
    #配置第二台从库
    [root@db03 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=3
    

    2)查看是否开启GTID

    mysql> show variables like '%gtid%';
    +---------------------------------+-----------+
    | Variable_name                   | Value     |
    +---------------------------------+-----------+
    | binlog_gtid_simple_recovery     | OFF       |
    | enforce_gtid_consistency        | OFF       |
    | gtid_executed                   |           |
    | gtid_mode                       | OFF       |
    | gtid_next                       | AUTOMATIC |
    | gtid_owned                      |           |
    | gtid_purged                     |           |
    | simplified_binlog_gtid_recovery | OFF       |
    +---------------------------------+-----------+
    8 rows in set (0.00 sec)
    

    3)开启GTID

    #主库配置
    [root@db01 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=1
    log_bin=/usr/local/mysql/data/mysql-bin
    gtid_mode=on
    enforce_gtid_consistency
    log-slave-updates
    
    #从库1的配置
    [root@db02 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=2
    log_bin=/usr/local/mysql/data/mysql-bin
    gtid_mode=on
    enforce_gtid_consistency
    log-slave-updates
    
    #从库2的配置
    [root@db02 ~]# vim /etc/my.cnf
    [mysqld]
    server_id=3
    log_bin=/usr/local/mysql/data/mysql-bin
    gtid_mode=on
    enforce_gtid_consistency
    log-slave-updates
    
    
    

    4)扩展

    #配置log-slave-updates参数的场景(主库的binlog在写入中继日志的同时,也写入从库的binlog)
    1.基于GTID的主从复制(报错)
    2.双主架构,mysql+keepalived
    3.级联复制
    4.MHA
    

    5)主库创建用户

    mysql> grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
    

    6)主库数据同步到从库

    mysqldump -uroot -p -R --triggers --master-data=2 --single-transaction -A > /tmp/full.sql
    scp ...
    mysql ... < full.sql
    

    7)从库配置主从

    change master to
    master_host='172.16.1.51',
    master_user='rep',
    master_password='123',
    master_auto_position=1;
    
    #自动连接主库位置点(当前binlog 120)
    master_auto_position=1
    
  • 相关阅读:
    6 全局锁和表锁
    oracle ogg--ogg搭建过程中遇到的错误及处理
    5 深入浅出索引(下)
    4 深入浅出索引(上)
    oracle ogg 单实例双向-新增表,修改表结构(oracle-oracle
    oracle ogg 单实例双向复制搭建(oracle-oracle)--Oracle GoldenGate
    Iview 中 获取 Menu 导航菜单 选中的值
    idea中git分支的使用
    vue使用axios进行ajax请求
    web前端_Vue框架_设置浏览器上方的标题和图标
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/13405363.html
Copyright © 2011-2022 走看看