共计 2040 个字符,预计需要花费 6 分钟才能阅读完成。
这篇文章将为大家详细讲解有关 MySQL 中怎样实现主从同步,文章内容质量较高,因此丸趣 TV 小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
(1) statement:记录每一条更改数据的 sql;
优点:binlog 文件较小,节约 I /O,性能较高。
缺点:不是所有的数据更改都会写入 binlog 文件中,尤其是使用 MySQL 中的一些特殊函数 (如 LOAD_FILE()、UUID() 等)和一些不确定的语句操作,从而导致主从数据无法复制的问题。
(2) row:不记录 sql,只记录每行数据的更改细节
优点:详细的记录了每一行数据的更改细节,这也意味着不会由于使用一些特殊函数或其他情况导致不能复制的问题。
缺点:由于 row 格式记录了每一行数据的更改细节,会产生大量的 binlog 日志内容,性能不佳,并且会增大主从同步延迟出现的几率。
(3) mixed:一般的语句修改使用 statment 格式保存 binlog,如一些函数,statement 无法完成主从复制的操作,则采用 row 格式保存 binlog,MySQL 会根据执行的每一条具体的 sql 语句来区分对待记录的日志形式,也就是在 Statement 和 Row 之间选择一种。
(二)binlog 日志内容
mysqlbinlog 命令查看的内容如下:
根据事件类型查看的 binlog 内容:
(三)binlog 事件类型
MySQL binlog 记录的所有操作实际上都有对应的事件类型的,譬如 STATEMENT 格式中的 DML 操作对应的是 QUERY_EVENT 类型,ROW 格式下的 DML 操作对应的是 ROWS_EVENT 类型,如果想了解更多请参考官方文档,有关 binlog 日志内容不在这里过多赘述,简单介绍一下是为了更好的理解主从复制的细节,下面我们进入正题。
四、MySQL 主从复制原理
mysql 主从复制需要三个线程,master(binlog dump thread)、slave(I/O thread、SQL thread)。
master
(1)binlog dump 线程:当主库中有数据更新时,那么主库就会根据按照设置的 binlog 格式,将此次更新的事件类型写入到主库的 binlog 文件中,此时主库会创建 log dump 线程通知 slave 有数据更新,当 I / O 线程请求日志内容时,会将此时的 binlog 名称和当前更新的位置同时传给 slave 的 I / O 线程。
slave
(2)I/ O 线程:该线程会连接到 master,向 log dump 线程请求一份指定 binlog 文件位置的副本,并将请求回来的 binlog 存到本地的 relay log 中,relay log 和 binlog 日志一样也是记录了数据更新的事件,它也是按照递增后缀名的方式,产生多个 relay log( host_name-relay-bin.000001)文件,slave 会使用一个 index 文件 ( host_name-relay-bin.index) 来追踪当前正在使用的 relay log 文件。
(3)SQL 线程:该线程检测到 relay log 有更新后,会读取并在本地做 redo 操作,将发生在主库的事件在本地重新执行一遍,来保证主从数据同步。此外,如果一个 relay log 文件中的全部事件都执行完毕,那么 SQL 线程会自动将该 relay log 文件删除掉。
下面是整个复制过程的原理图:
四、主从同步延迟
mysql 的主从复制都是单线程的操作,主库对所有 DDL 和 DML 产生 binlog,binlog 是顺序写,所以效率很高,slave 的 I / O 线程到主库取日志,效率也比较高,但是,slave 的 SQL 线程将主库的 DDL 和 DML 操作在 slave 实施。DML 和 DDL 的 IO 操作是随即的,不是顺序的,成本高很多,还可能存在 slave 上的其他查询产生 lock 争用的情况,由于 SQL 也是单线程的,所以一个 DDL 卡住了,需要执行很长一段事件,后续的 DDL 线程会等待这个 DDL 执行完毕之后才执行,这就导致了延时。当主库的 TPS 并发较高时,产生的 DDL 数量超过 slave 一个 sql 线程所能承受的范围,延时就产生了,除此之外,还有可能与 slave 的大型 query 语句产生了锁等待导致。
由于主从同步延迟是客观存在的,我们只能从我们自己的架构上进行设计,尽量让主库的 DDL 快速执行。下面列出几种常见的解决方案:
业务的持久化层的实现采用分库架构,mysql 服务可平行扩展,分散压力。
服务的基础架构在业务和 mysql 之间加入 memcache 或者 Redis 的 cache 层。降低 mysql 的读压力;
使用比主库更好的硬件设备作为 slave;
sync_binlog 在 slave 端设置为 0;
ndash;logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。
禁用 slave 的 binlog
关于 MySQL 中怎样实现主从同步就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。