MYSQL 主从复制 --- binlog
一个MYSQL数据库存在的问题
在谈主从复制之前,应该都会有一个疑问,那么就是一个MYSQL数据库存在的问题呢?
- 读和写所有压力都由一台数据库承担,压力大
- 数据库服务器磁盘损坏则数据丢失,单点故障
为了解决我们可以使用MYSQL的主从复制处理,那么什么是主从复制呢?
主从复制的概念
MySQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的二进制日志 binlog 功能。简单的说,就是一台或多台MySQL数据库(slave,即从库)从另一台MySQL数据库(master,即主库)进行日志的复制,然后再解析日志并应用到自身,最终实现 从库 的数据和 主库 的数据保持一致。
BINLOG:记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,MySQL的主从复制, 就是通过该binlog实现的。默认MySQL是未开启该日志的。更详细的binlog可以阅读MYSQL日志文章
主从复制实现的过程
我们从主从复制的概念中知道它主要是依赖于binlog 日志,而且这个过程是异步的,即主库上执行事务操作线程不会等待复制binlog的线程完成。如下图:
MYSQL主从复制过程
从图中可以知道,MYSQL复制过程分为三步:
- 写入 Binlog:主库写 binlog 日志,提交事务,并更新本地存储数据
- 同步 Binlog:把 binlog 复制到所有从库上,每个从库把 binlog 写到暂存日志中
- 回放 Binlog:回放 binlog,并更新存储引擎中的数据
上图更详细的解释如下:
MySQL 主库在收到客户端提交事务的请求之后,会先写入 binlog,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功”的响应
从库会创建一个专门的 I/O 线程,连接主库的 log dump 线程,来接收主库的 binlog 日志,再把 binlog 信息写入 relay log 的中继日志里,再返回给主库“复制成功”的响应
从库会创建一个用于回放 binlog 的线程,去读 relay log 中继日志,然后回放 binlog 更新存储引擎中的数据,最终实现主从的数据一致性
这要实现了主从复制过程,那么我们经常使用到的有哪些场景呢?比如读写分离。即写数据时只写主库,在读数据时只读从库,这样即使写请求会锁表或者锁记录,也不会影响读请求的执行。如下图:
MYSQL主从架构的读写分离
到这里基本知道了什么是主从复制了,那么在使用过程中是不是从库可以无限多呢?
答案:当然不是的。因为从库数量增加,从库连接上来的 I/O 线程也比较多,主库也要创建同样多的 log dump 线程来处理复制的请求,对主库资源消耗比较高,同时还受限于主库的网络带宽。所以,一般个主库跟 2~3 个从库(1 主 2 从 1 备主),这就是一主多从的 MySQL 集群结构
MySQL 集群结构
- 主从(Master-Slaves)
- 主主(Master-Master)
- 主从从 … (Master-Slaves-Slaves…)
- 主主从 (Master - Master - Slaves)
常规复制架构—主从(Master-Slaves)
在实际应用场景中,MySQL 复制 90% 以上都是一个 Master 复制到一个或者多个 Slave 的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。如下图:
主从 (Master-Slaves)
一个 Master 复制多个 Slave 的架构实施非常简单,多个 Slave 和单个 Slave 的实施 并没有实质性的区别。在 Master 端并不 Care 有多少个 Slave 连上了自己,只要有 Slave 的 IO 线程通过了连接认证,向他请求指定位置之后的 Binary Log 信息,他就会按照该 IO 线程的要求,读取自己的 Binary Log 信息,返回给 Slave 的 IO 线程。
Dual Master 复制架构 —主主(Master - Master)
双主(Dual Master)复制架构适用于DBA做维护时需要主从切换的场景,通过双主复制架构避免了重复搭建从库的麻烦,双主复制架构如下图所示:
主主 (Master - Master)
主库Master1和Master互为主从,所有客户端的写请求都访问主库Master1或Master2。加入DBA需要做日常维护操作,为了避免影响服务,需进行一下操作:
- 首先,在Master1库上停止Slave线程(STOP SLAVE),避免后续对Master2库的维护操作操作被实时复制到Master1库上对服务造成影响。
- 其次,在Master2库上停止Slave线程(STOP SLAVE),开始日常维护操作,例如修改varchar字段从长度10增加到200。
- 然后,在Master2库上完成维护操作之后,打开Master2库上的Slave线程(STRART SLAVE),让Master2的数据和Master1库同步,同步完成后,把应用的写操作切换到Master2库上。
- 最后,确认Master1库上没有应用访问后,打开Master1的Slave线程(START SLAVE)即可
通过双主复制架构能够大大减轻一主多从架构下对主库进行维护带来的额外搭建从库的工作。可以配合一个第三方的工具,比如keepalived 轻松做到 IP 的漂移,停机维护也不会影响写操作。
级联复制架构 —主从从 … (Master - Slaves - Slaves …)
如果读压力加大,就需要更多的 slave 来解决,但是如果slave的复制全部从 master 复制,势必会加大 master 的复制IO的压力,所以就出现了级联复制,减轻 master 压力。如下图:
主从从 … (Master - Slaves - Slaves …)
但是,这个框架有一个缺点就是slave 延迟更加大了
Dual Master与级联复制结合架构 —主主从 (Master - Master - Slaves)
级联复制在一定程度上面确实解决了 Master 因为所附属的 Slave 过多而成为瓶颈的问题,但是他并不能解决人工维护和出现异常需要切换后可能存在重新搭建 Replication的问题。如下图:
主主从 (Master - Master - Slaves)
这样就解决了单点 master 的问题,解决了slave 级联延迟的问题。
主从复制有哪些模型
主从复制模型是通过sync_binlog参数(具体可以阅读MYSQL日志)来控制的,主要有三种:
- 同步复制:MySQL 主库提交事务的线程要等待所有从库的复制成功响应,才返回客户端结果。这种方式在实际项目中,基本上没法用,原因有两个:一是性能很差,因为要复制到所有节点才返回响应;二是可用性也很差,主库和所有从库任何一个数据库出问题,都会影响业务。
- 异步复制(默认模型):MySQL 主库提交事务的线程并不会等待 binlog 同步到各从库,就返回客户端结果。这种模式一旦主库宕机,数据就会发生丢失。
- 半同步复制:MySQL 5.7 版本之后增加的一种复制方式,介于两者之间,事务线程不用等待所有的从库复制成功响应,只要一部分复制成功响应回来就行,比如一主二从的集群,只要数据成功复制到任意一个从库上,主库的事务线程就可以返回给客户端。这种半同步复制的方式,兼顾了异步复制和同步复制的优点,即使出现主库宕机,至少还有一个从库有最新的数据,不存在数据丢失的风险。
主从复制解决的问题
数据分布 (Data distribution )
负载平衡(load balancing)
备份(Backups)
高可用性和容错行 High availability and failover
主从复制实验搭建
配置主从复制步骤
Master数据库:
- 安装数据库;
- 修改数据库配置文件,指明 server_id,开启二进制日志(log-bin);
- 启动数据库,查看当前是哪个日志,position 号是多少;
- 登录数据库,授权数据复制用户(IP 地址为从机 IP 地址,如果是双向主从,这里的 还需要授权本机的 IP 地址,此时自己的 IP 地址就是从 IP 地址);
- 备份数据库(记得加锁和解锁);
- 传送备份数据到 Slave 上;
- 启动数据库;
以上步骤,为单向主从搭建成功,想搭建双向主从需要的步骤:
a. 登录数据库,指定 Master 的地址、用户、密码等信息(此步仅双向主从时需要);
b. 开启同步,查看状态;
Slave数据库:
- 安装数据库;
- 修改数据库配置文件,指明 server_id(如果是搭建双向主从的话,也要开启二进制 日志 log-bin);
- 启动数据库,还原备份;
- 查看当前是哪个日志,position 号是多少(单向主从此步不需要,双向主从需要);
- 指定 Master 的地址、用户、密码等信息;
- 开启同步,查看状态
例子
1.准备工作
准备两台机器,并安装好mysql,服务器信息如下:
- 防火墙
如果这两天机器有防火墙,并开启了防火墙,那么就要开发对应的端口,如下:
firewall-cmd --zone=public --add-port=3306/tcp --permanent --添加端口
firewall-cmd --zone=public --list-ports --查看开放的端口
防火墙更加详细的操作可以阅读LINUX防火墙文章。
- 启动mysql服务
把这两台mysql服务启动起来,如下:
systemctl start mysqld 或者 systemctl start mysql
然后验证是否启动成功,如下图启动成功:
注意事项
在搭建Mysql主从架构过程中,由于从服务器是克隆的主服务器系统,导致主从mysql uuid相同,解决办法,修改其中一台服务器的server-uuid,并保证server-uuid的格式正确,修改完成之后重启Mysql服务就可以了。
在修改配置文件之前,先登录Mysql客户端查看uuid,把返回的uuid复制,放到要修改的配置文件即可
查到uuid之后,修改uuid配置文件:
# vim /data/mysql/auto.cnf //如过找不到 find -name auto.cnf 找一下路径,这个文件一般在数据目录下
[auto]
server-uuid=267170ea-5f41-11ed-93db-000c29936244
# 按照这个16进制格式,修改server-uuid,重启mysql即可
- 主库配置
在mysql配置文件最下面增加配置:
log-bin=mysql-bin #[必须]启用二进制日志
server-id=1 #[必须]服务器唯一ID(唯一即可)
保存配置文件之后,重启主库Mysql服务:
systemctl restart mysqld 或者 systemctl restart mysql
然后登陆主库mysql服务,接着通过下面指令查看配置文件是否修改成功:
从上图可以看出已经修改成功,接着创建用户并授权:
GRANT REPLICATION SLAVE ON . to ‘ian’@‘%’ identified by ‘mysqltest’;
命令解析:
ian:是用户名字
mysqltest: 是密码
并且给ian用户授予REPLICATION SLAVE权限。常用于建立复制时所需要用到的用户权限,也就是slave必须被master授权具有该权限的用户,才能通过该用户复制。
创建完用户和授权之后,查看master同步状态,主要是那个文件开始和开始的位置:
show master status;
为什么要知道这两个值呢?因为在从库的时候要用到。到这里主库已经配置好了。
- 从库配置
修改从库配置文件:
server-id=12 #[必须]服务器唯一ID 保证唯一 需要主和从唯一就可
relay-log=relay-log
relay-log-index=relay-log.index
保存配置文件,然后重启从库数据库:
systemctl restart mysqld 或者 systemctl restart mysql
登录从库数据库,然后查看配置是否修改成功:
修改成功之后,在从库中设置主库地址和同步位置:
change master to master_host=‘192.168.0.117’,master_user=‘ian’,master_password=‘mysqltest’,master_log_file=‘mysql-bin.000008’,master_log_pos=23758;
参数说明:
A. master_host : 主库的IP地址
B. master_user : 访问主库进行主从复制的用户名(上面在主库创建的)
C. master_password : 访问主库进行主从复制的用户名对应的密码
D. master_log_file : 从哪个日志文件开始同步(上述查询master状态中展示的有)
E. master_log_pos : 从指定日志文件的哪个位置开始同步(上述查询master状态中展示的有)
然后查看从库数据库的状态:
show slave status \G;
\G : 在MySQL的sql语句后加上\G,表示将查询结果进行按列打印,可以使每个字段打印到单独的行。即将查到的结构旋转90度变成纵向;
- 测试
我们在主库中创建一个数据库test4,如下图:
然后我们在到从库中查看,可以知道:
然后我们可以在这个数据库里面添加一些测试数据,如添加一个user表,然后在表中添加一行数据,一样可以在从库中查看得到,那么我们就配置完成了。
问题1:如果Mysql的远程连接不上,出现下面问题
答案:在mysql配置中添加skip-grant-tables,并屏蔽掉bind_address配置项
问题2:MySQL主从复制,启动slave时,出现下面报错:
mysql> start slave;
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
可以看到报错,原来是找不到./server246-relay-bin.index文件,找到原因所在了,由于我使用的是冷备份文件恢复的实例,在mysql库中的slave_relay_log_info表中依然保留之前relay_log的信息,所以导致启动slave报错。
mysql提供了工具用来删除记录:
slave reset;
slave reset执行候做了这样几件事:
1、删除slave_master_info ,slave_relay_log_info两个表中数据;
2、删除所有relay log文件,并重新创建新的relay log文件;
3、不会改变gtid_executed 或者 gtid_purged的值
mysql> reset slave;
Query OK, 0 rows affected (0.01 sec)mysql> change master to …
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
这样slave 就可以启动了。
相关文章:

MySQL慢查询日志slowlog
慢速查询日志记录的是执行时间超过秒和检查的行数超过的SQL语句,这些语句通常是需要进行优化的。官方参考文档:https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html。

一文搞懂MySQL索引
官方介绍索引是帮助MySQL高效获取数据的数据结构。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往是存储在磁盘上的文件中的(可能存储在单独的索引文件中,也可能和数据一起存储在数据文件中)。我们通常所说的索引,包括聚集索引、覆盖索引、组合索引、前缀索引、唯一索引等,没有特别说明,默认都是使用B+树结构组织(多路搜索树,并不一定是二叉的)的索引。看到这里,你是不是对于自己的sql语句里面的索引的有了更多优化想法呢。

ON DUPLICATE KEY UPDATE 导致mysql自增主键ID跳跃增长
具体解决方案可以根据项目来选择,如果项目不大,可以考虑1和2。如果不考虑高并发问题,可以考虑3。

mysql唯一索引与null
根据NULL的定义,NULL表示的是未知,因此两个NULL比较的结果既不相等,也不不等,结果仍然是未知。根据这个定义,多个NULL值的存在应该不违反唯一约束,所以是合理的,在oracel也是如此。在mysql 的innodb引擎中,是允许在唯一索引的字段中出现多个null值的。有上面的表和数据可以看出,查询多条数据。

