免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: luren04
打印 上一主题 下一主题

【申请加精】MySQL 5.1参考手册  关闭 [复制链接]

论坛徽章:
0
101 [报告]
发表于 2008-04-15 15:29 |只看该作者
5.9.2. 示例用备份与恢复策略
5.9.2.1. 备份策略
5.9.2.2. 为恢复进行备份
5.9.2.3. 备份策略摘要
本节讨论进行备份的程序,在出现崩溃后,可以恢复数据:
·         操作系统崩溃

·         电源故障

·         文件系统崩溃

·         硬件问题(硬盘、母板等等)

该命令不包括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 atInnoDB: log sequence number 0 13674004InnoDB: Doing recovery: scanned up to log sequence number 0 13739520InnoDB: Doing recovery: scanned up to log sequence number 0 13805056InnoDB: Doing recovery: scanned up to log sequence number 0 13870592InnoDB: Doing recovery: scanned up to log sequence number 0 13936128...InnoDB: Doing recovery: scanned up to log sequence number 0 20555264InnoDB: Doing recovery: scanned up to log sequence number 0 20620800InnoDB: Doing recovery: scanned up to log sequence number 0 20664692InnoDB: 1 uncommitted transaction(s) which must be rolled backInnoDB: Starting rollback of uncommitted transactionsInnoDB: Rolling back trx no 16745InnoDB: Rolling back of trx no 16745 completedInnoDB: Rollback of uncommitted transactions completedInnoDB: Starting an apply batch of log records to the database...InnoDB: Apply batch completedInnoDB: Startedmysqld: ready for connections如果文件系统崩溃或出现硬件问题,我们可以假定重启后硬盘上的MySQLś数据不可用。这说明MySQL未能成功启动,因为一些硬盘数据块不再可读。在这种情况下,需要重新格式化硬盘,安装一个新的,或纠正问题。然后需要从备份中恢复MySQL数据,这说明我们必须先做好备份。要想确保,应及时返回并设计备份策略。

5.9.2.1. 备份策略
我们都知道必须按计划定期进行备份。可以用几个工具完全备份(在某个时间点的数据快照)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语法”。

5.9.2.2. 为恢复进行备份
现在假设在星期三上午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文件,我们可以用它来恢复大部分最新的数据更改,而不会丢失到崩溃时的数据。

5.9.2.3. 备份策略摘要
出现操作系统崩溃或电源故障时,InnoDB自己可以完成所有数据恢复工作。但为了确保你可以睡好觉,应遵从下面的指导:

·         一定用--log-bin或甚至--log-bin=log_name选项运行MySQL服务器,其中日志文件名位于某个安全媒介上,不同于数据目录所在驱动器。如果你有这样的安全媒介,最好进行硬盘负载均衡(这样能够提高性能)。

·         定期进行完全备份,使用mysqldump命令进行在线非块备份。

·         用FLUSH LOGS或mysqladmin flush-logs清空日志进行定期增量备份。

论坛徽章:
0
102 [报告]
发表于 2008-04-15 15:30 |只看该作者
5.9.3. 自动恢复
5.9.3.1. 指定恢复时间
5.9.3.2. 指定恢复位置
如果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密码。

5.9.3.1. 指定恢复时间
对于MySQL 4.1.4,可以在mysqlbinlog语句中通过--start-date和--stop-date选项指定DATETIME格式的起止时间。举例说明,假设在今天上午10:00(今天是2005年4月20日),执行SQL语句来删除一个大表。要想恢复表和数据,你可以恢复前晚上的备份,并输入:
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前一秒钟。你应检查日志以确保时间确切。下一节介绍如何实现。

5.9.3.2. 指定恢复位置
也可以不指定日期和时间,而使用mysqlbinlog的选项--start-position和--stop-position来指定日志位置。它们的作用与起止日选项相同,不同的是给出了从日志起的位置号。使用日志位置是更准确的恢复方法,特别是当由于破坏性SQL语句同时发生许多事务的时候。要想确定位置号,可以运行mysqlbinlog寻找执行了不期望的事务的时间范围,但应将结果重新指向文本文件以便进行检查。操作方法为:
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日志将反应事务执行的原时间。

