深度解析mysql登录原理
使用mysql数据库的第一步必然是建立连接登录,然后在上面执行SQL命令。无论是通过mysql的客户端,还是通过C-API,JDBC标准接口连接数据库,这个过程一定少不了。今天我们聊一聊mysql登陆具体过程,里面会涉及client与server的交互,并通过tcpdump抓包给大家展现这一过程。
TCP握手协议
远程连接数据库,mysql采用TCP协议通信,第一步是建立连接,即TCP的3次握手。mysql server端有一个监听线程等待client请求,client发起请求后,首先发一个sync包到服务端,服务端发一个ack包作为对客户端sync包的响应,同时发一个sync包到客户端,最后客户端再发一个ack包作为对服务端的响应。通过3次握手,TCP连接才算真正建立起来,这个时候mysql服务端会分配一个连接供客户端使用。记住,TCP的3次握手都是由TCP的协议栈完成,应用程序并无感知。但是,到目前为止,整个mysql连接过程还只完成了第一步--建立TCP连接。
下面附上TCP建立连接和断开连接的原理图。


MYSQL握手协议
TCP连接建立成功后,mysql客户端与mysql服务端开始进行通讯,进行mysql认证过程。(1)服务端首先会发一个握手包到客户端,(2)然后客户端向服务端发送认证信息(用户名,密码等),(3)服务端收到认证包后,会检查用户名与密码是否合法,并发送包告知客户端认证信息。如果合法,则登陆成功,否则,登陆失败。连接报错。有时候,我们通过show processlist看到User处于unauthenticated user ,这说明此时连接过程正处于第1步和第2步之间,服务端等待客户端发认证信息的过程中。
15922528 unauthenticated user 10.xx.2.74:53216 NULL Connect NULL Reading from net NULL
15923418 unauthenticated user connecting host NULL Connect NULL login NULL
tcpdump抓包验证
下面我们通过tcpdump抓网络包来验证我们的原理。由于测试在生产环境中进行,为了避免生产网段的IP泄露,对IP作了替换,但不影响分析过程。具体而言,10.aa.zz.142.10556代表客户端,10.bb.yy.104.3306代表服务器端,3306是服务器的监听端口号。
(1).在客户端上打开tcpdump命令,监听与10.bb.yy.104.3306的通信网络包,命令如下:
tcpdump -S -nn -tttt -i eth0 host 10.bb.yy.104 and port 3306 and tcp -c 100
-S 将tcp的序列号以绝对值形式输出,而不是相对值。
-nn 不进行端口名称的转换。
-tttt 在每一行中输出由date处理的默认格式的时间戳。
-i eth0 指定监听的网络接口
host 10.bb.yy.104 and port 3306 设置监听10.bb.yy.104:3306的网络包
-c 100 表示监听100包就结束。
(2).在客户端上,利用mysql命令远程连接服务端10.bb.yy.104,
mysql –h10.bb.yy.104 –P3306 –uxxx –pxxx
登陆成功后,然后直接执行exit,退出
(3)分析tcpdump抓取的网络包,重点分析建立TCP连接,MYSQL认证和TCP断开连接的过程。如下图,图中第1部分是TCP连接建立的过程,第2部分是MYSQL认证的过程,第3部分是登陆成功后,发送基本元数据信息的过程,第4部分是断开连接的过程。通过图中的标示,我们可以清晰的看到TCP建立连接的3次握手,MYSQL认证以及TCP断开连接的4次挥手过程。

