MySQL进阶 – MySQL是怎样运行的

MySQL的客户端/服务器架构

以我们平时使用的微信为例,它其实是由两部分组成的,一部分是客户端程序,一部分是服务器程序。客户端可能有很多种形式,比如手机APP,电脑软件或者是网页版微信,每个客户端都有一个唯一的用户名,就是你的微信号,另一方面,腾讯公司在他们的机房里运行着一个服务器软件,我们平时操作微信其实都是用客户端来和这个服务器来打交道。比如狗哥用微信给猫爷发了一条消息的过程其实是这样的:

  1. 消息被客户端包装了一下,添加了发送者和接收者信息,然后从狗哥的微信客户端传送给微信服务器;

  2. 微信服务器从消息里获取到它的发送者和接收者,根据消息的接收者信息把这条消息送达到猫爷的微信客户端,猫爷的微信客户端里就显示出狗哥给他发了一条消息。

MySQL的使用过程跟这个是一样的,它的服务器程序直接和我们存储的数据打交道,然后可以有好多客户端程序连接到这个服务器程序,发送增删改查的请求,然后服务器就响应这些请求,从而操作它维护的数据。和微信一样,MySQL的每个客户端都需要提供用户名密码才能登录,登录之后才能给服务器发请求来操作某些数据。我们日常使用MySQL的情景一般是这样的:

  1. 启动MySQL服务器程序。
  2. 启动MySQL客户端程序并连接到服务器程序。
  3. 在客户端程序中输入一些命令语句作为请求发送到服务器程序,服务器程序收到这些请求后,会根据请求的内容来操作具体的数据并向客户端返回操作结果。

我们知道计算机很牛逼,在一台计算机上可以同时运行多个程序,比如微信、QQ、音乐播放器、文本编辑器啥的,每一个运行着的程序也被称为一个进程。我们的MySQL服务器程序和客户端程序本质上都算是计算机上的一个进程,这个代表着MySQL服务器程序的进程也被称为MySQL数据库实例,简称数据库实例

每个进程都有一个唯一的编号,称为进程ID,英文名叫PID,这个编号是在我们启动程序的时候由操作系统随机分配的,操作系统会保证在某一时刻同一台机器上的进程号不重复。比如你打开了计算机中的QQ程序,那么操作系统会为它分配一个唯一的进程号,如果你把这个程序关掉了,那操作系统就会把这个进程号回收,之后可能会重新分配给别的进程。当我们下一次再启动 QQ程序的时候分配的就可能是另一个编号。每个进程都有一个名称,这个名称是编写程序的人自己定义的,比如我们启动的MySQL服务器进程的默认名称为mysqld, 而我们常用的MySQL客户端进程的默认名称为mysql

MySQL的安装

不论我们通过下载源代码自行编译安装的方式还是直接使用官方提供的安装包进行安装之后,MySQL的服务器程序和客户端程序都会被安装到我们的机器上。不论使用上述两者的哪种安装方式,一定一定一定(重要的话说三遍)要记住你把MySQL安装到哪了,换句话说,一定要记住MySQL的安装目录。

小贴士: `MySQL`的大部分安装包都包含了服务器程序和客户端程序,不过在Linux下使用RPM包时会有单独的服务器RPM包和客户端RPM包,需要分别安装。

另外,MySQL可以运行在各种各样的操作系统上,我们后边会讨论在类UNIX操作系统和Windows操作系统上使用的一些差别。为了方便大家理解,我在macOS 操作系统(苹果电脑使用的操作系统)和Windows操作系统上都安装了MySQL,它们的安装目录分别是:

  • macOS操作系统上的安装目录:
/usr/local/mysql/
  • Windows操作系统上的安装目录:
C:\Program Files\MySQL\MySQL Server 5.7

下边我会以这两个安装目录为例来进一步扯出更多的概念,不过一定要注意,这两个安装目录是我的运行不同操作系统的机器上的安装目录,一定要记着把下边示例中用到安装目录的地方替换为你自己机器上的安装目录。

