实现自己的数据库驱动——MySQL网络协议(一)

前言

在上一篇博客中,为了解释ThreadLocal的应用场景,所以提到了JDBC中的connection。用过的朋友们一定熟悉下面的代码。具体就是先获取一个connnection,然后在connection中进行CURD。或者是基于ORM框架如hibernateMybatis,但其实他们的底层都是基于mysql-connector-java.jar

你想输入的替代文字

很多时候我们并不清楚程序是如何和数据库进行交互的,比如简单的查询命令,程序是如何从MySQL中获取的呢?这个就是我这篇博客的主题,我会简单解释一下MySQL的网络通信协议,以及所需的技术栈。

原本想在网上找一下有没有类似的轮子,发现多数是将jdbc重新分装一些,本质使用的还是Java中实现好的connector。所以在后续的博客中根据协议去实现自己的connector.jar

MySQL连接方式

根据网上查到资料,MySQL目前有五种连接方式,分别是TCP/IP,TLS/SSL,Unix Sockets,Shared Memory,Named pipes,下面我们就来看看这五种的区别:

方式 默认开启 支持系统 只支持本机 如何开启 参数配置
TCP/IP 所有系统 –skip-networking=yes/no. –port –bind-address
TLS/SSL 所有系统(基于TCP/IP)之上 –ssl=yes/no. –ssl-* options
Unix Sockets 类Unix系统 设置–socket= 来关闭. –socket=socket path
Shared Memory Windows系统 –shared-memory=on/off. –shared-memory-base-name=
Named pipes Windows系统 –enable-named-pipe=on/off. –socket=

首先看一下Unix Sockets和Shared Memory都是只支持本机的,所以如果你的程序和数据库是在一台机子的,就可以考虑这两种协议。

这两种协议我也不是很清楚,所以本文是基于我比较熟悉的TCP/IP协议。

MySQL通信协议

借网上一张图,简单的给大家解释一下MySQL通信过程中数据包。

你想输入的替代文字

用户发送CRUD操作给数据库的数据包过程:

  1. 首先Client先与Server通过TCP三次握手建立连接
  2. 建立连接之后,Server发送Handshake数据包给Client,Handshake含有数据库的版本、协议版本、用于后期加密的Salt等。
  3. Client接收到Server的Handshake包之后,解析其中数据,最主要是获得Salt,然后把用户名、密码(利用salt+sha1进行加密)、schema(要操作的数据库名)等信息打包成一个AuthPacket,用来认证请求。
  4. Server接受到AuthPacket之后,对其的身份进行验证,验证成功发送一个OK Packet。否则发送Error Packet。
  5. Client接受到OK Packet之后就发送Query Packet给Server。
  6. Server返回结果查询的,将Result Packet返回给Client。
  7. Client解析Result Packet完毕,发送Request Quit。
  8. 四次握手断开连接。

上述是一次Query数据库的过程,其中涉及到数据包,后面将会用WireShark来详细解释上诉包的数据结构。

技术栈

有了上面的铺垫,我想你们大致也有了一个思路了。这里可以利用Socket或者NIO来实现数据库的通信。然后通过了解MySQL的网络协议数据包的结构,用WireShark来分析,分析之后打包发送。

其中wireShark和网络协议是这块技术的核心。另外编程中涉及到一些加密的皮毛,进制位上的转换的细节等,这写在后面会详细的解释。

下一篇主要是针对wireShark的使用,以及MySQL网络协议数据包的解析。这两部分结合一起说明效果会更好。