MySQL主从复制(基于binlog日志方式)
主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。主从复制的作用1.做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。2.架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。3.读写分离,使数据库能支撑更大的并发。a.从服务器可以执行查询工作(就是我们常说的读功能),降低主服务器压力;(主库写,从库读,降压)

MySQL 中 is null 和 =null 的区别
如果 set ANSI_NULLS为 ON 时,表示SQL语句遵循SQL-92标准;如果 set ANSI_NULLS 为 OFF 时,表示不遵从 SQL-92 标准。但SQL-92 标准要求对null的 = 或不等于 (!= ,) 比较取值都为 false,也就是 =null 或者 null,返回的都是false。null 在MySQL中不代表任何值,通过运算符是得不到任何结果的,因此只能用 is null(默认情况)MySQL 中 null 不代表任务实际的值,类似于一个未知数。

MySQL数据库查询语句之组函数,子查询语句
当一个SQL的执行需要借助另一个SQL的执行结果时,则需要进行SQL嵌套,该语法结构称之为子查询。先筛选出符合要求的数据,再对符合要求的数据进行分组时,分组的工作量会被减少,效率更高。先确定从哪张表进行操作-->对表中数据进行分组-->基于分组结果进行查询操作。执行顺序:优先执行小括号内的子SQL,根据子SQL的执行结果再执行外层SQL。执行顺序:from-->where-->group by-->select。执行顺序:from-->group by-->select。

