一、MySQL主从搭建

搭建主从架构的MySQL常用的有两种实现方式:

  1. 基于binlog的fileName + postion模式完成主从同步。
  2. 基于gtid完成主从同步搭建。

本篇就介绍如何使用第一种方式完成MySQL主从环境的搭建。

基于fileName和position去实现主从复制,所谓的fileName就是bin-log的name,position指的是slave需要从master的binlog的哪个位置开始同步数据。

这种模式同步数据方式麻烦的地方就是需要我们自己通过如下的命令去查找应该从哪个bin-log的哪个position去开始同步。

二、主库

2.1、确定主库的binlog是否开启

命令:show variables like 'bin-log'

原因:了解MySQL中常见的三个日志:

  1. 单机MySQL的undolog日志中记录着如何将现有的数据恢复成被修改前的旧数据。
  2. 单机MySQL的redolog. 中记录事物日志。
  3. 主从模式的MySQL通过bin-log日志同步数据。

2.2、骚气的命令

  1. grant replication slave on *.* to MySQLsync@"127.0.0.1" identified by "MySQLsync123";

这条命令是在干什么呢?

捋一下思路:我们做主从同步,在主库这边我们其实会单独创建一个账号用于实现主从同步。下面的命令其实就会帮我们创建出 username=mysqlsync password=mysqlsync123的账户专门用户主从同步使用。

执行完上面的命令后,执行如下的命令查看上面的grant执行结果:

  1. select user, host from mysql.user like '%mysqlsync%'

2.3、记录主库的master状态

注意主库的查看主库当前是第几个binlog,已经数据的position。

因为一会从库就是根据这两个信息知道自己该从主库的第几个binlog的什么positon开始同步。

三、从库

3.1、从库和主库保持同步

从库执行change语句,和主库保持同步

  1. CHANGE MASTER TO
  2. MASTER_HOST='10.157.23.158',
  3. MASTER_USER='mysqlsync',
  4. MASTER_PASSWORD='mysqlsync123',
  5. MASTER_PORT=8882,
  6. MASTER_LOG_FILE='mysql-bin.000008',
  7. MASTER_LOG_POS=1013;
  8. CHANGE MASTER TO
  9. MASTER_HOST = '${new_master_ip}',
  10. MASTER_USER = '${user}',
  11. MASTER_PASSWORD = '${password}',
  12. MASTER_PORT = ${new_master_port},
  13. master_auto_position = 1;
  14. CHANGE MASTER TO
  15. MASTER_HOST = '10.157.23.123',
  16. MASTER_USER = 'mysqlsync',
  17. MASTER_PASSWORD = 'mysqlsync123',
  18. MASTER_PORT = 8882,
  19. master_auto_position = 1;

3.2、开启主从同步

  1. start slave
  2. show slave status \G

当我们可以看到 io线程和sql线程的状态都是yes时,说明此刻主从同步已经搭建完成了。

3.3、从库:如何断开主从

  1. stop slave io_thread
  2. stop slave sql_thread

3.4、主库:如何断开主从

把用于进行主从同步的账号删除就好了

  1. drop user ${user}@${slave_ip}

四、中断处理

中断处理部分说的是,一开始我们搭建主从很可能并不是一番风顺的,就比如上面的Slave_IO_Running和Slave_SQL_Running很可能处于NO的状态。下面介绍一下常见的解决方式。

4.1、Slave_IO_Running异常

Slave_IO_Running:no/connecting

这说明从库连接不上主库,或者是一直处于正在连接的状态。

可能是主库没有对从库进行授权,如果已经授权了那么重启一下salve。

另一种原因就是master和slave的mysqld相关配置文件中,配置了相同server_id。

还有可能你在执行change master命令时,输入的主库相关的信息本来就是错误的。

4.2、Slave_Sql_Running异常

Slave_Sql_Running:no

一般这种情况是bin-log中的sql出问题了。

第一种情况:可能我们配置了slave只能读,但是却有写请求打过来了,导致slave不能继续往下执行。

第二种解决思路:让slave跳过有问题的这个事件,但是还是得把事件的原因查明白,不然不推荐直接跳过这个事件。

  1. stop slave;
  2. set global sql_slave_skip_counter=1;
  3. start slave;

