《MySQL是怎样运行的:从根儿上理解MySQL》笔记2

Posted 幽幽子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《MySQL是怎样运行的:从根儿上理解MySQL》笔记2相关的知识,希望对你有一定的参考价值。

第二节:启动选项和系统变量

-----------------------------------------------------------
  mysql的服务器程序和客户端程序也有很多设置项,比如对于MySQL服务器程序,我们可以指定诸如允许同时连入的客户端数量、客户端和服务器通信方式、表的默认存储引擎、查询缓存的大小吧啦吧啦的设置项。对于MySQL客户端程序,我们之前已经见识过了,可以指定需要连接的服务器程序所在主机的主机名或IP地址、用户名及密码等信息。
  这些设置项一般都有各自的默认值,比方说服务器允许同时连入的客户端的默认数量是151,表的默认存储引擎是InnoDB,我们可以在程序启动的时候去修改这些默认值,对于这种在程序启动时指定的设置项也称之为启动选项(startup options),这些选项控制着程序启动后的行为。在MySQL安装目录下的bin目录中的各种可执行文件,不论是服务器相关的程序(比如mysqld、mysqld_safe)还是客户端相关的程序(比如mysql、mysqladmin),在启动的时候基本都可以指定启动参数。这些启动参数可以放在命令行中指定,也可以把它们放在配置文件中指定。

