主从复制

概述

在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能,
一般都会采用「主从复制」。比如:在复杂的业务系统中,有一句sql执行后
导致锁表,并且这条sql的的执行时间有比较长,那么此sql执行的期间导致
服务不可用,这样就会严重影响用户的体验度。主从复制中分为主服务器
(master)和从服务器(slave),主服务器负责写,而从服务器负责读,
Mysql的主从复制的过程是一个异步的过程。这样读写分离的过程能够是整体的
服务性能提高,即使写操作时间比较长,也不影响读操作的进行。

复制的基本原理

slave会从master主机读取binlog二进制日志文件来进行数据同步

三个线程

Mysql的主从复制中主要有三个线程:

  • 1.master(binlog dump thread)
  • 2.slave(I/O thread 、SQL thread),Master一条线程和Slave中的两条线程。

master(binlog dump thread)

主要负责Master库中有数据更新的时候,会按照binlog格式,将更新的事件类型写入到主库的binlog文件中。
Master会创建log dump线程通知Slave主库中存在数据更新,这就是为什么主库的binlog日志一定要
开启的原因。

  • 1.通知并传送二进制日志事件给从库
  • 2.接收从库的ACK反馈信息

I/O thread

线程在Slave中创建,该线程用于请求Master,Master会返回binlog的名称
以及当前数据更新的位置、binlog文件位置的副本。然后,将binlog保存在
relay log(中继日志)中,中继日志也是记录数据更新的信息。

SQL线程

也是在Slave中创建的,当Slave检测到中继日志有更新,就会将更新的内容
同步到Slave数据库中,这样就保证了主从的数据的同步。

同步策略(sql默认异步)

  • 同步策略
    Master会等待所有的Slave都回应后才会提交,这个主从的同步的性能会严重的影响。

  • 半同步策略
    Master至少会等待一个Slave回应后提交。如何开启半同步请看链接

在mysql5.7.4后开启半同步复制会新增一个ACK Receiver线程专门用作
接收从库返回的ACK请求,这将之前Binlog Dump线程的发送和接收工作
分为了两个线程来处理

  • 异步策略
    Master不用等待Slave回应就可以提交。

  • 延迟策略
    Slave要落后于Master指定的时间。

对于不同的业务需求,有不同的策略方案,但是一般都会采用最终一致性,
不会要求强一致性,毕竟强一致性会严重影响性能。

3步曲:

  • 1.master将改变记录到二进制日志(binlog)这些记录过程叫做二进制日志事件,binary log events;
  • 2.slave将master的binary log events拷贝到它的中继日志(relay log);
  • 3.slave重做中继日志中的事件,将改变应用到自己的数据库中,mysql复制是异步的且串行化的。

复制规则:

  • 1.每个slave只有一个master
  • 2.每个slave只能有一个唯一的服务器ID
  • 3.每个master可以有多个slave
  • 4.复制的最大问题是延时

复制常见配置

中小型互联网公司的一主一从,大公司专门DBA数据库集群,容灾备份处理。

一主一从常见配置

  • 1.mysql数据库的版本需要一致

  • 2.主机从机都关闭防火墙,要互相ping的通

  • 3.现在我们用windows做主机数据库,linux做从机数据库
    (先互相测试是否能ping通)ifconfig

    1
    telnet 10.167.218.136
  • 4.主从都配置在【mysqld】结点下,都是小写
    主机windows修改my.ini配置文件,(我的是linux)主机linux修改my.cnf配置文件

  • 主节点配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    1.vim /etc/my.cnf
    [mysqld]
    ## 同一局域网内注意要唯一
    server-id=100
    ## 开启二进制日志功能,可以随便取(关键)
    log-bin=mysql-bin
    修改配置后需要重启才能生效:
    service mysql restart
    2.重启之后进入mysql:
    mysql –u root -p
    在master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
    语句
    CREATE USER 'slave'@'%' IDENTIFIED BY '@#$Rfg345634523rft4fa';
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
    flush privileges;
    语句中的%代表所有服务器都可以使用这个用户,如果想指定特定的ip,将%改成ip即可。
    查看主mysql的状态:
    show master status\G;
    记录下File和Position的值,并且不进行其他操作以免引起Position的变化。
    从哪个文件的哪一位置开始抄写。!
  • 从节点修改配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    [mysqld] 
    ## 设置server_id,注意要唯一
    server-id=101
    ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用 log-bin=mysql-slave-bin
    ## relay_log配置中继日志
    relay_log=edu-mysql-relay-bin
    修改配置后需要重启才能生效:
    service mysql restart
    重启之后进入mysql:
    mysql -uroot –p
    语法:
    change master to master_host='172.17.0.2', master_user='slave', master_password='@#$Rfg345634523rft4fa', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 2830, master_connect_retry=30;
    master_host :Master的地址
    master_port:Master的端口号
    master_user:用于数据同步的用户
    master_password:用于同步的用户的密码
    master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
    master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
    master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

    4.在从mysql中查看主从同步状态:
    show slave status \G;
    此时的SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。
    开启主从复制:
    start slave;

    5.再次查看同步状态:
    show slave status \G;
    SlaveIORunning 和 SlaveSQLRunning 都是Yes说明主从复制已经开启。
    若SlaveIORunning一直是Connecting,有下面4种原因:
    1、网络不通,检查ip端口
    2、密码不对,检查用于同步的用户名和密码
    3、pos不对,检查Master的Position
    4、mysql8特有的密码规则问题引起:
    ALTER USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY '@#$Rfg345634523rft4fa';
    将密码规则修改为:mysql_native_password
    如果需要指定想要主从同步哪个数据库,可以在master的my.cnf添加配置:
    binlog-do-db:指定mysql的binlog日志记录哪个db
    或者在slave的my.cnf添加配置:
    replicate-do-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可 replicate-ignore-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可

    6.如果想要同步所有库和表,在从mysql执行:
    STOP SLAVE SQL_THREAD; CHANGE REPLICATION FILTER REPLICATE_DO_DB = (); start SLAVE SQL_THREAD;
    如果以上步骤出现问题,可以查看日志:
    /etc/log/mysqld.log
    至此完成了mysql8主从同步搭建工作。
  • 5.主从复制需要注意的问题:

    • 1.my.cnf修改过后需要重启mysqld

      1
      2
      service mysqld restart
      systemctl restart mysqld
    • 2.重启主服务器会导致file和position的变更

      1
      2
      3
      4
      5
      show master status\G;
      这时候要注意**从服务器**的对应参数:
      master_log_file
      master_log_pos需要跟着变更
      语法:change master to master_log_file = 156, master_log_pos=’ mysql-bin.000005’
    • 3.注意防火墙的问题
      先用从机telnet主机,注意下载telnet

      1
      2
      3
      4
      5
      service iptables stop 关闭防火墙
      systemctl stop firewalld.service
      https://blog.csdn.net/shijiebei2009/article/details/40047077
      https://blog.csdn.net/ytangdigl/article/details/79796961
      注意加端口号
    • 4.密码问题mysql8用的密码

      1
      2
      https://blog.csdn.net/zhengbin9/article/details/82729861
      注意修改密码用native_password,修改后注意重启mysqld
    • 5.如果service mysqld start无法打开
      可以cat /var/log/mysqld.log查看错误信息

主从复制的作用

  • 1.做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。
  • 2.有利于架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,
    此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
  • 3.读写分离,使数据库能支撑更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,
    导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,
    保证了前台速度。
分享到