3.1 参数文件
在第1章中已经介绍过了,当MySQL实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等。在默认情况下,MySQL实例会按照一定的顺序在指定的位置进行读取,用户只需通过命令mysql--help | grep my.cnf来寻找即可。
MySQL数据库参数文件的作用和Oracle数据库的参数文件极其类似,不同的是,Oracle实例在启动时若找不到参数文件,是不能进行装载(mount)操作的。MySQL稍微有所不同,MySQL实例可以不需要参数文件,这时所有的参数值取决于编译MySQL时指定的默认值和源代码中指定参数的默认值。但是,如果MySQL实例在默认的数据库目录下找不到mysql架构,则启动同样会失败,此时可能在错误日志文件中找到如下内容:
090922 16:25:52 mysqld started
090922 16:25:53 InnoDB: Started; log sequence number 8 2801063211
InnoDB: !!! innodb_force_recovery is set to 1 !!!
090922 16:25:53 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.host' doesn't exist
090922 16:25:53 mysqld ended
MySQL的mysql架构中记录了访问该实例的权限,当找不到这个架构时,MySQL实例不会成功启动。
MySQL数据库的参数文件是以文本方式进行存储的。用户可以直接通过一些常用的文本编辑软件(如vi和emacs)进行参数的修改。
3.1.1 什么是参数
简单地说,可以把数据库参数看成一个键/值(key/value)对。第2章已经介绍了一个对于InnoDB存储引擎很重要的参数innodb_buffer_pool_size。如我们将这个参数设置为1G,即innodb_buffer_pool_size=1G。这里的“键”是innodb_buffer_pool_size,“值”是1G,这就是键值对。可以通过命令SHOW VARIABLES查看数据库中的所有参数,也可以通过LIKE来过滤参数名。从MySQL 5.1版本开始,还可以通过information_schema架构下的GLOBAL_VARIABLES视图来进行查找,如下所示。
mysql> SELECT * FROM
-> GLOBAL_VARIABLES
-> WHERE VARIABLE_NAME LIKE 'innodb_buffer%'\G;
*************************** 1. row ***************************
VARIABLE_NAME: INNODB_BUFFER_POOL_SIZE
VARIABLE_VALUE: 1073741824
1 row in set (0.00 sec)
mysql>SHOW VARIABLES LIKE 'innodb_buffer%'\G;
*************************** 1. row ***************************
Variable_name: innodb_buffer_pool_size
Value: 1073741824
1 row in set (0.00 sec)
无论使用哪种方法,输出的信息基本上都一样的,只不过通过视图GLOBAL_VARIABLES需要指定视图的列名。推荐使用命令SHOW VARIABLES,因为这个命令使用更为简单,且各版本的MySQL数据库都支持。
Oracle数据库存在所谓的隐藏参数(undocumented parameter),以供Oracle“内部人士”使用,SQL Server也有类似的参数。有些DBA曾问我,MySQL中是否也有这类参数。我的回答是:没有,也不需要。即使Oracle和SQL Server中都有些所谓的隐藏参数,在绝大多数的情况下,这些数据库厂商也不建议用户在生产环境中对其进行很大的调整。
3.1.2 参数类型
MySQL数据库中的参数可以分为两类:
?动态(dynamic)参数
?静态(static)参数
动态参数意味着可以在MySQL实例运行中进行更改,静态参数说明在整个实例生命周期内都不得进行更改,就好像是只读(read only)的。可以通过SET命令对动态的参数值进行修改,SET的语法如下:
SET
| [global | session] system_var_name= expr
| [@@global. | @@session. | @@]system_var_name= expr
这里可以看到global和session关键字,它们表明该参数的修改是基于当前会话还是整个实例的生命周期。有些动态参数只能在会话中进行修改,如autocommit;而有些参数修改完后,在整个实例生命周期中都会生效,如binlog_cache_size;而有些参数既可以在会话中又可以在整个实例的生命周期内生效,如read_buffer_size。举例如下:
mysql>SET read_buffer_size=524288;
Query OK, 0 rows affected (0.00 sec)
mysql>SELECT @@session.read_buffer_size\G;
*************************** 1. row ***************************
@@session.read_buffer_size: 524288
1 row in set (0.00 sec)
mysql>SELECT @@global.read_buffer_size\G;
*************************** 1. row ***************************
@@global.read_buffer_size: 2093056
1 row in set (0.00 sec)
上述示例中将当前会话的参数read_buffer_size从2MB调整为了512KB,而用户可以看到全局的read_buffer_size的值仍然是2MB,也就是说如果有另一个会话登录到MySQL实例,它的read_buffer_size的值是2MB,而不是512KB。这里使用了set global|session来改变动态变量的值。用户同样可以直接使用SET@@globl|@@session来更改,如下所示:
mysql>SET @@global.read_buffer_size=1048576;
Query OK, 0 rows affected (0.00 sec)
mysql>SELECT @@session.read_buffer_size\G;
*************************** 1. row ***************************
@@session.read_buffer_size: 524288
1 row in set (0.00 sec)
mysql>SELECT @@global.read_buffer_size\G;
*************************** 1. row ***************************
@@global.read_buffer_size: 1048576
1 row in set (0.00 sec)
这次把read_buffer_size全局值更改为1MB,而当前会话的read_buffer_size的值还是512KB。这里需要注意的是,对变量的全局值进行了修改,在这次的实例生命周期内都有效,但MySQL实例本身并不会对参数文件中的该值进行修改。也就是说,在下次启动时MySQL实例还是会读取参数文件。若想在数据库实例下一次启动时该参数还是保留为当前修改的值,那么用户必须去修改参数文件。要想知道MySQL所有动态变量的可修改范围,可以参考MySQL官方手册的Dynamic System Variables的相关内容。
对于静态变量,若对其进行修改,会得到类似如下错误:
mysql>SET GLOBAL datadir='/db/mysql';
ERROR 1238 (HY000): Variable 'datadir' is a read only variable