第三种思路:我们提前配置好错误号机制,当slave在同步的过程中,碰到我们配置的错误号采取自动跳过的机会而不再去默认的终止同步数据。

  1. # 一般我们可以像下面这样,在my.cnf中的[MySQLd]的启动参数中添加如下内容
  2. --slave-skip-errors=1062,1053
  3. --slave-skip-errors=all
  4. --slave-skip-errors=ddl_exist_errors
  5. # 通过如下语句查看当前MySQL配置的变量
  6. MySQL> show variables like 'slave_skip%';
  7. # 通过如下命令可以查看到出现的errorno
  8. show slave status; # 观察Last_Errno
  9. # 常见的errorno
  10. 1007:数据库已存在,创建数据库失败
  11. 1008:数据库不存在,删除数据库失败
  12. 1050:数据表已存在,创建数据表失败
  13. 1051:数据表不存在,删除数据表失败
  14. 1054:字段不存在,或程序文件跟数据库有冲突
  15. 1060:字段重复,导致无法插入
  16. 1061:重复键名
  17. 1068:定义了多个主键
  18. 1094:位置线程ID
  19. 1146:数据表缺失,请恢复数据库
  20. 1053:复制过程中主服务器宕机
  21. 1062:主键冲突 Duplicate entry '%s' for key %d

第四种思路:手动给slave调整fileName和position的位置(如何允许放弃之前的一部分数据,而从当前最新的数据开始同步)

  1. # 停掉slave
  2. slave stop
  3. # 进入master
  4. # 停止master的写操作
  5. # 查看master中当前bin-log和position
  6. show master status
  7. # 切换回slave从新根据最新的position和bin-log进行同步
  8. # 进入master,开启master的写操作

五、流程

通过fileName和position完成定位,从库会向主库发送命令,BINLOG_DUMP ,命令中包含有positon和fileName, 主库获取到这些信息之后,指定name到指定position往从库发送bin-log

六、可能会遇到的问题

6.1、问题一:

change master时报错了

报错说:ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.

原因是我之前使用过gtid进行同步数据,当时将master_auto_position设置成了1,再想使用手动指定position的主从同步方式需要得像下面这样,change回去。

  1. CHANGE MASTER TO
  2. MASTER_AUTO_POSITION=0;

6.2、问题二:

如果我随便写了个position再搭建主从时,会发生什么?

下面的 MASTER_LOG_POS = 1003 就是我随便写的一个position,然后你可以看到两个现象

  1. Slave_IO_Running : No
  2. Last_IO_Error 位置报了个严重的错误
  1. mysql> CHANGE MASTER TO
  2. -> MASTER_HOST='10.157.23.xxx',
  3. -> MASTER_USER='mysqlsync',
  4. -> MASTER_PASSWORD='mysqlsync123',
  5. -> MASTER_PORT=8882,
  6. -> MASTER_LOG_FILE='mysql-bin.000008',
  7. -> MASTER_LOG_POS=1003;
  8. Query OK, 0 rows affected, 2 warnings (0.01 sec)
  9. mysql> start slave;
  10. Query OK, 0 rows affected (0.00 sec)
  11. mysql> show slave status\G;
  12. *************************** 1. row ***************************
  13. Slave_IO_State:
  14. Master_Host: 10.157.23.158
  15. Master_User: mysqlsync
  16. Master_Port: 8882
  17. Connect_Retry: 60
  18. Master_Log_File: mysql-bin.000008
  19. Read_Master_Log_Pos: 1003
  20. Relay_Log_File: relay-log.000002
  21. Relay_Log_Pos: 320
  22. Relay_Master_Log_File: mysql-bin.000008
  23. Slave_IO_Running: No
  24. Slave_SQL_Running: Yes
  25. Replicate_Do_DB:
  26. Replicate_Ignore_DB:
  27. Replicate_Do_Table:
  28. Replicate_Ignore_Table:
  29. Replicate_Wild_Do_Table:
  30. Replicate_Wild_Ignore_Table: mysql.%,test.%
  31. Last_Errno: 0
  32. Last_Error:
  33. Skip_Counter: 0
  34. Exec_Master_Log_Pos: 1003
  35. Relay_Log_Space: 521
  36. Until_Condition: None
  37. Until_Log_File:
  38. Until_Log_Pos: 0
  39. Master_SSL_Allowed: No
  40. Master_SSL_CA_File:
  41. Master_SSL_CA_Path:
  42. Master_SSL_Cert:
  43. Master_SSL_Cipher:
  44. Master_SSL_Key:
  45. Seconds_Behind_Master: NULL
  46. Master_SSL_Verify_Server_Cert: No
  47. Last_IO_Errno: 1236
  48. Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event 'mysql-bin.000008' at 1003, the last event read from './mysql-bin.000008' at 123, the last byte read from './mysql-bin.000008' at 1022.'
  49. Last_SQL_Errno: 0
  50. Last_SQL_Error:
  51. Replicate_Ignore_Server_Ids:
  52. Master_Server_Id: 2787871625
  53. Master_UUID: a5f1d6b2-8f9a-11ea-8138-b8599f2ef058
  54. Master_Info_File: mysql.slave_master_info
  55. SQL_Delay: 0
  56. SQL_Remaining_Delay: NULL
  57. Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
  58. Master_Retry_Count: 86400
  59. Master_Bind:
  60. Last_IO_Error_Timestamp: 200529 10:22:46
  61. Last_SQL_Error_Timestamp:
  62. Master_SSL_Crl:
  63. Master_SSL_Crlpath:
  64. Retrieved_Gtid_Set:
  65. Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222,
  66. 40efcb1b-7a1f-11ea-84ac-b8599f229b38:1-20,
  67. 7e2dcb21-7d3b-11ea-aa0c-b8599f2ef058:1-18,
  68. 9e6027f2-7ae9-11ea-ac13-b8599f2ef058:1409-7176,
  69. a5f1d6b2-8f9a-11ea-8138-b8599f2ef058:6-9:12-13:15,
  70. e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11
  71. Auto_Position: 0
  72. Replicate_Rewrite_DB:
  73. Channel_Name:
  74. Master_TLS_Version:
  75. 1 row in set (0.00 sec)

6.3、问题三:

假设我们有这样的场景:

场景:现在主库有7条数据,从库有5条数据,搭建主从时如何让从库从第六条开始同步?

这种情况仅仅是我们在做这种小实验,为啥这样说呢?如果是为线上的业务搭建搭建主从MySQL的话,大概率我们会清空主库然后再做同步。如果数据很重要,我们会对主库中的数据进行一次全量拷贝到从库(拷贝var包)。再做主从同步。

在线上的环境中,主从的数据是会强一致的,从库只会接受业务方的读流量,也许网络环境很恶劣从库同步的速度明显比主库写入到速度低,但是只要从库没有说跳过了某个binlog而少同步了某条记录,我们都可以认为它们是正常的主从同步。不会出现主从中断的情况。

线上的环境中什么情况下会出现主从中断呢?比如说,从库同步数据时,从库同步binlog时丢了一条数据,这时业务上突然来了条update语句,要更新数据,然后从库美滋滋的回放在主库dump过来的binlog时发现,竟然自己没有需要更新的这条记录,就会报错,这时为了业务止损,我们要在第一时间下线从库,然后去分析哪里出现问题了。

针对这个实验我们这样去binlog中查看第5,6条数据的position,然后在从库中使用相应的position完成主从数据的同步。

进入主库,通过下面的命令查看binlog

  1. mysqlbinlog --no-defaults -vv --base64-output=decode-rows ../var/mysql-bin.000008 | less

找到了指定的binlog和指定的end_log_pos

比如从库中没有第10,11条数据,我们就能通过end_log_pos = postion = 1013完成定位。

  1. CHANGE MASTER TO
  2. MASTER_HOST='10.157.23.158',
  3. MASTER_USER='mysqlsync',
  4. MASTER_PASSWORD='mysqlsync123',
  5. MASTER_PORT=8882,
  6. MASTER_LOG_FILE='mysql-bin.000008',
  7. MASTER_LOG_POS=1013;

开启同步,并查看状态

  1. start slave;
  2. show slave status\G;

再去查看从库就能发现,从你指定的position开始往后和主库的数据保持同步的。


6.4、问题四:

问:主从接流量的情况是怎样的?业务的CRUD请求是如何被主从平分消费的?

答:默认这种架构下是读写分离,也就是说,仅读流量会打到从库中

问:那如果我们在从库所在的机器上本地登陆,然后手动执行删除的操作能成功吗?

答:是的,可以执行成功。

问:我可以简单粗暴的限制从库仅读吗?

答:可以的,像下面这样

  1. mysql> show variables like '%read_only%';
  2. +-----------------------+-------+
  3. | Variable_name | Value |
  4. +-----------------------+-------+
  5. | innodb_read_only | OFF |
  6. | read_only | OFF |
  7. | super_read_only | OFF |
  8. | transaction_read_only | OFF |
  9. | tx_read_only | OFF |
  10. +-----------------------+-------+
  11. 5 rows in set (0.00 sec)
  12. set global read_only=0; #关闭只读,可以读写
  13. set global read_only=1; #开始只读模式

6.5、问题五:

假设主库中有1~7 共7条数据,从库中有1~5五条数据。也就是说,主库从库中前五条数据一样,但是主库比从库多了两条新数据。

这时我们搭建主从同步时搞一搞事情,重复这个动作:在从库断开同步,然后查到主库第一个binlog中的数据的记录,确定我们要查找的position,再重新构建主从环境。观察一下从库这边数据的同步情况,以及会出现什么问题?从库这边的数据会成为double吗?

答:数据不会double的


6.6、问题六:

假设从库执行changemaster时,主库MASTER_HOST填错了:

在查看slave 状态时,我们可以看到Last_IO_Error列有报错提示: error connecting to master

  1. mysql> CHANGE MASTER TO
  2. -> MASTER_HOST='10.157.23.158',
  3. -> MASTER_USER='mysqlsync',
  4. -> MASTER_PASSWORD='mysqlsync123',
  5. -> MASTER_PORT=8882,
  6. -> MASTER_LOG_FILE='mysql-bin.000008',
  7. -> MASTER_LOG_POS=1013;
  8. Query OK, 0 rows affected, 2 warnings (0.01 sec)
  9. mysql> start slave;
  10. Query OK, 0 rows affected (0.00 sec)
  11. mysql> show slave status\G;
  12. *************************** 1. row ***************************
  13. Slave_IO_State: Connecting to master
  14. Master_Host: 10.157.23.123
  15. Master_User: mysqlsync
  16. Master_Port: 8882
  17. Connect_Retry: 60
  18. Master_Log_File: mysql-bin.000008
  19. Read_Master_Log_Pos: 1003
  20. Relay_Log_File: relay-log.000001
  21. Relay_Log_Pos: 4
  22. Relay_Master_Log_File: mysql-bin.000008
  23. Slave_IO_Running: Connecting
  24. Slave_SQL_Running: Yes
  25. Replicate_Do_DB:
  26. Replicate_Ignore_DB:
  27. Replicate_Do_Table:
  28. Replicate_Ignore_Table:
  29. Replicate_Wild_Do_Table:
  30. Replicate_Wild_Ignore_Table: mysql.%,test.%
  31. Last_Errno: 0
  32. Last_Error:
  33. Skip_Counter: 0
  34. Exec_Master_Log_Pos: 1003
  35. Relay_Log_Space: 154
  36. Until_Condition: None
  37. Until_Log_File:
  38. Until_Log_Pos: 0
  39. Master_SSL_Allowed: No
  40. Master_SSL_CA_File:
  41. Master_SSL_CA_Path:
  42. Master_SSL_Cert:
  43. Master_SSL_Cipher:
  44. Master_SSL_Key:
  45. Seconds_Behind_Master: NULL
  46. Master_SSL_Verify_Server_Cert: No
  47. Last_IO_Errno: 2003
  48. Last_IO_Error: error connecting to master 'mysqlsync@10.157.23.123:8882' - retry-time: 60 retries: 1
  49. Last_SQL_Errno: 0
  50. Last_SQL_Error:
  51. Replicate_Ignore_Server_Ids:
  52. Master_Server_Id: 0
  53. Master_UUID:
  54. Master_Info_File: mysql.slave_master_info
  55. SQL_Delay: 0
  56. SQL_Remaining_Delay: NULL
  57. Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
  58. Master_Retry_Count: 86400
  59. Master_Bind:
  60. Last_IO_Error_Timestamp: 200529 10:13:34
  61. Last_SQL_Error_Timestamp:
  62. Master_SSL_Crl:
  63. Master_SSL_Crlpath:
  64. Retrieved_Gtid_Set:
  65. Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222,
  66. 40efcb1b-7a1f-11ea-84ac-b8599f229b38:1-20,
  67. 7e2dcb21-7d3b-11ea-aa0c-b8599f2ef058:1-18,
  68. 9e6027f2-7ae9-11ea-ac13-b8599f2ef058:1409-7176,
  69. a5f1d6b2-8f9a-11ea-8138-b8599f2ef058:6-9:12-13:15,
  70. e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11
  71. Auto_Position: 0
  72. Replicate_Rewrite_DB:
  73. Channel_Name:
  74. Master_TLS_Version:

6.7、问题七:

假设这种场景:假设主从现在的数据是一致的,然后你在从库所在的机器上本地登陆,然后手动删除一条,再从主库写入数据,那从库还能同步成功吗?

答:从库依然会同步成功,但是其实这时候已经算是事故了,主从数据不一致,万一业务打来一条sql刚好使用你删的数据,那就会报错。

如果觉得对你有帮助欢迎关注我,后面还会分享通过gtid搭建主从mysql以及其他相关的知识点

