分类: Mysql/postgreSQL
2008-05-12 15:19:43
对于连接问题,服务器错误日志是有用的信息源。请参见5.11.1节,“错误日志”。如果服务器是用“--log-warnings”选项启动的,在错误日志中可能会发现下述消息:
010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh'
如果“Aborted connections”(放弃连接)消息出现在错误日志中,可能的原因是:
1. 客户端程序在退出之前未调用mysql_close()。
2. 客户端的空闲时间超过wait_timeout或interactive_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服务器不可用”。
表已满错误出现的方式有数种:
· 你正在使用低于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文件的操作系统上使用ISAM或MyISAM表,数据文件或索引文件达到了该限制值。
· 你正在使用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;
仅应为具有BLOB或TEXT列的表指定AVG_ROW_LENGTH。在该情况下,MySQL不能仅根据行数优化所需的空间。
如果对某些查询遇到下述类型的错误,它意味着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:磁盘上无剩余空间。
例如,如果你正使用mysql_use_result(),并打算在调用mysql_free_result()之前执行新查询,就会出现该问题。如果你试图执行两次查询,但并未在两次查询之间调用mysql_use_result()或mysql_store_result(),也会出现该问题。
如果遇到下述错误,表示当启动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';
如果遇到下述错误之一,通常意味着当前数据库中不存在具有给定名称的表:
表'tbl_name'不存在
无法找到文件:'tbl_name' (errno: 2)
在某些情况下,表或许存在,但未正确引用它:
· 由于MySQL使用目录和文件来保存数据库和表,如果它们位于区分文件名大小写的文件系统上,数据库和表名也区分文件大小写。
· 即使对于不区分大小写的文件系统,如Windows,在查询内对给定表的所有引用必须使用相同的大小写。
可以使用SHOW TABLES检查位于当前数据库中的表。请参见13.5.4节,“SHOW语法”。
如果存在字符集问题,可能会遇到下述错误:
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. 将字符集定义文件复制到客户端预期的位置。
如果遇到“ERROR '...'未发现(errno: 23)”,“无法打开文件:... (errno: 24)”,或来自MySQL的具有errno 23或errno 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_safe或mysqld时才能覆盖它(请记住,在该情况下,还需使用“--user”选项启动服务器,以便在启动后不再以根用户身份继续运行)。如果需要增加操作系统限制的对各进程可用文件描述符的数目,请参阅系统文档。
注释:如果运行tcsh shell,ulimit不工作!请求当前限制值时,tcsh还能通报不正确的值。在该情况下,应使用sh启动mysqld_safe。
当你链接到应用程序以使用MySQL客户端库时,可能会遇到以mysql_开始的未定义引用错误,如下所示:
/tmp/ccFKsdPa.o: 在函数`main'中:
/tmp/ccFKsdPa.o(.text+0xb): 对`mysql_init'的未定义引用。
/tmp/ccFKsdPa.o(.text+0x31): 对`mysql_real_connect'的未定义引用。
/tmp/ccFKsdPa.o(.text+0x57): 对`mysql_real_connect'的未定义引用。
/tmp/ccFKsdPa.o(.text+0x69): 对`mysql_error'的未定义引用。
/tmp/ccFKsdPa.o(.text+0x9a): 对`mysql_close'的未定义引用。
通过在链接命令后增加“-Ldir_path -lmysqlclient”选项,应能解决该问题,其中,dir_path代表客户端库所在目录的路径名。要想确定正确的目录,可尝试下述命令:
shell> mysql_config --libs
来自mysql_config的输出可能会指明应在链接命令上指定的其他库。
对于非压缩或压缩函数,如果遇到未定义引用错误,可在链接命令后添加-lz,并再次尝试。
对于应在系统上存在的函数(如connect),如果遇到未定义引用错误,请检查相关函数的手册页,以便确定应在链接命令上增加哪些库。
对于系统上不存在的函数,可能会遇到未定义引用错误,如下所示:
mf_format.o(.text+0x201): 对`__lxstat'的未定义引用。
它通常意味着你的MySQL客户端库是在与你的系统不100%兼容的系统上编译的。在该情况下,应下载最新的MySQL源码分发版,并自己编译MySQL。请参见2.8节,“使用源码分发版安装MySQL”。
当你试图执行MySQL程序时,可能会遇到运行时未定义引用错误。如果这类错误指明了以mysql_开始的符号,或指明未发现mysqlclient库,这意味着你的系统无法找到共享的libmysqlclient.so库。对其的更正方式是,通知系统在库所在位置搜索共享库。请使用与系统相适应的下述方法:
· 将libmysqlclient.so所在目录的路径添加到LD_LIBRARY_PATH环境变量中。
· 将libmysqlclient.so所在目录的路径添加到LD_LIBRARY环境变量中。
· 将libmysqlclient.so拷贝到可被系统搜索的目录下,如/lib,然后通过执行ldconfig更新共享库信息。
解决该问题的另一种方法是,以静态方式将你的程序与“-static”选项链接在一起,或在链接代码之前删除动态MySQL库。使用第2种方法之前,应确保没有使用动态库的其它程序。
在Windows平台上,能够使用普通用户账户以Windows服务方式运行服务器。
在Unix平台上,不是任何用户都能启动并运行MySQL服务器mysqld的。但是,处于安全方面的原因,应避免以Unix根用户身份运行服务器。要想更改mysqld,使之能以正常的无特权Unix用户user_name身份运行,必须采取下述步骤:
如果服务器正在运行,停止它(使用mysqladmin shutdown)。
更改数据库目录和文件,允许user_name读写其中的文件(可能需要以Unix根用户身份完成这类设置):
shell> chown -R user_name /path/to/mysql/datadir
如果未这样做,当以user_name身份运行时,服务器无法访问数据库或表。
如果MySQL数据目录下的目录或文件采用的是符号链接,还需跟踪这些链接,并更改它们指向的目录和文件。chown –R可帮助你跟踪符号链接。
以user_name身份启动服务器。如果你正在使用MySQL 3.22或更高版本,另一种可选方式是,以Unix根用户身份启动mysqld,并使用--user=user_name选项。mysqld启动,然后在接受任何连接前,切换至Unix用户user_name并以该用户身份运行。
要想在系统启动时自动以给定的用户身份启动服务器,可在服务器数据目录下的/etc/my.cnf选项文件或my.cnf选项文件的[mysqld]组中,通过增加用户选项来指定用户名。。例如:
[mysqld]
user=user_name
如果你的Unix机器本身并不安全,应在授权表中为MySQL根账户指定密码。如不然,任何在该机器上具有登录账户的用户都能使用“--user=root”选项运行mysql客户端,并执行任何操作。在任何情况下均应为MySQL账户指定密码,这是个好主意,尤其是在服务器主机上存在其他登录账户时,更是如此。请参见2.9节,“安装后的设置和测试”。
如果遇到与文件许可有关的问题,可能数启动mysqld时UMASK环境变量设置得不正确。例如,当你创建表时,MySQL可能会发出下述错误消息:
ERROR: 无法找到文件:'path/with/filename.frm' (Errcode: 13)
UMASK的默认值是0660。通过下述方式启动mysqld_safe,可改变该情况:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> mysqld_safe &
在默认情况下,MySQL用0700的许可创建数据库和RAID目录。你可以通过设置UMASK_DIR变量更改该行为。如果你设置了它的值,将使用组合的UMASK和UMASK_DIR值创建新目录。例如,如果你打算为所有新的目录授予组访问权限,可:
shell> UMASK_DIR=504 # = 770 in octal
shell> export UMASK_DIR
shell> mysqld_safe &
在MySQL 3.23.25和更高版本中,如果是以0开始的,MySQL将认为UMASK和UMASK_DIR的值均采用八进制形式。
如果你从未为MySQL设置根用户密码,服务器在以根用户身份进行连接时不需要密码。但是,建议你为每个账户设置密码。请参见5.6.1节,“通用安全指南”。
如果你以前设置了根用户密码,但却忘记了该密码,可设置新的密码。下述步骤是针对Windows平台的。在本节后面的内容中,介绍了针对Unix平台的步骤。
在Windows平台下,该步骤是:
以系统管理员身份登录到系统。
如果MySQL服务器正在运行,停止它。对于作为Windows服务运行的服务器,进入服务管理器:
开始菜单->控制面板->管理工具->服务
然后在列表中找出MySQL服务器,并停止它。
如果服务器不是作为服务而运行的,可能需要使用任务管理器来强制停止它。
创建1个文本文件,并将下述命令置于单一行中:
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPassword');
用任意名称保存该文件。在本例中,该文件为C:\mysql-init.txt。
打开控制台窗口,进入DOS命令提示:
开始菜单->运行-> cmd
假定你已将MySQL安装到C:\mysql。如果你将MySQL安装到了另一位置,请对下述命令进行相应的调整。
在DOS命令提示符下,执行命令:
C:\> C:\mysql\bin\mysqld-nt --init-file=C:\mysql-init.txt
在服务器启动时,执行由“--init-file”选项命名的文件的内容,更改根用户密码。当服务器成功启动后,应删除C:\mysql-init.txt。
如果你使用MySQL安装向导安装了MySQL,或许需要指定“--defaults-file”选项:
C:\> C:\Program Files\MySQL\MySQL Server 5.1\bin\mysqld-nt.exe
--defaults-file="C:\Program Files\MySQL\MySQL Server 5.1\my.ini"
--init-file=C:\mysql-init.txt
使用服务管理器,可找到恰当的“--defaults-file”设置:
开始菜单->控制面板->管理工具->服务
在列表中找出MySQL服务,右击,并选择“属性”选项。在可执行字段的Path(路径)中包含“--defaults-file”设置。
停止MySQL服务器,然后在正常模式下重启它。如果以服务方式运行服务器,应从Windows服务窗口启动它。如果以手动方式启动了服务器,能够像正常情形下一样使用命令。
应能使用新密码进行连接。
在Unix环境下,重置根用户密码的步骤如下:
以Unix根用户身份、或以运行mysqld服务器的相同身份登录到系统。
找到包含服务器进程ID的.pid文件。该文件的准确位置和名称取决于你的分发版、主机名和配置。常见位置是/var/lib/mysql/、/var/run/mysqld/和/usr/local/mysql/data/。一般情况下,文件名的扩展名为.pid,并以mysqld或系统的主机名开始。
在下述命令中使用.pid文件的路径名,向mysqld进程发出正常的kill(而不是kill -9),可停止MySQL服务器:
shell> kill `cat /mysql-data-directory/host_name.pid`
注意,cat命令使用符号“`”而不是“’”:这会使cat的输出代入到kill命令中。
创建文本文件,并将下述命令放在文件内的1行上:
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPassword');
用任意名称保存文件。对于本例,文件为~/mysql-init。
用特殊的“--init-file=~/mysql-init”选项重启MySQL服务器:
shell> mysqld_safe --init-file=~/mysql-init &
文件init-file的内容在服务器启动时执行,更改根用户密码。服务器成功启动后,应删除~/mysql-init。
应能使用新密码进行连接。
作为可选方式,在任何平台上,可使用mysql客户端设置新密码(但该方法不够安全):
停止mysqld,并用“--skip-grant-tables --user=root”选项重启它(Windows用户可省略--user=root部分)。
使用下述命令连接到mysqld服务器:
shell> mysql -u root
在mysql客户端发出下述语句:
mysql> UPDATE mysql.user SET Password=PASSWORD('newpwd')
-> WHERE User='root';
mysql> FLUSH PRIVILEGES;
用打算使用的实际根用户密码替换“newpwd”。
应能使用新密码进行连接。