A. 问题和常见错误 / A.2. 使用MySQL程序时的常见错误

A.2. 使用MySQL程序时的常见错误

A.2.1. 拒绝访问
A.2.2. 无法连接到[local] MySQL服务器
A.2.3. 客户端不支持鉴定协议
A.2.4. 输入密码时出现密码错误
A.2.5. 主机的host_name被屏蔽
A.2.6. 连接数过多
A.2.7. 内存溢出
A.2.8. MySQL服务器不可用
A.2.9. 信息包过大
A.2.10. 通信错误和失效连接
A.2.11. 表已满
A.2.12. 无法创建文件/写入文件
A.2.13. 命令不同步
A.2.14. 忽略用户
A.2.15. 表tbl_name不存在
A.2.16. 无法初始化字符集
A.2.17. 文件未找到

本节列出了用户运行MySQL服务器时常会遇到的一些错误。尽管问题是在你尝试运行客户端时出现的,但对很多问题的解决方案来说,需要更改MySQL服务器的配置。

A.2.1. 拒绝访问

导致拒绝访问错误的原因很多。该错误常与连接时服务器允许客户端使用的MySQL账户有关。请参见5.7.8节,“拒绝访问错误的原因。请参见5.7.2节,“权限系统工作原理”

A.2.2. 无法连接到[local] MySQL服务器

A.2.2.1. 在Windows上与MySQL服务器的连接失败

Unix平台上的MySQL客户端能够以两种不同的方式连接到mysqld服务器:通过文件系统中的文件(默认为/tmp/mysql.sock)使用Unix套接字进行连接,或通过端口号使用TCP/IP进行连接。Unix套接字文件的连接速度比TCP/IP快,但仅能在与相同计算机上的服务器相连时使用。如果未指定指定主机名或指定了特殊的主机名localhost,将使用Unix套接字。

如果MySQL服务器运行在Windows 9xMe上,仅能通过TCP/IP进行连接。如服务器运行在Windows NT2000XP2003上,而且使用--enable-named-pipe选项启动,如果在运行服务器的机器上运行客户端,也能使用命名管道进行连接。默认情况下,命名管道的名称为MySQL。如果在连接到mysqld时未给定主机名,MySQL客户端首先会尝试连接到命名管道。如果不能工作,将连接到TCP/IP端口。使用“.”作为主机名,可在Windows平台上强制使用命名管道。

错误(2002)“无法连接到…”通常意味着在系统没有运行的MySQL服务器,或在连接到服务器时使用了不正确的Unix套接字文件名或TCP/IP端口号。

首先检查服务器主机上是否有名为mysqld的进程(在Unix平台上使用ps xa | grep mysqld,或在Windows平台上使用任务管理器)。如果没有这类进程,应启动服务器。请参见2.9.2.3节,“启动MySQL服务器以及其故障诊断和排除”

如果mysqld进程正在运行,可使用下述命令检查。在你的具体设置中,端口号或Unix套接字文件名可能会有所不同。host_ip代表运行服务器的机器的IP编号。

shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h host_ip version
shell> mysqladmin --protocol=socket --socket=/tmp/mysql.sock version

注意,应与主机名命令一起使用“`”而不是“’”,这会使主机名输出(当前主机名)被代入mysqladmin命令。如果没有主机名命令或正运行在Windows平台上,应以手动方式输入机器的主机名(无“`”符号),后跟-h选项。也可以使用TCP/IP协议用-h 127.0.0.1连接到本地主机。

下面给出了一些“无法连接到本地MySQL服务器”错误的可能原因:

1.    Mysqld未运行。请检查操作系统的进程列表以确保mysqld进程正在运行。

2.    你正在具有很多TCP/IP连接的Windows平台上运行MySQL服务器。如果你的客户端经常出现错误,请参见A.2.2.1节,“在Windows上与MySQL服务器的连接失败”,以找出规避方法。

