从根儿上理解MySQL.docx

上传人:暗伤 文档编号:96178238 上传时间:2023-09-19 格式:DOCX 页数:389 大小:9.10MB
返回 下载 相关 举报
从根儿上理解MySQL.docx_第1页
第1页 / 共389页
从根儿上理解MySQL.docx_第2页
第2页 / 共389页
点击查看更多>>
资源描述

《从根儿上理解MySQL.docx》由会员分享,可在线阅读,更多相关《从根儿上理解MySQL.docx(389页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、0 第0章 万里长征第一步(非常重要)-如何愉快的阅读本小册0.1 购买前警告此小册并非数据库入门书籍,需要各位知道增删改查是啥意思,并且能用 SQL 语言写出来,当然并不要求各位知道的太多,你甚至可以不知道连接的语法都可以。不过如果你连 SELECT 、 INSERT 这些单词都没听说过那本小册并不适合你。此小册非正经科学专著,亦非十二五国家级规划教材,也没有大段代码和详细论证,有的全是图,喜欢正经论述的同学请避免购买本小册。此小册作者乃一无业游民,非专业大佬,没有任何职称,只是单单喜欢把复杂问题讲清楚的那种快感,所以喜欢作者有 Google、Facebook 高级开发工程师,二百年工作经验

2、等 Title 的同学请谨慎购买。此小册是用于介绍 MySQL 的工作原理以及对我们程序猿的影响,并不是介绍概念设计、逻辑设计、物理设计、范式化之类的数据库设计方面的知识,希望了解上述这些知识的同学来错地方了。文章标题中的“从根儿上理解MySQL”其实是专门雇了 UC 震惊部小编起的,纯属为了吸引大家眼球。严格意义上说,本书只是介绍 MySQL 内核的一些核心概念的小白进阶书籍。大家读完本小册也不会一下子晋升业界大佬,当上 CTO,迎娶白富美,走上人生巅峰。希望本小册能够帮助大家解决一些工作、面试过程中的问题,逐渐成为一个更好的工程师,有兴趣的小伙伴可以再深入研究一下 MySQL,说不定你就是

3、下一个数据库泰斗啦。0.2 购买并阅读本小册的建议本小册是一本待出版的纸质书籍,并非一些杂碎文章的集合,是非常有结构和套路的,所以大家阅读时千万不能当作厕所蹲坑、吃饭看手机时的所谓 碎片化读物 。碎片化阅读只适合听听矮大紧、罗胖子他们扯扯犊子,开阔一下视野用的。对于专业的技术知识来说,大家必须付出一个完整的时间段进行体系化学习,这样尊重知识,工资才能尊重你。顺便说一句,我已经好久都不听罗胖子扯犊子了,刚开始办罗辑思维的时候觉得他扯的还可以,越往后越觉得都钻钱眼儿里了,天天在鼓吹焦虑,让大家去买他们的鸡汤课。不过听听矮大紧就挺好啊,不累本小册是由 Markdown 写成,在电脑端阅读体验十分舒服

4、,当然你非要用小手机看我也不拦着你,但是效果打了折扣是你的损失。为了保证最好的阅读体验,不用一个没学过的概念去介绍另一个新概念,本小册的章节有严重的依赖性,比如你在没读 InnoDB 数据页结构前千万不要就去读 B+ 树索引,所以大家最好从前看到尾,不要跳着看!不要跳着看!不要跳着看!,当然,不听劝告我也不能说啥,祝你好运。大家可能买过别的小册,有的小册一篇文章可能用5分钟、10分钟读完,不过我的小册子每一篇文章都比较长,因为我把高耦合的部分都集中在一篇文章中了。文章中埋着各种伏笔,所以大家看的时候可能不会觉察出来很突兀的转变,所以在阅读一篇文章的时候千万不要跳着看!不要跳着看!不要跳着看!大

5、家在看本小册之前应该断断续续看过一些与本小册内容相关的知识,只是不成体系,细节学习的不够。对于这部分读者来说,希望大家像倚天屠龙记里的张无忌一样,在学张三丰的太极剑法时先忘记之前的武功, 忘的越干净,学的越得真传。这样才能跟着我的套路走下去。如果你真的是个小白的话,那这里头的数字都是假的:一篇文章能用2个小时左右的时间掌握就很不错了。说句扫大家兴的话,虽然我已经很努力的想让大家的学习效率提升n倍,但是不幸的是想掌握一门核心技术仍然需要大家多看几遍(不然工资那么好涨啊)。0.3 关于工具本小册中会涉及很多 InnoDB 的存储结构的知识,比如记录结构、页结构、索引结构、表空间结构等等,这些知识是

6、所有后续知识的基础,所以是重中之重,需要大家认真对待。Jeremy Cole 已经使用 Ruby 开发了一个简易的解析这些基础结构的工具,github地址是:innodb_ruby的github地址( InnoDB 中的一些存储结构(此工具虽然是针对 MySQL 5.6 的,但是幸好 MySQL 的基础存储结构基本没多大变化,所以大部分场景下这个 innodb_ruby 工具还是可以使用的)。0.4 关于盗版在写这本小册之前,我天真的以为只需要找几本参考书,看看 MySQL 的官方文档,遇到不会的地方百度谷歌一下就可以在 3 个月内解决这本书,后来的现实证明我真的想的太美了。不仅花了大量的时间

7、阅读各种书籍和源码,而且有的时候知识耦合太厉害,为了更加模块化的把知识表述清楚,我又花了大量的时间来思考如何写作才能符合用户认知习惯,还花了非常多的时间来画各种图表,总之就是心累啊我希望的是:各位同学可以用很低的成本来更快速学会一些看起来生涩难懂的知识,但是毕竟我不是马云,不能一心一意做公益,希望各位通过正规渠道获得小册,尊重一下版权。还有各位写博客的同学,引用的少了叫借鉴,引用的多了就,就有点那个了。希望各位不要大段大段的复制粘贴,用自己的话写出来的知识才是自己的东西。我知道不论我们怎样强调版权意识,总是有一部分小伙伴喜欢不劳而获,总是喜欢想尽各种渠道来弄一份盗版的看,希望这部分同学看完之后

8、记住能拍个大腿:这个叫小孩子的家伙写的真不错,之后在工作或者面试中用到了书里的东西还能想起我,当然,读完了之后记得关注一下公众号我们都是小青蛙。小贴士: 我一直有个想法,就是如何降低教育成本。现在教育的盈利收费模式都太单一,就是直接跟学生收上课费,导致课程成为一种2C的商品,价格高低其实和内容质量并不是很相关,所以课程提供商会投入更大的精力做他们的渠道营销。所以现在的在线教育市场就是渠道为王,招生为王。我们其实可以换一种思路,在线教育的优势其实是传播费用更低,一个人上课和一千万人上课的费用区别其实就是服务器使用的多少罢了,所以我们可能并不需要那么多语文老师、数学老师,我们用专业的导演、专业的声

9、优、专业的动画制作、专业的后期、专业的剪辑、专业的编剧组成的团队为某个科目制作一个专业的课程就好了嘛(顺便说一句,我就可以转行做课程编剧了)!把课程当作电影、电视剧来卖,只要在课程中植入广告,或者在播放平台上加广告就好了嘛,我们也可以在课程里培养偶像,来做一波粉丝经济。这样课程生产方也赚钱,学生们也省钱,最主要的是可以更大层度上促进教育公平,多好。0.5 关于错误0.5.1 准确性问题我不是神,并不是书中的所有内容我都一一对照源码来验证准确性(阅读的大部分源码是关于查询优化和事务处理的),如果各位发现了文中有准确性问题请直接联系我,我会加入 Bug 列表中修正的。0.5.2 阅读体验问题大家知

10、道大部分人在长大之后就忘记了自己小时候的样子,我写本书的初衷就是有很多资料我看不懂,看的我脑壳疼,之后才决定从小白的角度出发来写一本小白都能看懂的技术书籍。但是由于后来自己学的东西越来越多, 可能有些地方我已经忘掉了小白的想法是怎么样的,所以大家在阅读过程中有任何阅读不畅快的地方都可以给我提,我也会加入bug列表中逐一优化。0.6 关于转发如果你从本小册中获取到了自己想要的知识,并且这个过程是比较轻松愉快的,希望各位能帮助转发本小册,解放一下学不懂这些知识的童鞋们,多节省一下他们的学习时间以及让学习过程不再那么痛苦。大家的技术都长进了,咱国家的技术也就慢慢强起来了。0.7 关于疑惑虽然我觉得文

11、章写的已经很清晰了,但毕竟只是“我觉得”,不是大家觉得。传道授业解惑,解惑很重要。在学习一门知识时,我们最容易让一些问题绊住脚步,大家在阅读小册时如果发现了任何你觉得让你很困惑的问题,都可以直接加微信 xiaohaizi4919 问我,或者到群里提问题(最好到群里提,这样大家都能看到,也省的重复提问),我在力所能及的范围内尽力帮大家解答。0.8 闲话如果有的同学购买本小册后觉得并不是自己的菜,那很遗憾,我不能给你退款,钱是掘金这个平台收的。不过我还是觉得绝大部分同学读过后肯定有物超所值的感受,面试一般的数据库问题再也难不倒各位了,工作中一般的数据库问题也都是小菜一碟了,想继续研究 MySQL

12、源码的同学也找到方向了,如果你觉得 29.9 元不能表达你淘到宝的喜悦之情,那这好说,给我发红包就好了。1 第1章 装作自己是个小白-重新认识MySQL标签: MySQL是怎样运行的1.1 MySQL的客户端服务器架构以我们平时使用的微信为例,它其实是由两部分组成的,一部分是客户端程序,一部分是服务器程序。客户端可能有很多种形式,比如手机APP,电脑软件或者是网页版微信,每个客户端都有一个唯一的用户名,就是你的微信号,另一方面,腾讯公司在他们的机房里运行着一个服务器软件,我们平时操作微信其实都是用客户端来和这个服务器来打交道。比如狗哥用微信给猫爷发了一条消息的过程其实是这样的:1. 消息被客户

13、端包装了一下,添加了发送者和接收者信息,然后从狗哥的微信客户端传送给微信服务器;2. 微信服务器从消息里获取到它的发送者和接收者,根据消息的接收者信息把这条消息送达到猫爷的微信客户端,猫爷的微信客户端里就显示出狗哥给他发了一条消息。MySQL 的使用过程跟这个是一样的,它的服务器程序直接和我们存储的数据打交道,然后可以有好多客户端程序连接到这个服务器程序,发送增删改查的请求,然后服务器就响应这些请求,从而操作它维护的数据。和微信一样, MySQL 的每个客户端都需要提供用户名密码才能登录,登录之后才能给服务器发请求来操作某些数据。我们日常使用 MySQL 的情景一般是这样的:1. 启动 MyS

14、QL 服务器程序。2. 启动 MySQL 客户端程序并连接到服务器程序。3. 在客户端程序中输入一些命令语句作为请求发送到服务器程序,服务器程序收到这些请求后,会根据请求的内容来操作具体的数据并向客户端返回操作结果。我们知道计算机很牛逼,在一台计算机上可以同时运行多个程序,比如微信、QQ、音乐播放器、文本编辑器啥的,每一个运行着的程序也被称为一个 进程 。我们的 MySQL 服务器程序和客户端程序本质上都算是计算机上的一个 进程 ,这个代表着 MySQL 服务器程序的进程也被称为 MySQL数据库实例 ,简称 数据库实例 。每个进程都有一个唯一的编号,称为 进程ID ,英文名叫 PID ,这个

15、编号是在我们启动程序的时候由操作系统随机分配的,操作系统会保证在某一时刻同一台机器上的进程号不重复。比如你打开了计算机中的QQ程序,那么操作系统会为它分配一个唯一的进程号,如果你把这个程序关掉了,那操作系统就会把这个进程号回收,之后可能会重新分配给别的进程。当我们下一次再启动 QQ程序的时候分配的就可能是另一个编号。每个进程都有一个名称,这个名称是编写程序的人自己定义的,比如我们启动的 MySQL 服务器进程的默认名称为 mysqld , 而我们常用的 MySQL 客户端进程的默认名称为 mysql 。1.2 MySQL的安装不论我们通过下载源代码自行编译安装的方式还是直接使用官方提供的安装包

16、进行安装之后, MySQL 的服务器程序和客户端程序都会被安装到我们的机器上。不论使用上述两者的哪种安装方式,一定一定一定(重要的话说三遍)要记住你把 MySQL 安装到哪了,换句话说,一定要记住 MySQL 的安装目录。小贴士: MySQL的大部分安装包都包含了服务器程序和客户端程序,不过在Linux下使用RPM包时会有单独的服务器RPM包和客户端RPM包,需要分别安装。另外, MySQL 可以运行在各种各样的操作系统上,我们后边会讨论在类 UNIX 操作系统和 Windows 操作系统上使用的一些差别。为了方便大家理解,我在 macOS 操作系统(苹果电脑使用的操作系统)和 Windows

17、 操作系统上都安装了 MySQL ,它们的安装目录分别是:macOS 操作系统上的安装目录:/usr/local/mysql/Windows 操作系统上的安装目录:C:Program FilesMySQLMySQL Server 5.7下边我会以这两个安装目录为例来进一步扯出更多的概念,不过一定要注意,这两个安装目录是我的运行不同操作系统的机器上的安装目录,一定要记着把下边示例中用到安装目录的地方替换为你自己机器上的安装目录。小贴士: 类UNIX操作系统非常多,比如FreeBSD、Linux、macOS、Solaris等都属于UNIX操作系统的范畴,我们这里使用macOS操作系统代表类UNIX

18、操作系统来运行MySQL。1.2.1 bin目录下的可执行文件在 MySQL 的安装目录下有一个特别特别重要的 bin 目录,这个目录下存放着许多可执行文件,以 macOS 系统为例,这个 bin 目录的绝对路径就是(在我的机器上):/usr/local/mysql/bin我们列出一些在 macOS 中这个 bin 目录下的一部分可执行文件来看一下(文件太多,全列出来会刷屏的):. mysql mysql.server - ./support-files/mysql.server mysqladmin mysqlbinlog mysqlcheck mysqld mysqld_multi mys

19、qld_safe mysqldump mysqlimport mysqlpump . (省略其他文件) 0 directories, 40 filesWindows 中的可执行文件与 macOS 中的类似,不过都是以 .exe 为扩展名的。这些可执行文件都是与服务器程序和客户端程序相关的,后边我们会详细唠叨一些比较重要的可执行文件,现在先看看执行这些文件的方式。对于有可视化界面的操作系统来说,我们拿着鼠标点点点就可以执行某个可执行文件,不过现在我们更关注在命令行环境下如何执行这些可执行文件,命令行通俗的说就是那些黑框框,这里的指的是类 UNIX 系统中的 Shell 或者 Windows 系统

20、中的 cmd.exe ,如果你现在还不知道怎么启动这些命令行工具,网上搜搜吧 下边我们以macOS 系统为例来看看如何启动这些可执行文件( Windows 中的操作是类似的,依葫芦画瓢就好了)使用可执行文件的相对绝对路径 假设我们现在所处的工作目录是 MySQL 的安装目录,也就是 /usr/local/mysql ,我们想启动 bin 目录下的 mysqld 这个可执行文件,可以使用相对路径来启动: ./bin/mysqld或者直接输入 mysqld 的绝对路径也可以: /usr/local/mysql/bin/mysqld将该 bin 目录的路径加入到环境变量 PATH 中如果我们觉得每次

21、执行一个文件都要输入一串长长的路径名贼麻烦的话,可以把该 bin 目录所在的路径添加到环境变量 PATH 中。环境变量 PATH 是一系列路径的集合,各个路径之间使用冒号 : 隔离开,比方说我的机器上的环境变量 PATH 的值就是: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin我的系统中这个环境变量 PATH 的值表明:当我在输入一个命令时,系统便会在 /usr/local/bin 、 /usr/bin: 、 /bin: 、 /usr/sbin 、 /sbin 这些目录下依次寻找是否存在我们输入的那个命令,如果寻找成功,则执行该目录下对应的可执行文件

22、。所以我们现在可以修改一下这个环境变量PATH ,把 MySQL 安装目录下的 bin 目录的路径也加入到 PATH 中,在我的机器上修改后的环境变量 PATH 的值为: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/mysql/bin这样现在不论我们所处的工作目录是啥,我们都可以直接输入可执行文件的名字就可以启动它,比如这样: mysqld方便多了哈 小贴士: 关于啥是环境变量以及如何在当前系统中添加或修改系统变量不是我们唠叨的范围,大家找本相关的书或者上网查一查哈1.3 启动MySQL服务器程序1.3.1 UNIX里启动服务

23、器程序在类 UNIX 系统中用来启动 MySQL 服务器程序的可执行文件有很多,大多在 MySQL 安装目录的 bin 目录下,我们一起来瞅瞅。1.3.1.1 mysqldmysqld 这个可执行文件就代表着 MySQL 服务器程序,运行这个可执行文件就可以直接启动一个服务器进程。但这个命令不常用,我们继续往下看更牛逼的启动命令。1.3.1.2 mysqld_safemysqld_safe 是一个启动脚本,它会间接的调用 mysqld ,而且还顺便启动了另外一个监控进程,这个监控进程在服务器进程挂了的时候,可以帮助重启它。另外,使用 mysqld_safe 启动服务器程序时,它会将服务器程序的

24、出错信息和其他诊断信息重定向到某个文件中,产生出错日志,这样可以方便我们找出发生错误的原因。1.3.1.3 mysql.servermysql.server 也是一个启动脚本,它会间接的调用 mysqld_safe ,在调用 mysql.server 时在后边指定 start参数就可以启动服务器程序了,就像这样:mysql.server start需要注意的是,这个 mysql.server 文件其实是一个链接文件,它的实际文件是 ./support-files/mysql.server。我使用的 macOS 操作系统会帮我们在 bin 目录下自动创建一个指向实际文件的链接文件,如果你的操作系

25、统没有帮你自动创建这个链接文件,那就自己创建一个呗 别告诉我你不会创建链接文件,上网搜搜呗另外,我们还可以使用 mysql.server 命令来关闭正在运行的服务器程序,只要把 start 参数换成 stop 就好了:mysql.server stop1.3.1.4 mysqld_multi其实我们一台计算机上也可以运行多个服务器实例,也就是运行多个 MySQL 服务器进程。 mysql_multi 可执行文件可以对每一个服务器进程的启动或停止进行监控。这个命令的使用比较复杂,本书主要是为了讲清楚 MySQL 服务器和客户端运行的过程,不会对启动多个服务器程序进行过多唠叨。1.3.2 Wind

26、ows里启动服务器程序Windows 里没有像类 UNIX 系统中那么多的启动脚本,但是也提供了手动启动和以服务的形式启动这两种方式, 下边我们详细看。1.3.2.1 mysqld同样的,在 MySQL 安装目录下的 bin 目录下有一个 mysqld 可执行文件,在命令行里输入 mysqld ,或者直接双击运行它就算启动了 MySQL 服务器程序了。1.3.2.2 以服务的方式运行服务器程序首先看看啥是个 Windows 服务?如果无论是谁正在使用这台计算机,我们都需要长时间的运行某个程序,而且需要在计算机启动的时候便启动它,一般我们都会把它注册为一个 Windows 服务 ,操作系统会帮我

27、们管理它。把某个程序注册为 Windows 服务的方式挺简单,如下:完整的可执行文件路径 -install -manual 服务名其中的 -manual 可以省略,加上它的话表示在 Windows 系统启动的时候不自动启动该服务,否则会自动启动。服务名 也可以省略,默认的服务名就是 MySQL 。比如我的 Windows 计算机上 mysqld 的完整路径是:C:Program FilesMySQLMySQL Server 5.7binmysqld所以如果我们想把它注册为服务的话可以在命令行里这么写:C:Program FilesMySQLMySQL Server 5.7binmysqld -

28、install在把 mysqld 注册为 Windows 服务之后,我们就可以通过下边这个命令来启动 MySQL 服务器程序了:net start MySQL当然,如果你喜欢图形界面的话,你可以通过 Windows 的服务管理器通过用鼠标点点点的方式来启动和停止服务(作为一个程序猿,还是用黑框框吧)。关闭这个服务也非常简单,只要把上边的 start 换成 stop 就行了,就像这样:net stop MySQL1.4 启动MySQL客户端程序在我们成功启动 MySQL 服务器程序后,就可以接着启动客户端程序来连接到这个服务器喽, bin 目录下有许多客户端程序,比方说 mysqladmin 、

29、 mysqldump 、 mysqlcheck 等等等等(好多呢,就不一一列举了)。这里我们重点要关注的是可执行文件 mysql ,通过这个可执行文件可以让我们和服务器程序进程交互,也就是发送请求, 接收服务器的处理结果。启动这个可执行文件时一般需要一些参数,格式如下:mysql -h主机名 -u用户名 -p密码各个参数的意义如下: |参数名|含义| |:-:|:-| | -h |表示服务器进程所在计算机的域名或者IP地址,如果服务器进程就运行在本机的话,可以省略这个参数,或者填 localhost 或者 127.0.0.1 。也可以写作 -host=主机名 的形式。| | -u |表示用户名

30、。也可以写作 -user=用户名 的形式。| | -p |表示密码。也可以写作 -password=密码 的形式。|小贴士: 像 h、u、p 这样名称只有一个英文字母的参数称为短形式的参数,使用时前边需要加单短划线,像 ho st、user、password 这样大于一个英文字母的参数称为长形式的参数,使用时前边需要加双短划线。后边会详细讨论这些参数的使用方式的,稍安勿躁比如我这样执行下边这个可执行文件(用户名密码按你的实际情况填写),就可以启动 MySQL 客户端,并且连接到服务器了。mysql -hlocalhost -uroot -p123456我们看一下连接成功后的界面:Welcome

31、 to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 2 Server version: 5.7.21 Homebrew Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of t

32、heir respective owners. Type help; or h for help. Type c to clear the current input statement. mysql 最后一行的 mysql 是一个客户端的提示符,之后客户端发送给服务器的命令都需要写在这个提示符后边。如果我们想断开客户端与服务器的连接并且关闭客户端的话,可以在 mysql 提示符后输入下边任意一个命令:1. quit2. exit3. q比如我们输入 quit 试试:mysql quit Bye输出了 Bye 说明客户端程序已经关掉了。注意注意注意,这是关闭客户端程序的方式,不是关闭服务器程序

33、的方式,怎么关闭服务器程序上一节里唠叨过了。如果你愿意,你可以多打开几个黑框框,每个黑框框都使用 mysql -hlocahhost -uroot -p123456 来运行多个客户端程序,每个客户端程序都是互不影响的。如果你有多个电脑,也可以试试把它们用局域网连起来,在一个电脑上启动 MySQL 服务器程序,在另一个电脑上执行 mysql 命令时使用 IP 地址作为主机名来连接到服务器。1.4.1 连接注意事项最好不要在一行命令中输入密码。我们直接在黑框框里输入密码很可能被别人看到,这和你当着别人的面输入银行卡密码没啥区别,所以我们在执行 mysql 连接服务器的时候可以不显式的写出密码,就像

34、这样: mysql -hlocahhost -uroot -p点击回车之后才会提示你输入密码: Enter password:不过这回你输入的密码不会被显示出来,心怀不轨的人也就看不到了,输入完成点击回车就成功连接到了服务器。如果你非要在一行命令中显式的把密码输出来,那 -p 和密码值之间不能有空白字符(其他参数名之间可以有空白字符),就像这样: mysql -h localhost -u root -p123456如果加上了空白字符就是错误的,比如这样: mysql -h localhost -u root -p 123456mysql 的各个参数的摆放顺序没有硬性规定,也就是说你也可以这么

35、写: mysql -p -u root -h localhost如果你的服务器和客户端安装在同一台机器上, -h 参数可以省略,就像这样: mysql -u root -p 如果你使用的是类 UNIX 系统,并且省略 -u 参数后,会把你登陆操作系统的用户名当作 MySQL 的用户名去处理。比方说我用登录操作系统的用户名是 xiaohaizi ,那么在我的机器上下边这两条命令是等价的: mysql -u xiaohaizi -p mysql -p对于 Windows 系统来说,默认的用户名是 ODBC ,你可以通过设置环境变量 USER 来添加一个默认用户名。1.5 客户端与服务器连接的过程我

36、们现在已经知道如何启动 MySQL 的服务器程序,以及如何启动客户端程序来连接到这个服务器程序。运行着的服务器程序和客户端程序本质上都是计算机上的一个进程,所以客户端进程向服务器进程发送请求并得到回复的过程本质上是一个进程间通信的过程! MySQL 支持下边三种客户端进程和服务器进程的通信方式。1.5.1 TCP/IP真实环境中,数据库服务器进程和客户端进程可能运行在不同的主机中,它们之间必须通过网络来进行通讯。MySQL 采用 TCP 作为服务器和客户端之间的网络通信协议。在网络环境下,每台计算机都有一个唯一的 IP地址 ,如果某个进程有需要采用 TCP 协议进行网络通信方面的需求,可以向操

37、作系统申请一个 端口号 ,这是一个整数值,它的取值范围是 065535 。这样在网络中的其他进程就可以通过 IP地址 + 端口号 的方式来与这个进程连接,这样进程之间就可以通过网络进行通信了。MySQL 服务器启动的时候会默认申请 3306 端口号,之后就在这个端口号上等待客户端进程进行连接,用书面一点的话来说, MySQL 服务器会默认监听 3306 端口。小贴士: TCP/IP网络体系结构是现在通用的一种网络体系结构,其中的TCP和IP是体系结构中两个非常重要的网络协议,如果你并不知道协议是什么,或者并不知道网络是什么,那恐怕兄弟你来错地方了,找本计算机网络的书去瞅瞅吧! 什么?计算机网络

38、的书写的都贼晦涩,看不懂?没关系,等我如果 3306 端口号已经被别的进程占用了或者我们单纯的想自定义该数据库实例监听的端口号,那我们可以在启动服务器程序的命令行里添加 -P 参数来明确指定一下端口号,比如这样:mysqld -P3307这样 MySQL 服务器在启动时就会去监听我们指定的端口号 3307 。如果客户端进程想要使用 TCP/IP 网络来连接到服务器进程,比如我们在使用 mysql 来启动客户端程序时,在 - h 参数后必须跟随 IP地址 来作为需要连接的服务器进程所在主机的主机名,如果客户端进程和服务器进程在一台计算机中的话,我们可以使用 127.0.0.1 来代表本机的 IP

39、地址 。另外,如果服务器进程监听的端口号不是默认的 3306 ,我们也可以在使用 mysql 启动客户端程序时使用 -P 参数(大写的 P ,小写的 p 是用来指定密码的)来指定需要连接到的端口号。比如我们现在已经在本机启动了服务器进程,监听的端口号为 3307 ,那我们启动客户端程序时可以这样写:mysql -h127.0.0.1 -uroot -P3307 -p不知大家发现了没有,我们在启动服务器程序的命令 mysqld 和启动客户端程序的命令 mysql 后边都可以使用 - P 参数,关于如何在命令后边指定参数,指定哪些参数我们稍后会详细唠叨的,稍微等等哈1.5.2 命名管道和共享内存如

40、果你是一个 Windows 用户,那么客户端进程和服务器进程之间可以考虑使用 命名管道 或 共享内存 进行通信。不过启用这些通信方式的时候需要在启动服务器程序和客户端程序时添加一些参数:使用 命名管道 来进行进程间通信需要在启动服务器程序的命令中加上 -enable-named-pipe 参数,然后在启动客户端程序的命令中加入 - pipe 或者 -protocol=pipe 参数。使用 共享内存 来进行进程间通信需要在启动服务器程序的命令中加上 -shared-memory 参数,在成功启动服务器后, 共享内存 便成为本地客户端程序的默认连接方式,不过我们也可以在启动客户端程序的命令中加入

41、-protocol=memory 参数来显式的指定使用共享内存进行通信。不过需要注意的是,使用 共享内存 的方式进行通信的服务器进程和客户端进程必须在同一台 Windows 主机中。小贴士: 命名管道和共享内存是Windows操作系统中的两种进程间通信方式,如果你没听过的话也不用纠结,并不妨碍我们介绍MySQL的知识1.5.3 Unix域套接字文件如果我们的服务器进程和客户端进程都运行在同一台操作系统为类 Unix 的机器上的话,我们可以使用 Unix域套接字文件 来进行进程间通信。如果我们在启动客户端程序的时候指定的主机名为 localhost ,或者指定了 - protocol=socke

42、t 的启动参数,那服务器程序和客户端程序之间就可以通过 Unix 域套接字文件来进行通信了。MySQL 服务器程序默认监听的 Unix 域套接字文件路径为 /tmp/mysql.sock ,客户端程序也默认连接到这个Unix 域套接字文件。如果我们想改变这个默认路径,可以在启动服务器程序时指定 socket 参数,就像这样:mysqld -socket=/tmp/a.txt这样服务器启动后便会监听 /tmp/a.txt 。在服务器改变了默认的 UNIX 域套接字文件后,如果客户端程序想通过 UNIX 域套接字文件进行通信的话,也需要显式的指定连接到的 UNIX 域套接字文件路径,就像这样:my

43、sql -hlocalhost -uroot -socket=/tmp/a.txt -p这样该客户端进程和服务器进程就可以通过路径为 /tmp/a.txt 的 Unix 域套接字文件进行通信了。1.6 服务器处理客户端请求其实不论客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。那服务器进程对客户端进程发送的请求做了什么处理,才能产生最后的处理结果呢?客户端可以向服务器发送增删改查各类请求, 我们这里以比较复杂的查询请求为例来画个图展示一下大致的过程:从图中我们可以看出

44、,服务器程序处理来自客户端的查询请求大致需要经过三个部分,分别是 连接管理 、 解析与优化 、 存储引擎 。下边我们来详细看一下这三个部分都干了什么。1.6.1 连接管理客户端进程可以采用我们上边介绍的 TCP/IP 、 命名管道或共享内存 、 Unix域套接字 这几种方式之一来与服务器进程建立连接,每当有一个客户端进程连接到服务器进程时,服务器进程都会创建一个线程来专门处理与这个客户端的交互,当该客户端退出时会与服务器断开连接,服务器并不会立即把与该客户端交互的线程销毁掉,而是把它缓存起来,在另一个新的客户端再进行连接时,把这个缓存的线程分配给该新客户端。这样就起到了不频繁创建和销毁线程的效

45、果,从而节省开销。从这一点大家也能看出, MySQL 服务器会为每一个连接进来的客户端分配一个线程,但是线程分配的太多了会严重影响系统性能,所以我们也需要限制一下可以同时连接到服务器的客户端数量,至于怎么限制我们后边再说哈在客户端程序发起连接的时候,需要携带主机信息、用户名、密码,服务器程序会对客户端程序提供的这些信息进行认证,如果认证失败,服务器程序会拒绝连接。另外,如果客户端程序和服务器程序不运行在一台计算机 上,我们还可以采用使用了 SSL (安全套接字)的网络连接进行通信,来保证数据传输的安全性。当连接建立后,与该客户端关联的服务器线程会一直等待客户端发送过来的请求, MySQL 服务

46、器接收到的请求只是一个文本消息,该文本消息还要经过各种处理,预知后事如何,继续往下看哈1.6.2 解析与优化到现在为止, MySQL 服务器已经获得了文本形式的请求,接着 还要经过九九八十一难的处理,其中的几个比较重要的部分分别是 查询缓存 、 语法解析 和 查询优化 ,下边我们详细来看。1.6.2.1 查询缓存如果我问你 9+816-3217 的值是多少,你可能会用计算器去算一下,或者牛逼一点用心算,最终得到了结果 35 ,如果我再问你一遍 9+816-3217 的值是多少,你还用再傻呵呵的算一遍么?我们刚刚已经算过了, 直接说答案就好了。 MySQL 服务器程序处理查询请求的过程也是这样,

47、会把刚刚处理过的查询请求和结果 缓存起来,如果下一次有一模一样的请求过来,直接从缓存中查找结果就好了,就不用再傻呵呵的去底层的表中查找了。这个查询缓存可以在不同客户端之间共享,也就是说如果客户端A刚刚查询了一个语句,而客户端B之后发送了同样的查询请求,那么客户端B的这次查询就可以直接使用查询缓存中的数据。当然, MySQL 服务器并没有人聪明,如果两个查询请求在任何字符上的不同(例如:空格、注释、大小写),都会导致缓存不会命中。另外,如果查询请求中包含某些系统函数、用户自定义变量和函数、一些系统表,如mysql 、information_schema、 performance_schema 数据库中的表,那这个请求就不会被缓存。以某些系统函数举例,可能同样的函数的两次调用会产生不一样的结果,比如函数 NOW ,每次调用都会产生最新的当前时间, 如果在一个查询请求中调用了这个函数,那即使查询请求的文本信息都一样,那不同时间的两次查询也应该得到不同的结果,如果在第一

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 技术方案

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