论坛徽章:
0
103 [报告]
发表于 2008-04-15 15:30 |只看该作者
5.9.4. 表维护和崩溃恢复
后面几节讨论如何使用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和服务器之间会出现不期望的相互干涉。

5.9.5. myisamchk:MyISAM表维护实用工具
5.9.5.1. 用于myisamchk的一般选项
5.9.5.2. 用于myisamchk的检查选项
5.9.5.3. myisamchk的修复选项
5.9.5.4. 用于myisamchk的其它选项
5.9.5.5. myisamchk内存使用
5.9.5.6. 将myisamchk用于崩溃恢复
5.9.5.7. 如何检查MyISAM表的错误
5.9.5.8. 如何修复表
5.9.5.9. 表优化
可以使用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来检查表。

5.9.5.1. 用于myisamchk的一般选项
本节描述的选项可以用于用myisamchk执行的任何类型的表维护操作。本节后面的章节中描述的选项只适合具体操作,例如检查或修复表。

·         --help,-?

显示帮助消息并退出。

·         --debug=debug_options, -# debug_options

输出调试记录文件。debug_options字符串经常是'd:t,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。这些语句由服务器执行,知道要使用的正确的全文参数值。

5.9.5.2. 用于myisamchk的检查选项
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选项运行时不应使用该选项。

5.9.5.3. myisamchk的修复选项
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打包的表解包。

5.9.5.4. 用于myisamchk的其它选项
myisamchk支持以下表检查和修复之外的其它操作的选项:
·         --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必须先解开打包的键块,然后重新创建索引并再次将键块打包。(在这种情况下,重新创建索引比更新每个索引的偏移量要快)。

5.9.5.5. 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。

5.9.5.6. 将myisamchk用于崩溃恢复
如果用--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前做进行备份。

论坛徽章:
0
104 [报告]
发表于 2008-04-15 15:31 |只看该作者
5.9.5.7. 如何检查MyISAM表的错误
要想检查MyISAM表,应使用下面的命令:
·         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(没有除表名以外的参数)就足够检查表了。

5.9.5.8. 如何修复表
本节描述如何对MyISAM表使用myisamchk(扩展名.MYI和.MYD)。

你还可以(并且应该,如果可能)使用CHECK TABLE和REPAIR TABLE语句来检查和修复MyISAM表。参见13.5.2.3节,“CHECK TABLE语法”和13.5.2.6节,“REPAIR TABLE语法”。

一张损坏的表的症状通常是查询意外中断并且能看到下述错误:

“tbl_name.frm”被锁定不能更改。
不能找到文件“tbl_name.MYI”(Errcode:nnn)。
文件意外结束。
记录文件被毁坏。
从表处理器得到错误nnn。
要想得到错误相关的详细信息,你可以运行perror nnn,其中nnn为错误编号。下面的示例显示了如何使用perror来找到最常用错误编号(用表的方式指出问题)的含义:

shell> perror 126 127 132 134 135 136 141 144 145126 = Index file is crashed / Wrong file format127 = Record-file is crashed132 = Old database file134 = Record was already deleted (or record file crashed)135 = No more room in record file136 = No more room in index file141 = Duplicate unique key or constraint on write or update144 = Table is crashed and last repair failed145 = 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意味着“快速恢复模式”)。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:

在继续前对数据文件进行备份。
使用myisamchk -r tbl_name(-r意味着“恢复模式”)。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。
如果前面的步骤失败,使用myisamchk --safe-recover tbl_name。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况(但是更慢)。
如果在修复时,你得到奇怪的错误(例如out of memory错误),或如果myisamchk崩溃,到阶段3。

阶段3:困难的修复

只有在索引文件的第一个16K块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:

把数据文件移到安全的地方。
使用表描述文件创建新的(空)数据文件和索引文件:
shell> mysql db_name
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
如果你的MySQL版本没有TRUNCATE TABLE,则使用DELETE FROM tbl_name。

将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)
回到阶段2。现在myisamchk -r -q应该工作了。(这不应该是一个无限循环)。

你还可以使用REPAIR TABLE tbl_name USE_FRM,将自动执行整个程序。

阶段4:非常困难的修复

只有.frm描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。

