Mysql主从复制原理及配置

Mysql主从架构

参考博客:https://blog.csdn.net/hguisu/article/details/7325124

复制概述

将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。

1.1 mysql支持的复制类型

  • 基于语句的复制:在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
  • 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
  • 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。

1.2 复制解决的问题

  • 数据分布
  • 负载均衡
  • 备份
  • 高可用性和容错行

1.3 复制工作过程

  • 1、master将改变记录到二进制日志中(binary log events);
  • 2、slave将master的binary log events拷贝到它的中继日志(relay log);
  • 3、slave重做中继日志中的事件,将改变反映它自己的数据。

img

​ 该过程的第一部分就是master记录二进制日志。在每个事务更新数据完成之前,master在二日志记录这些改变。MySQL将事务串行的写入二进制日志,即使事务中的语句都是交叉执行的。在事件写入二进制日志完成后,master通知存储引擎提交事务。
​ 下一步就是slave将master的binary log拷贝到它自己的中继日志。首先,slave开始一个工作线程——I/O线程。I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。
SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。
此外,在master中也有一个工作线程:和其它MySQL的连接一样,slave在master中打开一个连接也会使得master开始一个线程。复制过程有一个很重要的限制——复制在slave上是串行化的,也就是说master上的并行更新操作不能在slave上并行操作。

主从复制配置

  • 准备两台Mysql数据库服务器Master和Slave。
  • 环境:
    • Master:192.168.0.107
    • Slave:192.168.0.103

部署mysql

[root@gumi ~]# yum install mariadb mariadb-server -y

[root@gumi ~]# systemctl start mariadb.service
[root@gumi ~]# mysql_secure_installation
#初始化mysql

创建复制账号

1、在master的数据库中建立备份账户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中。

MariaDB [(none)]> grant replication slave,reload,super on *.* to backup@'192.168.0.103' identified by '1' ;
Query OK, 0 rows affected (0.00 sec)

建立一个backup账户,并且只能从192.168.0.103这个地址登录,密码为1.

拷贝数据

过程:确保主从数据库的数据起始相同。

完全新安装的主从服务器这一步则不需要。

配置master

  • 打开二进制日志。

    [root@gumi ~]# vim /etc/my.cnf
    [mysqld]
    server-id=1
    log-bin=mysql-bin
    
    [root@gumi ~]# systemctl restart mysql
    
    MariaDB [(none)]> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000001 |      245 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    

配置slave

[mysqld]
log_bin=mysql-bin
server_id=2
relay_log=mysq-relay-bin
log_slave_updataes=1
read_only=1

server_id:必须且唯一

log_bin:开启的二进制文件

relay_log:配置中继日志,log_slave_updates表示slave将复制事件写进自己的二进制日志。

read_only:尽量使用read_only,它防止改变数据。但是,read_only并不是很实用,特别是那些需要在salve上创建表的应用。

启动slave

下面就是让slave连接master并且开始重做master二进制日志中的时间。

  • 你不应该用配置文件进行该操作,而应该使用CHANGE MASTER TO语句,该语句可以完全取代对配置文件的修改,而且它可以为slave指定不同的master,而不需要停止服务器。
MariaDB [(none)]> change master to master_host='192.168.0.107', master_user='backup',master_password='1',master_log_file='mysql-bin.000001',master_log_pos=0;
Query OK, 0 rows affected (0.00 sec)

MASTER_LOG_POS的值为0,因为它是日志的开始位置。

你可以用SHOW SLAVE STATUS语句查看slave的设置是否正确:

MariaDB [(none)]> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.0.107
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 4
               Relay_Log_File: mysq-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000001
          Exec_Master_Log_Pos: 4
1 row in set (0.00 sec)

表明slave还没有开始复制过程。日志的位置为4而不是0,这是因为0只是日志文件的开始位置,并不是日志位置。实际上,MySQL知道的第一个事件的位置是4。

为了开始复制,可以运行: START SLAVE

运行show slave status查看输出结果

MariaDB [(none)]> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.107
                  Master_User: backup
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 245
               Relay_Log_File: mysq-relay-bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
          Exec_Master_Log_Pos: 245
              Relay_Log_Space: 822
1 row in set (0.00 sec)

这里可以看到:

 Slave_IO_Running: Yes
 Slave_SQL_Running: Yes

slave的I/0和SQL线程都已经开始运行。

此时,在Master上输入show processlist\G可以看到slave的I/0线程创建 的连接。

MariaDB [(none)]> show processlist\G
*************************** 1. row ***************************
      Id: 4
    User: backup
    Host: 192.168.0.103:54236
      db: NULL
 Command: Binlog Dump
    Time: 123
   State: Master has sent all binlog to slave; waiting for binlog to be updated
    Info: NULL
Progress: 0.000
*************************** 2. row ***************************
      Id: 5
    User: root
    Host: localhost
      db: NULL
 Command: Query
    Time: 0
   State: NULL
    Info: show processlist
Progress: 0.000
2 rows in set (0.00 sec)

在slaver中可以看到线程

MariaDB [test]> show processlist\G
*************************** 3. row ***************************
      Id: 4
    User: system user
    Host: 
      db: NULL
 Command: Connect
    Time: 61
   State: Slave has read all relay log; waiting for the slave I/O thread to update it
    Info: NULL
Progress: 0.000
3 rows in set (0.00 sec)

深入了解复制

posted @ 2021-03-02 16:14  Gumi-21  阅读(31)  评论(0)    收藏  举报