(15)binlog应用场景与原理(部分未完成)

一、基于binlog的主从复制

实现灾难恢复、水平扩展、统计分析、远程数据分发等功能。

每个写(Insert、Update、Delete,不包括Select)都对应一个事件。从库从主库拉取binlog:

第一步:master提交事务,改变记录二进制日志(binary log)中(二进制日志事件,binary log event,简称event)

第二步:slave启动I/O线程读取主库binary log中事件,记录到slave自己中继日志(relay log)中。

第三步:启动SQL线程,从relay log中读取事件,备库执行,实现更新。

二、binlog的应用场景

2.1 读写分离

每个Slave都连Master上,获取binlog本地复制。

slave之间做负载均衡。tddl、sharding-jdbc完成读写分离

2.2 数据恢复

2.3 数据最终一致性

数据库与redis缓存:只更新数据库

产生binlog。组件模拟slave,拉binlog异步更新缓存、索引或者发送MQ消息。如linkedin的databus,阿里canal,美团puma。

(1)增量索引

全量、增量索引。增量监听binlog变化,转换成es语法,实时索引更新。

(2)可靠消息

保证本地事务发送消息到MQ一致。用本地事务表或者独立消息服务保证,或RocketMQ事务消息。这两种方案,都侵入性,对业务不透明。订阅binlog发可靠消息,解耦、无侵入可靠消息一致性的奇淫技巧

(3)缓存一致性

只更新数据库,binlog异步更新缓存(删除,让业务回源到数据库)。更新失败,没有binlog,实现最终一致性。

问题:多个slave管理开销,流量大

优化:多slave获同一份binlog,本质上:一份binlog数据,不同场景用,互不影响。

消息中间件解决方案。支持consumer group概念,如kafka、rocketmq等。同一topic中数据,不同consumer group来消费,不同consumer group相互隔离,将binlog统一发送MQ的Topic中(用MQ高级特性。削峰、消息回溯功能)

2.4 异地多活

多个数据中心都写入数据,往对方同步。

数据冲突:双方同时插入相同主键值,同步时冲突

数据回环:库A中插入的数据,binlog同步到B中,产生binlog。B同步回库A,死循环。

阿里开源otter,美团)的DRC解决。异地多活场景下的数据同步之道

三、 Binlog事件详解

3.1 多文件存储

数据量多,分配多个文件存储。"show binary logs"查看当前有多少个binlog文件,每个大小

max_binlog_size,控制大小,默认1G

expire_logs_days,控制保留天数,默认0,永久保留。

生产环境,一条记录变更多次,记一条,对应binlog事件多个。无法保留所有

max_binlog_files(mysql的percona分支上),设置保留binlog数量,精确控制binlog文件占磁盘空间。非常有用,10分钟产生binlog文件,1G这种增长速度,1天144G,可控制binlog最多占用50G

3.2 Binlog管理事件

"show binlog events"看空binlog文件,只包含(部分)管理事件

三个事件类型:

Format_desc:binlog第一个事件。Mysql Server版本5.7.10,Binlog版本是4。

Previous_gtids:完整名,PREVIOUS_GTIDS_LOG_EVENT。Mysql 基于GTID复制,这binlog已执行过GTID。开启GTID选项才会有值

Rotate:binlog结束事件。指定文件名称mysql-bin.000004。

关于"show binlog events"语法显示的每一列的作用说明如下:

Log_name:binlog文件名

Pos:开始位置,占字节大小,结束位置(End_log_position)减去Pos,第一个事件位置从4开始。Mysql通过前4个字节,判断这是不是binlog文件。如pdf、doc、jpg都用前几个特定字符判断是否合法文件。

Server_id:事件mysql server_id,my.cnf中的server-id配置。

End_log_position:下事件开始位置

Info:当前事件描述信息

3.3 Statement模式下的事件

逻辑复制binary log文件

insert intouser(name) values("tianbowen");  show binlog events看binary log内容:

       红色框架中Event,是我们执行上面Insert语句产生的4个Event。下面进行详细的说明:

(划重点)首先,需要说明的是,每个事务都是以Query Event作为开始,其INFO列内容为"BEGIN",以Xid Event表示结束,其INFO列内容为COMMIT。即使对于单条更新SQL我们没有开启事务,Mysql也会默认的帮我们开启事务。因此在上面的红色框中,尽管我们只是执行了一个INSERT语句,没有开启事务,但是Mysql 默认帮我们开启了事务,所以第一个Event是Query Event,最后一个是Xid Event。

接着,是一个Intvar Event,因为我们的Insert语句插入的表中,主键是自增的(AUTO_INCREMENT)列,Mysql首先会自增一个值,这就是Intvar Event的作用,这里我们看到INFO列的值为INSERT_ID=1,也就是说,这次的自增主键id为1。需要注意的是,这个事件,只会在Statement模式下出现。

