主从同步(多结构主从)

​ 可以实现数据自动同步的服务结构,大大提升了数据的安全可靠性,当正在提供服务的数据库实例宕机时,另外一台数据库实例也可以提供完整的可靠的数据。

主从前提:master必须启用binlog日志,设置server-id。

实现原理:

​ 在开启主从后,slave会开启两个进程,分别是Slave_IO、Slave_SQL。

Slave_IO:

​ 在master节点上添加一个角色并赋予replication slave权限,Slave_IO从节点slave会使用这个master授权账户去master主节点拷贝binlog日志SQL命令到slave的relay-log(中继日志)文件。会在该mysql的默认data目录生成relay-log.info记录了当前使用的中继日志文件名、偏移量、master的binlog文件名、偏移量等信息,主机名-relay-bin.index ,中继日志文件索引文件 记录了当前使用的中继文件名。主机名-relay-bin.XXXXXX中继日志文件 记录了Slave_IO从master上拷过来的SQL语句。

Slave_SQL:

​ 执行本机relay-log文件里的SQL语句,实现与Master数据一致。

主从同步有三种结构:主从、链式复制(主从从)、一主多从、互为主从。

  • 主从:至少两个数据库实例组成。A是主实例(master节点),B是从实例(slave节点)。A作为客户端时时连接使用的数据库实例,B数据库实例时时复制A服务器的binlog日志d的SQL语句执行。

    A (主)----B(从)

  • 链式复制:至少由三个数据库实例组成。A(Master)作为客户端时时连接使用的数据库实例,B(slave)实例时时复制A(master)实例的binlog日志d的SQL语句执行,但是也是作为C(slave)实例的主实例。

    A (主)----B(从,主)-----C(从)

  • 一主多从:至少由三个数据库实例组成,A(Master)作为客户端时时连接使用的数据库实例,BC..(slave)都作为A(Master)的从库都从A进行复制binlog日志SQL命令。与链式复制不同的是一主多从,从都向 同一台Master 拷贝他的binlog进行执行。

    A(主)-----BC...(从)

  • 互为主从 :至少由两个数据库实例组成,AB他们都是对方的从库,也同时是对方的主库。不管在那台上执行,对方都会拷贝binlog日志SQL命令进行执行。

    A(主,从) --- B(主,从)

  • 链式复制的搭建:

    • 一、启用master节点的binlog日志,设置server_id。若实例既为master又为slave的中间实例必须在mysqld下打开允许log_slave_updates允许级联复制。并重启服务,检查binlog是否启用成功,并备份传到到中间实例。

      # 主实例master1:192.168.4.1    (中间实例)master-slave2:192.168.4.2     从实例slave2:192.168.4.3
      # 主实例开启binlog
      sed -i '4a log_bin=master1' /etc/my.cnf
      # 主实例设置服务器ID
      sed -i '5a server_id=1' /etc/my.cnf
      # 主实例修改日志记录模式为混合模式(你还可以修改为行模式、报表模式、混合模式请参考我的这篇https://www.cnblogs.com/lqinghua/p/11675093.html)
      sed -i '6a binlog_format="Mixed"' /etc/my.cnf
      # 你还可以修改复制模式(异步模式、全同步模式、半同步模式请参考我的这篇https://www.cnblogs.com/lqinghua/p/11687636.html)
      # 重启mysql服务并检查是否正确开启了binlog
      systemctl restart mysqld && mysql -uroot -p12345 -e "show master status \G"
      mysql: [Warning] Using a password on the command line interface can be insecure.
      *************************** 1. row ***************************
                   File: master1.000001
               Position: 154
           Binlog_Do_DB: 
       Binlog_Ignore_DB: 
      Executed_Gtid_Set:
      # 正确开启了binlog二进制日志记录,现在添加从服务器角色授权,我写博客图方便就全部授权了所有数据库。
      mysql -uroot -p12345 -e 'grant replication slave on *.* to slave@"%" identified by "123456";'
      mysql -uroot -p12345 -e 'show grants for slave@"%";'
      mysql: [Warning] Using a password on the command line interface can be insecure.
      +-----------------------------------------------+
      | Grants for slave@%                            |
      +-----------------------------------------------+
      | GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' |
      +-----------------------------------------------+
      # 刷新权限
      mysql -uroot -p12345 -e "flush privileges;" 
      # 授权成功,那么开始备份数据库的数据,这边我使用mysqldump进行备份。
      # 重要1:生产环境中因为mysqldump会锁库锁表务必谨慎操作,免得影响生产业务。
      # 我这里还使用了--master-data参数用来记录当前实例的binlog日志文件名和偏移量。
      mysqldump -uroot -p12345 --master-data -B testdb userdb new1 > /tmp/fullback.sql
      # 来查看下备份的sql文件中的binlog当前文件名和偏移量,看博文的请将grep后的master1 改成你设置的名字,如果在主配置文件中没有指定叫什么 是log_bin,那么就请换成你的主机名。 
      grep master1 /tmp/fullback.sql 
      CHANGE MASTER TO MASTER_LOG_FILE='master1.000001', MASTER_LOG_POS=438;
      scp /tmp/fullback.sql root@192.168.4.2:/tmp/
      
      • 中间实例的配置(中间实例是master1(192.168.4.1)的从库,同时它也是实例slave2:192.168.4.3的主库),所以也需要打开主配置文件的binlog,并设置server_id,然后将他设置为master的从实例后,先检查是否成功。
      # 现在开始中间实例的配置,配置主配置文件/etc/my.cnf。
      sed -i '4a log_bin=master-slave2' /etc/my.cnf
      # 多个server_id不允许重复。
      sed -i '5a server_id=2' /etc/my.cnf
      # 修改日志记录模式。
      sed -i '6a binlog_format="Mixed"' /etc/my.cnf
      # 重要:因为是链式复制,本实例即为主也为从必须要打开log_slave_updates允许级联复制。
      sed -i '7a log_slave_updates' /etc/my.cnf
      # 重启mysql服务并查看是否开启记录二进制文件。
      systemctl restart mysqld && mysql -uroot -p12345 -e "show master status \G"mysql: [Warning] Using a password on the command line interface can be insecure.
      *************************** 1. row ***************************
                   File: master-slave2.000001
               Position: 154
           Binlog_Do_DB: 
       Binlog_Ignore_DB: 
      Executed_Gtid_Set:
      # 恢复从msater导过来的数据库数据。
      mysql -uroot -p12345 < /tmp/fullback.sql
      # 查看是否导入成功。
      [root@master-slave2 ~]# mysql -uroot -p12345  -e "show databases;"
      mysql: [Warning] Using a password on the command line interface can be insecure.
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | new1               |
      | performance_schema |
      | sys                |
      | testdb             |
      | userdb             |
      +--------------------+
      # 添加主实例信息。因为导入的备份的sql文件中已经含有“CHANGE MASTER TO MASTER_LOG_FILE='master1.000001', MASTER_LOG_POS=438;” 指定即可
      mysql -uroot -p12345  -e 'change master to master_user="slave",master_password="12345",master_host="192.168.4.1",master_log_file="master1.000001",master_log_pos=438;'
      # 开启同步
      mysql -uroot -p12345 -e "start slave;"
      # 查看IO线程和SQL线程
      mysql -uroot -p12345 -e "show slave status \G" | grep IO_Running
      mysql: [Warning] Using a password on the command line interface can be insecure.
                   Slave_IO_Running: Yes
      mysql -uroot -p12345 -e "show slave status \G" | grep SQL_Running |head -1
      mysql: [Warning] Using a password on the command line interface can be insecure.
                  Slave_SQL_Running: Yes
      # 那么到这里已经实现了本中间实例做master1实例的从节点。
      
      • 中间实例做从实例slave2:192.168.4.3实例的主节点。这里最主要是在主配置文件中要确定打开了log_slave_updates
      # 在确定一次是否打开了允许级联复制
      grep log_slave_updates /etc/my.cnf
      # 授权从实例同步账号
      mysql -uroot -p12345 -e 'grant replication slave on *.* to slave@"%" identified by "123456";'
      mysql -uroot -p12345 -e 'show grants for slave@"%";'
      mysql: [Warning] Using a password on the command line interface can be insecure.
      +-----------------------------------------------+
      | Grants for slave@%                            |
      +-----------------------------------------------+
      | GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' |
      +-----------------------------------------------+
      # 刷新权限
      mysql -uroot -p12345 -e "flush privileges;" 
      # 导出数据库复制到从实例slave2:192.168.4.3
      mysqldump -uroot -p12345 --master-data -B testdb userdb new1 > /tmp/fullbackmaster2.sql
      scp /tmp/fullbackmaster2.sql root@192.168.4.3:/tmp
      
      • 最后一步修改从实例192.168.4.3的主配置文件/etc/my.cnf server_id ,并导入数据,添加master信息,开启同步。
      # 设置server_id,并重启服务
      sed -i '5a server_id=3' /etc/my.cnf && systemctl restart mysqld
      # 导入备份实例数据
      mysql -uroot -p12345 -e "show databases;"
      mysql: [Warning] Using a password on the command line interface can be insecure.
      +--------------------+
      | Database           |
      +--------------------+
      | information_schema |
      | mysql              |
      | new1               |
      | performance_schema |
      | sys                |
      | testdb             |
      | userdb             |
      +--------------------+
      # 得到备份文件中的logfile名和偏移量
      grep master-slave2 /tmp/fullbackmaster2.sql 
      CHANGE MASTER TO MASTER_LOG_FILE='master-slave2.000001', MASTER_LOG_POS=797351;
      # 设定同步master实例的信息
      mysql -uroot -p12345 -e 'change  master to  master_user="slave",master_password="123456",master_host="192.168.4.2",master_log_file="master-slave2.000001",master_log_pos=797351;'
      # 查看IO线程和SQL线程是否OK
      mysql -uroot -p12345 -e "show slave status \G" | grep IO_Running
      mysql: [Warning] Using a password on the command line interface can be insecure.
                   Slave_IO_Running: Yes
      mysql -uroot -p12345 -e "show slave status \G" | grep SQL_Running |head -1
      mysql: [Warning] Using a password on the command line interface can be insecure.
                  Slave_SQL_Running: Yes
      
      • 测试阶段:
      # 在实例master1(192.168.4.1)上创建一个数据库,创建一个表,插入一条数据看下。
      mysql -uroot -p12345 -e 'create database test1;'
      mysql -uroot -p12345 -e 'create table test1.tb1(id int(10));'
      mysql -uroot -p12345 -e 'insert into  test1.tb1 values (1),(2),(3);'
      for i in {1..3} ;do ssh root@192.168.4.$i 'mysql -uroot -p12345 -e "select * from test1.tb1;"' ; done
      mysql: [Warning] Using a password on the command line interface can be insecure.
      id
      1
      2
      3
      mysql: [Warning] Using a password on the command line interface can be insecure.
      id
      1
      2
      3
      mysql: [Warning] Using a password on the command line interface can be insecure.
      id
      1
      2
      3
      
posted @ 2019-10-17 00:24  不愿透露姓名的先生  阅读(787)  评论(0编辑  收藏  举报