阿里开源MySQL中间件Canal快速入门( 二 )


数据库主从同步一致性问题我们通常使用MySQL主从复制来解决MySQL的单点故障问题,其通过逻辑复制的方式把主库的变更同步到从库,主备之间无法保证严格一致的模式,
于是,MySQL的主从复制带来了主从“数据一致性”的问题 。「MySQL的复制分为:异步复制、半同步复制、全同步复制 。」
异步复制MySQL默认的复制即是异步复制,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,「主如果crash掉了,此时主上已经提交的事务可能并没有传到从库上,如果此时,强行将从提升为主,可能导致新主上的数据不完整 。」

?
主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上 。
?
全同步复制指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端 。「因为需要等待所有从库执行完该事务才能返回」,所以全同步复制的性能必然会收到严重的影响 。
?
当主库提交事务之后,所有的从库节点必须收到、AppLY并且提交这些事务,然后主库线程才能继续做后续操作 。但缺点是,主库完成一个事务的时间会被拉长,性能降低 。
?
半同步复制是介于全同步复制与全异步复制之间的一种,「主库只需要等待至少一个从库节点收到」并且 Flush Binlog 到 Relay Log 文件即可,主库不需要等待所有从库给主库反馈 。同时,「这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈」,如此,节省了很多时间 。
?
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端 。相对于异步复制,半同步复制提高了数据的安全性,「同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间 。所以,半同步复制最好在低延时的网络中使用 。」
?

阿里开源MySQL中间件Canal快速入门

文章插图
 
「事实上,半同步复制并不是严格意义上的半同步复制,MySQL半同步复制架构中,主库在等待备库ack时候,如果超时会退化为异步后,也可能导致“数据不一致” 。」
?
当半同步复制发生超时时(由
rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制 。当master dump线程发送完一个事务的所有事件之后,如果在
rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制 。
?
关于半同步复制的详细原理分析可以看这篇引申文章,在此不展开:
https://www.cnblogs.com/ivictor/p/5735580.html
回到Canal的工作原理回顾了数据库从库的数据同步原理,理解Canal十分简单,直接引用官网原文:
  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)
Canal实战开启MySQL Binlog这个步骤我在之前的文章教你使用Binlog日志恢复误删的MySQL数据已经提到过,这里完善了一下,再贴一下,方便大家 。
首先进入数据库控制台,运行指令:
mysql> show variables like'log_bin%';+---------------------------------+-------+| Variable_name| Value |+---------------------------------+-------+| log_bin| OFF|| log_bin_basename||| log_bin_index||| log_bin_trust_function_creators | OFF|| log_bin_use_v1_row_events| OFF|+---------------------------------+-------+5 rows in set (0.00 sec)可以看到我们的binlog是关闭的,都是OFF 。接下来我们需要修改Mysql配置文件,执行命令:
sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf在文件末尾添加:
log-bin=/var/lib/mysql/mysql-binbinlog-format=ROW保存文件,重启mysql服务:
sudo service mysql restart重启完成后,查看下mysql的状态:
systemctl status mysql.service这时,如果你的mysql版本在5.7或更高版本,就会报错:
Jan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.190791Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)Jan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.190839Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)Jan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.359713Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (seJan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.361395Z 0 [Note] /usr/sbin/mysqld (mysqld 5.7.28-0ubuntu0.16.04.2-log) starting as process 5930 ...Jan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.363017Z 0 [ERROR] You have enabled the binary log, but you haven't provided the mandatory server-id. Please refer to the proper serverJan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.363747Z 0 [ERROR] AbortingJan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.363922Z 0 [Note] Binlog endJan 06 15:49:58 VM-0-11-ubuntu mysqld[5930]: 2020-01-06T07:49:58.364108Z 0 [Note] /usr/sbin/mysqld: Shutdown completeJan 06 15:49:58 VM-0-11-ubuntu systemd[1]: mysql.service: Main process exited, code=exited, status=1/FAILURE


推荐阅读