mysql开启可以使用IP有权限访问
为实际的IP地址和你想要设置的密码。请小心操作,并确保你了解每个命令的作用。如果你对此有任何疑问,最好咨询经验丰富的数据库管理员。来设置或修改用户的密码。相反,你需要分两步来完成这个过程:首先创建或修改用户,并设置密码;然后授予相应的权限。用户应该能够从指定的内网IP地址访问MySQL服务器。用户已存在并且你只是想更改其密码或允许从另一个地址访问,使用。在MySQL 8.0及更高版本中,语句的语法有所变化。替换为你的内网IP地址,

雪花算法生成ID、UUID生成ID和MySql自增ID优缺点分析
综上所述,UUID适用于分布式系统和需要保密的场景,雪花ID适用于分布式系统和高并发环境,MySQL自增ID适用于单机系统和高效查询的场景。根据具体的业务需求和系统架构,选择合适的主键类型。通过本文的介绍和对比,希望读者能够更好地理解在MySQL中不推荐使用UUID或者雪花ID作为主键的原因,并能够根据实际情况做出明智的选择。在MySQL中,使用自增整数作为主键是一种常见的做法,因为它具有较小的存储空间、高效的索引和自动增长的特性。然而,具体选择何种主键类型还是要根据具体的业务需求和数据特点来决定。