从一个备份恢复描述文件然后回到阶段3。你也可以恢复索引文件然后回到阶段2。对后者,你应该用myisamchk -r启动。
如果你没有进行备份但是确切地知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件,但是让.MYD数据文件独自留下来了。回到阶段2并且尝试重建索引文件。
5.9.5.9. 表优化
为了组合碎片记录并且消除由于删除或更新记录而浪费的空间,以恢复模式运行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表维护实用工具”。

论坛徽章:
0
105 [报告]
发表于 2008-04-15 15:35 |只看该作者
5.9.6. 建立表维护计划
定期对表进行检查而非等到问题出现后再检查数据库表是一个好主意。检查和修复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

5.9.7. 获取关于表的信息
为了获得关于一个表的描述或统计,使用下面的命令:

·         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.MYMmyisamchk -d输出示例:

MyISAM file:     company.MYIRecord format:   Fixed lengthData records:    1403698  Deleted blocks:         0Recordlength:    226 table description:Key Start Len Index   Type1   2     8   unique  double2   15    10  multip. text packed stripped3   219   8   multip. double4   63    10  multip. text packed stripped5   167   2   multip. unsigned short6   177   4   multip. unsigned long7   155   4   multip. text8   138   4   multip. unsigned long9   177   4   multip. unsigned long    193   1           textmyisamchk -d -v 输出示例:

MyISAM file:         companyRecord format:       Fixed lengthFile-version:        1Creation time:       1999-10-30 12:12:51Recover time:        1999-10-31 19:13:01Status:              checkedData records:            1403698  Deleted blocks:              0Datafile parts:          1403698  Deleted data:                0Datafile pointer (bytes):      3  Keyfile pointer (bytes):     3Max datafile length:  3791650815  Max keyfile length: 4294967294Recordlength:                226 table description:Key Start Len Index   Type                  Rec/key     Root Blocksize1   2     8   unique  double                      1 15845376      10242   15    10  multip. text packed stripped        2 25062400      10243   219   8   multip. double                     73 40907776      10244   63    10  multip. text packed stripped        5 48097280      10245   167   2   multip. unsigned short           4840 55200768      10246   177   4   multip. unsigned long            1346 65145856      10247   155   4   multip. text                     4995 75090944      10248   138   4   multip. unsigned long              87 85036032      10249   177   4   multip. unsigned long             178 96481280      1024    193   1           textmyisamchk -eis 输出示例:

Checking MyISAM file: companyKey:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4Total:    Keyblocks used:  98%  Packed:   17% Records:          1403698    M.recordlength:     226Packed:             0%Recordspace used:     100%   Empty space:          0%Blocks/Record:   1.00Record blocks:    1403698    Delete blocks:        0Recorddata:     317235748    Deleted data:         0Lost space:             0    Linkdata:             0 User time 1626.51, System time 232.36Maximum resident set size 0, Integral resident set size 0Non physical pagefaults 0, Physical pagefaults 627, Swaps 0Blocks in 0 out 0, Messages in 0 out 0, Signals 0Voluntary context switches 639, Involuntary context switches 28966myisamchk -eiv 输出示例:

Checking MyISAM file: companyData records: 1403698   Deleted blocks:       0- check file-size- check delete-chainblock_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: 1Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4- check data record references index: 2Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4- check data record references index: 3Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4- check data record references index: 4Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3- check data record references index: 5Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3- check data record references index: 6Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3- check data record references index: 7Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3- check data record references index: 8Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3- check data record references index: 9Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4Total:    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.00Record blocks:   1403698   Delete blocks:      0Recorddata:    317235748   Deleted data:       0Lost space:            0   Linkdata:           0 User time 1639.63, System time 251.61Maximum resident set size 0, Integral resident set size 0Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0Blocks in 4 out 0, Messages in 0 out 0, Signals 0Voluntary 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表”。

论坛徽章:
0
106 [报告]
发表于 2008-04-15 15:38 |只看该作者

5.10. MySQL本地化和国际应用

本节描述如何配置服务器来使用不同的字符集。还讨论如何设置服务器的时区并启用各个连接的时区支持。
5.10.1. 数据和排序用字符集
5.10.1.1. 使用德国字符集
默认情况下,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但是一般情况不需要。

5.10.1.1. 使用德国字符集
在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节,“西欧字符集”。