建立连接
这个过程主要体现在第一部分,客户端10.aa.zz.142.10556,首先发一个编号为1491894492的SYN包,服务端收到后,发送了1491894492+1的ACK包,并发送了一个2727774925的SYN包,最后客户端再发送一个2727774925+1的包进行应答。
MYSQL认证
这个过程主要体现在第二部分,服务端10.bb.yy.104:3306首先发一个认证包给客户端,然后客户端再发送包含用户密码的认证包给服务器,验证成功后,服务端最后给客户端一个应答,那么整个认证过程就结束了,至于第3部分是服务端与客户端相互发送的一些元数据信息,比如版本信息之类的。
断开连接
这个过程主要体现在第四部分,客户端发起exit命令时,开始触发这个动作。客户端首先发一个编号为1491894724的FIN包,然后服务器发送一个1491894724+1的ACK包作为应答,并发送一个编号为2727775120的FIN包,最后客户端发送2727775120+1作为应答,整个过程结束。
数据包标记解析
S=SYN 发起连接标志,一般用于建立TCP连接
P=PUSH 传送数据标志,一般用于传输数据
F=FIN 关闭连接标志,一般用于关闭TCP连接
ack 表示应答包
RST= RESET 异常关闭连接
.表示没有任何标志
源码实现
用于MYSQL认证代码主要集中在函数native_password_authenticate中,具体调用层次为:login_connection->check_connection->acl_authenticate->do_auth_once->native_password_authenticate,函数逻辑很简单,就是调用write_packet往客户端发一个认证包,然后调用read_packet等待客户端返回包含用户名、密码等信息的包,最后解析包中的信息进行密码验证,成功后,会在调用Protocol::send_ok发一个认证成功网络包,这个过程可以在图中的第二步全部体现。底层socket通信代码主要集中在sql/net_serv.cc中,具体而言读采用接口my_net_read,写采用接口my_net_write。
问题
(1).Unix socket方式登陆与TCP方式登陆有什么区别和联系?
Unix socket是实现进程间通信的一种方式,mysql支持利用Unix socket来实现客户端-服务端的通信,但要求客户端和服务端在同一台机器上。对于unix socket而言,同样也是一种套接字,监听线程会同时监听TCP socket和Unix socket,接受到请求然后处理,后续的处理逻辑都是一致的,只不过底层通信方式不一样罢了。
mysql -h127.0.0.1 –P3306 –uxxx –pxxx [TCP通讯方式]
mysql -uxxx –pxxx –S/usr/mysql/mysql.sock [unix socket通信方式]
(2).监听socket是否与通信socket公用一个端口?
我们知道,服务端一直有一个监听socket在3306端口监听,等待新进来的客户请求,一旦一个请求过来,服务端会重新创建一个新的通信socket,这个新的socket专门用于与这个客户通信,而监听socket则继续监听。虽然是2个套接字,但监听socket和通信socket都是同一个端口,通过netstat可以确认这个问题。
(3).连接超时参数connect_timeout在何时作用?
这个参数实质就是在MYSQL认证过程起作用,如果在这个过程中,客户端超过connect_timeout时间仍然没有发送密码认证包过来,则会主动断开连接。
参考文档
http://www.pythian.com/blog/what-is-an-unauthenticated-user/
http://www.tuicool.com/articles/mY7nmu
深度解析mysql登录原理的更多相关文章
- 程序员收藏必看系列:深度解析MySQL优化(二)
程序员收藏必看系列:深度解析MySQL优化(一) 性能优化建议 下面会从3个不同方面给出一些优化建议.但请等等,还有一句忠告要先送给你:不要听信你看到的关于优化的“绝对真理”,包括本文所讨论的内容,而 ...
- 深度探索MySQL主从复制原理
深度探索MySQL主从复制原理 一 .概要 MySQL Replication (MySQL 主从复制) 是什么? 为什么要主从复制以及它的实现原理是什么? 1.1 MySQL 主从复制概念 MySQ ...
- 深度解析MySQL启动时报“The server quit without updating PID file”错误的原因
很多童鞋在启动mysql的时候,碰到过这个错误, 首先,澄清一点,出现这个错误的前提是:通过服务脚本来启动mysql.通过mysqld_safe或mysqld启动mysql实例并不会报这个错误. 那么 ...
- 你真的理解索引吗?从数据结构层面解析mysql索引原理
从<mysql存储引擎InnoDB详解,从底层看清InnoDB数据结构>中,我们已经知道了数据页内各个记录是按主键正序排列并组成了一个单向链表的,并且各个数据页之间形成了双向链表.在数据页 ...
- linux ssh 使用深度解析(key登录详解)
SSH全称Secure SHell,顾名思义就是非常安全的shell的意思,SSH协议是IETF(Internet Engineering Task Force)的Network Working Gr ...
- 深度解析SpringMvc实现原理手写SpringMvc框架
http://www.toutiao.com/a6340568603607171329/?tt_from=mobile_qq&utm_campaign=client_share&app ...
- mysql索引原理深度解析
mysql索引原理深度解析 一.总结 一句话总结: mysql索引是b+树,因为b+树在范围查找.节点查找等方面优化 hash索引,完全平衡二叉树,b树等 1.数据库中最常见的慢查询优化方式是什么? ...
- java8Stream原理深度解析
Java8 Stream原理深度解析 Author:Dorae Date:2017年11月2日19:10:39 转载请注明出处 上一篇文章中简要介绍了Java8的函数式编程,而在Java8中另外一个比 ...
- 并发编程(十五)——定时器 ScheduledThreadPoolExecutor 实现原理与源码深度解析
在上一篇线程池的文章<并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)>中从ThreadPoolExecutor源码分析了其运行机制.限于篇幅,留下了Scheduled ...
随机推荐
- slf4j log4j logback关系详解和相关用法
slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...
- (十六)WebGIS中偏移补偿量引发的问题之探讨
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在上一章里讲解地图平移功能的实现时,我在最后提出了两个问题: ...
- C#基于两种需求向图片添加水印
使用场景 1.也就是大家经常用的,一般是图片的4个角落,基于横纵坐标来添加. 2.在图片内基于固定位置,文字始终居中.刚开始我基于第一种场景来根据水印汉字的长度来计算坐标,后来发现方法始终不可靠.现在 ...
- jQuery方法position()与offset()区别
参考别人写得比较明白的,红色部分为重点吧: 使用jQuery获取元素位置时,我们会使用position()或offset()方法,两个方法都返回一个包含两个属性的对象-左边距和上边距,它们两个的不同点 ...
- OpenCV2:Mat属性type,depth,step
在OpenCV2中Mat类无疑使占据着核心地位的,前段时间初学OpenCV2时对Mat类有了个初步的了解,见OpenCV2:Mat初学.这几天试着用OpenCV2实现了图像缩小的两种算法:基于等间隔采 ...
- HTML特殊符号汇总
较常用的飘黄处理了 ´ ´ © © > > µ µ ® ® & & ° ° ¡ ¡ » » ¦ ¦ ÷ ÷ ¿ ¿ ¬ ¬ § § • • ½ ½ « « ¶ ¶ ¨ ...
- 基于Metronic的Bootstrap开发框架经验总结(12)--页面链接收藏夹功能的实现
在一个系统里面,往往有很多菜单项目,每个菜单项对应一个页面,一般用户只需要用到一些常用的功能,如果每次都需要去各个层次的菜单里面去找对应的功能,那确实有点繁琐.特别是在菜单繁多,而客户又对系统整体不熟 ...
- java 中包的概念,常量,静态与继承
一.包的概念:创建,使用. 1.新建包: 最上面一行,之前不能再有其它代码了. package 包名; 注意:包名一般都有命名的规范.例如:com.itnba.maya.zy(从大到小). 2.使用包 ...
- Error LNK1104 cannot open file 'libboost_system-vc140-mt-gd-1_58.lib'
I had a similar problem when trying to use boost unit testing in Visual Studio 2015 (Community Editi ...
- 【linux草鞋应用编程系列】_6_ 重定向和VT100编程
一.文件重定向 我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...