3.    你正在使用MIT-pthreads的系统上运行。如果你正在运行不具有固有线程的操作系统,mysqld将使用MIT-pthreads软件包。请参见2.1.1节,“MySQL支持的操作系统”。但是,并非所有的MIT-pthreads版本均支持Unix套接字文件。在不支持套接字文件的系统上,连接到服务器时,必须明确指定主机名。请使用下述命令来检查是否连接到了服务器:

4.           shell> mysqladmin -h `hostname` version

5.    某人移动了mysqld使用的Unix套接字文件(默认为/tmp/mysql.sock)。例如,你可能执行了将旧文件从/tmp目录删除的cron任务。你总能执行mysqladmin version来检查mysqladmin试图使用的Unix套接字文件是否的确存在。在该情况下,更正方式是更改cron任务,不删除mysql.sock文件,或将套接字文件置于其他地方。请参见A.4.5节,“如何保护或更改MySQL套接字文件/tmp/mysql.sock

6.    你使用--socket=/path/to/socket选项启动了mysqld服务器,当忘记将套接字文件的新名称通知客户端程序。如果更改了关于服务器的套接字路径,也必须通知MySQL客户端。可在运行客户端程序时使用相同的—socket选项来完成该任务。此外,你还应确保客户端具有访问文件mysql.sock的权限。要想找出套接字文件的位置,可使用:

7.           shell> netstat -ln | grep mysql

请参见A.4.5节,“如何保护或更改MySQL套接字文件/tmp/mysql.sock

8.    你正在使用Linux而且1个服务器线程已死亡(内核已清除)。在此情况下,在重启MySQL服务器之前,必须杀死其他mysqld线程(例如,使用killmysql_zap脚本)。请参见A.4.2节,“如果MySQL依然崩溃,应作些什么”

9.    服务器或客户端程序不具有访问包含Unix套接字文件的目录或套接字文件本身的恰当权限。在该情况下,必须更改目录或套接字文件的访问权限,以便服务器或客户端程序能够访问它们,或用–socket选项重启mysqld,在该选项中指定服务器能创建、而且客户端可访问的目录下的套接字文件名。

如果遇到错误消息“无法连接到some_host上的MySQL服务器”,可尝试采取下述步骤以找出问题所在:

·         执行“telnet some_host 3306并按两次回车键,检查服务器是否运行在该主机上(3306是默认的MySQL端口号。如果你的服务器正在监听不同的端口,请更改该值)。如果有1MySQL服务器正在运行并监听该端口,你应收到包含服务器版本号的回应。如果遇到错误,如“telnet:无法连接到远程主机:拒绝连接,表示在该定端口上没有运行的服务器。

·         如果服务器正运行在本地主机上,请使用Unix套接字文件,并使用mysqladmin -h localhost variables进行连接。验证服务器监听的TCP/IP端口号(它是port变量的值)。

·         确保你的mysqld服务器未用--skip-networking选项启动。如果使用了该选项,将无法使用TCP/IP连接到它。

·         检查并确认不存在屏蔽了对MySQL访问的防火墙。需要配置诸如ZoneAlarmWindows XP个人防火墙等应用程序,以允许对MySQL服务器的外部访问。

A.2.2.1. 在Windows上与MySQL服务器的连接失败

当你在具有很多TCP/IP连接的Windows上运行MySQL服务器,并经常在客户端上遇到“无法连接到MySQL服务器”错误时,可能是因为Windows不允许足够的临时(短命)端口用于这类连接。

默认情况下,Windows允许用于使用5000个临时(短命)TCP端口。任何端口关闭后,它将在TIME_WAIT状态保持120秒。与重新初始化全新的连接相比,该状态允许以更低的开销重新使用连接。但是,在该时间逝去前,无法再次使用该端口。

对于小的可用TCP端口堆栈(5000),以及具有TIME_WAIT状态的大量在短时间内打开和关闭的TCP端口,你很可能遇到端口耗尽问题。处理该问题的方法有两种:

·         通过调查连接池以及可能的持久连接,减少快速消耗的TCP端口数。

·         调整Windows注册表中的某些设置(请参见下面)。

要点:下述步骤涉及更改Windows 注册表。更改注册表之前,请备份注册表,并确认你已掌握在出现问题时恢复注册表的方法。关于备份年、恢复和编辑注册表的更多信息,请请参见Microsoft知识库中的下述文献:http://support.microsoft.com/kb/256986/EN-US/

·         启动注册表编辑器(Regedt32.exe)。

·         在注册表中确定下述键值的位置:

·                HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

·         在“编辑”菜单上点击“添加值”,然后增加下述注册值:

·                Value Name: MaxUserPort
·                Data Type: REG_DWORD
·                Value: 65534

它用于设置为任何用户提供的临时端口数。有效范围介于500065534之间(十进制)。默认值为0x13885000,十进制)。

·         在“编辑”菜单上点击“添加值”,然后增加下述注册值:

·                Value Name: TcpTimedWaitDelay
·                Data Type: REG_DWORD
·                Value: 30

它用于设置关闭之前将TCP端口连接保持在TIME_WAIT状态的秒数。有效范围介于0秒和300秒之间。默认值为0x78120秒)。

·         退出注册表编辑器。

·         重新引导机器。

注释:撤销上述设置十分简单,就像删除你创建的注册表一样。

A.2.3. 客户端不支持鉴定协议

MySQL 5.1采用了基于密码混编算法的鉴定协议,它与早期客户端(4.1之前)使用的协议不兼容。如果你将服务器升级到4.1之上,用早期的客户端进行连接可能失败,并给出下述消息:

shell> mysql
客户端不支持服务器请求的鉴定协议:请考虑升级MySQL客户端。

要想解决该问题,应使用下述方法之一:

·         升级所有的客户端程序,以使用4.1.1或更新的客户端库。

·         4.1版之前的客户端连接到服务器时,请使用仍具有4.1版之前风格密码的账户。

·         对于需要使用4.1版之前的客户端的每位用户,将密码恢复为4.1版之前的风格。可以使用SET PASSWORD语句和OLD_PASSWORD()函数完成该任务:

·                mysql> SET PASSWORD FOR
·                    -> 'some_user'@'some_host' = OLD_PASSWORD('newpwd');

也可以使用UPDATEFLUSH PRIVILEGES

mysql> UPDATE mysql.user SET Password = OLD_PASSWORD('newpwd')
    -> WHERE Host = 'some_host' AND User = 'some_user';
mysql> FLUSH PRIVILEGES;

用你打算使用的密码替换前例中的“newpwd”。MySQL不能告诉你原来的密码是什么,因此,你需要选择新的密码。

·         通知服务器使用旧的密码混编算法:

1.    使用“--old-passwords”选项启动mysqld

2.    对于已将密码更新为较长4.1格式的每个账户,为其指定具有旧格式的密码。可以使用下述查询确定这些账户:

3.                 mysql> SELECT Host, User, Password FROM mysql.user
4.                     -> WHERE LENGTH(Password) > 16;

对于查询显示的每个账户记录,请使用HostUser值,并使用OLD_PASSWORD()函数以及SET PASSWORDUPDATE之一指定密码,如前面所介绍的那样。

注释:在早期的PHP版本中,mysql扩展不支持MySQL 4.1.1和更高版中的鉴定协议。无论使用的PHP版本是什么,它均是正确的。如果你打算与MySQL 4.1或更高版本一起使用mysql扩展,需要使用前面介绍的选项之一,配置MySQL,以便与较早的客户端一起使用。mysqli扩展(支持改进的MySQL”,在PHP 5中增加)与MySQL 4.1和更高版本中使用的改进的密码混编算法兼容,不需要对MySQL进行特殊配置就能使用该MySQL客户端库。关于mysqli扩展的更多信息,请参见http://php.net/mysqli