然后,还是一个Query Event,这里记录的就是我们插入的SQL。这也体现了Statement模式的作用,就是记录我们执行的SQL。

Statement模式下还有一些不常用的Event,如USER_VAR_EVENT,这是用于记录用户设置的变量,仅仅在Statement模式起作用。如:

执行以下SQL:

set@name='tianshouzhi';insertintouser(name)values(@name);

这里,我们插入sql的时候,通过引用一个变量。此时查看binlog变化,这里为了易于观察,在执行show binlog events时,指定了binlog文件和from的位置,即只查看指定binlog文件中从指定位置开始的event。如下:

可以看到,依然符合我们所说的,对于这个插入语句,依然默认开启了事务。主键自曾值INSERT_ID=2。

当然,我们也看到了User var这个事件,其记录了我们的设置的变量值,只不过以16进制显示。

3.4 Row模式下的事件

某条sql影响的所有行记录变更前变更后的值。主要10个事件:

很直观的,我们看到了INSERT、DELETE、UPDATE操作都有3个版本(v0、v1、v2),v0和v1已经过时,我们只需要关注V2版本。

此外,还有一个TABLE_MAP_EVENT,这个event我们需要特别关注,可以理解其作用就是记录了INSERT、DELETE、UPDATE操作的表结构。

下面,我们通过案例演示,ROW模式是如何记录变更前后记录的值,而不是记录SQL。这里只演示UPDATE,INSERT和DELETE也是类似。

在前面的操作步骤中,我们已经插入了2条记录,如下:

现在需要从Statement模式切换到Row模式,重启Mysql之后,执行以下SQL更新这两条记录:

updateusersetname='wangxiaoxiao';

在binary log中,会把这2条记录变更前后的值都记录下来,以下是一个逻辑示意图:

该逻辑示意图显示了,在默认情况下,受到影响的记录行,每个字段变更前的和变更后的值,都会被记录下来,即使这个字段的值没有发生变化

接着,我们还是通过"show binlog events"语法来验证:

首先我们可以看到的是,在Row模式下,单条SQL依然会默认开启事务,通过Query Event(值为BEGIN)开始,以Xid Event结束。

接着,我们看到了一个Table_map 事件,就是前面提到的TABLE_MAP_EVENT,在INFO列,我们可以看到其记录table_id为108,操作的是test库中user表。

最后,是一个Update_rows事件,然而其INFO,并没有像Statement模式那样,显示一条SQL,我们无法直接看到其变更前后的值是什么。

由于存储的都是二进制内容,直接vim无法查看,我们需要借助另外一个工具mysqlbinlog来查看其内容。如下:

截图中显示了2个event,第一个红色框就是Table_map事件,第二个是Update_rows事件。

在第二个红色框架中,显示了两个Update sql,这是只是mysqlbinlog工具为了方便我们查看,反解成SQL而已。我们看到了WHERE以及SET子句中,并没有直接列出字段名,而是以@1@2这样的表示字段位于数据库表中的顺序。事实上,这里显示的内容,WHERE部分就是每个字段修改前的值,而SET部分,则是每个字段修改后的值,也就是变更前后的值都会记录。

这里我们思考以下mysqlbinlog工具的工作原理,其可以将二进制数据反解成SQL进行展示。那么,如果我们可以自己解析binlog,就可以做数据恢复,这并非是什么难事。例如用户误删除的数据,执行的是DETELE语句,由于Row模式下会记录变更之前的字段的值,我们可以将其反解成一个INSERT语句,重新插入,从而实现数据恢复。

3.4.1 binlog_row_image参数

我们经常会看到一些Row模式和Statement模式的比较。ROW模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,binlog日志就会变大,带来磁盘IO上的开销,以及网络开销。

事实上,这个行为可以通过binlog_row_image控制其有3个值,默认为FULL: 

FULL : 记录列的所有修改,即使字段没有发生变更也会记录。 

MINIMAL :只记录修改的列。 

NOBLOB :如果是text类型或clob字段,不记录这些日志。 

我们可以将其修改为MINIMAL,则可以只记录修改的列的值。

3.4.2 binlog_rows_query_log_events参数

在Statement模式下,直接记录SQL比较直观,事实上,在Row模式下,也可以记录。mysql提供了一个binlog_rows_query_log_events参数,默认为值为FALSE,如果为true的情况下,会通过Rows Query Event来记录SQL。

my.cnf开启row模式原始sql记录(需重启)添加:binlog-rows-query-log_events=1

insert into user(name)values("maoxinyi");  binlog中看到Rows Query Event

3.5 GTID相关事件

GTID复制。修改my.cnf开启GTID:gtid-mode=onenforce-gtid-consistency=true

执行事务之前,都记录GTID Event  insert into user("name")values("zhuyihan");binlog内容:

执行sql手工切换下个binlog:mysql> flush logs;Query OK, 0 rows affected (0.00 sec)

之前执行过GTID在下一个文件中出现。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容