论坛徽章:
0
107 [报告]
发表于 2008-04-15 15:39 |只看该作者
5.10.2. 设置错误消息语言
默认情况下,mysqld用英语给出错误消息,但也可以用以下语言显示:Czech、Danish、Dutch、Estonian、French、German、Greek、Hungarian、Italian、Japanese、Korean、Norwegian、Norwegian-ny、Polish、Portuguese、Romanian、Russian、Slovak、Spanish或 Swedish。
要想在启动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文件来重新更改。

5.10.3. 添加新的字符集
本节讨论在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个字。

参见5.10.4节,“字符定义数组”。

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=MYNUMBER10.        * .configure. strxfrm_multiply_MYSET=N11.        * .configure. mbmaxlen_MYSET=N12.        */configure程序使用该注释自动将字符集包括进MySQL库中。

在下面章节中解释strxfrm_multiply和mbmaxlen 行。只有需要字符串比较函数或多字节字符集函数时,才需要单独将它们包括进来。

13.然后你应创建下面的函数:

my_strncoll_MYSET()
my_strcoll_MYSET()
my_strxfrm_MYSET()
my_like_range_MYSET()
参见5.10.5节,“字符串比较支持”

14.将字符集名添加到configurE.in的CHARSETS_AVAILABLE和COMPILED_CHARSETS列。

15.重新配置、编译并测试。

sql/share/charsets/README文件中包括详细的说明。

如果你想要MySQL分发中的字符集,请向MySQL内部邮件系统发邮件。参见1.7.1.1节,“The MySQL邮件列表”。

5.10.4. 字符定义数组
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

5.10.5. 字符串比较支持
如果语言的排序规则比较复杂,不能用简单sort_order[]表来处理,需要使用字符串比较函数。
最好的文档是已有字符集。以big5、czech、gbk、sjis和tis160字符集作为例子。

你必须在文件顶部的特殊注释处指定strxfrm_multiply_MYSET=N值。N应设置为字符串在my_strxfrm_MYSET过程中可能增长的最大比例(必须为正整数)。

5.10.6. 多字节字符支持
如果你想要添加包括多字节字符的新字符集支持,需要使用多字节字符函数。
最好的文档是已有字符集。以euc_kr、gb2312,gbk、sjis和ujis字符集作为例子。这些字符集位于strings目录的ctype-charset.c文件中。

必须在文件顶部的特殊注释处指定mbmaxlen_MYSET=N值。N应设置为字符集内最长字符的字节数。