关于密码混编和鉴定功能的额外背景知识,请参见5.7.9节,“MySQL 4.1中的密码哈希处理”

A.2.4. 输入密码时出现密码错误

使用无下述密码值的“—password”-p”选项调用时,MySQL客户端程序将提示输入密码:
shell> mysql -u user_name -p
Enter password:

在某些系统上,当你在选项文件或命令行上指定时,你可能会发现密码能够工作,但是当你在“Enter password:”提示下以交互方式输入密码时,你可能会发现输入的密码不工作。当系统所提供的用于读取密码的库将密码值限定在少数字符时(典型情况下为8个),就会出现该问题。这是与系统库有关的问题,与MySQL无关。要想处理该问题,可将MySQL密码更改为由8个字符或更少字符构成的值,或将密码置于选项文件中。

A.2.5. 主机的host_name被屏蔽

如果遇到下述错误,表示mysqld已收到来来自主机“host_name”的很多连接请求,但该主机却在中途中断。

由于出现很多连接错误,主机'host_name'被屏蔽。
可使用'mysqladmin flush-hosts'解除屏蔽。

允许的中断连接请求的数目由max_connect_errors系统变量的值决定。当超出max_connect_errors规定的连接请求时,mysqld将认为某处出错(例如,某人正试图插入),并屏蔽主机的进一步连接请求,直至执行了mysqladmin flush-hosts命令,或发出了FLUSH HOSTS语句为止。请参见5.3.3节,“服务器系统变量”

在默认情况下,mysqld会在10次连接错误后屏蔽主机。你可以通过下述方式启动服务器来调整该值:

shell> mysqld_safe --max_connect_errors=10000 &

如果在给定主机上遇到该错误,首先应核实该主机的TCP/IP连接是否正确。如果存在网络问题,增加max_connect_errors变量的值不会有任何好处。

A.2.6. 连接数过多

当你试图连接到mysqld服务器时遇到“过多连接”错误,这表示所有可用的连接均已被其他客户端使用。

允许的连接数由max_connections系统变量控制。默认值为100。如果需要支持更多的连接,应使用该变量的较大值重启mysqld

mysqld实际上允许max_connections+1个客户端进行连接。额外的连接保留给具有SUPER权限的账户。通过为系统管理员而不是普通用户授予SUPER权限(普通用户不应具有该权限),系统管理员能够连接到服务器,并使用SHOW PROCESSLIST来诊断问题,即使已连接的无特权客户端数已达到最大值也同样。请参见13.5.4.16节,“SHOW PROCESSLIST语法”

MySQL能支持的最大连接数取决于给定平台上线程库的质量。LinuxSolaris应能支持500-1000个并发连接,具体情况取决于RAM容量,以及客户端正在作什么。MySQL AB提供的静态Linux库能支持高达4000个连接。

A.2.7. 内存溢出

如果使用mysql客户端程序发出了查询,并收到下述错误之一,则表示mysql没有足够内存来保存全部查询结果:

mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
错误2008: MySQL client ran out of memory

要想更正该问题,首先应检查查询是否正确。返回这么多行是否合理?如果不合理,更正查询并再次尝试。否则,应使用“--quick”选项调用mysql。这样,将使用mysql_use_result() C API函数来检索结果集,这类函数能够降低客户端上的负载(但会加重服务器上的负载)。

A.2.8. MySQL服务器不可用

在本节中,还介绍了出现查询错误期间,与丢失了服务器连接有关的事宜。

MySQL服务器不可用错误的最常见原因是服务器超时以及连接已关闭。在该情况下,通常能见到下述错误代码之一(具体的错误代码与操作系统有关):

错误代码

描述

CR_SERVER_GONE_ERROR

客户端无法将问题发送至服务器。

CR_SERVER_LOST

写入服务器时客户端未收到错误,但也未获得问题的完整答案(或任何答案)。

