迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 数据库 > MySQL >

Mysql主从复制的实现细节(一)主服务器探究

作者:迹忆 最近更新:2022/11/13 浏览次数:

这篇文章主要从主从复制的实现机制方面来进行论述,可能对于我们实际应用没有直接的帮助,但是理解其原理毕竟对于以后的维护和优化能起到事半功倍的效果。由于本人水平有限,文字之中有欠妥的地方还请大家批评指正。

Mysql一次主从复制需要有三个线程来实现,其中一个线程(Binlog dump thread)在主服务器上,其它两个线程(Slave I/O thread , Slave SQL thread)在从服务器上(如果一台主服务器配两台从服务器那主服务器上就会有两个Binlog dump 线程,而每个从服务器上各自有两个线程)。下面我们分别来介绍

主服务器线程 Binlog dump thread

Binlog dump 线程是当有从服务器连接的时候由主服务器创建,其大致工作过程经历如下几个阶段
 


首先bin-log日志文件加锁,然后读取更新的操作,读取完毕以后将锁释放掉,最后将读取的记录发送给从服务器。

我们可以使用如下的命令来查看该线程的信息

mysql> SHOW PROCESSLIST\G

以我的系统为例,因为我这系统中是一台主服务器和两台从服务器,所以会列出两条Binlog dump线程的信息

*************************** 1. row ***************************
     Id: 2
   User: repuser
   Host: 192.168.144.131:41544
     db: NULL
Command: Binlog Dump
   Time: 54
  State: Master has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL
*************************** 2. row ***************************
     Id: 3
   User: repuser
   Host: 192.168.144.132:40888
     db: NULL
Command: Binlog Dump
   Time: 31
  State: Master has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL

上述字段中的state字段会有以下几种状态

1. Sending binlog event to slave
表示Binlog dump 线程已经读取完binlog日志中更新的event,现在正在发送给从服务器

2. Finished reading one binlog; switching to next binlog
表示Binlog dump 线程已经读取完一个binlog日志,现在正在打开下一个binlog日志读取来发送给从服务器

3. Master has sent all binlog to slave; waiting for binlog to be updated
这就是上面我们看到的state的值,表示Binlog dump 线程已经读取完所有的binlog日志文件,并且将其发送给了从服务器。现在处于空闲状态,正在等待读取有新的操作的binlog日志文件

4. Waiting to finalize termination
这个状态持续的很短暂,我们几乎看不到。当线程停止的时候显示此状态

上述几个状态就是一次主从复制过程中Binlog dump 线程所经历的状态,如果我们是在测试的环境中,上述1、2、4状态我们几乎是看不到的,因为它执行的很快。

在主从系统中主服务器上的一个主要的文件就是bin-log日志,该线程操作的文件也是此日志文件,因此这是我们需要在配置文件my.cnf 中打开bin-log日志的原因,使用此文件来记录我们的更新操作

[mysqld]
log-bin = mysql-bin
server-id = 1

还有一点需要注意,在上面已经说过,但是在这里觉得有必要再重复一遍,就是有多少个从服务器连接主服务器上就有多少个Binlog dump 线程

Binary Log 简单介绍

因为Binlog dump 线程操作的文件是bin-log 日志文件,并且实现主从复制在主服务器上主要依靠bin-log日志文件,所以我们简单介绍一下bin-log日志文件。

bin-log 日志文件有两种格式,一种是Statement-Based,另一种是Row-Based。

Statement-Based优点和缺点分析

优点

1. bin-log日志包含了描述数据库操作的事件,但是这些事件包含的情况只是对数据库进行改变的操作,例如 insert、update、create、delete等操作。相反对于select、desc等类似的操作并不会去记录,并且它记录的是语句,所以相对于Row-Based来说这样会占用更少的存储空间。

2. 因为bin-log日志文件记录了所有的改变数据库的语句,所以此文件可以作为以后的数据库的审核依据

缺点

1. 不安全,并不是所有的改变数据的语句都会被记录复制。任何的非确定性的行为都是很难被记录复制的。

例如:对于delete 或者update语句,如果使用了limit但是并没有 order by ,这就属于非确定性的语句,就不会被记录

2. 对于没有索引条件的update语句,必须锁定更多的数据,降低了数据库的性能。

3. insert……select 语句同样也需要锁定大量的数据,对数据库的性能有所损耗。

获取更详细的信息可以参考官方文档——Statement-Based的优点和缺点

Row-Based优点和缺点分析

优点

1. 所有的改变都会被复制,这是最安全的复制方式