【小白专用】C# 连接 MySQL 数据库
C# 连接 MySQL 数据库

如何用pthon连接mysql和mongodb数据库【极简版】
发现宝藏 前言 1. 连接mysql 1.1 安装 PyMySQL 1.2 导入 PyMySQL 1.3 建立连接 1.4 创建游标对象 1.5 执行查询 1.6 关闭连接 1.7 完整示例 2. 连接mongodb 2.1 安装 PyMongo 2.2 导入 PyMongo 2.3 建立连接 2.4

MySQL索引优化实战
对于这种varchar(255)的大字段可能会比较占用磁盘空间,可以稍微优化下,比如针对这个字段的前20个 字符建立索引,就是说,对这个字段里的每个值的前20个字符放在索引树里,类似于 KEY index(name(20),age,position)。此时你在where条件里搜索的时候,如果是根据name字段来搜索,那么此时就会先到索引树里根据name 字段的前20个字符去搜索,定位到之后前20个字符的前缀匹配的部分数据之后,再回到聚簇索引提取出来 完整的name字段值进行比对。

《mybatis》--大数据量查询解决方案
之前写百万以及千万的导出数据的时候,对于将数据写道csv文件并压缩这里没有什么大问题了,但是出现了其他问题为:1、我们需要将数据从数据库中拿出来,并且在进行装配的时候出现了一些问题。2、对于整体内存安全来说,如果直接将数据从数据库中拿出来百万级别以上的数据对于内存是非常不友好的。当问题出现比较大的时候会直接触发GC,造成瘫痪。目前开发以及项目测试的是更多的使用mybatis来进行开发的,所以本文章讨论以及解决的的就是如何使用mybaits来解决流式查询并单条处理的问题。

ClickHouse 与mysql等关系型数据库对比
先用一张图帮助理解两者的本质上的区。

Windows安装MySQL及网络配置
向日葵软件是一种远程控制软件,可以让用户在不同设备之间进行远程桌面访问和文件传输。用户可以通过向日葵软件,在任何具有互联网连接的设备上远程控制其他设备,包括计算机、智能手机和平板电脑。用户只需安装向日葵软件,并使用登录凭据连接到目标设备,就可以实时控制目标设备上的屏幕、键盘和鼠标。向日葵软件还提供了一些辅助功能,如文件传输、远程打印和远程会议等。这使得向日葵软件成为一个方便实用的远程协助工具,适用于个人用户、技术支持人员和企业用户等各种场景。