在默认情况下,如果未发生任何事,8小时后服务器将关闭连接。也可以在启动mysqld时,通过设置wait_timeout变量更改时间限制。请参见5.3.3节,“服务器系统变量”.

如果有1个脚本,你仅需要再次发出查询,让客户端再次进行自动连接即可。其中,假定在客户端中启用了自动再连接功能(对于mysql命令行客户端,这是默认设置)。

MySQL服务器不可用错误的一些其他常见原因如下:

·         你(或db系统管理员)使用KILL语句或mysqladmin kill命令杀死了正在运行的线程。

·         你试图在关闭了与服务器的连接后运行查询。这表明应更正应用程序中的逻辑错误。

·         你在客户端一侧遇到TCP/IP连接超时错误。如果你使用了命令:mysql_options(..., MYSQL_OPT_READ_TIMEOUT,...)mysql_options(..., MYSQL_OPT_WRITE_TIMEOUT,...),就可能出现该问题。在该情况下,增加超时值可能有助于问题的解决。

·         你在服务器端遇到超时错误,而且禁止了客户端中的自动再连接功能(MYSQL结构中的再连接标志等于0)。

·         你正在使用Windows客户端,而且在发出命令之前服务器撤销了连接(或许是因为已超过wait_timeout

Windows平台上出现问题的原因,在某些情况下,将TCP/IP连接写入服务器时,MySQL未收到来自操作系统的错误,但当试图从连接读取答案时出现错误。

在该情况下,即使MYSQL结构中的再连接标志等于1MySQL也不会执行自动再连接并再次发出查询,这是因为它不知道服务器是否收到原始查询。

对此的解决方式是:如果自上一次查询以来经过了较长时间,在连接上执行mysql_ping(正是MyODBC所作的);或在mysqld服务器上将wait_timeout设置得很高,使之实际上不存在超时。

·         如果你向服务器发出了不正确或过大的查询,也会遇到这类问题。如果mysqld收到过大或无序的信息包,它会认为客户端出错,并关闭连接。如果需要执行较大的查询(例如,正在处理大的BLOB列),可通过设置服务器的max_allowed_packet变量,增加查询限制值,该变量的默认值为1MB。或许,你还需增加客户端上的最大信息包大小。关于设置信息包大小的更多信息,请参见A.2.9节,“信息包过大”

·         如果你的客户端低于4.0.8而且你的服务器高于4.0.8,当你接收16MB或更大的信息包时,可能会丢失连接。

·         如果MySQL是用“--skip-networking”选项启动的,也会见到MySQL服务器不可用错误。

·         你遇到了执行查询时服务器宕机的缺陷。

通过执行mysqladmin version并检查服务器的正常工作时间,可检查服务器是否宕机并重启。如果客户端连接是因mysqld崩溃和重启而断开的,应将重点放在查找崩溃你方面。首先应再次检查发出的查询是否再次杀死了服务器。请参见A.4.2节,“如果MySQL依然崩溃,应作些什么”

用“--log-warnings=2选项启动mysqld,可获得关于连接的更多信息。这样,就能将某些断开连接错误记录到hostname.err文件中。请参见5.11.1节,“错误日志”

如果你打算创建与该问题有关的缺陷报告,务必包含下述信息:

1.    指明MySQL服务器是否宕机。通过服务器错误日志可发现这方面的信息。请参见A.4.2节,“如果MySQL依然崩溃,应作些什么”

2.    如果特定查询杀死了mysqld,而且在运行查询前用CHECK TABLE检查了涉及的表,你是否能提供可重复的测试范例?请参见E.1.6节,“如果出现表崩溃,请生成测试案例”

3.    MySQL服务器中,系统变量wait_timeout的值是什么?mysqladmin variables给出了该变量的值)。

4.    你是否尝试使用“--log”选项来运行mysqld,以确定是否在日志中出现问题?

另请参见A.2.10节,“通信错误和失效连接”

请参见1.7.1.2节,“请教问题或通报缺陷”

