MySQL主从复制及优化

复制方式:
  1. 基于语句的复制(逻辑复制)、基于行的复制。两种方式都是通过在主库上记录二进制日志、在备库重放日志的方式来实现异步的数据复制。
  2. 两种复制方式意味着,在同一时间点备库上的数据可能与主库存在不一致,并且无法保证主备之间的延迟。
复制带来的开销:复制不会增加主库的开销,主要是启用二进制日志的开销。每个备库会对主库增加一些负载(如网络I/O),尤其是当备库请求从主库读取旧的二进制日志时,可能会造成更高的I/O开销。另外锁竞争也可能阻碍事务的提交。
通过复制可以带来更好的读扩展,但对于写操作并不适合。并且当使用一主多备时,会有多份数据拷贝,其中这些数据库服务器的缓存中存储了大部分相同的数据库,这并不是一种经济的硬件使用方式。复制解决的问题:
  • 数据分布:可以随意地停止或开始复制,并在不同的地理位置来分布数据备份。
  • 负载均衡:可以将读操作分布到多个服务器上,实现对读密集型应用的优化。
  • 备份:实现数据备份。
  • 高可用性和故障切换:复制能帮助应用避免MySQL单点失败,构建一个良好的故障切换系统能显著缩短宕机时间。
  • MySQL升级:使用一个高本版MySQL作为备库,保证在升级全部实例前,查询能够在备库按预期执行。
复制的工作步骤(主从复制原理):

  1. master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。
  2. salve开启一个I/O Thread,该线程在master打开一个普通连接,主要工作是启动一个二进制转储线程。该线程会读取主库bin log的事件,如果读取的进度已经跟上了master,就进入睡眠状态并等待master产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中。
  3. salve的SQL线程读取中继日志,并顺序执行该日志中的SQL事件。当SQL线程追赶上I/O线程时,中继日志通常已在系统缓存中,所以中继日志开销很低。
  • 每个从服务器都会收到主服务器二进制日志的全部内容的副本。
  • 从服务器设备负责决定应该执行二进制日志中的哪些语句。
  • 除非另行指定,否则主从二进制日志中的所有事件都在从库上执行。
MySQL主从同步时延迟原因和数据丢失:只有Mysql事务在主库执行并记录到二进制日志中,从库才能从主库二进制日志中读取已执行完的事务,并将这些事务保存到从库的中继日中,然后从库的sql线程才能从中继日志中读取内容并执行。
在这个过程中,有几点是影响主从延迟的因素:
  • 主库写入二进制日志的时间,更多是执行事务的时间
  • 二进制日志传输时间,即从主库传输到从库并写入中继日志的时间
  • 默认下从库只有一个SQL线程,主库并发的修改在从库上都是串行化执行。比如DDL和DML操作在主库上是顺序写的,但在从库上是随机的,成本会高,并且可能出现于从库上其他查询产生锁竞争,导致SQL线程被阻塞。
  因此在高并发场景下,产生的DDL数量超过从库一个SQL线程所能承受的范围时,延时就产生了,刚写入主库的数据可能读不到,要过几十甚至几百毫秒才能读到。极端情况下还存在,主库突然宕机,数据恰好没有同步到从库,那么有些数据在从库是没有的,造成了数据丢失。核心因素:数据库业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高,读写bin long带来的性能影响,网络传输延迟。
如何解决MySQL主从同步的延时问题:
  • 事务执行影响:控制主库事务大小,分割大事务,避免大事务在从库上的SQL线程造成阻塞
  • 日志传输时间影响:使用MIXED日志格式,减少二进制日志量,设置set binlong_row_image=minimal
  • 并行复制解决SQL线程影响:使用多线程复制处理,增加SQL线程数据,在MySQL5.7中对从库配置:从库开启多个线程,并行读取relay log中的日志,然后按表分发或按行分发。stop slave --停止复制 set global slave_parallel_type ='logical_clock';---设置链路并发同步类型为逻辑时钟模式 set global slave_parallel_workers=4;---设置所需要的复制线程数量 start slave;
  • 架构上:
    • 分库架构,Mysql服务平行扩展,分散压力
    • 在业务和Mysql之间引入缓存中间件,降低读压力
    • 使用比主库更好的硬件设备做从库,mysql压力小,延迟会变小,如一下措施:好服务器,4核比2核性能好。存储采用SSD提升随机写性能。主从之间处于同一个交换机,网络环境好
MySQL主从同步加速:
  • 降低数据安全性:sync_binlog在slave端设置为0,MySQL不控制binlog的刷新,由文件系统自己控制。如果系统崩溃,在binlog_cache中所有信息会丢失
  • –logs-slave-updates 从服务器从主服务器接收到的更新不记入它的bin log。从服务器只有relay-binlog中有master上执行的语句,binlog本身没有
  • 直接禁用slave端的binlog
  • slave端,如果使用的存储引擎是innodb,设置flush方式,innodb_flush_log_at_trx_commit =2。将日志从innodb log buffer写入到redo log中。设置为2代表,每次事务提交会写入日志文件,但不会立即刷新到磁盘,日志文件会每秒刷一次到磁盘,即使数据丢失一般不会超过1-2秒的更新。
半同步复制(semi-sync):主要用于解决主库宕机后,数据丢失问题,主库写完binlog后,强制此时立即将数据同步到从库,从库将日志写入自己本地relay log后,返回一个ack给主库,主库接收到至少一个从库的ack后,才认为写操作完成,性能有一定的降低。
 
posted @ 2025-04-16 17:26  难得  阅读(54)  评论(0)    收藏  举报