小贴士: 类UNIX操作系统非常多,比如FreeBSD、Linux、macOS、Solaris等都属于UNIX操作系统的范畴,我们这里使用macOS操作系统代表类UNIX操作系统来运行MySQL。

bin目录下的可执行文件

MySQL的安装目录下有一个特别特别重要的bin目录,这个目录下存放着许多可执行文件,以macOS系统为例,这个bin目录的绝对路径就是(在我的机器上):

/usr/local/mysql/bin

我们列出一些在macOS中这个bin目录下的一部分可执行文件来看一下(文件太多,全列出来会刷屏的):

.├── mysql├── mysql.server -> ../support-files/mysql.server├── mysqladmin├── mysqlbinlog├── mysqlcheck├── mysqld├── mysqld_multi├── mysqld_safe├── mysqldump├── mysqlimport├── mysqlpump... (省略其他文件)0 directories, 40 files

Windows中的可执行文件与macOS中的类似,不过都是以.exe为扩展名的。这些可执行文件都是与服务器程序和客户端程序相关的,后边我们会详细唠叨一些比较重要的可执行文件,现在先看看执行这些文件的方式。

对于有可视化界面的操作系统来说,我们拿着鼠标点点点就可以执行某个可执行文件,不过现在我们更关注在命令行环境下如何执行这些可执行文件,命令行通俗的说就是那些黑框框,这里的指的是类UNIX系统中的Shell或者Windows系统中的cmd.exe,如果你现在还不知道怎么启动这些命令行工具,网上搜搜吧~ 下边我们以macOS系统为例来看看如何启动这些可执行文件(Windows中的操作是类似的,依葫芦画瓢就好了)

  • 使用可执行文件的相对/绝对路径

    假设我们现在所处的工作目录是MySQL的安装目录,也就是/usr/local/mysql,我们想启动bin目录下的mysqld这个可执行文件,可以使用相对路径来启动:

    ./bin/mysqld
    

    或者直接输入mysqld的绝对路径也可以:

    /usr/local/mysql/bin/mysqld
    
  • 将该bin目录的路径加入到环境变量PATH

    如果我们觉得每次执行一个文件都要输入一串长长的路径名贼麻烦的话,可以把该bin目录所在的路径添加到环境变量PATH中。环境变量PATH是一系列路径的集合,各个路径之间使用冒号:隔离开,比方说我的机器上的环境变量PATH的值就是:

    /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    

    我的系统中这个环境变量PATH的值表明:当我在输入一个命令时,系统便会在/usr/local/bin/usr/bin:/bin:/usr/sbin/sbin这些目录下依次寻找是否存在我们输入的那个命令,如果寻找成功,则执行该目录下对应的可执行文件。所以我们现在可以修改一下这个环境变量PATH,把MySQL安装目录下的bin目录的路径也加入到PATH中,在我的机器上修改后的环境变量PATH的值为:

    /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/mysql/bin
    

    这样现在不论我们所处的工作目录是啥,我们都可以直接输入可执行文件的名字就可以启动它,比如这样:

    mysqld
    

    方便多了哈~

    小贴士: 关于啥是环境变量以及如何在当前系统中添加或修改系统变量不是我们唠叨的范围,大家找本相关的书或者上网查一查哈~

启动MySQL服务器程序

UNIX里启动服务器程序

在类UNIX系统中用来启动MySQL服务器程序的可执行文件有很多,大多在MySQL安装目录的bin目录下,我们一起来瞅瞅。

mysqld

mysqld这个可执行文件就代表着MySQL服务器程序,运行这个可执行文件就可以直接启动一个服务器进程。但这个命令不常用,我们继续往下看更牛逼的启动命令。

mysqld_safe

mysqld_safe是一个启动脚本,它会间接的调用mysqld,而且还顺便启动了另外一个监控进程,这个监控进程在服务器进程挂了的时候,可以帮助重启它。另外,使用mysqld_safe启动服务器程序时,它会将服务器程序的出错信息和其他诊断信息重定向到某个文件中,产生出错日志,这样可以方便我们找出发生错误的原因。