-----------------------------------------------------------
在命令行上使用选项

  如果我们在启动客户端程序时在-h参数后边紧跟服务器的IP地址,这就意味着客户端和服务器之间需要通过TCP/IP网络进行通信。
  如果我们在启动服务器程序的时候就禁止各客户端使用TCP/IP网络进行通信,可以在启动服务器程序的命令行里添加skip-networking启动选项,就像这样:mysqld --skip-networking
  可以看到,我们在命令行中指定启动选项时需要在选项名前加上--前缀。另外,如果选项名是由多个单词构成的,它们之间可以由短划线-连接起来,也可以使用下划线_连接起来,也就是说skip-networking和skip_networking表示的含义是相同的。所以上边的写法与下边的写法是等价的:mysqld --skip_networking

  查询表的创建语句:show create table user_bill;
  CREATE TABLE `user_bill` (
    `id` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `create_time` datetime(6) DEFAULT NULL,
    `create_user_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
    `last_update_time` datetime(6) DEFAULT NULL,
    `last_update_user_id` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
    `amount` int(11) NOT NULL,
    `inner_pay_order_number` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `outer_pay_order_number` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `pay_type` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `payment_status` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `payment_type` varchar(50) COLLATE utf8mb4_bin NOT NULL,
    `remark` varchar(200) COLLATE utf8mb4_bin NOT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |

  所以在启动服务器程序的命令行后边指定启动选项的通用格式就是这样的:

  --启动选项1[=值1] --启动选项2[=值2] ... --启动选项n[=值n]
  也就是说我们可以将各个启动选项写到一行中,各个启动选项之间使用空白字符隔开,在每一个启动选项名称前边添加--。对于不需要值的启动选项,比方说skip-networking,它们就不需要指定对应的值。对于需要指定值的启动选项,比如default-storage-engine我们在指定这个设置项的时候需要显式的指定它的值,比方说InnoDB、MyISAM啦什么的~ 在命令行上指定有值的启动选项时需要注意,<<选项名、=、选项值之间不可以有空白字符>>,比如写成下边这样就是不正确的:
  mysqld --default-storage-engine = MyISAM --错误写法

  每个MySQL程序都有许多不同的选项。大多数程序提供了一个--help选项,你可以查看该程序支持的全部启动选项以及它们的默认值。例如,使用mysql --help可以看到mysql程序支持的启动选项,mysqld_safe --help可以看到mysqld_safe程序支持的启动选项。查看mysqld支持的启动选项有些特别,需要使用mysqld --verbose --help。

-----------------------------------------------------------

选项的长形式和短形式

  短形式的选项名只有一个字母,与使用长形式选项时需要在选项名前加两个短划线--不同的是,使用短形式选项时在选项名前只加一个短划线-前缀。
mysqld -P3307
  使用短形式指定启动选项时,选项名和选项值之间可以没有间隙,或者用空白字符隔开(-p选项有些特殊,-p和密码值之间不能有空白字符),也就是说上边的命令形式和下边的是等价的:
  mysqld -P 3307
  选项名是区分大小写的,比如-p和-P选项拥有完全不同的含义,大家需要注意一下。

 

-----------------------------------------------------------
配置文件中使用选项

  在命令行中设置启动选项只对当次启动生效,也就是说如果下一次重启程序的时候我们还想保留这些启动选项的话,还得重复把这些选项写到启动命令行中,这样真的神烦唉!于是设计MySQL的大叔们提出一种配置文件(也称为选项文件)的概念,我们把需要设置的启动选项都写在这个配置文件中,每次启动服务器的时候都从这个文件里加载相应的启动选项。由于这个配置文件可以长久的保存在计算机的硬盘里,所以只需我们配置一次,以后就都不用显式的把启动选项都写在启动命令行中了,所以我们推荐使用配置文件的方式来设置启动选项。

配置文件的路径
  MySQL程序在启动时会寻找多个路径下的配置文件,这些路径有的是固定的,有的是可以在命令行指定的。根据操作系统的不同,配置文件的路径也有所不同

类Unix操作系统中的配置文件
在类UNIX操作系统中,MySQL会按照下列路径来寻找配置文件:
  --路径名--备注--
  --/etc/my.cnf--
  --/etc/mysql/my.cnf--
  --SYSCONFDIR/my.cnf--
  --$MYSQL_HOME/my.cnf--特定于服务器的选项(仅限服务器)--
  --defaults-extra-file--命令行指定的额外配置文件路径--
  --~/.my.cnf--用户特定选项--
  --~/.mylogin.cnf--用户特定的登录路径选项(仅限客户端)--
解释:
  SYSCONFDIR表示在使用CMake构建MySQL时使用SYSCONFDIR选项指定的目录。默认情况下,这是位于编译安装目录下的etc目录。
  MYSQL_HOME是一个环境变量,该变量的值是我们自己设置的,我们想设置就设置,不想设置就不设置。该变量的值代表一个路径,我们可以在该路径下创建一个my.cnf配置文件,那么这个配置文件中只能放置关于启动服务器程序相关的选项(言外之意就是其他的配置文件既能存放服务器相关的选项也能存放客户端相关的选项,.mylogin.cnf除外,它只能存放客户端相关的一些选项)。如果大家使用mysqld_safe启动服务器程序,而且我们也没有主动设置这个MySQL_HOME环境变量的值,那这个环境变量的值将自动被设置为MySQL的安装目录,也就是MySQL服务器将会在安装目录下查找名为my.cnf配置文件(别忘了mysql.server会调用mysqld_safe,所以使用mysql.server启动服务器时也会在安装目录下查找配置文件)。
  列表中的最后两个以~开头的路径是用户相关的,类UNIX 系统中都有一个当前登陆用户的概念,每个用户都可以有一个用户目录,~就代表这个用户目录,大家可以查看HOME环境变量的值来确定一下当前用户的用户目录。之所以说列表中最后两个配置文件是用户相关的,是因为不同的类UNIX系统的用户都可以在自己的用户目录下创建.my.cnf或者.mylogin.cnf,换句话说,不同登录用户使用的.my.cnf或者.mylogin.cnf配置文件是不同的。
defaults-extra-file的含义与Windows中的一样。
  .mylogin.cnf的含义也同Windows中的一样,再次强调一遍,它不是纯文本文件,只能使用mysql_config_editor实用程序去创建或修改,用于存放客户端登陆服务器时的相关选项。

  使用mysqld_safe程序启动服务器时,会间接调用mysqld,所以对于传递给mysqld_safe的启动选项来说,如果mysqld_safe程序不处理,会接着传递给mysqld程序处理。比方说skip-networking选项是由mysqld处理的,mysqld_safe并不处理,但是如果我们我们在命令行上这样执行:mysqld_safe --skip-networking
  则在mysqld_safe调用mysqld时,会把它处理不了的这个skip-networking选项交给mysqld处理。

 

-----------------------------------------------------------
配置文件的内容

与在命令行中指定启动选项不同的是,配置文件中的启动选项被划分为若干个组,每个组有一个组名,用中括号[]扩起来,像这样:
    [server]
    (具体的启动选项...)
    [mysqld]
    (具体的启动选项...)
    [mysqld_safe]
    (具体的启动选项...)
    [client]
    (具体的启动选项...)
    [mysql]
    (具体的启动选项...)
    [mysqladmin]
    (具体的启动选项...)

例子:
    [server]
    option1 #这是option1,该选项不需要选项值
    option2 = value2 #这是option2,该选项需要选项值
    ...
  在配置文件中指定启动选项的语法类似于命令行语法,但是配置文件中只能使用长形式的选项。在配置文件中指定的启动选项不允许加--前缀,并且每行只指定一个选项,而且=周围可以有空白字符(命令行中选项名、=、选项值之间不允许有空白字符)。另外,在配置文件中,我们可以使用#来添加注释,从#出现直到行尾的内容都属于注释内容,读取配置文件时会忽略这些注释内容。

  配置文件中不同的选项组是给不同的启动命令使用的,如果选项组名称与程序名称相同,则组中的选项将专门应用于该程序。例如, [mysqld]和[mysql]组分别应用于mysqld服务器程序和mysql客户端程序。不过有两个选项组比较特别:
    [server]组下边的启动选项将作用于所有的服务器程序。
    [client]组下边的启动选项将作用于所有的客户端程序。

为了直观感受一下,我们挑一些启动命令来看一下它们能读取的选项组都有哪些:

  -------启动命令-------类别-------能读取的组-------

  -------mysqld-------启动服务器-------[mysqld]、[server]-------

  -------mysqld_safe-------启动服务器-------[mysqld]、[server]、[mysqld_safe]-------

  -------mysql.server-------启动服务器-------[mysqld]、[server]、[mysql.server]-------

  -------mysql-------启动客户端-------[mysql]、[client]-------

  -------mysqladmin-------启动客户端-------[mysqladmin]、[client]-------

  -------mysqldump-------启动客户端-------[mysqldump]、[client]-------

直接用mysqld启动服务器程序:mysqld
  程序启动的时候,就会默认的到我们上边提到的配置文件路径下查找配置文件,其中就包括/etc/mysql/my.cnf。
  如果我们想指定mysql.server程序的启动参数,则必须将它们放在配置文件中,而不是放在命令行中。mysql.server仅支持start和stop作为命令行参数。

 

-----------------------------------------------------------
特定MySQL版本的专用选项组

  我们可以在选项组的名称后加上特定的MySQL版本号,比如对于[mysqld]选项组来说,我们可以定义一个[mysqld-5.7]的选项组,它的含义和[mysqld]一样,只不过只有版本号为5.7的mysqld程序才能使用这个选项组中的选项。

-----------------------------------------------------------
配置的优先级与覆盖

  我们前边唠叨过MySQL将在某些固定的路径下搜索配置文件,我们也可以通过在命令行上指定defaults-extra-file启动选项来指定额外的配置文件路径。MySQL将按照我们在上表中给定的顺序依次读取各个配置文件,如果该文件不存在则忽略。值得注意的是,如果我们在多个配置文件中设置了相同的启动选项,那以最后一个配置文件中的为准。

同一个配置文件中多个组的优先级
  我们说同一个命令可以访问配置文件中的多个组,比如mysqld可以访问[mysqld]、[server]组,如果在同一个配置文件中,比如~/.my.cnf,在这些组里出现了同样的配置项,比如这样:
[server]
default-storage-engine=InnoDB
[mysqld]
default-storage-engine=MyISAM
  那么,将以最后一个出现的组中的启动选项为准,比方说例子中default-storage-engine既出现在[mysqld]组也出现在[server]组,因为[mysqld]组在[server]组后边,就以[mysqld]组中的配置项为准。

-----------------------------------------------------------
defaults-file的使用

  如果我们不想让MySQL到默认的路径下搜索配置文件(就是上表中列出的那些),可以在命令行指定defaults-file选项,比如这样(以UNIX系统为例):mysqld --defaults-file=/tmp/myconfig.txt
  这样,在程序启动的时候将只在/tmp/myconfig.txt路径下搜索配置文件。如果文件不存在或无法访问,则会发生错误。
  注意`defaults-extra-file`和`defaults-file`的区别,使用`defaults-extra-file`可以指定额外的配置文件搜索路径(也就是说那些固定的配置文件路径也会被搜索)。

-----------------------------------------------------------
命令行和配置文件中启动选项的区别

  在命令行上指定的绝大部分启动选项都可以放到配置文件中,但是有一些选项是专门为命令行设计的,比方说defaults-extra-file、defaults-file这样的选项本身就是为了指定配置文件路径的,再放在配置文件中使用就没啥意义了。另外有一点需要特别注意,如果同一个启动选项既出现在命令行中,又出现在配置文件中,那么以命令行中的启动选项为准!

-----------------------------------------------------------
系统变量

  MySQL服务器程序运行过程中会用到许多影响程序行为的变量,它们被称为MySQL系统变量,MySQL服务器程序的系统变量有好几百条,我们就不一一列举了。每个系统变量都有一个默认值,我们可以使用命令行或者配置文件中的选项在启动服务器时改变一些系统变量的值。大多数的系统变量的值也可以在程序运行过程中修改,而无需停止并重新启动它。

SHOW VARIABLES [LIKE 匹配的模式];
  由于系统变量实在太多了,如果我们直接使用SHOW VARIABLES查看的话就直接刷屏了,所以通常都会带一个LIKE过滤条件来查看我们需要的系统变量的值。

  大部分的系统变量都可以通过启动服务器时传送启动选项的方式来进行设置。如何填写启动选项我们上边已经花了大篇幅来唠叨了,就是下边两种方式:通过命令行添加启动选项。通过配置文件添加启动选项。
  对于启动选项来说,如果启动选项名由多个单词组成,各个单词之间用短划线-或者下划线_连接起来都可以,但是它对应的系统变量的单词之间必须使用下划线_连接起来。

服务器程序运行过程中设置
  系统变量比较牛逼的一点就是,对于大部分系统变量来说,它们的值可以在服务器程序运行过程中进行动态修改而无需停止并重启服务器。不过系统变量有作用范围之分。

设置不同作用范围的系统变量
  我们前边说过,多个客户端程序可以同时连接到一个服务器程序。对于同一个系统变量,我们有时想让不同的客户端有不同的值。比方说狗哥使用客户端A,他想让当前客户端对应的默认存储引擎为InnoDB,所以他可以把系统变量default_storage_engine的值设置为InnoDB;猫爷使用客户端B,他想让当前客户端对应的默认存储引擎为MyISAM,所以他可以把系统变量default_storage_engine的值设置为MyISAM。这样可以使狗哥和猫爷的的客户端拥有不同的默认存储引擎,使用时互不影响,十分方便。但是这样各个客户端都私有一份系统变量会产生这么两个问题:
  有一些系统变量并不是针对单个客户端的,比如允许同时连接到服务器的客户端数量max_connections,查询缓存的大小query_cache_size,这些公有的系统变量让某个客户端私有显然不合适。
  一个新连接到服务器的客户端对应的系统变量的值该怎么设置?
  为了解决这两个问题,设计MySQL的大叔提出了系统变量的作用范围的概念,具体来说作用范围分为这两种:
    GLOBAL:全局变量,影响服务器的整体操作。
    SESSION:会话变量,影响某个客户端连接的操作。(注:SESSION有个别名叫LOCAL)
  在服务器启动时,会将每个全局变量初始化为其默认值(可以通过命令行或选项文件中指定的选项更改这些默认值)。然后服务器还为每个连接的客户端维护一组会话变量,客户端的会话变量在连接时使用相应全局变量的当前值初始化。
以default_storage_engine举例,在服务器启动时会初始化一个名为default_storage_engine,作用范围为GLOBAL的系统变量。之后每当有一个客户端连接到该服务器时,服务器都会单独为该客户端分配一个名为default_storage_engine,作用范围为SESSION的系统变量,该作用范围为SESSION的系统变量值按照当前作用范围为GLOBAL的同名系统变量值进行初始化。
  很显然,通过启动选项设置的系统变量的作用范围都是GLOBAL的,也就是对所有客户端都有效的,因为在<系统启动>的时候还没有客户端程序连接进来呢。了解了系统变量的GLOBAL和SESSION作用范围之后,我们再看一下在服务器程序运行期间通过客户端程序设置系统变量的语法:SET [GLOBAL|SESSION] 系统变量名 = 值;
  或者写成这样也行:SET [@@(GLOBAL|SESSION).]var_name = XXX;

  比如我们想在服务器运行过程中把作用范围为GLOBAL的系统变量default_storage_engine的值修改为MyISAM,也就是想让之后新连接到服务器的客户端都用MyISAM作为默认的存储引擎,那我们可以选择下边两条语句中的任意一条来进行设置:
    语句一:SET GLOBAL default_storage_engine = MyISAM;
    语句二:SET @@GLOBAL.default_storage_engine = MyISAM;
  如果只想对本客户端生效,也可以选择下边三条语句中的任意一条来进行设置:
    语句一:SET SESSION default_storage_engine = MyISAM;
    语句二:SET @@SESSION.default_storage_engine = MyISAM;
    语句三:SET default_storage_engine = MyISAM;
  从上边的语句三也可以看出,如果在设置系统变量的语句中省略了作用范围,默认的作用范围就是SESSION。也就是说SET 系统变量名 = 值和SET SESSION 系统变量名 = 值是等价的。

查看不同作用范围的系统变量
  既然系统变量有作用范围之分,那我们的SHOW VARIABLES语句查看的是什么作用范围的系统变量呢?
  答:默认查看的是SESSION作用范围的系统变量。
    SHOW SESSION VARIABLES LIKE \'default_storage_engine\';
    SHOW GLOBAL VARIABLES LIKE \'default_storage_engine\';

  如果某个客户端改变了某个系统变量在`GLOBAL`作用范围的值,并不会影响该系统变量在当前已经连接的客户端作用范围为`SESSION`的值,只会影响后续连入的客户端在作用范围为`SESSION`的值。

注意事项
  并不是所有系统变量都具有GLOBAL和SESSION的作用范围。
  有一些系统变量只具有GLOBAL作用范围,比方说max_connections,表示服务器程序支持同时最多有多少个客户端程序进行连接。
  有一些系统变量只具有SESSION作用范围,比如insert_id,表示在对某个包含AUTO_INCREMENT列的表进行插入时,该列初始的值。
  有一些系统变量的值既具有GLOBAL作用范围,也具有SESSION作用范围,比如我们前边用到的default_storage_engine,而且其实大部分的系统变量都是这样的,
  有些系统变量是只读的,并不能设置值。
  比方说version,表示当前MySQL的版本,我们客户端是不能设置它的值的,只能在SHOW VARIABLES语句里查看。

启动选项和系统变量的区别
  启动选项是在程序启动时我们程序员传递的一些参数,而系统变量是影响服务器程序运行行为的变量,它们之间的关系如下:
    大部分的系统变量都可以被当作启动选项传入。
    有些系统变量是在程序运行过程中自动生成的,是不可以当作启动选项来设置,比如auto_increment_offset、character_set_client啥的。
    有些启动选项也不是系统变量,比如defaults-file。

-----------------------------------------------------------
状态变量

  为了让我们更好的了解服务器程序的运行情况,MySQL服务器程序中维护了好多关于程序运行状态的变量,它们被称为状态变量。比方说Threads_connected表示当前有多少客户端与服务器建立了连接,Handler_update表示已经更新了多少行记录吧啦吧啦。
  由于状态变量是用来显示服务器程序运行状况的,所以它们的值只能由服务器程序自己来设置,我们程序员是不能设置的。与系统变量类似,状态变量也有GLOBAL和SESSION两个作用范围的,所以查看状态变量的语句可以这么写:
    SHOW [GLOBAL|SESSION] STATUS [LIKE 匹配的模式];
  类似的,如果我们不写明作用范围,默认的作用范围是SESSION,比方说这样:
    mysql> SHOW STATUS LIKE \'thread%\';

以上是关于《MySQL是怎样运行的:从根儿上理解MySQL》笔记2的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 是怎样运行的:从根儿上理解 MySQL:字符集和比较规则

图解|从根儿上理解MySQL的索引

MySQL-3 行记录的存储结构

实战篇:MySQL优化系列--SQL优化实战

终于有一本书能把MySQL讲明白了,豆瓣评分9.7,而且还很有趣

终于有一本书能把MySQL讲明白了,豆瓣评分9.4,而且还很有趣