深入理解Mysql事务隔离级别与锁机制
我们的数据库一般都会并发执行多个事务,多个事务可能会并发的对相同的一批数据进行增删改查操作,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。这些问题的本质都是数据库的多事务并发问题,为了解决多事务并发问题,数据库设计了事务隔离机制、锁机制、MVCC多版本并发控制隔离机制,用一整套机制来解决多事务并发问题。接下来,我们会深入讲解这些机制,让大家彻底理解数据库内部的执行原理。

MySQL是如何保证数据不丢失的?
上篇文章《InnoDB在SQL查询中的关键功能和优化策略》对InnoDB的查询操作和优化事项进行了说明。但是,MySQL作为一个存储数据的产品,怎么确保数据的持久性和不丢失才是最重要的,感兴趣的可以跟随本文一探究竟。

where查询条件的字段顺序打乱会影响命中索引吗?
答案是:不影响我们的where后边条件字段打乱会影响命中索引吗?先来进行下边的实验:可以看到实验结果,where条件字段顺序没有按照索引的字段顺序,依然不影响命中索引。因为Mysql中有查询优化器,会自动优化查询顺序。

MySQL删除会走索引吗
MySQL是关系型数据库管理系统的一种, 网站在进行数据的增删改查的时候,我们往往需要使用 MySQL 数据库。而删除操作就是在 MySQL 数据库中删除指定的数据或者表格的操作。

Linux多种方法安装MySQL
源码安装:优点是安装包比较小,只有十多M,缺点是安装依赖的库多,安装编译时间长,安装步骤复杂容易出错。使用官方编译好的二进制文件安装:优点是安装速度快,安装步骤简单,缺点是安装包很大,300M左右。yum安装。rpm安装。

Linux中mysql 默认安装位置&Linux 安装 MySQL
MySQL在Linux系统上的默认安装位置是目录。这是MySQL服务器的数据目录,包含所有数据库文件。通过检查MySQL二进制文件的路径,我们可以确认MySQL是否正确安装。在目录中,MySQL使用一系列文件和子目录来组织和存储数据。确保理解MySQL数据目录的结构对于管理和维护MySQL数据库至关重要。按照顺序安装即可解决。

MySQL数据库索引以及使用唯一索引实现幂等性
一次和多次请求某一个资源对于资源本身应该具有同样的结果任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

【微服务】mysql + elasticsearch数据双写设计与实现
在很多电商网站中,对商品的搜索要求很高,主要体现在页面快速响应搜索结果。这就对服务端接口响应速度提出了很高的要求。
基于 MySQL 多通道主主复制的机房容灾方案
文章中介绍了多种 MySQL 高可用技术,并介绍了根据自身需求选择多通道主主复制技术的过程和注意事项。

MySQL中的 增 删 查 改(CRUD)
文章浏览阅读1.8k次,点赞60次,收藏56次。insert into 表名 value(数据,数据),.......;可以单行,多行插入。为查询结果的列取别名select 表达式/列名as 别名 from 表名;去重:DISTINCTselect distinct 单列/多列 from 表名;会去除查询结果中的重复项(只保留一项)select 条件查询的执行顺序遍历表中的每个记录把当前记录的值带入条件,根据条件进行筛选如果这条记录满足条件,保留并进行列上的表达式的计算如果有 order by 会在所有行都被获取到之后(表

【MySQL从删库到跑路 | 基础第二篇】——谈谈SQL中的DML语句
详细介绍SQL中的DML语句(增加、修改、删除操作)。

【MySQL基础|第三篇】--- 详谈SQL中的DQL语句
详解MySQL中SQL的基础查询、条件查询、聚合函数、分组查询、排序查询、分页查询。

【MySQL函数篇】—— 字符串函数(超详细)
详细介绍MySQL函数中的字符串函数。

MySQL常用函数集锦 --- 字符串|数值|日期|流程函数总结
主要讲解MySQL中的字符串、日期、数值、流程函数。

详细介绍MySQL中的六种约束
详细介绍MySQL中的六种约束