mysql.server

mysql.server也是一个启动脚本,它会间接的调用mysqld_safe,在调用mysql.server时在后边指定start参数就可以启动服务器程序了,就像这样:

mysql.server start

需要注意的是,这个 mysql.server 文件其实是一个链接文件,它的实际文件是 ../support-files/mysql.server。我使用的macOS操作系统会帮我们在bin目录下自动创建一个指向实际文件的链接文件,如果你的操作系统没有帮你自动创建这个链接文件,那就自己创建一个呗~ 别告诉我你不会创建链接文件,上网搜搜呗~

另外,我们还可以使用mysql.server命令来关闭正在运行的服务器程序,只要把start参数换成stop就好了:

mysql.server stop

mysqld_multi

其实我们一台计算机上也可以运行多个服务器实例,也就是运行多个MySQL服务器进程。mysql_multi可执行文件可以对每一个服务器进程的启动或停止进行监控。这个命令的使用比较复杂,本书主要是为了讲清楚MySQL服务器和客户端运行的过程,不会对启动多个服务器程序进行过多唠叨。

Windows里启动服务器程序

Windows里没有像类UNIX系统中那么多的启动脚本,但是也提供了手动启动和以服务的形式启动这两种方式,下边我们详细看。

mysqld

同样的,在MySQL安装目录下的bin目录下有一个mysqld可执行文件,在命令行里输入mysqld,或者直接双击运行它就算启动了MySQL服务器程序了。

以服务的方式运行服务器程序

首先看看啥是个Windows 服务?如果无论是谁正在使用这台计算机,我们都需要长时间的运行某个程序,而且需要在计算机启动的时候便启动它,一般我们都会把它注册为一个Windows 服务,操作系统会帮我们管理它。把某个程序注册为Windows服务的方式挺简单,如下:

"完整的可执行文件路径" --install [-manual] [服务名]

其中的-manual可以省略,加上它的话表示在Windows系统启动的时候不自动启动该服务,否则会自动启动。服务名也可以省略,默认的服务名就是MySQL。比如我的Windows计算机上mysqld的完整路径是:

C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld

所以如果我们想把它注册为服务的话可以在命令行里这么写:

"C:\Program Files\MySQL\MySQL Server 5.7\bin\mysqld" --install

在把mysqld注册为Windows服务之后,我们就可以通过下边这个命令来启动MySQL服务器程序了:

net start MySQL

当然,如果你喜欢图形界面的话,你可以通过Windows的服务管理器通过用鼠标点点点的方式来启动和停止服务(作为一个程序猿,还是用黑框框吧~)。

关闭这个服务也非常简单,只要把上边的start换成stop就行了,就像这样:

net stop MySQL

启动MySQL客户端程序

在我们成功启动MySQL服务器程序后,就可以接着启动客户端程序来连接到这个服务器喽,bin目录下有许多客户端程序,比方说mysqladminmysqldumpmysqlcheck等等等等(好多呢,就不一一列举了)。这里我们重点要关注的是可执行文件mysql,通过这个可执行文件可以让我们和服务器程序进程交互,也就是发送请求,接收服务器的处理结果。启动这个可执行文件时一般需要一些参数,格式如下:

mysql -h主机名  -u用户名 -p密码

各个参数的意义如下:

参数名 含义
-h 表示服务器进程所在计算机的域名或者IP地址,如果服务器进程就运行在本机的话,可以省略这个参数,或者填localhost或者127.0.0.1。也可以写作 --host=主机名的形式。
-u 表示用户名。也可以写作 --user=用户名的形式。
-p 表示密码。也可以写作 --password=密码的形式。

小贴士: 像 h、u、p 这样名称只有一个英文字母的参数称为短形式的参数,使用时前边需要加单短划线,像 host、user、password 这样大于一个英文字母的参数称为长形式的参数,使用时前边需要加双短划线。后边会详细讨论这些参数的使用方式的,稍安勿躁~