2. 对于 update、insert……select等语句锁定更少的行

3. 此种方式和大多数的数据库系统一样,所以了解其他的系统的人员可以很容易的转到mysql

缺点

1. 使用不方便,我们不能通过bin-log日志文件查看什么语句执行了,也无从知道在从服务器上接收到什么语句,我们只能看到什么数据改变了

2. 因为记录的是数据,所以说bin-log日志文件占用的存储空间要比Statement-based大。

3. 对于数据量大的操作其花费的时间有更长

获取更详细的信息可以参考官方文档——Row-Based的优点和缺点

bin-log日志文件默认的格式为Statement-Based,如果想改变其格式在开启服务的时候使用—binlog-format选项,其具体命令如下

# mysqld_safe –user=msyql –binlog-format=格式 &

bin-log日志文件管理

对于bin-log日志文件,其默认的名称为 mysql-bin.xxxxxx。而且还有一个索引文件mysql-bin.index,其中记录了当前所有的bin-log日志文件。

对于新的主服务器只有一个bin-log日志文件 mysql-bin.000001。此时所有的操作都有这个文件来记录,如果我们想更换bin-log日志文件,可以使用如下命令

Mysql>flush logs;

此时会创建一个mysql-bin.000002文件来记录以后的操作。除了使用上述命令以外,当bin-log日志文件达到其最大值的时候也会产生新的bin-log日志文件

其文件最大值和文件名包括索引文件的名称可以使用 –max_binlog_size、--log-bin和—log-bin-index 选项来改变,具体命令如下

# mysqld_safe –user=msyql –max_binlog_size=文件长度 –log-bin=新的日志文件名称 –log-bin-index=新索引文件名 &

对于主服务器来说,总起来一句话:主服务器针对于每一个从服务器都创建一个Binlog dump线程,用来读取bin-log日志中更新的操作将其发送给从服务器,发送完毕以后继续等待bin-log日志是否有更新。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

使用 Mysqldump 备份 MySQL 中的数据

发布时间:2023/05/09 浏览次数:192 分类:MySQL

本篇文章将介绍如何使用 mysqldump 只备份数据。 在这里,我们将探讨 --no-create-info 、--compact 、--skip-triggers 和 --no-create-db 选项。

更新 MySQL 表中的主键

发布时间:2023/05/09 浏览次数:61 分类:MySQL

本篇文章介绍如何更新 MySQL 表中的主键。 我们将使用 ALTER 命令对主键进行任何更改。更新 MySQL 表中的主键 我们可以在多种情况下更新 MySQL 表中的主键。

在 MySQL 中获取命令历史记录

发布时间:2023/05/09 浏览次数:150 分类:MySQL

本文重点介绍了在 Windows 和 Linux 中获取我们已执行的 MySQL 命令历史记录的各种方法。MySQL命令历史

Oracle 的 decode 函数在 MySQL 中的等价物

发布时间:2023/05/09 浏览次数:115 分类:MySQL

本篇文章介绍了三种替代实现,我们可以将它们用作 MySQL 中 Oracle 的 decode() 函数的等价物。 为此,我们将使用 IF()、CASE 以及 FIELD() 和 ELT() 的组合。

在 Linux 中安装 MySQL 客户端

发布时间:2023/05/09 浏览次数:72 分类:MySQL

在 Linux 中安装 MySQL 客户端的命令。Linux 和 Unix 等环境作为命令行界面工作,仅在命令的帮助下运行。

在 MySQL 中转换为十进制

发布时间:2023/05/09 浏览次数:150 分类:MySQL

有时,我们可能需要将一种数据类型转换为另一种数据类型。 下面是我们如何使用带有 DECIMAL(M,D) 的 CAST() 和 CONVERT() 函数在 MySQL 中转换为十进制。

在 MySQL 中获取当前日期和时间

发布时间:2023/05/09 浏览次数:145 分类:MySQL

本篇文章我们将学习 NOW()、CURRENT_TIMESTAMP()(也写为 CURRENT_TIMESTAMP)和 SYSDATE() 来获取 MySQL 中的当前日期和时间。 我们还将看到这三个功能之间的比较。在 MySQL 中获取当前日期和时间

更改 MySQL 服务器中的 max_allowed_packet Size

发布时间:2023/05/09 浏览次数:142 分类:MySQL

本篇文章介绍如何更改 MySQL 服务器中的 max_allowed_packet 大小。 为了了解这一点,我们将使用两个操作系统,Windows 10 和 Linux (Ubuntu)。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便