image.png | left | 682x296

复制是 MySQL 的一项功能,允许服务器将更改从一个实例复制到另一个实例。

1)主服务器将所有数据和结构更改记录到二进制日志中。
2)从属服务器从主服务器请求该二进制日志并在本地应用其内容。
3)IO:请求主库,获取上一次执行过的新的事件,并存放到relaylog
4)SQL:从relaylog中将sql语句翻译给从库执行

1)两台或两台以上的数据库实例
2)主库要开启二进制日志
3)主库要有复制用户
4)主库的server_id和从库不同
5)从库需要在开启复制功能前,要获取到主库之前的数据(主库备份,并且记录binlog当时位置)
6)从库在第一次开启主从复制时,时必须获知主库:ip,port,user,password,logfile,pos
7)从库要开启相关线程:IO、SQL
8)从库需要记录复制相关用户信息,还应该记录到上次已经从主库请求到哪个二进制日志
9)从库请求过来的binlog,首先要存下来,并且执行binlog,执行过的信息保存下来

++主库:++

1)主库binlog:记录主库发生过的修改事件
2)dump thread:给从库传送(TP)二进制日志线程

++从库:++

1)relay-log(中继日志):存储所有主库TP过来的binlog事件
2)master.info:存储复制用户信息,上次请求到的主库binlog位置点
3)IO thread:接收主库发来的binlog日志,也是从库请求主库的线程
4)SQL thread:执行主库TP过来的日志

++原理++

1)通过change master to语句告诉从库主库的ip,port,user,password,file,pos
2)从库通过start slave命令开启复制必要的IO线程和SQL线程
3)从库通过IO线程拿着change master to用户密码相关信息,连接主库,验证合法性
4)从库连接成功后,会根据binlog的pos问主库,有没有比这个更新的
5)主库接收到从库请求后,比较一下binlog信息,如果有就将最新数据通过dump线程给从库IO线程
6)从库通过IO线程接收到主库发来的binlog事件,存储到TCP/IP缓存中,并返回ACK更新master.info
7)将TCP/IP缓存中的内容存到relay-log中
8)SQL线程读取relay-log.info,读取到上次已经执行过的relay-log位置点,继续执行后续的relay-log日志,执行完成后,更新relay-log.info

修改主库的配置文件

  1. vim /etc/my.cnf
  2. #在[mysqld]标签下开启binlog和server_id
  3. log_bin=mysql-bin
  4. server_id =1

重启数据库(两种方式)后进入

  1. [root@db01 ~]# /etc/init.d/mysqld restart
  2. [root@db01 ~]# systemctl restart mysqld

查看日志状态

  1. mysql> show master status;
  2. +------------------+----------+--------------+------------------+-------------------+
  3. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  4. +------------------+----------+--------------+------------------+-------------------+
  5. | mysql-bin.000003 | 120 | | | |
  6. +------------------+----------+--------------+------------------+-------------------+
  7. 1 row in set (0.00 sec)

创建一个复制用户

  1. mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123';
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> show master status; #binlog pos 变成了324
  4. +------------------+----------+--------------+------------------+-------------------+
  5. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  6. +------------------+----------+--------------+------------------+-------------------+
  7. | mysql-bin.000003 | 324 | | | |
  8. +------------------+----------+--------------+------------------+-------------------+
  9. 1 row in set (0.00 sec)

修改从库的配置文件

  1. vim /etc/my.cnf
  2. #在[mysqld]标签下开启server_id 从库server_id不可与主库相同,从库之间可以一致
  3. server_id =2

重启数据库后进入执行change master to 语句

  1. mysql> change master to
  2. master_host='10.0.0.51', #主库ip
  3. master_user='rep', #主从复制用户
  4. master_password='123', #主从复制用户密码
  5. master_log_file='mysql-bin.000003', #binlog
  6. master_log_pos=324, #binlog 起始点
  7. master_port=3306; #数据库端口

开启slave

  1. mysql> start slave;

查看slave状态(yes开启成功)

  1. mysql> show slave status\G

image.png | left | 826x461

查看主库上的库

  1. mysql> show databases;
  2. +--------------------+
  3. | Database |
  4. +--------------------+
  5. | information_schema |
  6. | mysql |
  7. | performance_schema |
  8. | test |
  9. +--------------------+
  10. 4 rows in set (0.00 sec)

创建一个新库zeq

  1. mysql> create database zeq;
  2. Query OK, 1 row affected (0.00 sec)
  3. mysql> show databases;
  4. +--------------------+
  5. | Database |
  6. +--------------------+
  7. | information_schema |
  8. | mysql |
  9. | performance_schema |
  10. | test |
  11. | zeq |
  12. +--------------------+
  13. 5 rows in set (0.00 sec)

查看从库

  1. mysql> show databases; #从库上已经复制过来了
  2. +--------------------+
  3. | Database |
  4. +--------------------+
  5. | information_schema |
  6. | mysql |
  7. | performance_schema |
  8. | test |
  9. | zeq |
  10. +--------------------+
  11. 5 rows in set (0.01 sec)

IO线程

++连接主库++

1)user password ip port
2)网络:不通,延时高,防火墙

++请求binlog++

1)binlog不存在或者损坏

++更新relay-log和master.info++

SQL线程
1)relay-log出现问题
2)从库做写入了

  • 操作对象已存在(create)
  • 操作对象不存在(insert update delete drop truncate alter)
  • 约束问题、数据类型、列属性

处理方法一:

  1. #临时停止同步
  2. mysql> stop slave;
  3. #将同步指针向下移动一个(可重复操作)
  4. mysql> set global sql_slave_skip_counter=1;
  5. #开启同步
  6. mysql> start slave;

处理方法二:

  1. #编辑配置文件
  2. vim /etc/my.cnf
  3. #在[mysqld]标签下添加以下参数
  4. slave-skip-errors=1032,1062,1007

但是以上操作都是有风险存在的

处理方法三:

1)重新备份数据库,恢复到从库
2)给从库设置为只读

  1. #在命令行临时设置
  2. mysql> set global read_only=1;
  3. #在配置文件中永久生效/etc/my.cnf
  4. read_only=1

企业中一般会延时3-6小时

延时从库配置方法
从库操作

  1. #停止主从
  2. mysql>stop slave;
  3. #设置延时为180秒
  4. mysql>change master to master_delay = 180;
  5. #开启主从
  6. mysql>start slave;
  7. #查看状态
  8. mysql> show slave status \G
  9. SQL_Delay: 60
  10. 3.延时从库停止方法
  11. #停止主从
  12. mysql> stop slave;
  13. #设置延时为0
  14. mysql> CHANGE MASTER TO MASTER_DELAY = 0;
  15. #开启主从
  16. mysql> start slave;

image.png | left | 826x420

  1. 主库执行
  2. SET GLOBAL rpl_semi_sync_master_enabled = 0;
  3. SET GLOBAL rpl_semi_sync_master_wait_no_slave = 0;
  4. 从库执行:
  5. SET GLOBAL rpl_semi_sync_slave_enabled = 0;

版权声明:本文为zeq912原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/zeq912/p/10095026.html