比如我这样执行下边这个可执行文件(用户名密码按你的实际情况填写),就可以启动MySQL客户端,并且连接到服务器了。

mysql -hlocalhost -uroot -p123456

我们看一下连接成功后的界面:

Welcome to the MySQL monitor.  Commands end with ; or \g.Your MySQL connection id is 2Server 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 itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> 

最后一行的mysql>是一个客户端的提示符,之后客户端发送给服务器的命令都需要写在这个提示符后边。

如果我们想断开客户端与服务器的连接并且关闭客户端的话,可以在mysql>提示符后输入下边任意一个命令:

  1. quit
  2. exit
  3. \q

比如我们输入quit试试:

mysql> quitBye

输出了Bye说明客户端程序已经关掉了。注意注意注意,这是关闭客户端程序的方式,不是关闭服务器程序的方式,怎么关闭服务器程序上一节里唠叨过了。

如果你愿意,你可以多打开几个黑框框,每个黑框框都使用mysql -hlocalhost -uroot -p123456来运行多个客户端程序,每个客户端程序都是互不影响的。如果你有多个电脑,也可以试试把它们用局域网连起来,在一个电脑上启动MySQL服务器程序,在另一个电脑上执行mysql命令时使用IP地址作为主机名来连接到服务器。

连接注意事项

  • 最好不要在一行命令中输入密码。

    我们直接在黑框框里输入密码很可能被别人看到,这和你当着别人的面输入银行卡密码没啥区别,所以我们在执行mysql连接服务器的时候可以不显式的写出密码,就像这样:

    mysql -hlocalhost -uroot -p
    

    点击回车之后才会提示你输入密码:

    Enter password:
    

    不过这回你输入的密码不会被显示出来,心怀不轨的人也就看不到了,输入完成点击回车就成功连接到了服务器。

  • 如果你非要在一行命令中显式的把密码输出来,那-p和密码值之间不能有空白字符(其他参数名之间可以有空白字符),就像这样:

    mysql -h localhost -u root -p123456
    

    如果加上了空白字符就是错误的,比如这样:

    mysql -h localhost -u root -p 123456
    
  • mysql的各个参数的摆放顺序没有硬性规定,也就是说你也可以这么写:

    mysql -p  -u root -h localhost
    
  • 如果你的服务器和客户端安装在同一台机器上,-h参数可以省略,就像这样:

    mysql -u root -p  
    
  • 如果你使用的是类UNIX系统,并且省略-u参数后,会把你登陆操作系统的用户名当作MySQL的用户名去处理。

    比方说我用登录操作系统的用户名是xiaohaizi,那么在我的机器上下边这两条命令是等价的:

    mysql -u xiaohaizi -pmysql -p

    对于Windows系统来说,默认的用户名是ODBC,你可以通过设置环境变量USER来添加一个默认用户名。

客户端与服务器连接的过程

我们现在已经知道如何启动MySQL的服务器程序,以及如何启动客户端程序来连接到这个服务器程序。运行着的服务器程序和客户端程序本质上都是计算机上的一个进程,所以客户端进程向服务器进程发送请求并得到回复的过程本质上是一个进程间通信的过程!MySQL支持下边三种客户端进程和服务器进程的通信方式。

TCP/IP

真实环境中,数据库服务器进程和客户端进程可能运行在不同的主机中,它们之间必须通过网络来进行通讯。MySQL采用TCP作为服务器和客户端之间的网络通信协议。在网络环境下,每台计算机都有一个唯一的IP地址,如果某个进程有需要采用TCP协议进行网络通信方面的需求,可以向操作系统申请一个端口号,这是一个整数值,它的取值范围是0~65535。这样在网络中的其他进程就可以通过IP地址 + 端口号的方式来与这个进程连接,这样进程之间就可以通过网络进行通信了。