5.10.7. 字符集问题
如果你想要使用没有编译为二进制的字符集,可能会遇到下面的问题:
·         你的程序的字符集保存路径不正确。(默认为/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检查表的字符集名和编号。

5.10.8. MySQL服务器时区支持
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 mysqlmysql_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节,“复制特性和已知问题”。

论坛徽章:
0
108 [报告]
发表于 2008-04-15 15:41 |只看该作者

5.11. MySQL日志文件

MySQL有几个不同的日志文件,可以帮助你找出mysqld内部发生的事情:

日志文件
记入文件中的信息类型

错误日志
记录启动、运行或停止mysqld时出现的问题。

查询日志
记录建立的客户端连接和执行的语句。

更新日志
记录更改数据的语句。不赞成使用该日志。

二进制日志
记录所有更改数据的语句。还用于复制。

慢日志
记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。


默认情况下,所有日志创建于mysqld数据目录中。通过刷新日志,你可以强制 mysqld来关闭和重新打开日志文件(或者在某些情况下切换到一个新的日志)。当你执行一个FLUSH LOGS语句或执行mysqladmin flush-logs或mysqladmin refresh时,出现日志刷新。参见13.5.5.2节,“FLUSH语法”。

如果你正使用MySQL复制功能,从复制服务器将维护更多日志文件,被称为接替日志。相关讨论参见第6章:MySQL中的复制。

5.11.1. 错误日志
错误日志文件包含了当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文件。

5.11.2. 通用查询日志
如果你想要知道mysqld内部发生了什么,你应该用--log[=file_name]或-l [file_name]选项启动它。如果没有给定file_name的值, 默认名是host_name.log。所有连接和语句被记录到日志文件。当你怀疑在客户端发生了错误并想确切地知道该客户端发送给mysqld的语句时,该日志可能非常有用。
mysqld按照它接收的顺序记录语句到查询日志。这可能与执行的顺序不同。这与更新日志和二进制日志不同,它们在查询执行后,但是任何一个锁释放之前记录日志。(查询日志还包含所有语句,而二进制日志不包含只查询数据的语句)。

服务器重新启动和日志刷新不会产生新的一般查询日志文件(尽管刷新关闭并重新打开一般查询日志文件)。在Unix中,你可以通过下面的命令重新命名文件并创建一个新文件:

shell> mv hostname.log hostname-old.logshell> mysqladmin flush-logsshell> cp hostname-old.log to-backup-directoryshell> rm hostname-old.log在Windows中,服务器打开日志文件期间你不能重新命名日志文件。你必须先停止服务器然后重新命名日志文件。然后,重启服务器来创建新的日志文件。

5.11.3. 二进制日志
二进制日志以一种更有效的格式,并且是事务安全的方式包含更新日志中可用的所有信息。

二进制日志包含了所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个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处理磁盘满的方式”。

5.11.4. 慢速查询日志
用--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写入慢查询日志。

用查询缓存处理的查询不加到慢查询日志中,因为表有零行或一行而不能从索引中受益的查询也不写入慢查询日志。

5.11.5. 日志文件维护
MySQL服务器可以创建各种不同的日志文件,从而可以很容易地看见所进行的操作。参见5.11节,“MySQL日志文件”。但是,你必须定期清理这些文件,确保日志不会占用太多的硬盘空间。

当启用日志使用MySQL时,你可能想要不时地备份并删除旧的日志文件,并告诉MySQL开始记入新文件。参见5.9.1节,“数据库备份”。

在 Linux (Redhat)的安装上,你可为此使用mysql-log-rotate脚本。如果你从RPM分发安装MySQL,脚本应该自动被安装了。

在其它系统上,你必须自己安装短脚本,你可从cron等入手处理日志文件。

你可以通过mysqladmin flush-logs或SQL语句FLUSH LOGS来强制MySQL开始使用新的日志文件。

日志清空操作做下列事情:

如果使用标准日志(--log)或慢查询日志(--log-slow-queries),关闭并重新打开日志文件。(默认为mysql.log和`hostname`-slow.log)。
如果使用更新日志(--log-update)或二进制日志(--log-bin),关闭日志并且打开有更高序列号的新日志文件。
如果你只使用更新日志,你只需要重新命名日志文件,然后在备份前清空日志。例如,你可以这样做:

shell> cd mysql-data-directoryshell> mv mysql.log mysql.oldshell> mysqladmin flush-logs然后做备份并删除“mysql.old”。

论坛徽章:
0
109 [报告]
发表于 2008-04-15 15:42 |只看该作者

5.12. 在同一台机器上运行多个MySQL服务器

在一些情况下,你可能想要在同一台机器上运行多个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选项。

正如下面几节所讨论的那样,可以通过设置环境变量或用指定的命令行选项来启动更多的服务器。但是,如果你需要在一个更稳定的基础上运行多个服务器,一个更方便的方法是使用选项文件来为每个服务器指定那些选项值,它对每个服务器必须是唯一的。

5.12.1. 在Windows下运行多个服务器
5.12.1.1. 在命令行中启动多个Windows服务器
5.12.1.2. 做为服务启动多个Windows服务器
在Windows中,可以从命令行手动启动来运行多个服务器,每个服务器使用合适的操作参数。在基于Windows NT的系统中,安装几个服务器时,你还有将多个服务器安装为Windows服务并运行的选项。关于从命令行运行MySQL服务器或作为服务运行的一般说明在 2.3节,“在Windows上安装MySQL”中给出。本节描述怎样确保你用不同的启动选项值(对于每个服务器必须是唯一的,例如数据目录)启动各个服务器。这些选项的描述见5.12节,“在同一台机器上运行多个MySQL服务器”。

5.12.1.1. 在命令行中启动多个Windows服务器
为了从命令行手动启动多个服务器,可以在命令行中或在选项文件中指定适当的选项。把选项放在选项文件中比较方便,但是需要确保每个服务器可以获得自己的选项。为了实现,为每个创建一个选项文件,并且运行服务时通过--defaults-file选项告诉服务器选项文件名。
假设你想要在端口3307使用数据目录C:\mydata1运行mysqld,并且想在端口3308使用数据目录C:\mydata1运行mysqld-max。(要想这样做,启动服务器之前要确保,每个数据目录存在并且有自己的mysql数据库拷贝,它包含 授权表)。

然后创建两个选项文件。例如,创建一个文件名为C:\my-opts1.cnf的配置文件,它看起来象这个样子:

[mysqld]datadir = C:/mydata1port = 3307创建第二个文件名为C:\my-opts1.cnf的配置文件,它看起来象这个样子:

mysqld]datadir = C:/mydata2port = 3308然后,用它们自己的选项文件启动每个服务器:

C:\> C:\mysql\bin\mysqld --defaults-file=C:\my-opts1.cnfC:\> 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:/mydata1port = 3307enable-named-pipesocket = mypipe1然后,这样启动服务器:

C:\> C:\mysql\bin\mysqld-nt --defaults-file=C:\my-opts1.cnf同样修改第2个服务器使用的C:\my-opts2.cnf文件。

5.12.1.2. 做为服务启动多个Windows服务器
在基于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 mysqld1C:\> 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 mysqld1C:\> NET STOP mysqld2·         方法2:为每个服务器用不同的文件指定选项,当你安装服务时使用--defaults-file告诉每个服务器使用什么文件。此时,每个文件应用一个[mysqld]组列出选项。

使用这种方法为4.1.8版本的mysqld-nt指定选项,应象这样创建一个C:\my-opts1.cnf文件:

[mysqld]basedir = C:/mysql-4.1.8port = 3307enable-named-pipesocket = mypipe1对于5.1.2-alpha版的mysqld-nt,象这样创建一个C:\my-opts2.cnf文件:

[mysqld]basedir = C:/mysql-5.1.2-alpha port = 3308enable-named-pipesocket = mypipe2安装服务如下(在一个单一行中输入每个命令):

C:\> C:\mysql-4.1.8\bin\mysqld-nt -- installmysqld1           --defaults-file=C:\my-opts1.cnfC:\> C:\mysql-5.1.2-alpha\bin\mysqld-nt -- installmysqld2           --defaults-file=C:\my-opts2.cnf当你作为服务安装一个MySQL服务器时,要想使用--defaults-file选项,你必须在此选项之前加服务名。

安装服务后,按照与前面的示例相同的方法启动和停止。

要想卸载多个服务,对每个服务使用mysqld --remove,在--remove选项后指定服务名。如果服务名是 默认的(MySQL),你可以不指定。

5.12.2. 在Unix中运行多个服务器
在Unix中运行多个服务器最容易的方法是使用不同的TCP/IP端口s和Unix套接字文件编译,因此每个实例在不同的网络接口侦听。另外,每个安装应在不同的基础目录中编译,那将自动为你的每个服务器产生使用不同的编译进来的数据目录、日志文件和PID文件位置。

假设一个现有的4.1.8版本服务器配置为默认TCP/IP端口号(3306)和Unix套接字文件(/tmp/mysql.sock)。要想配置一个新的5.1.2-alpha版的服务器来使用不同的操作参数,使用一个configure命令,大概象这样使用:

shell> ./configure --with-tcp-port=port_number \             --with-unix-socket-path=file_name \             --prefix=/usr/local/mysql-5.1.2-alpha这里,port_number和file_name必须不同于默认TCP/IP端口号和Unix套接字文件路径名,并且--prefix值应指定一个不同于现有MySQL安装目录的安装目录。

如果你有一个MySQL服务器正侦听一个给定的端口号,你可以使用下面的命令来找出针对一些重要配置变量它使用了那些操作参数,包括基础目录和Unix套接字文件名:

shell> mysqladmin --host=host_name --port=port_number variables通过该命令显示的信息,当配置其它服务器时,你可以告诉服务器该选项没有使用的值。

请注意,如果你指定localhost作为一个主机名,mysqladmin默认使用Unix套接字文件连接,而不是TCP/IP。从 MySQL 4.1开始,通过--protocol= TCP | SOCKET | PIPE | MEMORY}选项,你可以显示地指定连接协议。