A.2.9. 信息包过大

通信信息包是发送至MySQL服务器的单个SQL语句,或发送至客户端的单一行。

MySQL 5.1服务器和客户端之间最大能发送的可能信息包为1GB

MySQL客户端或mysqld服务器收到大于max_allowed_packet字节的信息包时,将发出信息包过大错误,并关闭连接。对于某些客户端,如果通信信息包过大,在执行查询期间,了能回遇到丢失与MySQL服务器的连接错误。

客户端和服务器均有自己的max_allowed_packet变量,因此,如你打算处理大的信息包,必须增加客户端和服务器上的该变量。

如果你正在使用mysql客户端程序,其max_allowed_packet变量的默认值为16MB。要想设置较大的值,可用下述方式启动mysql

mysql> mysql --max_allowed_packet=32M

它将信息包的大小设置为32MB

服务器的默认max_allowed_packet值为1MB。如果服务器需要处理大的查询,可增加该值(例如,如果准备处理大的BLOB列)。例如,要想将该设置为16MB,可采用下述方式启动服务器:

mysql> mysqld --max_allowed_packet=16M

也能使用选项文件来设置max_allowed_packet要想将服务器的该变量设置为16MB,可在选项文件中增加下行内容:

[mysqld]
max_allowed_packet=16M

增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或mysqld必须返回大的结果行时mysqld才会分配更多内存。该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。

如果你正是用大的BLOB值,而且未为mysqld授予为处理查询而访问足够内存的权限,也会遇到与大信息包有关的奇怪问题。如果怀疑出现了该情况,请尝试在mysqld_safe脚本开始增加ulimit -d 256000,并重启mysqld

A.2.10. 通信错误和失效连接

对于连接问题,服务器错误日志是有用的信息源。请参见5.11.1节,“错误日志”。如果服务器是用“--log-warnings”选项启动的,在错误日志中可能会发现下述消息:

010301 14:38:23  Aborted connection 854 to db: 'users' user: 'josh'

如果“Aborted connections”(放弃连接)消息出现在错误日志中,可能的原因是:

1.    客户端程序在退出之前未调用mysql_close()

2.    客户端的空闲时间超过wait_timeoutinteractive_timeout秒,未向服务器发出任何请求。请参见5.3.3节,“服务器系统变量”

3.    客户端在数据传输中途突然结束。

出现这类情况时,服务器将增加“Aborted_clients”(放弃客户端)状态变量。

出现下述情况时,服务器将增加“Aborted_clients”(放弃客户端)状态变量。

·         客户端不具有连接至数据库的权限。

·         客户端采用了不正确的密码。

·         连接信息包不含正确信息。

·         获取连接信息包的时间超过connect_timeout秒。请参见5.3.3节,“服务器系统变量”

如果出现这类情况,可能表明某人正试图侵入你的服务器!

对于放弃客户端或放弃连接问题,其他可能的源应包括:

·         Linux一起使用以太网协议,半双工或全双工。很多Linux以太网驱动均存在该缺陷。应通过FTP在客户端和服务器机器之间传输大文件来测试该缺陷。如果传输处于burst-pause-burst-pause(爆发-暂停-爆发-暂停)模式,表明你遇到了Linux双工故障。唯一的解决方法是,将网卡和Hub/交换器的双工模式切换为全双工或半双工,并对结果进行测试以确定最佳设置。

·         与线程库有关的某些问题导致读取中断。

·         配置不良的TCP/IP

·         有问题的以太网、Hub、交换器、电缆等。仅能通过更换硬件才能恰当诊断。

·         变量max_allowed_packet过小或查询要求的内存超过为mysqld分配的内存。请参见A.2.9节,“信息包过大”

另请参见A.2.8节,“MySQL服务器不可用”

A.2.11. 表已满

表已满错误出现的方式有数种:

·         你正在使用低于3.23版的MySQL服务器,而且“内存中”临时表超过了tmp_table_size字节。要想避免该问题,可使用“-O tmp_table_size=val”选项以便mysqld增加临时表的大小,或在发出有问题的查询之前,使用SQL选项SQL_BIG_TABLES请参见13.5.3节,“SET语法”

也可以使用“--big-tables”选项启动mysqld。它与使用针对所有查询的SQL_BIG_TABLES完全相同。

MySQL 3.23起,该问题应不再出现。如果“内存中”临时表超过tmp_table_size,服务器会自动将其转换为基于磁盘的MyISAM表。

·         你正在使用InnoDB表,并超出了InnoDB表空间。在该情况下,解决方法是增加InnoDB表空间。请参见15.2.7节,“添加和删除InnoDB数据和日志文件

·         你正在仅支持2GB文件的操作系统上使用ISAMMyISAM表,数据文件或索引文件达到了该限制值。

·         你正在使用MyISAM表,而且表所需的空间超过内部指针允许的大小。如果在创建表时未指定MAX_ROWS表,MySQL将使用myisam_data_pointer_size系统变量。默认值为6字节,它足以容纳65536TB数据。请参见5.3.3节,“服务器系统变量”

使用该语句,可检查最大数据/索引大小:

SHOW TABLE STATUS FROM database LIKE 'tbl_name';

也可以使用myisamchk -dv /path/to/table-index-file

如果指针大小过小,可使用ALTER TABLE更正该问题:

ALTER TABLE tbl_name MAX_ROWS=1000000000 AVG_ROW_LENGTH=nnn;

仅应为具有BLOBTEXT列的表指定AVG_ROW_LENGTH在该情况下,MySQL不能仅根据行数优化所需的空间。

A.2.12. 无法创建文件/写入文件

如果对某些查询遇到下述类型的错误,它意味着MySQL不能为临时目录下的结果集创建临时文件:

无法创建/写入文件'\\sqla3fe_0.ism'

前述错误是Windows平台上的典型消息,Unix平台上的消息与之类似。

一种更正方式是使用“--tmpdir”选项启动mysqld,或在选项文件的[mysqld]部分增加该选项。例如,要想指定目录C:\temp,可使用:

[mysqld]
tmpdir=C:/temp

目录C:\temp必须存在,并有足够的空间允许MySQL写入它。请参见4.3.2节,“使用选项文件”

该错误的另一个原因可能是许可事宜。请确认MySQL服务器能够写入tmpdir目录。

此外,还用使用perror检查错误代码。服务器无法写入表的一个原因是文件系统已满。

shell> perror 28
错误代码28:磁盘上无剩余空间。

A.2.13. 命令不同步

如果遇到“命令不同步”错误,将无法在你的客户端代码中运行该命令,你正在以错误顺序调用客户端函数。

例如,如果你正使用mysql_use_result(),并打算在调用mysql_free_result()之前执行新查询,就会出现该问题。如果你试图执行两次查询,但并未在两次查询之间调用mysql_use_result()mysql_store_result(),也会出现该问题。

A.2.14. 忽略用户

如果遇到下述错误,表示当启动mysqld时或重新加载授权表时,在用户表中发现具有非法密码的账户。

发现用户'some_user'@'some_host'密码错误:忽略用户。

作为其结果,许可系统将简单忽略账户。

在下面的介绍中,指明了可能的原因和问题的更正措施:

1.    或许,你正打算用旧的用户表运行新版本的mysqld。执行mysqlshow mysql user检查Password(密码)列是否短于16个字符,通过该方式可检查该问题。如果结果是肯定的,可运行脚本/add_long_password脚本更正该问题。

2.    账户具有旧的密码(8字符长),而且未使用“--old-protocol”选项启动mysqld。更新用户表中的账户,使之具有新的密码,或使用“--old-protocol”选项重启mysqld

3.    在用户表中未使用PASSWORD()函数指定了密码。使用mysql用新密码更新用户表中的账户,务必使用PASSWORD()函数:

4.           mysql> UPDATE user SET Password=PASSWORD('newpwd')
5.               -> WHERE User='some_user' AND Host='some_host';

A.2.15. 表tbl_name不存在

如果遇到下述错误之一,通常意味着当前数据库中不存在具有给定名称的表:

'tbl_name'不存在
无法找到文件:'tbl_name' (errno: 2)

在某些情况下,表或许存在,但未正确引用它:

·         由于MySQL使用目录和文件来保存数据库和表,如果它们位于区分文件名大小写的文件系统上,数据库和表名也区分文件大小写。

·         即使对于不区分大小写的文件系统,如Windows,在查询内对给定表的所有引用必须使用相同的大小写。

可以使用SHOW TABLES检查位于当前数据库中的表。请参见13.5.4节,“SHOW语法”

A.2.16. 无法初始化字符集

如果存在字符集问题,可能会遇到下述错误:

MySQL连接失败:无法初始化字符集charset_name

导致该错误的原因:

·         字符集为多字节字符集,但客户端不支持该字符集。在该情况下,需要使用“--with-charset=charset_name”或“--with-extra-charsets=charset_name”选项运行configure以重新编译客户端。请参见2.8.2节,“典型配置选项

所有的标准MySQL二进制文件均是采用“--with-extra-character-sets=complex”编译的,能够支持所有的多字节字符集。请参见5.10.1节,“数据和排序用字符集”

·         字符集是未编译到mysqld中的简单字符集,而且字符集定义文件不在客户端预期的位置。

在该情况下,需要采取下述方法之一解决问题:

1.    重新编译客户端,使之支持字符集。请参见2.8.2节,“典型配置选项

2.    为客户端指定字符集定义文件所在的目录。对于很多客户端,可使用“--character-sets-dir”选项完成该任务。

3.    将字符集定义文件复制到客户端预期的位置。

A.2.17. 文件未找到

如果遇到“ERROR '...'未发现(errno: 23)”无法打开文件:... (errno: 24)”,或来自MySQL的具有errno 23errno 24的其它错误,它表示未为MySQL服务器分配足够的文件描述符。你可以使用perror实用工具来了解错误编号的含义:

shell> perror 23
错误代码23:文件表溢出
shell> perror 24
错误代码24:打开文件过多
shell> perror 11
错误代码11:资源暂时不可用

这里的问题是,mysqld正试图同时打开过多的文件。你可以通知mysqld不要一次打开过多文件,或增加mysqld可用文件描述符的数目。

要想通知mysqld将一次打开的文件控制在较小的数目上,可降低table_cache系统变量的值(),从而减少表高速缓冲(默认值为64)。降低max_connections的值也能降低打开文件的数目(默认值为100)。

要想更改mysqld可用的文件描述符的数目,可在mysqld_safe上使用“--open-files-limit”选项或设置(自MySQL 3.23.30开始)open_files_limit系统变量。请参见5.3.3节,“服务器系统变量”。设置这些值的最简单方式是在选项文件中增加1个选项。请参见4.3.2节,“使用选项文件”。如果mysqld的版本较低,不支持设置打开文件的数目,可编辑mysqld_safe脚本。在脚本中有1个注释掉的行ulimit -n 256。你可以删除#’字符取消对该行的注释,更改数值256,以设置mysqld可用的文件描述符数目。

“--open-files-limit”ulimit能够增加文件描述符的数目,但最高不能超过操作系统限制的数目。此外还有1个“硬”限制,仅当以根用户身份启动mysqld_safemysqld时才能覆盖它(请记住,在该情况下,还需使用“--user”选项启动服务器,以便在启动后不再以根用户身份继续运行)。如果需要增加操作系统限制的对各进程可用文件描述符的数目,请参阅系统文档。

注释:如果运行tcsh shellulimit不工作!请求当前限制值时,tcsh还能通报不正确的值。在该情况下,应使用sh启动mysqld_safe