网站设计网站优化公司,顺德品牌网站建设公司,打开全网搜索,企业展示型网站php无论你是前端还是后端#xff0c;只要是一个合格的开发者#xff0c;对于MySQL这个名词相信都不陌生#xff0c;MySQL逐渐成为了最受欢迎的关系型数据库#xff0c;无论你是大前端#xff0c;亦或是Java、Go、Python、C/C、PHP....等这些语言的程序员#xff0c;对于MySQ…无论你是前端还是后端只要是一个合格的开发者对于MySQL这个名词相信都不陌生MySQL逐渐成为了最受欢迎的关系型数据库无论你是大前端亦或是Java、Go、Python、C/C、PHP....等这些语言的程序员对于MySQL是必然要掌握的核心技术之一程序员不能没有MySQL就像西方不能失去耶路撒冷一般。 当然MySQL也不仅仅是唯一的数据库与它类似的关系型数据库竞品还有很多例如Oracle、SQLServer、PostgreSQL、DB2....这其中使用最为广泛的是Oracle但Oracle实际上并不怎么受程序员欢迎或者说Oracle并不怎么受中小企业的Boss欢迎原因嘛大家都清楚无非因为它收费罢了。 也正是由于Oracle收费的原因才导致MySQL像如今这么流行正所谓时势造英雄MySQL作为免费的开源数据库也正是抓住了这个风口所以才越发流行。对于MySQL用一句话形容很贴切“天不生我MySQL编程万古如长夜”。 一、MySQL概述与系列预告
MySQL数据库是由瑞典的MySQL AB公司开发的后面这家企业被Sun公司收购最后Sun公司又被Oracle以74亿美元收购所以本质上MySQL现在隶属于Oracle旗下因此大家也会发现MySQL后面的高版本会有收费版出现。 实际上如果MySQL没有并入Oracle的话是有很大几率问鼎数据库榜首的造化弄人。 整个MySQL系列会按上述目录进行全面阐述但上述目录只是预期规划内容实际撰写过程中可能会适当调整但给出的技术点都会事无巨细的讲到内容只多不少因此大家感兴趣的话可以点个关注由我伴随诸君一同彻底掌握MySQL数据库。
二、MySQL整体结构浅析 本章作为MySQL系列的开篇之作当然也有一定的原因毕竟只有先对MySQL的整体架构有了一个宏观的认知才能更好的理解每个细节点的知识。 MySQL与我们开发项目时相同为了能够合理的规划整体架构设计也会将整个MySQL服务抽象成几个大的模块然后在内部进行实现因此先来看看MySQL的整体架构开局先上一张图 从上往下看依次会分为网络连接层、系统服务层、存储引擎层、以及文件系统层往往编写SQL后都会遵守着MySQL的这个架构往下走。
连接层主要是指数据库连接池会负责处理所有客户端接入的工作。服务层主要包含SQL接口、解析器、优化器以及缓存缓冲区四块区域。存储引擎层这里是指MySQL支持的各大存储引擎如InnoDB、MyISAM等。文件系统层涵盖了所有的日志以及数据、索引文件位于系统硬盘上。
OK~除了上述的四层外还有客户端这个客户端可以是各类编程语言如Java、Go、Python、C/C、PHP、Node、.Net....也可以是一些数据库的可视化软件例如Navicat、SQLyog等也可以是mysql-cli命令行工具。总之只要能与MySQL建立网络连接都可以被称为是MySQL的客户端。 MySQL-Server就是上述图中的那玩意儿一般来说客户端负责编写SQL而服务端则负责SQL的执行与数据的存储。 对MySQL的整体架构有了简单了解后接下来详细的拆解一下MySQL-Server的每个层面。
三、网络连接层 在之前的《网络之旅》的文章中我们提到过一点当一个客户端尝试与MySQL建立连接时MySQL内部都会派发一条线程负责处理该客户端接下来的所有工作。而数据库的连接层负责的就是所有客户端的接入工作MySQL的连接一般都是基于TCP/IP协议建立网络连接因此凡是可以支持TCP/IP的语言几乎都能与MySQL建立连接。 其实MySQL还支持另一种连接方式就是Unix系统下的Socket直连但这种方式一般使用的较少。 虽然MySQL是基于TCP/IP协议栈实现的连接建立工作但并非使用HTTP协议建立连接的一般建立连接的具体协议都会根据不同的客户端实现如jdbc、odbc...这类的。在这里先暂且不纠结连接MySQL时的协议类型先来看看一般是怎么连接MySQL的如下 mysql -h 127.0.0.1 -uroot -p123456 例如上述这条指令-h表示MySQL所在的服务器IP地址-u表示本次连接所使用的用户名-p则代表着当前用户的账号密码当执行这条指令后会与MySQL-Server建立网络连接也就是会经历《TCP的三次握手过程》。当然MySQL也支持SSL加密连接如果采用这种方式建立连接那还会经过《SSL多次握手过程》当握手结束网络建立成功后则会开始正式的数据库连接建立工作。
TCP网络连接建立成功后MySQL服务端与客户端之间会建立一个session会话紧接着会对登录的用户名和密码进行效验MySQL首先会查询自身的用户表信息判断输入的用户名是否存在如果存在则会判断输入的密码是否正确如若密码错误或用户名不存在就会返回1045的错误码如下信息 ERROR 1045 (28000): Access denied for user zhuzilocalhost (using password: YES) 如果你在连接数据库的过程中出现了上述的错误信息那绝对是你输入的用户名或密码错误导致的当账号及密码正确时此时就会进入MySQL的命令行接下来可以执行SQL操作。 但实际上在用户名和密码都正确的情况下MySQL还会做一些些小动作也就是会进行授权操作查询每个用户所拥有的权限并对其授权后续SQL执行时都会先判断是否具备执行相应SQL语句的权限然后再执行。 OK~经过上述流程后数据库连接就建立成功了数据库连接建立成功后MySQL与客户端之间会采用半双工的通讯机制工作与之对应的还有“全双工、单工”的工作模式
全双工代表通讯的双方在同一时间内即可以发送数据也可以接收数据。半双工代表同一时刻内单方要么只能发送数据要么只能接受数据。单工当前连接只能发送数据或只能接收数据也就是“单向类型的通道”。
到这里MySQL也会“安排”一条线程维护当前客户端的连接这条线程也会时刻标识着当前连接在干什么工作可以通过show processlist;命令查询所有正在运行的线程 执行结果如下(root账号可以查询所有线程) Id当前线程的ID值可以利用这个ID使用kill强杀线程。User当前线程维护的数据库连接与之对应的用户是谁。Host与当前线程保持连接关系的客户端地址IPPort。db目前线程在哪个数据库中执行SQL。Command当前线程正在执行的SQL类型如 Create DB正在执行创建数据库的操作。Drop DB正在执行删除数据库的操作。Execute正在执行预编译的SQLPreparedStatement。Close Stmt正在关闭一个PreparedStatement。Query正在执行普通的SQL语句。Sleep正在等待客户端发送SQL语句。Quit当前客户端正在退出连接。Shutdown正在关闭MySQL服务端。Time表示当前线程处于目前状态的时间单位是秒。State表示当前线程的状态有如下几种 Updating当前正在执行update语句匹配数据做修改操作。Sleeping正在等待客户端发送新的SQL语句。Starting目前正在处理客户端的请求。Checking table目前正在表中查询数据。Locked当前线程被阻塞其他线程获取了执行需要的锁资源。Sending Data目前执行完成了Select语句正在将结果返回给客户端。Info一般记录当前线程正在执行的SQL默认显示前一百个字符查看完整的SQL可以使用show full processlist;命令。
其实从这个结果上来看我们能够很明显的看到数据库中各个线程的信息这条指令对于以后做线上排查时有很大的作用目前先简单了解接着来看看数据库连接池。
3.1、数据库连接池(Connection Pool) Connection Pool翻译过来的意思就是连接池那为什么需要有这个东西呢因为前面聊到过所有的客户端连接都需要一条线程去维护而线程资源无论在哪里都属于宝贵资源因此不可能无限量创建所以这里的连接池就相当于Tomcat中的线程池主要是为了复用线程、管理线程以及限制最大连接数的。 连接池的最大线程数可以通过参数max-connections来控制如果到来的客户端连接超出该值时新到来的连接都会被拒绝关于最大连接数的一些命令主要有两条
show variables like %max_connections%;查询目前DB的最大连接数。set GLOBAL max_connections 200;修改数据库的最大连接数为指定值。
对于不同的机器配置可以适当的调整连接池的最大连接数大小以此可以在一定程度上提升数据库的性能。除了可以查询最大连接数外MySQL本身还会对客户端的连接数进行统计对于这点可以通过命令show status like Threads%;查询 其中各个字段的释义如下
Threads_cached目前空闲的数据库连接数。Threads_connected当前数据库存活的数据库连接数。Threads_createdMySQL-Server运行至今累计创建的连接数。Threads_running目前正在执行的数据库连接数。
对于几个字段很容易理解额外要说明的一点是Threads_cached这个字段从名称上来看似乎跟缓存有关系其实也没错因为这里是有一个数据库内部的优化机制。当一个客户端连接断开后对于数据库连接却不会立马销毁而是会先放入到一个缓存连接池当中。这样就能在下次新连接到来时省去了创建线程、分配栈空间等一系列动作但这个值不会是无限大的一般都在32左右。 连接池的优化思想与Java线程池相同会将数据库创建出的连接对象放入到一个池中一旦出现新的访问请求会复用这些连接一方面提升了性能第二方面还节省了一定程度上的资源开销。