如果只是用一个不同的Unix套接字文件和TCP/IP端口号启动,不必编译新的MySQL服务器。还可以在运行时指定这些值。这样做的一个方法是使用命令行选项:

shell> mysqld_safe --socket=file_name --port=port_number要启动第二个服务器,提供不同的--socket和--port选项值,并且传递一个--datadir=path选项给mysqld_safe,以便服务器使用一个不同的数据目录。

达到相似效果的另一个方法是使用环境变量来设置 Unix套接字文件名和TCP/IP端口号:

shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sockshell> MYSQL_TCP_PORT=3307shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORTshell> mysql_install_db --user=mysqlshell> mysqld_safe --datadir=/path/to/datadir &这是一个快速启动第二个服务器以用于测试的方法。该方法的最大好处是环境变量设定值适用于你从相同的shell调用的任何客户端程序。因而,那些客户端连接自动指向第二个服务器!

附录F:环境变量包括你可以使用的影响mysqld的其它环境变量列表。

对于自动服务器启动,对于每个服务器,机器引导时执行的启动脚本应执行下面的命令,每个命令用一个相应的选项文件路径:

mysqld_safe --defaults-file=path每个选项文件应包含一个给定服务器特定的选项值。

在Unix中,mysqld_multi脚本是启动多个服务器的另一个方法。参见5.1.5节,“mysqld_multi:管理多个MySQL服务器的程序”。

5.12.3. 在多服务器环境中使用客户端程序
当你想要用一个客户端程序连接一个MySQL服务器时,该服务器侦听不同的网络接口,而不是编译到你的客户端的网络接口,你可以使用下面的方法:

·         启动客户端,用--host=host_name --port=port_number通过TCP/IP来连接一个远程服务器,用--host=127.0.0.1 --port=port_number通过TCP/IP来连接一个本地服务器,或者用--host=localhost --socket=file_name通过一个Unix套接字文件或一个Windows命名管道来连接一个本地服务器。

·         从MySQL 4.1起,启动客户端时用--protocol=tcp通过TCP/IP来连接,用--protocol=socket通过一个Unix套接字文件来连接,用--protocol=pipe通过一个命名管道来连接,或用--protocol=memory通过共享内存来连接。对于TCP/IP连接,你可能还需要指定--host和--port选项。对于其它类型的连接,你可能需要指定一个--socket选项来指定一个Unix套接字文件或命名管道名,或者一个--shared-memory-base-name选项来指定共享内存名。共享内存连接仅在Windows中支持。

·         在Unix中,在你启动客户端之前,设置MYSQL_UNIX_PORT和MYSQL_TCP_PORT环境变量来指定Unix套接字文件和TCP/IP端口号。如果你经常使用具体的套接字文件或端口号,你可以在.login文件中放置命令来设置环境变量以便你每次登录时该命令起作用。参见附录F:环境变量。

·         在一个选项文件的[client]组中指定默认Unix套接字文件和TCP/IP端口号。例如,你可以在Windows中使用C:\my.cnf文件,或在Unix中主目录内使用.my.cnf文件。参见4.3.2节,“使用选项文件”。

·         在C程序中,在mysql_real_connect()调用时,你可以指定套接字文件或端口号参数。通过调用mysql_options(),你还可以有程序读选项文件。参见25.2.3节,“C API函数描述”。

·         如果你正在使用Perl DBD::mysql模块,你可以从MySQL选项文件中读取选项。例如:

·                $dsn = "DBI:mysql:test;mysql_read_default_group=client;"·                        . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";·                    $dbh = DBI->connect($dsn, $user, $password);参见25.4节,“MySQL Perl API”。

其它程序接口可以为读选项文件提供相似的功能。

论坛徽章:
0
110 [报告]
发表于 2008-04-15 15:43 |只看该作者

5.13. MySQL查询高速缓冲

查询缓存存储SELECT查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。

如果你有一个不经常改变的表并且服务器收到该表的大量相同查询,查询缓存在这样的应用环境中十分有用。对于许多Web服务器来说存在这种典型情况,它根据数据库内容生成大量的动态页面。

注释:查询缓存不返回旧的数据。当表更改后,查询缓存值的相关条目被清空。

注释:如果你有许多mysqld服务器更新相同的MyISAM表,在这种情况下查询缓存不起作用。

