分类: Mysql/postgreSQL
2008-05-11 17:47:48
MySQL可以检查X509证书的属性和基于用户名和密码的通用鉴定方法。要想为MySQL账户指定SSL相关选项,使用GRANT语句的REQUIRE子句。参见13.5.1.3节,“GRANT和REVOKE语法”。
有多种可能来限制一个账户的连接类型:
· 如果账户没有SSL或X509需求,如果用户名和密码合法,允许未加密的连接。但是,如果客户有正确的证书和密钥文件,在客户选项中可以使用加密连接。
· REQUIRE SSL选项限制服务器只允许该账户的SSL加密连接。请注意如果有ACL记录允许非SSL连接,该选项会被忽略。
· mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
· -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
· REQUIRE X509表示客户必须有合法证书但确切的证书、分发者和主体不重要。唯一的需求是应可以被某个CA认证机构验证它的签名。
· mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
· -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
· REQUIRE ISSUER 'issuer'限制连接企图,即客户必须出示CA 'issuer'签发的合法X509证书。如果客户出示了一个合法证书,但是是由不同的分发者签发,服务器拒绝连接。使用X509证书表示要加密,因此不需要SSL选项。
· mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
· -> IDENTIFIED BY 'goodsecret'
· -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/
· O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';
请注意ISSUER值应做为单一字符串输入。
· REQUIRE SUBJECT 'subject' 限制连接企图,即客户必须出示主题为'subject'的合法X509证书。如果客户出示了一个合法证书,但是有不同的主题,服务器拒绝连接。
· mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
· -> IDENTIFIED BY 'goodsecret'
· -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
· O=MySQL demo client certificate/
CN=Tonu Samuel/Email=tonu@example.com';
请注意SUBJECT值应做为单一字符串输入。
· REQUIRE CIPHER 'cipher'用来确保使用足够强的密码和密钥长度。如果使用旧的短加密密钥算法,SSL本身可能很弱。使用该选项,我们可以索取确切的加密方法来连接。
· mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
· -> IDENTIFIED BY 'goodsecret'
-> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
在REQUIRE子句中,可以结合使用SUBJECT、ISSUER和CIPHER选项:
mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
-> IDENTIFIED BY 'goodsecret'
-> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/
O=MySQL demo client certificate/
CN=Tonu Samuel/Email=tonu@example.com'
-> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/
O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com'
-> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
请注意SUBJECT和ISSUER值应做为单一字符串输入。
在MySQL 5.1中,在REQUIRE选项之间可以选用AND关键字。
选项的顺序不重要,但任何选项不能用两次。
· --ssl
对于服务器,该选项规定该服务器允许SSL连接。对于客户端程序,它允许客户使用SSL连接服务器。单单该选项不足以使用SSL连接。还必须指定--ssl-ca、--ssl-cert和--ssl-key选项。
通常从反向使用该选项表示不应使用SSL。要想实现,将选项指定为--skip-ssl或--ssl=0。
请注意使用--ssl不需要SSL连接。例如,如果编译的服务器或客户不支持SSL,则使用普通的未加密的连接。
确保使用SSL连接的安全方式是使用含REQUIRE SSL子句的GRANT语句在服务器上创建一个账户。然后使用该账户来连接服务器,服务器和客户端均应启用SSL支持。
· --ssl-ca=file_name
含可信SSL CA的清单的文件的路径。
· --ssl-capath=directory_name
包含pem格式的可信SSL CA证书的目录的路径。
· --ssl-cert=file_name
SSL证书文件名,用于建立安全连接。
· --ssl-cipher=cipher_list
允许的用于SSL加密的密码的清单。cipher_list的格式与OpenSSL ciphers命令相同。
示例:--ssl-cipher=ALL:-AES:-EXP
· --ssl-key=file_name
SSL密钥文件名,用于建立安全连接。
1. 在Windows主机上安装SSH客户端。作为用户,我所发现的最好的非免费客户端来自的SecureCRT。另一个选则是http://www.f-secure.com/的f-secure。你还可以从http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/ 的Google找到一些免费客户端。
2. 启动Windows SSH客户端。设置Host_Name = yourmysqlserver_URL_or_IP。设置userid=your_userid以便登录服务器。此userid值可以与你的MySQL账户的用户名不相同。
3. 设置端口映射。可以进行远程映射(设置local_port: 3306, remote_host: yourmysqlservername_or_ip, remote_port: 3306)或本地映射(设置port: 3306, host: localhost, remote port: 3306)。
4. 进行保存,否则下次需要重设。
5. 刚创建的SSH会话登录服务器。
6. 在Windows机器上启动相应ODBC应用程序(例如Access)。
7. 在Windows中创建一个新的文件按照常用方法通过ODBC驱动程序链接MySQL,不同的是要为MySQL服务器输入localhost,而不是yourmysqlservername。
你应有使用SSH加密的ODBC连接到MySQL。
本节讨论如何进行数据库备份(完全备份和增量备份),以及如何执行表的维护。本节描述的SQL语句语法参见第5章:数据库管理。此处提供的大多数信息主要适合MyISAM表。InnoDB备份程序参见15.2.8节,“InnoDB数据库的备份和恢复”。
因为MySQL表保存为文件方式,很容易备份。要想保持备份的一致性,对相关表执行LOCK TABLES操作,然后对表执行FLUSH TABLES。参见13.4.5节,“LOCK TABLES和UNLOCK TABLES语法”和13.5.5.2节,“FLUSH语法”。你只需要读锁定;这样当你复制数据库目录中的文件时,允许其它客户继续查询表。需要FLUSH TABLES语句来确保开始备份前将所有激活的索引页写入硬盘。
如果你想要进行SQL级别的表备份,你可以使用SELECT INTO ...OUTFILE或BACKUP TABLE。对于SELECT INTO ...OUTFILE, 输出的文件不能先存在。对于BACKUP TABLE也如此,因为覆盖完整的文件会有安全风险。参见13.2.7节,“SELECT语法”和13.5.2.2节,“BACKUP TABLE语法”。
备份数据库的另一个技术是使用mysqldump程序或mysqlhotcopy脚本。参见8.8节,“mysqldump:数据库备份程序”和8.9节,“mysqlhotcopy:数据库备份程序”。
1. 完全备份数据库:
2. shell> mysqldump --tab=/path/to/some/dir --opt db_name
或:
shell> mysqlhotcopy db_name /path/to/some/dir
只要服务器不再进行更新,还可以只复制所有表文件(*.frm、*.MYD和*.MYI文件)。mysqlhotcopy脚本使用该方法。(但请注意如果数据库包含InnoDB表,这些方法不工作。InnoDB不将表的内容保存到数据库目录中,mysqlhotcopy只适合MyISAM表)。
3. 如果mysqld在运行则停止,然后用--log-bin[=file_name]选项来启动。参见5.11.3节,“二进制日志”。二进制日志文件中提供了 执行mysqldump之后对数据库的更改进行复制所需要的信息。
对于InnoDB表,可以进行在线备份,不需要对表进行锁定;参见8.8节,“mysqldump:数据库备份程序”。
MySQL支持增量备份:需要用--log-bin选项来启动服务器以便启用二进制日志;参见5.11.3节,“二进制日志”。当想要进行增量备份时(包含上一次完全备份或增量备份之后的所有更改),应使用FLUSH LOGS回滚二进制日志。然后,你需要将从最后的完全或增量备份的某个时刻到最后某个点的所有二进制日志复制到备份位置。这些二进制日志为增量备份;恢复时,按照下面的解释应用。下次进行完全备份时,还应使用FLUSH LOGS或mysqlhotcopy --flushlogs回滚二进制日志。参见8.8节,“mysqldump:数据库备份程序”和8.9节,“mysqlhotcopy:数据库备份程序”。
如果MySQL服务器为从复制服务器,则无论选择什么备份方法,当备份从机数据时,还应备份master.info和relay-log.info文件。恢复了从机数据后,需要这些文件来继续复制。如果从机执行复制LOAD DATA INFILE命令,你应还备份用--slave-load-tmpdir选项指定的目录中的SQL_LOAD-*文件。(如果未指定,该位置默认为tmpdir变量值)。从机需要这些文件来继续复制中断的LOAD DATA INFILE操作。
如果必须恢复MyISAM表,先使用REPAIR TABLE或myisamchk -r来恢复。99.9%的情况下该方法可以工作。如果myisamchk失败,试试下面的方法。请注意只有用--log-bin选项启动了MySQL从而启用二进制日志它才工作;参见5.11.3节,“二进制日志”。
1. 恢复原mysqldump备份,或二进制备份。
2. 执行下面的命令重新更新二进制日志:
3. shell> mysqlbinlog hostname-bin.[0-9]* | mysql
在某些情况下,你可能只想要从某个位置重新运行某些二进制日志。(通常你想要从恢复备份的日期重新运行所有二进制日志,查询不正确时例外)。关于mysqlbinlog工具和如何使用它的详细信息参见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。
还可以对具体文件进行选择备份:
· 要想复制表,使用SELECT * INTO OUTFILE 'file_name' FROM tbl_name。
· 要想重载表,使用LOAD DATA INFILE 'file_name' REPLACE ...并恢复。要避免复制记录,表必须有PRIMARY KEY或一个UNIQUE索引。当新记录复制唯一键值的旧记录时,REPLACE关键字可以将旧记录替换为新记录。
如果备份时遇到服务器性能问题,可以有帮助的一个策略是在从服务器而不是主服务器上建立复制并执行备份。参见6.1节,“复制介绍”。
如果使用Veritas文件系统,可以这样备份:
1. 从客户端程序执行FLUSH TABLES WITH READ LOCK。
2. 从另一个shell执行mount vxfs snapshot。
3. 从第一个客户端执行UNLOCK TABLES。
4. 从快照复制文件。
5. 卸载快照。
· 操作系统崩溃
· 电源故障
· 文件系统崩溃
· 硬件问题(硬盘、母板等等)
该命令不包括mysqldump和mysql程序的--user和—password等选项。应包括必要的选项让MySQL服务器允许你连接它。
我们假定数据保存在MySQL的InnoDB存储引擎中,支持事务和自动崩溃恢复。我们假定崩溃时MySQL服务器带负载。如果不带负载,则不需要恢复。
出现操作系统崩溃或电源故障时,我们可以假定重启后硬盘上的MySQLś数据仍可用。由于崩溃,InnoDB数据文件中的数据可能不再保持一致性,但InnoDB读取它的日志并会查到挂起的提交的和未提交的事务清单,它们没有清空到数据文件中。InnoDB自动卷回未提交的事务,并清空到它的数据文件中。通过MySQL错误日志将该恢复过程相关信息传达给用户。下面的例子为日志摘录:
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections
如果文件系统崩溃或出现硬件问题,我们可以假定重启后硬盘上的MySQLś数据不可用。这说明MySQL未能成功启动,因为一些硬盘数据块不再可读。在这种情况下,需要重新格式化硬盘,安装一个新的,或纠正问题。然后需要从备份中恢复MySQL数据,这说明我们必须先做好备份。要想确保,应及时返回并设计备份策略。
我们都知道必须按计划定期进行备份。可以用几个工具完全备份(在某个时间点的数据快照)MySQL。例如,InnoDB Hot Backup为InnoDB数据文件提供在线非数据块物理备份,mysqldump提供在线逻辑备份。这里使用mysqldump。
假定我们在星期日下午1点进行了备份,此时负荷较低。下面的命令可以完全备份所有数据库中的所有InnoDB表:
shell> mysqldump --single-transaction --all-databases > backup_sunday_1_PM.sql
这是在线非块备份,不会干扰对表的读写。我们以前假定我们的表为InnoDB表,因此--single-transaction使用一致性地读,并且保证mysqldump所看见的数据不会更改。(其它客户端对InnoDB表进行的更改不会被mysqldump进程看见)。如果我们还有其它类型的表,我们必须假定在备份过程中它们不会更改。例如,对于mysql数据库中的MyISAM表,我们必须假定在备份过程中没有对MySQL账户进行管理更改。
mysqldump命令产生的.sql文件包含一系列SQL INSERT语句,可以用来重载转储的表。
需要进行完全备份,但有时不方便。会产生大的备份文件并需要花时间来生成。从某个角度,完全备份并不理想,因为每个成功的完全备份包括所有数据,甚至自从上一次完全备份以来没有更改的部分。完成了初使完全备份后,进行增量备份会更有效。这样备份文件要小得多,备份时间也较短。不利之处是,恢复时不能只重载完全备份来恢复数据。还必须要用增量备份来恢复增量更改。
要想进行增量备份,我们需要保存增量更改。应使用--log-bin选项启动MySQL服务器,以便更新数据时将这些更改保存到文件中。该选项启用二进制日志,因此服务器写将每个更新数据的SQL语句写入MySQL二进制日志。让我们看看用--log-bin选项启动的已经运行多日的MySQL服务器的数据目录。我们找到以下MySQL二进制日志文件:
-rw-rw---- 1 guilhem guilhem 1277324 Nov 10 23:59 gbichot2-bin.000001
-rw-rw---- 1 guilhem guilhem 4 Nov 10 23:59 gbichot2-bin.000002
-rw-rw---- 1 guilhem guilhem 79 Nov 11 11:06 gbichot2-bin.000003
-rw-rw---- 1 guilhem guilhem 508 Nov 11 11:08 gbichot2-bin.000004
-rw-rw---- 1 guilhem guilhem 220047446 Nov 12 16:47 gbichot2-bin.000005
-rw-rw---- 1 guilhem guilhem 998412 Nov 14 10:08 gbichot2-bin.000006
-rw-rw---- 1 guilhem guilhem 361 Nov 14 10:07 gbichot2-bin.index
每次重启,MySQL服务器用序列中的下一个编号创建一个新的二进制日志文件。当服务器运行时,你还可以通过执行FLUSH LOGS SQL语句或mysqladmin flush-logs命令,告诉服务器关闭当前的二进制日志文件并创建一个新文件。mysqldump也有一个选项来清空日志。数据目录中的.index文件包含该目录下所有MySQL二进制日志的清单。该文件用于复制。
恢复时MySQL二进制日志很重要,因为它们是增量备份。如果进行完全备份时确保清空了日志,则后面创建的二进制日志文件包含了备份后的所有数据更改。让我们稍稍修改前面的mysqldump命令,让它在完全备份时能够清空 MySQL二进制日志,以便转储文件包含包含新的当前的二进制日志:
shell> mysqldump --single-transaction --flush-logs --master-data=2
--all-databases > backup_sunday_1_PM.sql
执行该命令后,数据目录则包含新的二进制日志文件,gbichot2-bin.000007。结果.sql文件包含下列行:
-- Position to start replication or point-in-time 恢复时y from
-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;
因为mysqldump命令可以执行完全备份,这些行表示两件事情:
· .sql文件包含所有写入gbichot2-bin.000007二进制日志文件或最新的文件之前的更改。
· 备份后所记录的所有数据更改不出现在.sql中,但出现在gbichot2-bin.000007二进制日志文件或最新的文件中。
在星期一下午1点,我们可以清空日志开始新的二进制日志文件来创建增量备份。例如,执行mysqladmin flush-logs命令创建gbichot2-bin.000008。星期日下午1点的完全备份和星期一下午1点之间的所有更改为文件gbichot2-bin.000007。该增量备份很重要,因此最好将它复制到安全的地方。(例如,备份到磁带或DVD上,或复制到另一台机器上)。在星期二下午1点,执行另一个mysqladmin flush-logs命令。星期一下午1点和星期二下午1点之间的所有所有更改为文件gbichot2-bin.000008(也应复制到某个安全的地方)。
MySQL二进制日志占据硬盘空间。要想释放空间,应随时清空。操作方法是删掉不再使用的二进制日志,例如进行完全备份时:
shell> mysqldump --single-transaction --flush-logs --master-data=2
--all-databases --delete-master-logs > backup_sunday_1_PM.sql
注释:如果你的服务器为复制主服务器,用mysqldump --delete-master-logs删掉MySQL二进制日志很危险,因为从服务器可能还没有完全处理该二进制日志的内容。
PURGE MASTER LOGS语句的描述中解释了为什么在删掉MySQL二进制日志之前应进行确认。参见13.6.1.1节,“PURGE MASTER LOGS语法”。
现在假设在星期三上午8点出现了灾难性崩溃,需要使用备份文件进行恢复。恢复时,我们首先恢复最后的完全备份(从星期日下午1点开始)。完全备份文件是一系列SQL语句,因此恢复它很容易:
shell> mysql < backup_sunday_1_PM.sql
在该点,数据恢复到星期日下午1点的状态。要想恢复从那时起的更改,我们必须使用增量备份,也就是,gbichot2-bin.000007和gbichot2-bin.000008二进制日志文件。根据需要从备份处取过这些文件,然后按下述方式处理:
shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql
我们现在将数据恢复到星期二下午1点的状态,但是从该时刻到崩溃之间的数据仍然有丢失。要想恢复,我们需要MySQL服务器将MySQL二进制日志保存到安全的位置(RAID disks, SAN, ...),应为与数据文件的保存位置不同的地方,保证这些日志不在毁坏的硬盘上。(也就是,我们可以用--log-bin选项启动服务器,指定一个其它物理设备上的与数据目录不同的位置。这样,即使包含该目录的设备丢失,日志也不会丢失)。如果我们执行了这些操作,我们手头上会有gbichot2-bin.000009文件,我们可以用它来恢复大部分最新的数据更改,而不会丢失到崩溃时的数据。
出现操作系统崩溃或电源故障时,InnoDB自己可以完成所有数据恢复工作。但为了确保你可以睡好觉,应遵从下面的指导:
· 一定用--log-bin或甚至--log-bin=log_name选项运行MySQL服务器,其中日志文件名位于某个安全媒介上,不同于数据目录所在驱动器。如果你有这样的安全媒介,最好进行硬盘负载均衡(这样能够提高性能)。
· 定期进行完全备份,使用mysqldump命令进行在线非块备份。
· 用FLUSH LOGS或mysqladmin flush-logs清空日志进行定期增量备份。
如果MySQL服务器启用了二进制日志,你可以使用mysqlbinlog工具来恢复从指定的时间点开始 (例如,从你最后一次备份)直到现在或另一个指定的时间点的数据。关于启用二进制日志的信息,参见5.11.3节,“二进制日志”。对于mysqlbinlog的详细信息,参见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。
要想从二进制日志恢复数据,你需要知道当前二进制日志文件的路径和文件名。一般可以从选项文件(即my.cnf or my.ini,取决于你的系统)中找到路径。如果未包含在选项文件中,当服务器启动时,可以在命令行中以选项的形式给出。启用二进制日志的选项为--log-bin。要想确定当前的二进制日志文件的文件名,输入下面的MySQL语句:
SHOW BINLOG EVENTS \G
你还可以从命令行输入下面的内容:
mysql --user=root -pmy_pwd -e 'SHOW BINLOG EVENTS \G'
将密码my_pwd替换为服务器的root密码。
mysqlbinlog --stop-date="2005-04-20 9:59:59" /var/log/mysql/bin.123456 \
| mysql -u root -pmypwd
该命令将恢复截止到在--stop-date选项中以DATETIME格式给出的日期和时间的所有数据。如果你没有检测到几个小时后输入的错误的SQL语句,可能你想要恢复后面发生的活动。根据这些,你可以用起使日期和时间再次运行mysqlbinlog:
mysqlbinlog --start-date="2005-04-20 10:01:00" /var/log/mysql/bin.123456 \
| mysql -u root -pmypwd \
在该行中,从上午10:01登录的SQL语句将运行。组合执行前夜的转储文件和mysqlbinlog的两行可以将所有数据恢复到上午10:00前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。
mysqlbinlog --start-date="2005-04-20 9:55:00" --stop-date="2005-04-20 10:05:00" \
/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
该命令将在/tmp目录创建小的文本文件,将显示执行了错误的SQL语句时的SQL语句。你可以用文本编辑器打开该文件,寻找你不要想重复的语句。如果二进制日志中的位置号用于停止和继续恢复操作,应进行注释。用log_pos加一个数字来标记位置。使用位置号恢复了以前的备份文件后,你应从命令行输入下面内容:
mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \
| mysql -u root -pmypwd
mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \
| mysql -u root -pmypwd \
上面的第1行将恢复到停止位置为止的所有事务。下一行将恢复从给定的起始位置直到二进制日志结束的所有事务。因为mysqlbinlog的输出包括每个SQL语句记录之前的SET TIMESTAMP语句,恢复的数据和相关MySQL日志将反应事务执行的原时间。
后面几节讨论如何使用myisamchk来检查或维护MyISAM表(对应.MYI和.MYD文件的表)。
你可以使用myisamchk实用程序来获得有关你的数据库表的信息或检查、修复、优化他们。下列小节描述如何调用myisamchk(包括它的选项的描述),如何建立表的维护计划,以及如何使用myisamchk执行各种功能。
尽管用myisamchk修复表很安全,在修复(或任何可以大量更改表的维护操作)之前先进行备份也是很好的习惯
影响索引的myisamchk操作会使ULLTEXT索引用full-text参数重建,不再与MySQL服务器使用的值兼容。要想避免,请阅读5.9.5.1节,“用于myisamchk的一般选项”的说明。
在许多情况下,你会发现使用SQL语句实现MyISAM表的维护比执行myisamchk操作要容易地多:
· 要想检查或维护MyISAM表,使用CHECK TABLE或REPAIR TABLE。
· 要想优化MyISAM表,使用OPTIMIZE TABLE。
· 要想分析MyISAM表,使用ANALYZE TABLE。
可以直接这些语句,或使用mysqlcheck客户端程序,可以提供命令行接口。
这些语句比myisamchk有利的地方是服务器可以做任何工作。使用myisamchk,你必须确保服务器在同一时间不使用表。否则,myisamchk和服务器之间会出现不期望的相互干涉。
可以使用myisamchk实用程序来获得有关数据库表的信息或检查、修复、优化他们。myisamchk适用MyISAM表(对应.MYI和.MYD文件的表)。
调用myisamchk的方法:
shell> myisamchk [options] tbl_name ...
options指定你想让myisamchk做什么。在后面描述它们。还可以通过调用myisamchk --help得到选项列表。
tbl_name是你想要检查或修复的数据库表。如果你不在数据库目录的某处运行myisamchk,你必须指定数据库目录的路径,因为myisamchk不知道你的数据库位于哪儿。实际上,myisamchk不在乎你正在操作的文件是否位于一个数据库目录;你可以将对应于数据库表的文件拷贝到别处并且在那里执行恢复操作。
如果你愿意,可以用myisamchk命令行命名几个表。还可以通过命名索引文件(用“ .MYI”后缀)来指定一个表。它允许你通过使用模式“*.MYI”指定在一个目录所有的表。例如,如果你在数据库目录,可以这样在目录下检查所有的MyISAM表:
shell> myisamchk *.MYI
如果你不在数据库目录下,可通过指定到目录的路径检查所有在那里的表:
shell> myisamchk /path/to/database_dir/*.MYI
你甚至可以通过为MySQL数据目录的路径指定一个通配符来检查所有的数据库中的所有表:
shell> myisamchk /path/to/datadir/*/*.MYI
推荐的快速检查所有MyISAM表的方式是:
shell> myisamchk --silent --fast /path/to/datadir/*/*.MYI
如果你想要检查所有MyISAM表并修复任何破坏的表,可以使用下面的命令:
shell> myisamchk --silent --force --fast --update-state \
-O key_buffer=64M -O sort_buffer=64M \
-O read_buffer=1M -O write_buffer=1M \
/path/to/datadir/*/*.MYI
该命令假定你有大于64MB的自由内存。关于用myisamchk分配内存的详细信息,参见5.9.5.5节,“myisamchk内存使用”。
当你运行myisamchk时,必须确保其它程序不使用表。否则,当你运行myisamchk时,会显示下面的错误消息:
warning: clients are using or haven't closed the table properly
这说明你正尝试检查正被另一个还没有关闭文件或已经终止而没有正确地关闭文件的程序(例如mysqld服务器)更新的表。
如果mysqld正在运行,你必须通过FLUSH TABLES强制清空仍然在内存中的任何表修改。当你运行myisamchk时,必须确保其它程序不使用表。避免该问题的最容易的方法是使用CHECK TABLE而不用myisamchk来检查表。
本节描述的选项可以用于用myisamchk执行的任何类型的表维护操作。本节后面的章节中描述的选项只适合具体操作,例如检查或修复表。
· --help,-?
显示帮助消息并退出。
· --debug=debug_options, -# debug_options
输出调试记录文件。debug_options字符串经常是'd:t:o,filename'。
· --silent,-s
沉默模式。仅当发生错误时写输出。你能使用-s两次(-ss)使myisamchk沉默。
· --verbose,-v
冗长模式。打印更多的信息。这能与-d和-e一起使用。为了更冗长,使用-v多次(-vv, -vvv)!
· --version, -V
显示版本信息并退出。
· --wait, -w
如果表被锁定,不是提示错误终止,而是在继续前等待到表被解锁。请注意如果用--skip-external-locking选项运行mysqld,只能用另一个myisamchk命令锁定表。
还可以通过--var_name=value选项设置下面的变量:
变量 |
默认值 |
decode_bits |
9 |
ft_max_word_len |
取决于版本 |
ft_min_word_len |
4 |
ft_stopword_file |
内建列表 |
key_buffer_size |
523264 |
myisam_block_size |
1024 |
read_buffer_size |
262136 |
sort_buffer_size |
2097144 |
sort_key_blocks |
16 |
stats_method |
nulls_unequal |
write_buffer_size |
262136 |
可以用myisamchk --help检查myisamchk变量及其 默认值:
当用排序键值修复键值时使用sort_buffer_size,使用--recover时这是很普通的情况。
当用--extend-check检查表或通过一行一行地将键值插入表中(如同普通插入)来修改键值时使用Key_buffer_size。在以下情况通过键值缓冲区进行修复:
· 使用--safe-recover。
· 当直接创建键值文件时,需要对键值排序的临时文件有两倍大。通常是当CHAR、VARCHAR、或TEXT列的键值较大的情况,因为排序操作在处理过程中需要保存全部键值。如果你有大量临时空间,可以通过排序强制使用myisamchk来修复,可以使用--sort-recover选项。
通过键值缓冲区的修复占用的硬盘空间比使用排序么少,但是要慢。
如果想要快速修复,将key_buffer_size和sort_buffer_size变量设置到大约可用内存的25%。可以将两个变量设置为较大的值,因为一个时间只使用一个变量。
myisam_block_size是用于索引块的内存大小。
stats_method影响当给定--analyze选项时,如何为索引统计搜集处理NULL值。它如同myisam_stats_method系统变量。详细信息参见5.3.3节,“服务器系统变量”和7.4.7节,“MyISAM索引统计集合”的myisam_stats_method的描述。
ft_min_word_len和ft_max_word_len表示FULLTEXT索引的最小和最大字长。ft_stopword_file为停止字文件的文件名。需要在以下环境中对其进行设置。
如果你使用myisamchk来修改表索引(例如修复或分析),使用最小和最大字长和停止字文件的 默认全文参数值(除非你另外指定)重建FULLTEXT索引。这样会导致查询失败。
出现这些问题是因为只有服务器知道这些参数。它们没有保存在MyISAM索引文件中。如果你修改了服务器中的最小或最大字长或停止字文件,要避免该问题,为用于mysqld的myisamchk指定相同的ft_min_word_len,ft_max_word_len和ft_stopword_file值。例如,如果你将最小字长设置为3,可以这样使用myisamchk来修复表:
shell> myisamchk --recover --ft_min_word_len=3 tbl_name.MYI
要想确保myisamchk和服务器使用相同的全文参数值,可以将它们放入选项文件的[mysqld]和[myisamchk]小节:
[mysqld]
ft_min_word_len=3
[myisamchk]
ft_min_word_len=3
除了myisamchk,还可以使用REPAIR TABLE、ANALYZE TABLE、OPTIMIZE TABLE或ALTER TABLE。这些语句由服务器执行,知道要使用的正确的全文参数值。
myisamchk支持下面的表检查操作选项:
· --check, -c
检查表的错误。如果你不明确指定操作类型选项,这就是默认操作。
· --check-only-changed, -C
只检查上次检查后有变更的表。
· --extend-check, -e
非常仔细地检查表。如果表有许多索引将会相当慢。该选项只能用于极端情况。一般情况下,可以使用myisamchk或myisamchk --medium-check来确定表内是否有错误。
如果你使用了--extend-check并且有充分的内存,将key_buffer_size变量设置为较大的值可以使修复操作运行得更快。
· --fast,-F
只检查没有正确关闭的表。
· --force, -f
如果myisamchk发现表内有任何错误,则自动进行修复。维护类型与--repair或-r选项指定的相同。
· --information, -i
打印所检查表的统计信息。
· --medium-check, -m
比--extend-check更快速地进行检查。只能发现99.99%的错误,在大多数情况下就足够了。
· --read-only, -T
不要将表标记为已经检查。如果你使用myisamchk来检查正被其它应用程序使用而没有锁定的表很有用,例如当用--skip-external-locking选项运行时运行mysqld。
· --update-state, -U
将信息保存在.MYI文件中,来表示表检查的时间以及是否表崩溃了。该选项用来充分利用--check-only-changed选项,但如果mysqld服务器正使用表并且正用--skip-external-locking选项运行时不应使用该选项。
myisamchk支持下面的表修复操作的选项:
· --backup, -B
将.MYD文件备份为file_name-time.BAK
· --character-sets-dir=path
字符集安装目录。参见5.10.1节,“数据和排序用字符集”。
· --correct-checksum
纠正表的校验和信息。
· --data-file-length=len, -D len
数据文件的最大长度(当重建数据文件且为“满”时)。
· --extend-check,-e
进行修复,试图从数据文件恢复每一行。一般情况会发现大量的垃圾行。不要使用该选项,除非你不顾后果。
· --force, -f
覆盖旧的中间文件(文件名类似tbl_name.TMD),而不是中断。
· --keys-used=val, -k val
对于myisamchk,该选项值为位值,说明要更新的索引。选项值的每一个二进制位对应表的一个索引,其中第一个索引对应位0。选项值0禁用对所有索引的更新,可以保证快速插入。通过myisamchk -r可以重新激活被禁用的索引。
· --no-symlinks, -l
不跟随符号连接。通常myisamchk修复一个符号连接所指的表。在MySQL 4.0中该选项不存在,因为从4.0开始的版本在修复过程中不移除符号链接。
· --parallel-recover, -p
与-r和-n的用法相同,但使用不同的线程并行创建所有键。这是alpha代码。自己承担风险!
· --quick,-q
不修改数据文件,快速进行修复。出现复制键时,你可以两次指定该项以强制myisamchk修改原数据文件。
· --recover, -r
可以修复几乎所有一切问题,除非唯一的键不唯一时(对于MyISAM表,这是非常不可能的情况)。如果你想要恢复表,这是首先要尝试的选项。如果myisamchk报告表不能用-r恢复,则只能尝试-o。在不太可能的情况下-r失败,数据文件保持完好)。
如果你有大量内存,你应增加sort_buffer_size的值。
· --safe-recover, -o
使用一个老的恢复方法读取,按顺序读取所有行,并根据找到的行更新所有索引树。这比-r慢些,但是能处理-r不能处理的情况。该恢复方法使用的硬盘空间比-r少。一般情况,你应首先用-r维修,如果-r失败则用-o。
如果你有大量内存,你应增加sort_buffer_size的值。
· (OBSOLETE) --set-character-set=name
在MySQL 5.1中不使用。参见--set-collation。
· --set-collation=name
更改用来排序表索引的校对规则。校对规则名的第一部分包含字符集名。
· --sort-recover, -n
强制myisamchk通过排序来解析键值,即使临时文件将可能很大。
· --tmpdir=path, -t path
用于保存临时文件的目录的路径。如果未设置,myisamchk使用TMPDIR环境变量的值。tmpdir可以设置为一系列目录路径,用于成功地以round-robin模式创建临时文件。在Unix中,目录名之间的间隔字符为冒号(‘:’),在Windows、NetWare和OS/2中为分号 (‘;’)。
· --unpack,-u
将用myisampack打包的表解包。
· --analyze,-a
分析键值的分布。这通过让联结优化器更好地选择表应该以什么次序联结和应该使用哪个键来改进联结性能。要想获取分布相关信息,使用myisamchk --description --verbose tbl_name命令或SHOW KEYS FROM tbl_name语句。
· --description, -d
打印出关于表的描述性信息。
· --set-auto-increment[=value], -A[value]
强制从给定值开始的新记录使用AUTO_INCREMENT编号(或如果已经有AUTO_INCREMENT值大小的记录,应使用更高值)。如果未指定value,新记录的AUTO_INCREMENT编号应使用当前表的最大值加上1。
· --sort-index, -S
以从高到低的顺序排序索引树块。这将优化搜寻并且将使按键值的表扫描更快。
· --sort-records=N, -R N
根据一个具体索引排序记录。这使你的数据更局部化并且可以加快在该键上的SELECT和ORDER BY的范围搜索。(第一次做排序可能很慢!)为了找出一张表的索引编号,使用SHOW INDEX,它以myisamchk看见他们的相同顺序显示一张表的索引。索引从1开始编号。
如果键没有打包(PACK_KEYS=0),它们的长度相同,因此当myisamchk 排序并移动记录时,只覆盖索引中的记录偏移量。如果键已经打包(PACK_KEYS=1),myisamchk必须先解开打包的键块,然后重新创建索引并再次将键块打包。(在这种情况下,重新创建索引比更新每个索引的偏移量要快)。
当你运行myisamchk时内存分配重要.MYIsamchk使用的内存大小不能超过用-O选项指定的。如果你想对每一个大表使用myisamchk,你必须首先确定你想使用多少内存。修复时可以使用的 默认值只有3MB。使用更大的内存,可以让myisamchk工作得更快一些。例如,如果有大于32MB的RAM,可以使用如下所示选项(除了你可以指定的其它选项):
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
对于大多数情况,使用-O sort=16M应该足够了。
应记住myisamchk使用TMPDIR中的临时文件。如果TMPDIR指向内存文件系统,你可能很容易得到内存溢出的错误。如果发生,设定TMPDIR指向有更多空间的文件系统目录并且重启myisamchk。
修复时myisamchk也需要大量硬盘空间:
· 将数据文件大小扩大一倍(原文件和复制文件)。如果你用--quick修复则不需要该空间;在这种情况下,只重新创建了索引文件。在文件系统上需要的空间与原数据文件相同!(创建的复制文件位于原文件所在目录)。
· 代替旧索引文件的新索引文件所占空间。修复工作一开始,就对旧索引文件进行了删减,因此你通常会忽略该空间。在文件系统上需要的该空间与原数据文件相同!
· 当使用--recover或---sort-recover(但不使用--safe-recover)时,需要排序缓冲区空间。需要的空间为:
· (largest_key + row_pointer_length) * number_of_rows * 2
可以用myisamchk -dv tbl_name检查键值和row_pointer_length的长度。在临时目录分配该空间(用TMPDIR或--tmpdir=path指定)。
如果在修复过程中出现硬盘空间问题,可以试试用--safe-recover代替--recover。
如果用--skip-external-locking运行mysqld(在某些系统上为 默认设置,例如Linux),当mysqld使用某个表时,你不能可靠地使用myisamchk来检查相同的表。当你运行myisamchk时如果可以确保没有人在通过mysqld访问表,在开始检查表前,你只需要运行mysqladmin flush-tables。如果你不能保证,则你检查表时你必须停止mysqld。如果mysqld更新表时运行myisamchk,你可能会获得表被破坏的警告,即使事实并非如此。
如果不使用--skip-external-locking,可以随时使用myisamchk来检查表。当检查表时,所有尝试更新表的客户端将等待,直到myisamchk准备好可以继续。
如果使用myisamchk来修复或优化表,必须确保mysqld服务器没有在使用该表(如果你正使用--skip-external-locking选项也适用)。如果不关闭mysqld,在运行myisamchk之前至少应执行mysqladmin flush-tables。如果服务器和myisamchk同时访问表,表可能会被破坏。
本节描述如何检查和处理MySQL数据库中的数据破坏。如果表经常被破坏,你应尽力找到原因。参见A.4.2节,“如果MySQL依然崩溃,应作些什么”。
关于MyISAM表怎样会被破坏的解释,参见15.1.4节,“MyISAM表方面的问题”。
在执行崩溃恢复时,理解在一个数据库中的每一个MyISAM表tbl_name对应的在数据库目录中的3个文件是很重要的:
文件 |
目的 |
tbl_name.frm |
定义(格式)文件 |
tbl_name.MYD |
数据文件 |
tbl_name.MYI |
索引文件 |
这3类文件的每一类都可能遭受不同形式的损坏,但是问题最常发生在数据文件和索引文件。
myisamchk通过一行一行地创建一个“.MYD”数据文件的副本来工作,它通过删除旧的“.MYD 文件并且重命名新文件到原来的文件名结束修复阶段。如果你使用--quick,myisamchk不创建一个临时“.MYD”文件,只是假定“.MYD”文件是正确的并且仅创建一个新的索引文件,不接触“.MYD”文件,这是安全的,因为myisamchk自动检测“.MYD”文件是否损坏并且在这种情况下,放弃修复。你也可以给myisamchk两个--quick选项。在这种情况下,myisamchk不会在一些错误上(象重复键)放弃,相反试图通过修改“.MYD”文件解决它们。通常,只有在太少的空闲磁盘空间上实施正常修复,使用两个--quick选项时才有用。在这种情况下,你至少应该在运行myisamchk前做进行备份。
· myisamchk tbl_name
这样能找出99.99%的错误。它不能找出的是仅仅涉及数据文件的损坏(这很不常见)。如果想要检查一张表,通常应该没有选项地运行myisamchk或用-s或--silent选项的任何一个。
· myisamchk -m tbl_name
这样能找出99.99%的错误。它首先检查所有索引条目的错误并通读所有行。它还计算行内所有键值的校验和,并确认校验和与索引树内键的校验和相匹配。
· myisamchk -e tbl_name
可以完全彻底地检查数据(-e意思是“扩展检查”)。它对每一行做每个键的读检查以证实它们确实指向正确的行。这在一个有很多键的大表上可能花很长时间。myisamchk通常将在它发现第一个错误以后停止。如果你想要获得更多的信息,可以增加--verbose(-v)选项。这使得myisamchk继续一直到最多20个错误。
· myisamchk -e -i tbl_name
象前面的命令一样,但是-i选项告诉myisamchk还打印出一些统计信息。
在一般使用中,一个简单的myisamchk(没有除表名以外的参数)就足够检查表了。
本节描述如何对MyISAM表使用myisamchk(扩展名.MYI和.MYD)。
你还可以(并且应该,如果可能)使用CHECK TABLE和REPAIR TABLE语句来检查和修复MyISAM表。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。
一张损坏的表的症状通常是查询意外中断并且能看到下述错误:
要想得到错误相关的详细信息,你可以运行perror nnn,其中nnn为错误编号。下面的示例显示了如何使用perror来找到最常用错误编号(用表的方式指出问题)的含义:
shell> perror 126 127 132 134 135 136 141 144 145
126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired
请注意错误135(记录文件中没有更多的空间)和错误136(索引文件中没有更多的空间)不是可以通过简单修复可以修复的错误。在这种情况下,必须使用ALTER TABLE来增加MAX_ROWS和AVG_ROW_LENGTH表选项值:
ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
如果你不知道当前的表的选项值,使用SHOW CREATE TABLE或DESCRIBE来查询。
对于其它的错误,你必须修复表。myisamchk通常可以检测和修复大多数问题。
修复过程包括四个阶段,此处将进行描述。开始修复前,应进入数据库目录并检查表文件的许可。在Unix中,确保它们对于运行mysqld的用户可读(你也应可读,因为你需要访问检查的文件)。如果你需要修改文件,你还必须拥有写访问权限。
用myisamchk修复表的选项的描述参见5.9.5节,“myisamchk:MyISAM表维护实用工具”的前几节。
下面几节列出了上述命令失败或你想要使用myisamchk提供的扩展特性等情况的例子。
如果你要通过命令行来修复表,必须首先停止mysqld服务器。请注意当你在远程服务器上运行mysqladmin shutdown时,mysqladmin返回后,mysqld服务器将仍然运行一会儿,直到停止所有查询并将所有键清空到硬盘上。
阶段1:检查你的表
如果你有很多时间,运行myisamchk *.MYI或myisamchk -e *.MYI。使用-s(沉默)选项禁止不必要的信息。
如果mysqld服务器处于宕机状态,应使用--update-state选项来告诉myisamchk将表标记为'检查过的'。
你必须只修复那些myisamchk报告有错误的表。对这样的表,继续到阶段2。
如果在检查时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
阶段2:简单安全的修复
注释:如果想更快地进行修复,当运行myisamchk时,你应将sort_buffer_size和Key_buffer_size变量的值设置为可用内存的大约25%。
首先,试试myisamchk -r -q tbl_name(-r -q意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:
如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。
阶段3:困难的修复
只有在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:
如果你的MySQL版本没有TRUNCATE TABLE,则使用DELETE FROM tbl_name。
回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。
你还可以使用REPAIR TABLE tbl_name USE_FRM,将自动执行整个程序。
阶段4:非常困难的修复
只有.frm描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。
为了组合碎片记录并且消除由于删除或更新记录而浪费的空间,以恢复模式运行myisamchk:
shell> myisamchk -r tbl_name
你可以用SQL的OPTIMIZE TABLE语句使用的相同方式来优化表,OPTIMIZE TABLE可以修复表并对键值进行分析,并且可以对索引树进行排序以便更快地查找键值。实用程序和服务器之间不可能交互操作,因为当你使用OPTIMIZE TABLE时,服务器做所有的工作。参见13.5.2.5节,“OPTIMIZE TABLE语法”。
myisamchk还有很多其它可用来提高表的性能的选项:
· -S, --sort-index
· -R index_num, --sort-records=index_num
· -a, --analyze
关于这些选项的完整的描述,参见5.9.5节,“myisamchk:MyISAM表维护实用工具”。
定期对表进行检查而非等到问题出现后再检查数据库表是一个好主意。检查和修复MyISAM表的一个方式是使用CHECK TABLE和REPAIR TABLE语句。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。
检查表的另一个方法是使用myisamchk。为维护目的,可以使用myisamchk -s检查表。-s选项(简称--silent)使myisamchk以沉默模式运行,只有当错误出现时才打印消息。
在服务器启动时检查表是一个好主意。例如,无论何时机器在更新当中重新启动了,你通常需要检查所有可能受影响的表。(即“预期的破坏了的表”)。要想自动检查MyISAM表,用--myisam-recover选项启动服务器。
一个更好的测试将是检查最后修改时间比“.pid”文件新的表。
你还应该在正常系统操作期间定期检查表。在MySQL AB,我们运行一个cron任务,每周一次检查所有重要的表,使用“crontab”文件中这样的行:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
可以打印损坏的表的信息,以便我们在需要时能够检验并且修复它们。
多年了我们还没有发现(的确是真的)都没有任何意外损坏的表时(由于除硬件故障外的其它原因造成损坏的表),每周一次对我们是足够了。
我们建议现在开始,你对所有最后24小时内被更新了的表每晚都执行myisamchk -s,直到你变得象我们那样信任MySQL。
一般情况,MySQL表很少需要维护。如果你用动态大小的行更改MyISAM表(含VARCHAR、BLOB或TEXT列的表)或有删除了许多行的表,你可能想要不时地(每月一次)整理/组合表的空间。
可以对有问题的表执行OPTIMIZE TABLE来优化。或者是,如果可以停一会mysqld服务器,进入数据目录,当服务器停止时使用该命令:
shell> myisamchk -r -s --sort-index -O sort_buffer_size=16M */*.MYI
为了获得关于一个表的描述或统计,使用下面的命令:
· myisamchk -d tbl_name
以“描述模式”运行myisamchk,生成表的描述。如果用--skip-external-locking选项启动MySQL服务器,myisamchk可以报告运行的表被更新的错误。然而,既然在描述模式中myisamchk不更改表,没有任何破坏数据的风险。
· myisamchk -d -v tbl_name
为了生成更多关于myisamchk正在做什么的信息,加上-v告诉它以冗长模式运行。
· myisamchk -eis tbl_name
仅显示表的最重要的信息。因为必须读取整个表,该操作很慢。
· myisamchk -eiv tbl_name
这类似 -eis,只是告诉你正在做什么。
下面为这些命令的输出示例。它们基于含这些数据和索引文件大小的表:
-rw-rw-r-- 1 monty tcx 317235748 Jan 12 17:30 company.MYD
-rw-rw-r-- 1 davida tcx 96482304 Jan 12 18:35 company.MYM
myisamchk -d输出示例:
MyISAM file: company.MYI
Record format: Fixed length
Data records: 1403698 Deleted blocks: 0
Recordlength: 226
table description:
Key Start Len Index Type
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
myisamchk -d -v 输出示例:
MyISAM file: company
Record format: Fixed length
File-version: 1
Creation time: 1999-10-30 12:12:51
Recover time: 1999-10-31 19:13:01
Status: checked
Data records: 1403698 Deleted blocks: 0
Datafile parts: 1403698 Deleted data: 0
Datafile pointer (bytes): 3 Keyfile pointer (bytes): 3
Max datafile length: 3791650815 Max keyfile length: 4294967294
Recordlength: 226
table description:
Key Start Len Index Type Rec/key Root Blocksize
1 2 8 unique double 1 15845376 1024
2 15 10 multip. text packed stripped 2 25062400 1024
3 219 8 multip. double 73 40907776 1024
4 63 10 multip. text packed stripped 5 48097280 1024
5 167 2 multip. unsigned short 4840 55200768 1024
6 177 4 multip. unsigned long 1346 65145856 1024
7 155 4 multip. text 4995 75090944 1024
8 138 4 multip. unsigned long 87 85036032 1024
9 177 4 multip. unsigned long 178 96481280 1024
193 1 text
myisamchk -eis 输出示例:
Checking MyISAM file: company
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%
Records: 1403698 M.recordlength: 226
Packed: 0%
Recordspace used: 100% Empty space: 0%
Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966
myisamchk -eiv 输出示例:
Checking MyISAM file: company
Data records: 1403698 Deleted blocks: 0
- check file-size
- check delete-chain
block_size 1024:
index 1:
index 2:
index 3:
index 4:
index 5:
index 6:
index 7:
index 8:
index 9:
No recordlinks
- check index reference
- check data record references index: 1
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 2
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
- check data record references index: 3
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
- check data record references index: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
- check data record references index: 5
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 6
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 7
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 8
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
- check data record references index: 9
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 9% Packed: 17%
- check records and index references
[LOTS OF ROW NUMBERS DELETED]
Records: 1403698 M.recordlength: 226 Packed: 0%
Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
Record blocks: 1403698 Delete blocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798
下面解释myisamchk产生的信息的类型。“keyfile”是索引文件。“记录”和“行”是同义词。
· MyISAM file
ISAM(索引)文件名。
· File-version
ISAM格式的版本。当前总是2。
· Creation time
数据文件创建的时间。
· Recover time
索引/数据文件上次被重建的时间。
· Data records
在表中有多少记录。
· Deleted blocks
有多少删除的块仍然保留着空间。你可以优化表以使这个空间减到最小。参见第7章:优化。
· Datafile parts
对动态记录格式,这指出有多少数据块。对于一个没有碎片的优化过的表,这与Data records相同。
· Deleted data
不能回收的删除数据有多少字节。你可以优化表以使这个空间减到最小。参见第7章:优化。
· Datafile pointer
数据文件指针的大小,以字节计。它通常是2、3、4或5个字节。大多数表用2个字节管理,但是目前这还不能从MySQL控制。对固定表,这是一个记录地址。对动态表,这是一个字节地址。
· Keyfile pointer
索引文件指针的大小,以字节计。它通常是1、2或3个字节。大多数表用 2 个字节管理,但是它自动由MySQL计算。它总是一个块地址。
· Max datafile length
表的数据文件(.MYD文件)能够有多长,以字节计。
· Max keyfile length
表的键值文件(.MYI文件)能够有多长,以字节计。
· Recordlength
每个记录占多少空间,以字节计。
· Record format
用于存储表行的格式。上面的例子使用Fixed length。其他可能的值是Compressed和Packed。
· table description
在表中所有键值的列表。对每个键,给出一些底层的信息:
o Key
该键的编号。
o Start
该索引部分从记录的哪里开始。
o Len
该索引部分是多长。对于紧凑的数字,这应该总是列的全长。对字符串,它可以比索引的列的全长短些,因为你可能会索引到字符串列的前缀。
o Index
unique或multip(multiple)。表明一个值是否能在该索引中存在多次。
o Type
该索引部分有什么数据类型。这是一个packed、stripped或empty选项的ISAM数据类型。
o Root
根索引块的地址。
o Blocksize
每个索引块的大小。默认是1024,但是从源码构建MySQL时,该值可以在编译时改变。
o Rec/key
这是由优化器使用的统计值。它告诉对该键的每个值有多少条记录。唯一键总是有一个1值。在一个表被装载后(或变更很大),可以用myisamchk -a更新。如果根本没被更新,给定一个30的默认值。
在上面例子的表中,第9个键有两个table description行。者说明它是有2个部分的多部键。
· Keyblocks used
键块使用的百分比是什么。当在例子中使用的表刚刚用myisamchk重新组织时,该值非常高(很接近理论上的最大值)。
· Packed
MySQL试图用一个通用后缀压缩键。这只能被用于CHAR/VARCHAR/DECIMAL列的键。对于左部分类似的长字符串,能显著地减少使用空间。在上面的第3个例子中,第4个键是10个字符长,可以减少60%的空间。
· Max levels
对于该键的B树有多深。有长键的大表有较高的值。
· Records
表中有多少行。
· M.recordlength
平均记录长度。对于有定长记录的表,这是准确的记录长度,因为所有记录的长度相同。
· Packed
MySQL从字符串的结尾去掉空格。Packed值表明这样做达到的节约的百分比。
· Recordspace used
数据文件被使用的百分比。
· Empty space
数据文件未被使用的百分比。
· Blocks/Record
每个记录的平均块数(即,一个碎片记录由多少个连接组成)。对固定格式表,这总是1。该值应该尽可能保持接近1.0。如果它变得太大,你可以重新组织表。参见第7章:优化。
· Recordblocks
多少块(链接)被使用。对固定格式,它与记录的个数相同。
· Deleteblocks
多少块(链接)被删除。
· Recorddata
在数据文件中使用了多少字节。
· Deleted data
在数据文件中多少字节被删除(未使用)。
· Lost space
如果一个记录被更新为更短的长度,就损失了一些空间。这是所有这样的损失之和,以字节计。
· Linkdata
当使用动态表格式,记录碎片用指针连接(每个4 ~ 7字节)。 Linkdata指这样的指针使用的内存量之和。
如果一张表已经用myisampack压缩了,myisamchk -d打印每个表列的附加信息。对于它的一个例子及其含义的描述,参见8.2节,“myisampack:生成压缩、只读MyISAM表”。
默认情况下,MySQL使用cp1252(Latin1)字符集根据Swedish/Finnish规则进行排序。这些 默认值适合美国和西欧大部分国家。
所有MySQL二进制分发版用--with-extra-charsets=complex编译而成。可以在所有标准程序中添加代码,使它们可以处理latin1和所有多字节二进制字符集。其它字符集根据需要从字符集定义文件载入。
字符集确定在名称中使用什么字符。它还确定如何用SELECT语句的ORDER BY和GROUP BY子句对字符串进行排序。
还可以在启动服务器时用--default-character-set选项更改字符集。字符集可以用--with-charset=charset和--with-extra-charsets=list-of-charsets | complex | all | none选项来configure,字符集配置文件列于SHAREDIR/charsets/Index。参见2.8.2节,“典型配置选项”。
还可以在你启动服务器时用--default-collation选项更改字符集 校对规则。校对规则必须是默认字符集的合法校对规则。(使用SHOW COLLATION语句来确定每个字符集使用哪个校对规则)。 参见2.8.2节,“典型配置选项”。
如果在运行MySQL时更改字符集,还会更改排序顺序。结果是你必须对所有表运行myisamchk -r -q --set-character-set=charset ,或正确地对索引进行排序。
当客户端连接MySQL服务器时,服务器告诉客户端服务器的默认字符集是什么。客户端切换到该字符集进行连接。
当转义SQL查询的字符串时,你应使用mysql_real_escape_string()。mysql_real_escape_string()等价于旧的mysql_escape_string()函数,不同的是它使用MYSQL连接句柄作为第一个参数,以便转义字符时可以使用相应的字符集。
如果客户端的编译路径不是服务器的安装目录,并且配置MySQL时没有包括MySQL二进制中的所有字符集,如果服务器运行时需要使用客户端设置的字符集之外的其它字符集,你必须告诉客户端从哪里找到更多的字符集。
可以指定--character-sets-dir选项来表示动态MySQL字符集所保存目录的路径。例如,可以将下面的行放入选项文件中:
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
你可以强制客户端使用专用字符集:
[client]
default-character-set=charset
但是一般情况不需要。
在MySQL 5.1中,分别指定字符集和 校对规则。这说明如果你想使用German排序顺序,你应选择latin1 字符集和latin1_german1_ci或latin1_german2_ci校对规则。例如,要用latin1_german1_ci校对规则启动服务器,应使用--character-set-server=latin1和--collation-server=latin1_german1_ci选项。
关于这两种校对规则的不同之处,参见10.10.2节,“西欧字符集”。
要想在启动mysqld后用具体语言显示错误消息,使用--language或-L选项。选项值可以为语言名称或错误消息文件的全路径。例如:
shell> mysqld --language=swedish
或:
shell> mysqld --language=/usr/local/share/swedish
语言名应为小写。
语言文件位于(默认情况下)MySQL基本目录的share/LANGUAGE目录下。
要想更改错误消息文件,应编辑errmsg.txt文件,然后执行下面的命令以生成errmsg.sys文件:
shell> comp_err errmsg.txt errmsg.sys
如果你升级到新版本的MySQL,记住使用新的errmsg.txt文件来重新更改。
本节讨论在MySQL中添加新字符集的程序。你必须有一个MySQL源码分发版。
要选择正确的程序,先确定字符集是简单字符集还是复杂字符集:
· 如果字符集不需要使用特殊字符串校对规则程序进行排序,并且不需要多字节字符支持,则为简单字符集。
· 如果需要上述某个特性,则为复杂字符集。
例如,latin1和danish为简单字符集,而big5和czech为复杂字符集。
在下面的程序中,字符集名用MYSET表示。
对于简单字符集,应:
1. 在sql/share/charsets/Index文件最后添加MYSET。并指定唯一的编号。
2. 创建文件sql/share/charsets/MYSET.conf。(你可以使用sql/share/charsets/latin1.conf的备份文件作为该文件的基础)。
该文件的语法很简单:
· 注释从‘#’字符开始,一直到该行末尾。
· 各字之间用任意数量的空格间隔开。
· 定义字符集时,每个字必须为十六进制格式的数字。
· ctype数组占据前257个字。to_lower[]、to_upper[]和sort_order[]数组依次占据256个字。
3. 将字符集名添加到configurE.in的CHARSETS_AVAILABLE和COMPILED_CHARSETS列。
4. 重新配置、编译并测试。
对于复杂字符集,应:
1. 在MySQL源码分发版中创建文件strings/ctype-MYSET.c。
2. 在sql/share/charsets/Index文件最后添加MYSET。并指定唯一的编号。
3. 看看已有的ctype-*.c文件(例如strings/ctype-big5.c),看看需要定义什么。请注意文件中的数组名必须为ctype_MYSET、to_lower_MYSET等等。对应简单字符集的数组。参见5.10.4节,“字符定义数组”。
4. 在文件顶部,添加注释:
5. /*
6. * This comment is parsed by configure to create ctype.c,
7. * so don't change it unless you know what you are doing.
8. *
9. * .configure. number_MYSET=MYNUMBER
10. * .configure. strxfrm_multiply_MYSET=N
11. * .configure. mbmaxlen_MYSET=N
12. */
configure程序使用该注释自动将字符集包括进MySQL库中。
在下面章节中解释strxfrm_multiply和mbmaxlen 行。只有需要字符串比较函数或多字节字符集函数时,才需要单独将它们包括进来。
13.然后你应创建下面的函数:
14.将字符集名添加到configurE.in的CHARSETS_AVAILABLE和COMPILED_CHARSETS列。
15.重新配置、编译并测试。
sql/share/charsets/README文件中包括详细的说明。
如果你想要MySQL分发中的字符集,请向MySQL内部邮件系统发邮件。参见1.7.1.1节,“The MySQL邮件列表”。
to_lower[]和to_upper[]是简单数组,含有小写和大写字符,对应字符集的每个成员。例如:
to_lower['A'] should contain 'a'
to_upper['a'] should contain 'A'
sort_order[]是一个映射,表示如何排列字符的顺序,以便进行比较和排序。通常(但非对于所有字符集)与to_upper[]相同,说明排序对大小写敏感。MySQL排序字符基于sort_order[]元素的值。对于更加复杂的排序规则,参见5.10.5节,“字符串比较支持”的字符串 校对规则讨论。
ctype[]是一个位数组,每个字符为一个元素。(请注意字符值索引to_lower[]、to_upper[]和sort_order[],但用字符值+ 1索引ctype[]。这是传统的转换方法,能够处理EOF)。
m_ctype.h中有下面的位掩码定义:
#define _U 01 /* Uppercase */
#define _L 02 /* Lowercase */
#define _N 04 /* Numeral (digit) */
#define _S 010 /* Spacing character */
#define _P 020 /* Punctuation */
#define _C 040 /* Control character */
#define _B 0100 /* Blank */
#define _X 0200 /* heXadecimal digit */
每个字符的ctype[]条目应为相应的描述字符的位掩码值的联合。例如,'A'是大写字符(_U)以及十六进制整数(_X),因此ctype['A'+1]应包含 值:
_U + _X = 01 + 0200 = 0201
最好的文档是已有字符集。以big5、czech、gbk、sjis和tis160字符集作为例子。
你必须在文件顶部的特殊注释处指定strxfrm_multiply_MYSET=N值。N应设置为字符串在my_strxfrm_MYSET过程中可能增长的最大比例(必须为正整数)。
最好的文档是已有字符集。以euc_kr、gb2312,gbk、sjis和ujis字符集作为例子。这些字符集位于strings目录的ctype-charset.c文件中。
必须在文件顶部的特殊注释处指定mbmaxlen_MYSET=N值。N应设置为字符集内最长字符的字节数。
· 你的程序的字符集保存路径不正确。(默认为/usr/local/mysql/share/mysql/charsets)。可以在运行有问题的程序时通过--character-sets-dir选项来修复。
· 字符集为多字节字符集,不能动态载入。在这种情况下,你必须重新编译程序,以支持字符集。
· 字符集为动态字符集,但你没有对应的配置文件。在这种情况下,你应从新MySQL分发安装该字符集的配置文件。
· 如果Index文件没有包含字符集名,程序将显示下面的错误消息:
· ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf'
· not found (Errcode:2)
在这种情况下,你应获得新Index文件或在当前文件中手动添加字符集。
对于MyISAM表,可以用myisamchk -dvv tbl_name检查表的字符集名和编号。
MySQL服务器有几个时区设置:
· 系统时区。服务器启动时便试图确定主机的时区,用它来设置system_time_zone系统变量。
· 服务器当前的时区。全局系统变量time_zone表示服务器当前使用的时区。初使值为'SYSTEM',说明服务器时区与系统时区相同。可以用--default-time-zone=timez选项显式指定初使值。如果你有SUPER 权限,可以用下面的语句在运行时设置全局变量值:
· mysql> SET GLOBAL time_zone = timezone;
· 每个连接的时区。每个客户端连接有自己的时区设置,用会话time_zone变量给出。其初使值与全局变量time_zone相同,但可以用下面的语句重设:
· mysql> SET time_zone = timezone;
可以用下面的方法查询当前的全局变量值和每个连接的时区:
mysql> SELECT @@global.time_zone, @@session.time_zone;
timezone值为字符串,表示UTC的偏移量,例如'+10:00'或'-6:00'。如果已经创建并装入mysql数据库中的时区相关表,你还可以使用命名的时区,例如'Europe/Helsinki'、'US/Eastern'或'MET'。值'SYSTEM'说明该时区应与系统时区相同。时区名对大小写不敏感。
MySQL安装程序在mysql数据库中创建时区表,但不装载。你必须手动装载。(如果你正从以前的版本升级到MySQL 4.1.3或更新版本,你应通过升级mysql数据库来创建表。参见2.10.2节,“升级授权表”中的说明)。
如果你的系统有自己的时区信息数据库(描述时区的一系列文件),应使用mysql_tzinfo_to_sql程序来填充时区表。示例系统如Linux、FreeBSD、Sun Solaris和Mac OS X。这些文件的可能位置为/usr/share/zoneinfo目录。如果你的系统没有时区信息数据库,可以使用本节后面描述的下载的软件包。
mysql_tzinfo_to_sql程序用来装载时区表。在命令行中,将时区信息目录路径名传递到mysql_tzinfo_to_sql并输出发送到mysql程序。例如:
shell> mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
mysql_tzinfo_to_sql读取系统时区文件并生成SQL语句。mysql处理这些语句并装载时区表。
mysql_tzinfo_to_sql还可以用来装载单个时区文件,并生成闰秒信息。
要想装载对应时区tz_name的单个时区文件tz_file,应这样调用mysql_tzinfo_to_sql:
shell> mysql_tzinfo_to_sql tz_file tz_name | mysql -u root mysql
如果你的时区需要计算闰秒,按下面方法初使化闰秒信息,其中tz_file是时区文件名:
shell> mysql_tzinfo_to_sql --leap tz_file | mysql -u root mysql
如果你的系统没有时区信息数据库 (例如,Windows或HP-UX),你可以从http://dev.mysql.com/downloads/timezones.html下载预构建时区表软件包。该软件包包含MyISAM时区表所用的.frm、.MYD和.MYI文件。这些表应属于mysql数据库,因此应将这些文件放到MySQL服务器数据目录的mysql子目录。操作时应关闭服务器。
警告!如果你的系统有时区信息数据库,请不要使用下载的软件包。而应使用mysql_tzinfo_to_sql实用工具!否则,MySQL和系统上其它应用程序处理日期时间的方法会有所不同。
关于在复制时时区设置相关请查阅6.7节,“复制特性和已知问题”。
MySQL有几个不同的日志文件,可以帮助你找出mysqld内部发生的事情:
日志文件 |
记入文件中的信息类型 |
错误日志 |
记录启动、运行或停止mysqld时出现的问题。 |
查询日志 |
记录建立的客户端连接和执行的语句。 |
更新日志 |
记录更改数据的语句。不赞成使用该日志。 |
二进制日志 |
记录所有更改数据的语句。还用于复制。 |
慢日志 |
记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。 |
默认情况下,所有日志创建于mysqld数据目录中。通过刷新日志,你可以强制 mysqld来关闭和重新打开日志文件(或者在某些情况下切换到一个新的日志)。当你执行一个FLUSH LOGS语句或执行mysqladmin flush-logs或mysqladmin refresh时,出现日志刷新。参见13.5.5.2节,“FLUSH语法”。
如果你正使用MySQL复制功能,从复制服务器将维护更多日志文件,被称为接替日志。相关讨论参见第6章:MySQL中的复制。
错误日志文件包含了当mysqld启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。
如果mysqld莫名其妙地死掉并且mysqld_safe需要重新启动它,mysqld_safe在错误日志中写入一条restarted mysqld消息。如果mysqld注意到需要自动检查或着修复一个表,则错误日志中写入一条消息。
在一些操作系统中,如果mysqld死掉,错误日志包含堆栈跟踪信息。跟踪信息可以用来确定mysqld死掉的地方。参见E.1.4节,“使用堆栈跟踪”。
可以用--log-error[=file_name]选项来指定mysqld保存错误日志文件的位置。如果没有给定file_name值,mysqld使用错误日志名host_name.err 并在数据目录中写入日志文件。如果你执行FLUSH LOGS,错误日志用-old重新命名后缀并且mysqld创建一个新的空日志文件。(如果未给出--log-error选项,则不会重新命名)。
如果不指定--log-error,或者(在Windows中)如果你使用--console选项,错误被写入标准错误输出stderr。通常标准输出为你的终端。
在Windows中,如果未给出--console选项,错误输出总是写入.err文件。
mysqld按照它接收的顺序记录语句到查询日志。这可能与执行的顺序不同。这与更新日志和二进制日志不同,它们在查询执行后,但是任何一个锁释放之前记录日志。(查询日志还包含所有语句,而二进制日志不包含只查询数据的语句)。
服务器重新启动和日志刷新不会产生新的一般查询日志文件(尽管刷新关闭并重新打开一般查询日志文件)。在Unix中,你可以通过下面的命令重新命名文件并创建一个新文件:
shell> mv hostname.log hostname-old.log
shell> mysqladmin flush-logs
shell> cp hostname-old.log to-backup-directory
shell> rm hostname-old.log
在Windows中,服务器打开日志文件期间你不能重新命名日志文件。你必须先停止服务器然后重新命名日志文件。然后,重启服务器来创建新的日志文件。
二进制日志以一种更有效的格式,并且是事务安全的方式包含更新日志中可用的所有信息。
二进制日志包含了所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句。语句以“事件”的形式保存,它描述数据更改。
注释:二进制日志已经代替了老的更新日志,更新日志在MySQL 5.1中不再使用。
二进制日志还包含关于每个更新数据库的语句的执行时间信息。它不包含没有修改任何数据的语句。如果你想要记录所有语句(例如,为了识别有问题的查询),你应使用一般查询日志。参见5.11.2节,“通用查询日志”。
二进制日志的主要目的是在恢复使能够最大可能地更新数据库,因为二进制日志包含备份后进行的所有更新。
二进制日志还用于在主复制服务器上记录所有将发送给从服务器的语句。参见第6章:MySQL中的复制。
运行服务器时若启用二进制日志则性能大约慢1%。但是,二进制日志的好处,即用于恢复并允许设置复制超过了这个小小的性能损失。
当用--log-bin[=file_name]选项启动时,mysqld写入包含所有更新数据的SQL命令的日志文件。如果未给出file_name值, 默认名为-bin后面所跟的主机名。如果给出了文件名,但没有包含路径,则文件被写入数据目录。建议指定一个文件名,原因参见A.8.1节,“MySQL中的打开事宜”。
如果你在日志名中提供了扩展名(例如,--log-bin=file_name.extension),则扩展名被悄悄除掉并忽略。
mysqld在每个二进制日志名后面添加一个数字扩展名。每次你启动服务器或刷新日志时该数字则增加。如果当前的日志大小达到max_binlog_size,还会自动创建新的二进制日志。如果你正使用大的事务,二进制日志还会超过max_binlog_size:事务全写入一个二进制日志中,绝对不要写入不同的二进制日志中。
为了能够知道还使用了哪个不同的二进制日志文件,mysqld还创建一个二进制日志索引文件,包含所有使用的二进制日志文件的文件名。默认情况下与二进制日志文件的文件名相同,扩展名为'.index'。你可以用--log-bin-index[=file_name]选项更改二进制日志索引文件的文件名。当mysqld在运行时,不应手动编辑该文件;如果这样做将会使mysqld变得混乱。
可以用RESET MASTER语句删除所有二进制日志文件,或用PURGE MASTER LOGS只删除部分二进制文件。参见13.5.5.5节,“RESET语法”和13.6.1节,“用于控制主服务器的SQL语句”。
二进制日志格式有一些已知限制,会影响从备份恢复。参见6.7节,“复制特性和已知问题”。
保存程序和触发器的二进制日志的描述参见20.4节,“存储子程序和触发程序的二进制日志功能”。
可以使用下面的mysqld选项来影响记录到二进制日志知的内容。又见选项后面的讨论。
· --binlog-do-db=db_name
告诉主服务器,如果当前的数据库(即USE选定的数据库)是db_name,应将更新记录到二进制日志中。其它所有没有明显指定的数据库 被忽略。如果使用该选项,你应确保只对当前的数据库进行更新。
对于CREATE DATABASE、ALTER DATABASE和DROP DATABASE语句,有一个例外,即通过操作的数据库来决定是否应记录语句,而不是用当前的数据库。
一个不能按照期望执行的例子:如果用binlog-do-db=sales启动服务器,并且执行USE prices; UPDATE sales.january SET amount=amount+1000;,该语句不写入二进制日志。
· --binlog-ignore-db=db_name
告诉主服务器,如果当前的数据库(即USE选定的数据库)是db_name,不应将更新保存到二进制日志中。如果你使用该选项,你应确保只对当前的数据库进行更新。
一个不能按照你期望的执行的例子:如果服务器用binlog-ignore-db=sales启动,并且执行USE prices; UPDATE sales.january SET amount=amount+1000;,该语句不写入二进制日志。
类似于--binlog-do-db,对于CREATE DATABASE、ALTER DATABASE和DROP DATABASE语句,有一个例外,即通过操作的数据库来决定是否应记录语句,而不是用当前的数据库。
要想记录或忽视多个数据库,使用多个选项,为每个数据库指定相应的选项。
服务器根据下面的规则对选项进行评估,以便将更新记录到二进制日志中或忽视。请注意对于CREATE/ALTER/DROP DATABASE语句有一个例外。在这些情况下,根据以下规则,所创建、修改或删除的数据库将代替当前的数据库。
1. 是否有binlog-do-db或binlog-ignore-db规则?
· 没有:将语句写入二进制日志并退出。
· 有:执行下一步。
2. 有一些规则(binlog-do-db或binlog-ignore-db或二者都有)。当前有一个数据库(USE是否选择了数据库?)?
· 没有:不要写入语句,并退出。
· 有:执行下一步。
3. 有当前的数据库。是否有binlog-do-db规则?
· 有:当前的数据库是否匹配binlog-do-db规则?
o 有:写入语句并退出。
o 没有:不要写入语句,退出。
· No:执行下一步。
4. 有一些binlog-ignore-db规则。当前的数据库是否匹配binlog-ignore-db规则?
· 有:不要写入语句,并退出。
· 没有:写入查询并退出。
例如,只用binlog-do-db=sales运行的服务器不将当前数据库不为sales的语句写入二进制日志(换句话说,binlog-do-db有时可以表示“忽视其它数据库”)。
如果你正进行复制,应确保没有从服务器在使用旧的二进制日志文件,方可删除它们。一种方法是每天一次执行mysqladmin flush-logs并删除三天前的所有日志。可以手动删除,或最好使用PURGE MASTER LOGS(参见13.6.1节,“用于控制主服务器的SQL语句”),该语句还会安全地更新二进制日志索引文件(可以采用日期参数)。
具有SUPER权限的客户端可以通过SET SQL_LOG_BIN=0语句禁止将自己的语句记入二进制记录。参见13.5.3节,“SET语法”。
你可以用mysqlbinlog实用工具检查二进制日志文件。如果你想要重新处理日志止的语句,这很有用。例如,可以从二进制日志更新MySQL服务器,方法如下:
shell> mysqlbinlog log-file | mysql -h server_name
关于mysqlbinlog实用工具的详细信息以及如何使用它,参见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。
如果你正使用事务,必须使用MySQL二进制日志进行备份,而不能使用旧的更新日志。
查询结束后、锁定被释放前或提交完成后则立即记入二进制日志。这样可以确保按执行顺序记入日志。
对非事务表的更新执行完毕后立即保存到二进制日志中。对于事务表,例如BDB或InnoDB表,所有更改表的更新(UPDATE、DELETE或INSERT) 被缓存起来,直到服务器接收到COMMIT语句。在该点,执行完COMMIT之前,mysqld将整个事务写入二进制日志。当处理事务的线程启动时,它为缓冲查询分配binlog_cache_size大小的内存。如果语句大于该值,线程则打开临时文件来保存事务。线程结束后临时文件被删除。
Binlog_cache_use状态变量显示了使用该缓冲区(也可能是临时文件)保存语句的事务的数量。Binlog_cache_disk_use状态变量显示了这些事务中实际上有多少必须使用临时文件。这两个变量可以用于将binlog_cache_size调节到足够大的值,以避免使用临时文件。
max_binlog_cache_size(默认4GB)可以用来限制用来缓存多语句事务的缓冲区总大小。如果某个事务大于该值,将会失败并 回滚。
如果你正使用更新日志或二进制日志,当使用CREATE ... SELECT or INSERT ... SELECT时,并行插入被转换为普通插入。这样通过在备份时使用日志可以确保重新创建表的备份。
请注意MySQL 5.1值的二进制日志格式与以前版本的MySQL不同,因为复制改进了。参见6.5节,“不同MySQL版本之间的复制兼容性”。
默认情况下,并不是每次写入时都将二进制日志与硬盘同步。因此如果操作系统或机器(不仅仅是MySQL服务器)崩溃,有可能二进制日志中最后的语句丢失了。要想防止这种情况,你可以使用sync_binlog全局变量(1是最安全的值,但也是最慢的),使二进制日志在每N次二进制日志写入后与硬盘同步。参见5.3.3节,“服务器系统变量”。即使sync_binlog设置为1,出现崩溃时,也有可能表内容和二进制日志内容之间存在不一致性。例如,如果使用InnoDB表,MySQL服务器处理COMMIT语句,它将整个事务写入二进制日志并将事务提交到InnoDB中。如果在两次操作之间出现崩溃,重启时,事务被InnoDB回滚,但仍然存在二进制日志中。可以用--innodb-safe-binlog选项解决该问题,可以增加InnoDB表内容和二进制日志之间的一致性。(注释:在MySQL 5.1中不需要--innodb-safe-binlog;由于引入了XA事务支持,该选项作废了)。
该选项可以提供更大程度的安全,还应对MySQL服务器进行配置,使每个事务的二进制日志(sync_binlog =1)和(默认情况为真)InnoDB日志与硬盘同步。该选项的效果是崩溃后重启时,在滚回事务后,MySQL服务器从二进制日志剪切 回滚的InnoDB事务。这样可以确保二进制日志反馈InnoDB表的确切数据等,并使从服务器保持与主服务器保持同步(不接收 回滚的语句)。
请注意即使MySQL服务器更新其它存储引擎而不是InnoDB,也可以使用--innodb-safe-binlog。在InnoDB崩溃恢复时,只从二进制日志中删除影响InnoDB表的语句/事务。如果崩溃恢复时MySQL服务器发现二进制日志变短了(即至少缺少一个成功提交的InnoDB事务),如果sync_binlog =1并且硬盘/文件系统的确能根据需要进行同步(有些不需要)则不会发生,则输出错误消息 ("二进制日志<名>比期望的要小")。在这种情况下,二进制日志不准确,复制应从主服务器的数据快照开始。
写入二进制日志文件和二进制日志索引文件的方法与写入MyISAM表相同。参见A.4.3节,“MySQL处理磁盘满的方式”。
用--log-slow-queries[=file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。获得初使表锁定的时间不算作执行时间。
如果没有给出file_name值, 默认未主机名,后缀为-slow.log。如果给出了文件名,但不是绝对路径名,文件则写入数据目录。
语句执行完并且所有锁释放后记入慢查询日志。记录顺序可以与执行顺序不相同。
慢查询日志可以用来找到执行时间长的查询,可以用于优化。但是,检查又长又慢的查询日志会很困难。要想容易些,你可以使用mysqldumpslow命令获得日志中显示的查询摘要来处理慢查询日志。
在MySQL 5.1的慢查询日志中,不使用索引的慢查询同使用索引的查询一样记录。要想防止不使用索引的慢查询记入慢查询日志,使用--log-short-format选项。参见5.3.1节,“mysqld命令行选项”。
在MySQL 5.1中,通过--log-slow-admin-statements服务器选项,你可以请求将慢管理语句,例如OPTIMIZE TABLE、ANALYZE TABLE和 ALTER TABLE写入慢查询日志。
用查询缓存处理的查询不加到慢查询日志中,因为表有零行或一行而不能从索引中受益的查询也不写入慢查询日志。
MySQL服务器可以创建各种不同的日志文件,从而可以很容易地看见所进行的操作。参见5.11节,“MySQL日志文件”。但是,你必须定期清理这些文件,确保日志不会占用太多的硬盘空间。
当启用日志使用MySQL时,你可能想要不时地备份并删除旧的日志文件,并告诉MySQL开始记入新文件。参见5.9.1节,“数据库备份”。
在 Linux (Redhat)的安装上,你可为此使用mysql-log-rotate脚本。如果你从RPM分发安装MySQL,脚本应该自动被安装了。
在其它系统上,你必须自己安装短脚本,你可从cron等入手处理日志文件。
你可以通过mysqladmin flush-logs或SQL语句FLUSH LOGS来强制MySQL开始使用新的日志文件。
日志清空操作做下列事情:
如果你只使用更新日志,你只需要重新命名日志文件,然后在备份前清空日志。例如,你可以这样做:
shell> cd mysql-data-directory
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs
然后做备份并删除“mysql.old”。
在一些情况下,你可能想要在同一台机器上运行多个mysqld服务器。你可能想要测试一个新的MySQL发布,同时不影响现有产品的设置。或者,你可能想使不同的用户访问来访问不同的mysqld服务器以便他们自己来管理。(例如,你可能是一个Internet服务提供商,希望为不同的客户来提供独立的MySQL安装)。
要想在一个单独的机器上运行多个服务器,每个服务器必须有唯一的各运行参数值。这些值可以在命令行中设置或在选项文件中设置。参见4.3节,“指定程序选项”。
至少下面的选项对每个服务器必须是不同的:
· --port=port_num
--port控制着TCP/IP连接的端口号。
· --socket=path
--socket控制Unix中的Unix套接字文件路径和在Windows中的命名管道名称。在Windows中,只有支持命名管道连接的服务器才需要明确指定管道名称。
· --shared-memory-base-name=name
该选项当前只在Windows中使用。它指定Windows服务器使用的、允许客户端通过共享内存来连接的共享内存名。
· --pid-file=path
该选项只在Unix中使用。它指出服务器在其中写入进程ID的文件名。
如果你使用下面的日志文件选项,对于每个服务器来说,它们必须是不同的:
· --log=path
· --log-bin=path
· --log-update=path
· --log-error=path
· --bdb-logdir=path
日志文件选项的描述参见5.11.5节,“日志文件维护”。
为了提高性能,你可以为每个服务器指定下面选项的不同的值,以便在物理磁盘之间平均分配负荷:
· --tmpdir=path
· --bdb-tmpdir=path
还推荐使用不同的临时目录,以便容易地确定哪个MySQL服务器创建了给定的临时文件。
一般情况,每个服务器应还使用不同的数据目录,可以通过--datadir=path选项来指定。
警告:一般情况,你决不要让两个服务器更新相同数据库中的数据。否则,如果你的操作系统不支持故障排除系统锁定,该可能会导致非常奇怪的结果。如果(不理会该警告)运行的多个服务器使用相同的数据目录并且启用了日志记录,你必须使用适当的选项来为每个服务器指定唯一的日志文件名。否则,服务器尝试用相同的文件来记录日志。请注意这种类型的设置只能在MyISAM和MERGE表上工作,对其它任何存储引擎不起作用。
多个服务器共享一个数据目录的警告也适用于NFS环境。允许多个MySQL服务器通过NFS访问一个共同的数据目录是一个非常不好的主义。
· 主要问题是NFS存在速度瓶颈。它不是用于这种用途。
· 用NFS的另一个冒险是你必须提出一个方法来确保两个或多个服务器不会相互干扰。NFS文件的锁定通常由lockd后台程序处理,但是目前,没有一个运行平台能够在每种情况下100%可靠地进行锁定。
使你更加容易:忘记在服务器之间通过NFS共享数据目录。一个较好的解决方案是使用包含几个CPU并且和使用有效处理多线程的操作系统的机器。
如果在不同的位置有多个MySQL的安装,一般情况可以用--basedir=path选项为每个服务器指定基本安装目录,使每个服务器使用不同的数据目录、日志文件和PID文件。(所有这些值的 默认值相对于根目录来确定)。那样的话, 你唯一需要指定的其它选项是--socket和--port选项。例如,假如使用tar文件二进制分发版安装不同的MySQL版本。这些安装在不同的位置,因此可以使用各个安装服务器相应的根目录中的bin/mysqld_safe命令来启动服务器。mysqld_safe确定正确的--basedir选项传递给mysqld,你仅需要为mysqld_safe指定--socket和--port选项。
正如下面几节所讨论的那样,可以通过设置环境变量或用指定的命令行选项来启动更多的服务器。但是,如果你需要在一个更稳定的基础上运行多个服务器,一个更方便的方法是使用选项文件来为每个服务器指定那些选项值,它对每个服务器必须是唯一的。
在Windows中,可以从命令行手动启动来运行多个服务器,每个服务器使用合适的操作参数。在基于Windows NT的系统中,安装几个服务器时,你还有将多个服务器安装为Windows服务并运行的选项。关于从命令行运行MySQL服务器或作为服务运行的一般说明在 2.3节,“在Windows上安装MySQL”中给出。本节描述怎样确保你用不同的启动选项值(对于每个服务器必须是唯一的,例如数据目录)启动各个服务器。这些选项的描述见5.12节,“在同一台机器上运行多个MySQL服务器”。
假设你想要在端口3307使用数据目录C:\mydata1运行mysqld,并且想在端口3308使用数据目录C:\mydata1运行mysqld-max。(要想这样做,启动服务器之前要确保,每个数据目录存在并且有自己的mysql数据库拷贝,它包含 授权表)。
然后创建两个选项文件。例如,创建一个文件名为C:\my-opts1.cnf的配置文件,它看起来象这个样子:
[mysqld]
datadir = C:/mydata1
port = 3307
创建第二个文件名为C:\my-opts1.cnf的配置文件,它看起来象这个样子:
mysqld]
datadir = C:/mydata2
port = 3308
然后,用它们自己的选项文件启动每个服务器:
C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnf
C:\> C:\mysql\bin\mysqld-max --defaults-file=C:\my-opts2.cnf
在NT中,每个服务器在前台启动(服务器退出前,不会显示新的提示符);需要在两个控制台窗口中执行这两个命令。
要想关闭服务器,必须连接到相应的端口号:
C:\> C:\mysql\bin\mysqladmin --port=3307 shutdown
C:\> C:\mysql\bin\mysqladmin --port=3308 shutdown
如刚才所讨论的,服务器配置允许客户端通过TCP/IP来连接。如果你的Windows版本支持命名管道并且你想允许命名管道连接,使用mysqld-nt或mysqld-max-nt服务器并指定启用命名管道并且指定管道名的选项。支持命名管道连接的每个服务器必须使用一个唯一的管道名。例如,C:\my-opts1.cnf文件可能象这样来书写:
[mysqld]
datadir = C:/mydata1
port = 3307
enable-named-pipe
socket = mypipe1
然后,这样启动服务器:
C:\> C:\mysql\bin\mysqld-nt --defaults-file=C:\my-opts1.cnf
同样修改第2个服务器使用的C:\my-opts2.cnf文件。
在基于NT的系统中,MySQL服务器可以以Windows服务的方式来运行。安装、控制和删除单个MySQL服务的过程描述见2.3.12节,“以Windows服务方式启动MySQL”。
你还可以以服务的方式安装多个MySQL服务器。此时,除了所有参数对每个服务器必须是唯一的,你还必须确保每个服务器使用不同的服务名。
在下面的说明中,假设你想要运行mysqld-nt服务器的两个不同的版本,它们分别安装在C:\mysql-4.1.8和C:\mysql-5.1.2-alpha目录中。(可能存在这种情况,如果你正在运行版本4.1.8作为你的产品服务器,还想使用5.1.2-alpha版本来进行测试)。
当用--install或--install-manual选项安装一个MySQL服务时,应遵从以下原则:
· 如果你没有指定服务名,服务器使用默认的MySQL服务名,从标准选项文件的[mysqld]组中读取选项。
· 如果你在--install选项后指定了服务名,服务器忽略[mysqld]选项组,从具有相同名的组中读取选项作为服务名。服务器从标准选项文件中读取选项。
· 如果你在服务名后面指定一个--defaults-file选项,服务器忽略标准选项文件,只从命名的文件的[mysqld]组读取选项。
注释:MySQL 4.0.17之前,只有使用默认服务名(MySQL)安装的一个服务器或使用服务名mysqld显式安装的一个服务器从标准选项文件读[mysqld]组。到4.0.17时,如果服务器读标准选项文件,则它们均读[mysqld]组,即使它们安装时使用了另一个服务名。这样允许你为选项使用[mysqld]组,用于所有MySQL服务器,并将根据每个服务器命名的选项组用于该服务器,即使用那个服务名安装的服务器。
根据前面叙述,你可以通过几个方法来设置多个服务器。下面的说明描述了一些示例。在尝试之前,应确保你首先关闭并且卸载了所有已有的MySQL服务器。
· 方法1:在一个标准选项文件中指定所有服务器选项。要想这样做,为每个服务器使用不同的服务名。假设你想使用服务名mysqld1运行4.1.8版的mysqld-nt并使用服务名mysqld2运行5.1.2-alpha版的mysqld-nt。在这种情况下,你可以为4.1.8使用[mysqld1]组,为5.1.2-alpha使用[mysqld2]组。例如,你可以象这样建立 C:\my.cnf文件:
· # options for mysqld1 service
· [mysqld1]
· basedir = C:/mysql-4.1.8
· port = 3307
· enable-named-pipe
· socket = mypipe1
·
· # options for mysqld2 service
· [mysqld2]
· basedir = C:/mysql-5.1.2-alpha
· port = 3308
· enable-named-pipe
· socket = mypipe2
如下面所示安装服务器,使用服务器的全路径名来确保Windows为每个服务注册正确的可执行程序:
C:\> C:\mysql-4.1.8\bin\mysqld-nt --install mysqld1
C:\> C:\mysql-5.1.2-alpha\bin\mysqld-nt --install mysqld2
为了启动服务器,使用服务管理器,或用带有适当的服务名的NET START:
C:\> NET START mysqld1
C:\> NET START mysqld2
要想停止服务,使用服务管理器,或用带有适当的服务名的NET STOP:
C:\> NET STOP mysqld1
C:\> NET STOP mysqld2
· 方法2:为每个服务器用不同的文件指定选项,当你安装服务时使用--defaults-file告诉每个服务器使用什么文件。此时,每个文件应用一个[mysqld]组列出选项。
使用这种方法为4.1.8版本的mysqld-nt指定选项,应象这样创建一个C:\my-opts1.cnf文件:
[mysqld]
basedir = C:/mysql-4.1.8
port = 3307
enable-named-pipe
socket = mypipe1
对于5.1.2-alpha版的mysqld-nt,象这样创建一个C:\my-opts2.cnf文件:
[mysqld]
basedir = C:/mysql-5.1.2-alpha port = 3308
enable-named-pipe
socket = mypipe2
安装服务如下(在一个单一行中输入每个命令):
C:\> C:\mysql-4.1.8\bin\mysqld-nt -- installmysqld1
--defaults-file=C:\my-opts1.cnf
C:\> C:\mysql-5.1.2-alpha\bin\mysqld-nt -- installmysqld2
--defaults-file=C:\my-opts2.cnf
当你作为服务安装一个MySQL服务器时,要想使用--defaults-file选项,你必须在此选项之前加服务名。
安装服务后,按照与前面的示例相同的方法启动和停止。
要想卸载多个服务,对每个服务使用mysqld --remove,在--remove选项后指定服务名。如果服务名是 默认的(MySQL),你可以不指定。