基于bin-log&position搭建主从架构MySQL

一、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、骚气的命令

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

这条命令是在干什么呢?

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

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

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

2.3、记录主库的master状态

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

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

image-20200526192749846

三、从库

3.1、从库和主库保持同步

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

CHANGE MASTER TO
    MASTER_HOST='10.157.23.158',MASTER_USER='mysqlsync',MASTER_PASSWORD='mysqlsync123',MASTER_PORT=8882,MASTER_LOG_FILE='mysql-bin.000008',MASTER_LOG_POS=1013;

  
 CHANGE MASTER TO
  MASTER_HOST = '${new_master_ip}',MASTER_USER = '${user}',MASTER_PASSWORD = '${password}',MASTER_PORT = ${new_master_port},master_auto_position = 1; 
  
CHANGE MASTER TO
  MASTER_HOST = '10.157.23.123',MASTER_USER = 'mysqlsync',MASTER_PASSWORD = 'mysqlsync123',MASTER_PORT = 8882,master_auto_position = 1; 

3.2、开启主从同步

start slave
show slave status \G

image-20200409150520640

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

3.3、从库:如何断开主从

stop slave io_thread
stop slave sql_thread

3.4、主库:如何断开主从

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

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跳过有问题的这个事件,但是还是得把事件的原因查明白,不然不推荐直接跳过这个事件。

stop slave;
set global sql_slave_skip_counter=1;
start slave;

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

# 一般我们可以像下面这样,在my.cnf中的[MySQLd]的启动参数中添加如下内容
--slave-skip-errors=1062,1053  
--slave-skip-errors=all  
--slave-skip-errors=ddl_exist_errors

# 通过如下语句查看当前MySQL配置的变量
MySQL> show variables like 'slave_skip%';  

# 通过如下命令可以查看到出现的errorno
show slave status; # 观察Last_Errno

# 常见的errorno
1007:数据库已存在,创建数据库失败
1008:数据库不存在,删除数据库失败
1050:数据表已存在,创建数据表失败
1051:数据表不存在,删除数据表失败
1054:字段不存在,或程序文件跟数据库有冲突
1060:字段重复,导致无法插入
1061:重复键名
1068:定义了多个主键
1094:位置线程ID
1146:数据表缺失,请恢复数据库
1053:复制过程中主服务器宕机
1062:主键冲突 Duplicate entry '%s' for key %d

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

# 停掉slave
slave stop
# 进入master
# 停止master的写操作
# 查看master中当前bin-log和position
show master status;
# 切换回slave从新根据最新的position和bin-log进行同步
# 进入master,开启master的写操作

五、流程

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

六、可能会遇到的问题

6.1、问题一:

change master时报错了

image-20200526202556494

报错说: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回去。

CHANGE MASTER TO
		MASTER_AUTO_POSITION=0;

6.2、问题二:

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

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

  1. Slave_IO_Running : No
  2. Last_IO_Error 位置报了个严重的错误
mysql>  CHANGE MASTER TO
    ->        MASTER_HOST='10.157.23.xxx',->         MASTER_USER='mysqlsync',->        MASTER_PASSWORD='mysqlsync123',->        MASTER_PORT=8882,->        MASTER_LOG_FILE='mysql-bin.000008',->       MASTER_LOG_POS=1003;
Query OK,0 rows affected,2 warnings (0.01 sec)

mysql> start slave;
Query OK,0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 10.157.23.123
                  Master_User: mysqlsync
                  Master_Port: 8882
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 1003
               Relay_Log_File: relay-log.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: No
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.%,test.%
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1003
              Relay_Log_Space: 521
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 1236
                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.'
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2787871625
                  Master_UUID: a5f1d6b2-8f9a-11ea-8138-b8599f2ef058
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp: 200529 10:22:46
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222,40efcb1b-7a1f-11ea-84ac-b8599f229b38:1-20,7e2dcb21-7d3b-11ea-aa0c-b8599f2ef058:1-18,9e6027f2-7ae9-11ea-ac13-b8599f2ef058:1409-7176,a5f1d6b2-8f9a-11ea-8138-b8599f2ef058:6-9:12-13:15,e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

6.3、问题三:

假设我们有这样的场景:

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

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

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

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

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

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

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

image-20200529095601076

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

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

CHANGE MASTER TO
    MASTER_HOST='10.157.23.158',MASTER_LOG_POS=1013;

开启同步,并查看状态

start slave;
show slave status\G;

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

6.4、问题四:

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

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

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

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

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

答:可以的,像下面这样

mysql> show variables like '%read_only%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | OFF   |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
5 rows in set (0.00 sec)


set global read_only=0;  #关闭只读,可以读写
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

mysql> CHANGE MASTER TO
    ->     MASTER_HOST='10.157.23.158',->     MASTER_USER='mysqlsync',->     MASTER_PASSWORD='mysqlsync123',->     MASTER_PORT=8882,->     MASTER_LOG_FILE='mysql-bin.000008',->     MASTER_LOG_POS=1013;
Query OK,0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Connecting to master
                  Master_Host: 10.157.23.123
                  Master_User: mysqlsync
                  Master_Port: 8882
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 1003
               Relay_Log_File: relay-log.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: Connecting
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table: mysql.%,test.%
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 1003
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 2003
                Last_IO_Error: error connecting to master 'mysqlsync@10.157.23.123:8882' - retry-time: 60  retries: 1
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 0
                  Master_UUID:
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp: 200529 10:13:34
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set: 00c755a6-7a07-11ea-8701-b8599f2ef058:33-222,e90fdd54-7e04-11ea-8b23-b8599f2ef058:1-11
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:

6.7、问题七:

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在正式开始之前,我们先来看下 MySQL 服务器的配置和版本号信息,如下图所示: “兵马未动粮草先行”,看完了相关的配置之后,我们先来创建一张测试表和一些测试数据。 -- 如果存在 person 表先删除 DROP TABLE IF EXISTS person; -- 创建 person 表,其中
> [合辑地址:MySQL全面瓦解](https://www.cnblogs.com/wzh2010/category/1859594.html "合辑地址:MySQL全面瓦解") # 1 为什么需要数据库备份 - 灾难恢复:当发生数据灾难的时候,需要对损坏的数据进行恢复和
物理服务机的CPU、内存、存储设备、连接数等资源有限,某个时段大量连接同时执行操作,会导致数据库在处理上遇到性能瓶颈。为了解决这个问题,行业先驱门充分发扬了分而治之的思想,对大库表进行分割,
然后实施更好的控制和管理,同时使用多台机器的CPU、内存、存储,提供更好的性能。而分治有两种实现方式:垂直拆
1 回顾 上一节我们详细讲解了如何对数据库进行分区操作,包括了 垂直拆分(Scale Up 纵向扩展)和 水平拆分(Scale Out 横向扩展) ,同时简要整理了水平分区的几种策略,现在来回顾一下。 2 水平分区的5种策略 2.1 Hash(哈希) 这种策略是通过对表的一个或多个列的Ha
navicat查看某个表的所有字段的详细信息 navicat设计表只能一次查看一个字段的备注信息,那怎么才能做到一次性查询表的信息呢?SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,COLUMN_KEY FROM information_schema.CO
文章浏览阅读4.3k次。转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52768613前言:数据库每天的数据不断增多,自动删除机制总体风险太大,想保留更多历史性的数据供查询,于是从小的hbase换到大的hbase上,势在必行。今天记录下这次数据仓库迁移。看下Agenda:彻底卸载MySQL安装MySQL_linux服务器进行数据迁移
文章浏览阅读488次。恢复步骤概要备份frm、ibd文件如果mysql版本发生变化,安装回原本的mysql版本创建和原本库名一致新库,字符集都要保持一样通过frm获取到原先的表结构,通过的得到的表结构创建一个和原先结构一样的空表。使用“ALTER TABLE DISCARD TABLESPACE;”命令卸载掉表空间将原先的ibd拷贝到mysql的仓库下添加用户权限 “chown . .ibd”,如果是操作和mysql的使用权限一致可以跳过通过“ALTER TABLE IMPORT TABLESPACE;”命令恢_alter table discard tablespace
文章浏览阅读225次。当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化:单表优化除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑、部署、运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的。而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量:字段尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNEDVARCHAR的长度只分配_开发项目 浏览记录表 过大怎么办
文章浏览阅读1.5k次。Mysql创建、删除用户MySql中添加用户,新建数据库,用户授权,删除用户,修改密码(注意每行后边都跟个;表示一个命令语句结束):1.新建用户登录MYSQL:@>mysql -u root -p@>密码创建用户:mysql> insert into mysql.user(Host,User,Password) values("localhost_删除mysql用户组
MySQL是一种开源的关系型数据库管理系统,被广泛应用于各类应用程序的开发中。对于MySQL中的字段,我们需要进行数据类型以及默认值的设置,这对于数据的存储和使用至关重要。其中,有一个非常重要的概念就是MySQL字段默认字符串。 CREATE TABLE `my_...
MySQL是一个流行的开源关系型数据库管理系统,广泛应用于Web应用程序开发、数据存储和管理。在使用MySQL时,正确设置字符集非常重要,以确保数据的正确性和可靠性。 在MySQL中,字符集表示为一系列字符和字母的集合。MySQL支持多种字符集,包括ASCII、UTF...
MySQL存储函数 n以内偶数 MySQL存储函数能够帮助用户简化操作,提高效率,常常被用于计算和处理数据。下面我们就来了解一下如何使用MySQL存储函数计算n以内的偶数。 定义存储函数 首先,我们需要定义一个MySQL存储函数,以计算n以内的偶数。下...
MySQL是一个流行的关系型数据库管理系统,基于客户机-服务器模式,可在各种操作系统上运行。 MySQL支持多种字符集,不同的字符集包括不同的字符,如字母、数字、符号等,并提供不同的排序规则,以满足不同语言环境的需求。 //查看MySQL支持的字符集与校对规...
在MySQL数据库中,我们有时需要对特定的字符串进行截取并进行分组统计。这种操作对于数据分析和报表制作有着重要的应用。下面我们将讲解一些基本的字符串截取和分组统计的方法。 首先,我们可以使用substring函数对字段中的字符串进行截取。假设我们有一张表stude...
MySQL提供了多种字符串的查找函数。下面我们就一一介绍。 1. LIKE函数 SELECT * FROM mytable WHERE mycolumn LIKE 'apple%'; 其中"apple%"表示以apple开头的字符串,%表示任意多个字符...
MySQL 是一种关系型数据库管理系统,广泛应用于各种不同规模和类型的应用程序中。在 MySQL 中,处理字符串数据是很常见的任务。有时候,我们需要在字符串的开头添加一定数量的 0 ,以达到一定的位数。比如,我们可能需要将一个数字转换为 4 位或 5 位的字符串,不足的...
MySQL是一种流行的关系型数据库管理系统,支持多种数据类型。以下是MySQL所支持的数据类型: 1. 数值型数据类型: - TINYINT 保存-128到127范围内的整数 - SMALLINT 保存-32768到32767范围内的整数 - MEDIU...
MySQL中存储Emoji表情字段类型 在现代互联网生态中,表情符号已经成为人们展示情感和思想的重要方式之一,因此将表情符号存储到数据库中是一个经常出现的问题。MySQL作为最流行的开源关系型数据库管理系统之一,也需要能够存储和管理这些表情符号的字段类型。 UT...
MySQL是一种关系型数据库管理系统。在MySQL数据库中,有多种不同的数据类型。而其中,最常见的数据类型之一就是字符串类型。在MySQL中,字符串类型的数据通常会被存储为TEXT或VARCHAR类型。 首先,让我们来看一下VARCHAR类型。VARCHAR是My...
MySQL字符串取整知识详解 MySQL是一种开源的关系型数据库管理系统,广泛应用于各个领域。在使用MySQL过程当中,我们经常需要对数据进行取整操作。本文将介绍如何使用MySQL字符串取整来处理数据取整问题。 什么是MySQL字符串取整? MySQL...