注释:查询缓存不适用于服务器方编写的语句。如果正在使用服务器方编写的语句,要考虑到这些语句将不会应用查询缓存。参见 25.2.4节,“C API预处理语句”。

下面是查询缓存的一些性能数据。这些结果是在Linux Alpha 2 x 500MHz系统(2GB RAM,64MB查询缓存)上运行MySQL基准组件产生的。

·         如果执行的所有查询是简单的(如从只有一行数据的表中选取一行),但查询是不同的,查询不能被缓存,查询缓存激活率是13%。这可以看作是最坏的情形。在实际应用中,查询要复杂得多,因此,查询缓存使用率一般会很低。

·         从只有一行的表中查找一行数据时,使用查询缓存比不使用速度快238%。这可以看作查询使用缓存时速度提高最小的情况。

服务器启动时要禁用查询缓存,设置query_cache_size系统变量为0。禁用查询缓存代码后,没有明显的速度提高。编译MySQL时,通过在configure中使用--without-query-cache选项,可以从服务器中彻底去除查询缓存能力。

5.13.1. 查询高速缓冲如何工作
本节描述查询缓存的工作原理。5.13.3节,“查询高速缓冲配置”描述了怎样控制是否使用查询缓存。

查询解析之前进行比较,因此下面的两个查询被查询缓存认为是不相同的:

SELECT * FROM tbl_nameSelect * from tbl_name查询必须是完全相同的(逐字节相同)才能够被认为是相同的。另外,同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。

从查询缓存中提取一个查询之前,MySQL检查用户对所有相关数据库和表的SELECT权限。如果没有权限,不使用缓存结果。

如果从查询缓存中返回一个查询结果,服务器把Qcache_hits状态变量的值加一,而不是Com_select变量。参见5.13.4节,“查询高速缓冲状态和维护”。

如果一个表被更改了,那么使用那个表的所有缓冲查询将不再有效,并且从缓冲区中移出。这包括那些映射到改变了的表的使用MERGE表的查询。一个表可以被许多类型的语句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。

COMMIT执行完后,被更改的事务InnoDB表不再有效。

使用InnoDB表时,查询缓存也在事务中工作,使用该表的版本号来检测其内容是否仍旧是当前的。

在MySQL 5.1中,视图产生的查询被缓存。

SELECT SQL_CALC_FOUND_ROWS ...和SELECT FOUND_ROWS() type类型的查询使用查询缓存。即使因创建的行数也被保存在缓冲区内,前面的查询从缓存中提取,FOUND_ROWS()也返回正确的值。

如果一个查询包含下面函数中的任何一个,它不会被缓存:

BENCHMARK()
CONNECTION_ID()
CURDATE()

CURRENT_DATE()
CURRENT_TIME()
CURRENT_TIMESTAMP()

CURTIME()
DATABASE()
带一个参数的ENCRYPT()

FOUND_ROWS()
GET_LOCK()
LAST_INSERT_ID()

LOAD_FILE()
MASTER_POS_WAIT()
NOW()

RAND()
RELEASE_LOCK()
SYSDATE()

不带参数的UNIX_TIMESTAMP()
USER()
  


在下面的这些条件下,查询也不会被缓存:

·         引用自定义函数(UDFs)。

·         引用自定义变量。

·         引用mysql系统数据库中的表。

·         下面方式中的任何一种:

SELECT ...IN SHARE MODESELECT ...FOR UPDATESELECT ...INTO OUTFILE ...SELECT ...INTO DUMPFILE ...SELECT * FROM ...WHERE autoincrement_col IS NULL最后一种方式不能被缓存是因为它被用作为ODBC工作区来获取最近插入的ID值。参见26.1.14.1节,“如何在ODBC中获取AUTO_INCREMENT列的值”。

·          被作为编写好的语句,即使没有使用占位符。例如,下面使用的查询:

char *my_sql_stmt = "SELECT a,b FROM table_c";   /* ...*/mysql_stmt_prepare(stmt,my_sql_stmt,strlen(my_sql_stmt));不被缓存。参见25.2.4节,“C API预处理语句”。

·         使用TEMPORARY表。

·         不使用任何表。

·         用户有某个表的列级权限。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP