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

    MySQL的主从复制

    #主从复制介绍
    主从复制基于binlog实现的
    主库发生新的操作,都会记录binlog
    从库取得主库的binlog进行回放
    主从复制的过程是异步的
    

    主从复制的前提

    (1) 2个或以上的数据库实例
    (2) 主库需要开启二进制日志
    (3) server_id要不同,区分不同的节点
    (4) 主库需要建立专用的复制用户
    (5) 从库应该通过备份主库,恢复的方法进行数据恢复
    (6) 告诉从库一些复制信息(ip port user pass,二进制日志起点)
    (7) 从库应该开启专门的复制线程
    

    主从复制搭建

    准备多实例
    [root@mysql ~]# systemctl start mysqld3307
    [root@mysql ~]# mysqld --initialize-insecure --user=mysql --basedir=/application/mysql --datadir=/data/3308/data
    [root@mysql ~]# systemctl start mysqld3308
    [root@mysql ~]# mysql -S /data/3308/mysql.sock -e "select @@port"
    +--------+
    | @@port |
    +--------+
    |   3308 |
    +--------+
    [root@mysql ~]# mysql -S /data/3307/mysql.sock -e "select @@port"
    [root@mysql ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock -e "select @@port"
    mysql: [Warning] Using a password on the command line interface can be insecure.
    +--------+
    | @@port |
    +--------+
    |   3307 |
    +--------+
    [root@mysql ~]# 
    
    检查配置文件
    [root@mysql ~]# cat /data/3307/my.cnf 
    [mysqld]
    basedir=/application/mysql
    datadir=/data/3307/data
    socket=/data/3307/mysql.sock
    log_error=/data/3307/mysql.log
    port=3307
    server_id=7
    log_bin=/data/3307/mysql-bin
    
    [root@mysql ~]# cat /data/3308/my.cnf 
    [mysqld]
    basedir=/application/mysql
    datadir=/data/3308/data
    socket=/data/3308/mysql.sock
    log_error=/data/3308/mysql.log
    port=3308
    server_id=8
    log_bin=/data/3308/mysql-bin
    [root@mysql ~]# 
    
    
    主库创建复制用户
    [root@mysql ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock -e "grant replication slave on *.* to 'repl'@'10.0.1.%' identified by '123456'"
    
    通过主库进行数据恢复
    #主库
    [root@mysql ~]# mysqldump -uroot -p123456 -S /data/3307/mysql.sock -A --master-data=2 --single-transaction -R -E --triggers >/mnt/full.sql
    
    #从库
    [root@mysql ~]# mysql -S /data/3308/mysql.sock 
    mysql> set sql_log_bin=0;
    mysql> source /mnt/full.sql
    mysql> set sql_log_bin=1;
    
    配置从库信息
    [root@mysql ~]# mysql -S /data/3308/mysql.sock 
    mysql> CHANGE MASTER TO
        -> MASTER_HOST='10.0.1.110',
        -> MASTER_USER='repl',
        -> MASTER_PASSWORD='123456',
        -> MASTER_PORT=3307,
        -> MASTER_LOG_FILE='mysql-bin.000007',
        -> MASTER_LOG_POS=444,
        -> MASTER_CONNECT_RETRY=10;
    
    
    从库开启复制线程
    [root@mysql ~]# mysql -S /data/3308/mysql.sock 
    mysql> start slave;
    
    
    检查主从复制状态
    [root@mysql ~]# mysql -S /data/3308/mysql.sock 
    mysql> show slave status G
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
    
    

    主从复制原理

    #主从复制中涉及的文件
    主库: 
    	binlog 
    从库: 
    	relaylog  中继日志
    	master.info  主库信息文件
    	relaylog.info relaylog应用的信息
    
    #主从复制中涉及的线程
    主库:
    	Binlog_Dump Thread : DUMP_T
    从库: 
    	SLAVE_IO_THREAD     : IO_T
    	SLAVE_SQL_THREAD    : SQL_T
    
    #主从复制工作(过程)原理
    (1) 从库 执行change master to语句 ,将以下信息保存至master.info文件中
    (2) 从库 start slave , 从库IO_T和SQL_T生成
    (3)Io_T ,读取master.info中主库连接信息(ip , port, user,password)
       连接主库,主库专门开启Dump_T,和从库IO_T进行交互
    (4) IO_T,读取 master.info ,复制的起点信息,找主库DUMP要最新的binlog
    (5)主库dump_T,截取最新的binlog,发送给从库IO_T
    (6)扩展: 基于TCP/IP网络工作模式,IO_T将日志存储到TCP/Ip缓存中,并返回ACK给主库.
    (7) IO_T最终会将缓存中数据,写入到relay_log文件中保存.更新master.info为新位置点.
    (8) SQL_T,读取relay-log.info信息,获取上次SQL_T回放的位置点.
    (9)SQL_T,根据位置点,向下回放最新的relaylog.并且再次更新relay-log.info文件为最新点.
    补充:
    (10) 主库dump_T 会持续的监控binlog的变化,一旦有新的日志生成,给从库发一些信号.
    (11) 从库 relay_log_purge线程会定期自动清理回放过的relay日志.
    

    主从复制监控

    mysql> show slave status G
    
    #主库有关的信息(master.info):
    Master_Host: 10.0.0.51
    Master_User: repl
    Master_Port: 3307
    Connect_Retry: 10
    Master_Log_File: mysql-bin.000004
    Read_Master_Log_Pos: 609
    
    #从库relay应用信息有关的(relay.info):
    Relay_Log_File: db01-relay-bin.000002
    Relay_Log_Pos: 320
    Relay_Master_Log_File: mysql-bin.000004
    
    #从库线程运行状态(排错)
    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
    

    主从复制故障

    #IO 线程故障 
    (1) 连接主库 
    网络不通,防火墙
    连接信息错误(ip,port,user,password)
    解决: 
    1. stop slave 
    2. reset slave all;
    3. change master to 
    4. start slave
    
    #请求Binlog
    主库日志损坏 ,丢失,不连续
    
    模拟故障:
    主库 reset master 处理
    
    解决:
    从库 
    stop slave ;
    reset slave all; 
    CHANGE MASTER TO 
    MASTER_HOST='10.0.1.110',
    MASTER_USER='repl',
    MASTER_PASSWORD='123456',
    MASTER_PORT=3307,
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=154,
    MASTER_CONNECT_RETRY=10;
    start slave;
    
    #SQL线程故障
    回放日志 (为什么SQL语句执行失败?)
    (1) 版本不一样(SQL_Mode)
    (2) 要创建的对象已存在 (主从数据不一致)
    (3) 要删除或修改的对象不存在(主从数据不一致)
    (5) 约束冲突(主键)
    
    处理建议: 
    1. 一切以主库为准.最彻底方法重新构建主从。
    2. 将从库设置为只读库,采用读写分离的中间件,防止从库写入
    mysql> show variables like '%read_only%';
    read_only=ON
    super_read_only=ON
    

    主从延时监控及原因

    5.6.1 主库方面原因
    #binlog写入不及时
    解决:
    sync_binlog=1	#每次事务提交时,一定保证binlog写入磁盘
    
    #传统复制
    默认情况下dump_t是串行传输binlog
    在并发事务量大时或者大事务,由于dump_t 是串型工作的,导致传送日志较慢
    MySQL 为了解决这个问题,5.6版本支持了GTID复制,使得dump_t可以并行传输事务.
    5.7版本之后,加强了GTID功能,建议都开启GTID
    
    #其他原因
    网络慢
    主机配置
    主从参数不一致
    从库较多
    
    #从库方面原因
    传统复制中如果主库并发事务量很大,或者出现大事务
    由于从库是单SQL线程,导致,不管传的日志有多少,只能一次执行一个事务.
    5.6 版本,有了GTID,可以实现多SQL线程,但是只能基于不同库的事务进行并发回放.(database) 
    5.7 版本中,增强了GTID,增加了seq_no,增加了新型的并发SQL线程模式(logical_clock),MTS技术
    
    主从延时监控
    #主从延时的监控
    mysql> show slave status G
            Seconds_Behind_Master: 0
    #主库方面监控
    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000007 |      609 |              |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    
    mysql> 
    
    [root@mysql data]# cat relay-log.info 
    7
    ./db01-relay-bin.000002
    953
    mysql3307-bin.000001
    21797376
    0
    0
    1
    
    [root@db01 data]# 
    
  • 相关阅读:
    第二十一章流 1流的操作 简单
    第二十章友元类与嵌套类 1友元类 简单
    第十九章 19 利用私有继承来实现代码重用 简单
    第二十章友元类与嵌套类 2嵌套类 简单
    第十九章 8链表类Node 简单
    第二十一章流 3用cin输入 简单
    第十九章 10 图书 药品管理系统 简单
    第十九章 11图书 药品管理系统 简单
    第二十一章流 4文件的输入和输出 简单
    第十九章 12 什么时候使用私有继承,什么时候使用包含 简单
  • 原文地址:https://www.cnblogs.com/opesn/p/12994033.html
Copyright © 2011-2022 走看看