### MySQL主从搭建Position的更多相关文章

  1. mysql 主从搭建步骤

    mysql 主从搭建步骤 1:主库开启master端bin-log 2:主库创建备份用户 3:主库全备 4:从库导入全备数据 5:从库修改change master to信息 6:从库slave st ...

  2. SQL Server、MySQL主从搭建,EF Core读写分离代码实现

    一.SQL Server的主从复制搭建 1.1.SQL Server主从复制结构图 SQL Server的主从通过发布订阅来实现 1.2.基于SQL Server2016实现主从 新建一个主库&quo ...

  3. MySQL主从搭建

    主服务器配置 1.编辑配置文件 # 如果不存在,就手动创建一个 vim /etc/my.cnf 在配置文件加入如下值: [mysqld] # 唯一的服务辨识号,数值位于 1 到 2^32-1之间. # ...

  4. MySql主从搭建详细步骤

    环境: linux64位,一台机器两个实例,主库3306端口,从库3307端口 步骤: 一.下载安装 先下载安装mysql,这里使用了5.7.21版本,具体过程不做详细说明,可自行查资料如何下载 二. ...

  5. mysql主从搭建之诡异事件

    今天在搭建主从后出现了主库system账号丢失INSERT权限的情况,记录如下 主库: system账号权限同root权限,并且mysql库已经删除 从库: mysql库存在,无system账号 主从 ...

  6. MariaDB(Mysql)-主从搭建

    卸载过程: 停止服务:systemctl stop mariadb 查询安装包:rpm -qa | grep mariadb 卸载: rpm -e mariadb-server rpm -e mari ...

  7. mysql主从搭建操作

    1.搭建说明准备工作:主从库已安装mysql软件以及xtracbackup备份工具.具体操作可参见mysql rpm安装文档. 介质 版本操作系统 Red Hat Enterprise Linux S ...

  8. mysql 主从搭建

    主要搭建步骤如下: 1.打开binlog,设置server_id     打开主库的--log-bin,并设置server_id 2.主库授权                --最好也在从库对主库授权 ...

  9. mysql之 MySQL 主从基于position复制原理概述

    1 .主从复制简介MySQL 主从复制就是将一个 MySQL 实例(Master)中的数据实时复制到另一个 MySQL 实例(slave)中,而且这个复制是一个异步复制的过程.实现整个复制操作主要由三 ...

随机推荐

  1. 题目分享Y

    题意:给出一个n个点n条边的图且不一定连通(原题面为每个节点出度为1),相邻节点不能同时被选,每个节点有其对应价值,求最多能获得多少价值?n<=1e6,val[i]<=1e6 分析:很容易 ...

  2. Spring官网阅读(十)Spring中Bean的生命周期(下)

    文章目录 生命周期概念补充 实例化 createBean流程分析 doCreateBean流程分析 第一步:factoryBeanInstanceCache什么时候不为空? 第二步:创建对象(crea ...

  3. java基础篇 之 接口

    组合接口时的名字冲突: 看下面这段代码: interface I1 { int f(); } interface I2 { void f(); } interface I3 { int f(int a ...

  4. 字节码编程,Byte-buddy篇一《基于Byte Buddy语法创建的第一个HelloWorld》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 相对于小傅哥之前编写的字节码编程: ASM.Javassist 系列,Byte Bu ...

  5. 使用PXE+Kickstart无人值守安装服务

    一.      配置DHCP服务程序 1)      按照图在虚拟机的虚拟网络编辑器中关闭自身的DHCP服务. 2)      当挂载好光盘镜像并把Yum仓库文件配置妥当后,就可以安装DHCP服务程序 ...

  6. 数组的操作。1,JS数组去重。2,把数组中存在的某个值,全部找出来。3在JS数组指定位置插入元素。。。

    1,数组去重 let arr = [1,2,3,4,5,6,1,2,3,'a','b','a']; let temp = []; // 作为存储新数组使用 for(let i = 0; i < ...

  7. Altera特殊管脚的使用

  8. js--bom对象

    bom:browser object model **navigator:获取浏览器的信息 **screen:获取屏幕的相关信息 **location:请求的url地址 **获取请求的url地址:lo ...

  9. CentOS7编译和安装GCC7.5

    CentOS7编译和安装GCC7.5 一.    环境介绍: CentOS7 虚拟机连上了互联网(为什么要强调这点呢,因为CentOS7每次进入系统,都需要手动点击右上角的Connect,才能连上互联 ...

  10. Python --函数学习3 (将函数存储在模块中)

    将函数存储在模块 函数可以将代码块和主程序分离,通过给函数指定描述性名称,可以让主程序更加容易理解,还可以更进一步,将函数存储在模块的独立文件中,再将模块导入到主程序.import 语句允许再当前运行 ...