MySQL服务器启动的时候会默认申请3306端口号,之后就在这个端口号上等待客户端进程进行连接,用书面一点的话来说,MySQL服务器会默认监听3306端口。

小贴士: `TCP/IP`网络体系结构是现在通用的一种网络体系结构,其中的`TCP`和`IP`是体系结构中两个非常重要的网络协议,如果你并不知道协议是什么,或者并不知道网络是什么,那恐怕兄弟你来错地方了,找本计算机网络的书去瞅瞅吧! 什么?计算机网络的书写的都贼晦涩,看不懂?没关系,等我~

如果3306端口号已经被别的进程占用了或者我们单纯的想自定义该数据库实例监听的端口号,那我们可以在启动服务器程序的命令行里添加-P参数来明确指定一下端口号,比如这样:

mysqld -P3307

这样MySQL服务器在启动时就会去监听我们指定的端口号3307

如果客户端进程想要使用TCP/IP网络来连接到服务器进程,比如我们在使用mysql来启动客户端程序时,在-h参数后必须跟随IP地址来作为需要连接的服务器进程所在主机的主机名,如果客户端进程和服务器进程在一台计算机中的话,我们可以使用127.0.0.1来代表本机的IP地址。另外,如果服务器进程监听的端口号不是默认的3306,我们也可以在使用mysql启动客户端程序时使用-P参数(大写的P,小写的p是用来指定密码的)来指定需要连接到的端口号。比如我们现在已经在本机启动了服务器进程,监听的端口号为3307,那我们启动客户端程序时可以这样写:

mysql -h127.0.0.1 -uroot -P3307 -p

不知大家发现了没有,我们在启动服务器程序的命令mysqld和启动客户端程序的命令mysql后边都可以使用-P参数,关于如何在命令后边指定参数,指定哪些参数我们稍后会详细唠叨的,稍微等等哈~

命名管道和共享内存

如果你是一个Windows用户,那么客户端进程和服务器进程之间可以考虑使用命名管道共享内存进行通信。不过启用这些通信方式的时候需要在启动服务器程序和客户端程序时添加一些参数:

  • 使用命名管道来进行进程间通信

    需要在启动服务器程序的命令中加上--enable-named-pipe参数,然后在启动客户端程序的命令中加入--pipe或者--protocol=pipe参数。

  • 使用共享内存来进行进程间通信

    需要在启动服务器程序的命令中加上--shared-memory参数,在成功启动服务器后,共享内存便成为本地客户端程序的默认连接方式,不过我们也可以在启动客户端程序的命令中加入--protocol=memory参数来显式的指定使用共享内存进行通信。

    不过需要注意的是,使用共享内存的方式进行通信的服务器进程和客户端进程必须在同一台Windows主机中。

小贴士: 命名管道和共享内存是Windows操作系统中的两种进程间通信方式,如果你没听过的话也不用纠结,并不妨碍我们介绍MySQL的知识~

Unix域套接字文件

如果我们的服务器进程和客户端进程都运行在同一台操作系统为类Unix的机器上的话,我们可以使用Unix域套接字文件来进行进程间通信。如果我们在启动客户端程序的时候指定的主机名为localhost,或者指定了--protocol=socket的启动参数,那服务器程序和客户端程序之间就可以通过Unix域套接字文件来进行通信了。MySQL服务器程序默认监听的Unix域套接字文件路径为/tmp/mysql.sock,客户端程序也默认连接到这个Unix域套接字文件。如果我们想改变这个默认路径,可以在启动服务器程序时指定socket参数,就像这样:

mysqld --socket=/tmp/a.txt

这样服务器启动后便会监听/tmp/a.txt。在服务器改变了默认的UNIX域套接字文件后,如果客户端程序想通过UNIX域套接字文件进行通信的话,也需要显式的指定连接到的UNIX域套接字文件路径,就像这样:

mysql -hlocalhost -uroot --socket=/tmp/a.txt -p

这样该客户端进程和服务器进程就可以通过路径为/tmp/a.txtUnix域套接字文件进行通信了。

请登录后发表评论