用Python开发MySQL增强半同步BinlogServer(T2通信篇)

导读

作者:曾永伟 ,知数堂10期学员,多年JAVA物流行业开发管理经验和PHP/Python跨境电商开发管理经验,对数据库系统情有独钟,善于运用SQL编程简化业务逻辑,去年开始正式从业MySQL DBA, 专注于DB系统自动化运维、MySQL云上实践。

本文为python-mysql-binlogserver系列的第二篇(T2通信篇),之后会陆续发布此系列的其他文章,请大家点击在看或者收藏,自行练习。

一想到你在关注我就忍不住有点紧张

一、概述

从前一篇文章我们已经了解了:

  • 二进制在计算机中的应用

  • 字符集与二进制的关系及其在Python中处理

  • 用struct来处理二进制的转换问题

  • Socket通信的基本编程方法

在本节中,我们将结合这些内容进一步来了解如何使Python和MySQL进行交互。

二、MySQL通信协议基础

在Python中,使用socket.secv接收数据或send发送数据的都是二进制流对象Bytes,我们需要结合MySQL通信协议来逐字节解析其具体的含义。

MySQL基础通信单位Packet,它由header + payload组成,header由3个字节的payload长度(最大16M字节数)和1个字节的流水号组成,在读取一个Packet时,通常先读4个字节,解析出payload的长度和payload的序号,再根据payload的长度把余下的正文读取出来。

解析Greeting包

当Client连接上MySQL Server后,MySQL会主动发送一个greeting包,把自己的状态和随机密文发送给Client, 等待Client响应帐户和密码等信息,验证失败发送ERR包并主动断开连接,验证成功后发送OK包,保持连接,等待Client发送其它"指令"。

接下来我先看一下Greeting包正文的官方说明:

为了更加直接的观察和理解,我这里去掉了对低版本的兼容格式,让其显得更加整洁。

我们来尝试用Python解析第一个Greeting包:

输出:

可见用Python解析出Greeting包的内容并没有想象中那么难,只要结合官方文档,用Python struct很容易就把二进制流还原成可读的文本信息。

为了使代码可以复用,我们将上面的代码进行一个简单的函数化封装,以方便给后面的例子调用:

封装Response包,完成验证

当Client得到Greeting包后,就可以结合两个随机码,组成认证回应包,完成MySQL的认证:

向服务器发送帐号及加密的密文,通过验证后,会得到OK包:

验证失败会得到如下结果:

执行查询

完成认证后,服务器就会保存连接,直到超时或Client主动退出才会中断连接。接下来我们就可以在完成认证后的socket上发送命令了,就像使用mysql client一样,只不过通过socket发送的数据还要是bytes对象,直接上菜:

三、Binlog文件格式

先简单回顾一下binlog文件中都有些什么内容:

可以看出,binlog文件内容就是有很多的Event组成,一个完整的binlog应该是由Format_desc event开始,Rotate event结束,它们充当Binlog文件的元数据,中间Event才是真正和数据相关Event,每一个Event的格式都不尽相同,需要单独作解析。不过我们的BinlogServer并不关心具体的Event内容,只需要把Event作为一个接收,存储和发送的基本单元即可,简单说就是,把Master发送的Event按顺序存储起来,当有Slave change过来以后,再从指定位置把Event一个一个的发送给Slave,仅此而已。

每一个Event都有自己的Headyier, 描述了它的创建时间、类型、Server Id、长度、下一个Event位置和flags信息,结合Event的长度和下个Event位置信息,我们可以很容易地实现顺序扫描一个Binlog文件中的所有Event:

输出:

是不是比想象中简单,如果你把基础篇的内容全部理解了,我相信上面这段代码不会难到你,相反如果你还不能理解上面这段代码,请移步回去多看几遍,多练几遍再回来。更多的Binlog相关知识,请参考官方文档。

四、小结

这一节我们把Socket通信的难关攻破了,已经完成了和MySQL服务器进行握手,登陆和执行查询,近距离的接触了MySQL的通信协议,学会了如何运用Python struct进行简单的解包和封包,也简单分析了binlog的组成及使用Python来解析binlog文件,最重要的是学会了结合官方文档来解决我们的实际问题。

下一节我们将在本节的基础上进入实战篇,利用Socket向Master发起Slave注册,发送BinlogDump指令,以获取Master上的Binlog Event并保存到本地文件中。

相关文档

  • https://dev.mysql.com/doc/internals/en/mysql-packet.html

  • https://dev.mysql.com/doc/internals/en/binlog-file-header.html

  • https://dev.mysql.com/doc/internals/en/binlog-event-header.html

  • https://github.com/alvinzane/py-mysql-binlogserver/tree/master/pymysqlbinlogserver/_tutorial

(本周先为大家献上这两篇文章,大家可以多练习,下周会继续发布此系列的文章,请持续关注哦~~)

扫码加入MySQL技术Q群

(群号: 650149401)

点“在看”给我一朵小黄花

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章