Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103728495
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类: Mysql/postgreSQL

2008-05-12 15:19:43

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

A.3. 与安装有关的事宜

A.3.1. 与MySQL客户端库的链接问题

当你链接到应用程序以使用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种方法之前,应确保没有使用动态库的其它程序。

A.3.2. 如何以普通用户身份运行MySQL

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节,“安装后的设置和测试”

A.3.3. 与文件许可有关的问题

如果遇到与文件许可有关的问题,可能数启动mysqldUMASK环境变量设置得不正确。例如,当你创建表时,MySQL可能会发出下述错误消息:

ERROR: 无法找到文件:'path/with/filename.frm' (Errcode: 13)

UMASK的默认值是0660。通过下述方式启动mysqld_safe,可改变该情况:

shell> UMASK=384  # = 600 in octal
shell> export UMASK
shell> mysqld_safe &

在默认情况下,MySQL0700的许可创建数据库和RAID目录。你可以通过设置UMASK_DIR变量更改该行为。如果你设置了它的值,将使用组合的UMASKUMASK_DIR值创建新目录。例如,如果你打算为所有新的目录授予组访问权限,可:

shell> UMASK_DIR=504  # = 770 in octal
shell> export UMASK_DIR
shell> mysqld_safe &

MySQL 3.23.25和更高版本中,如果是以0开始的,MySQL将认为UMASKUMASK_DIR的值均采用八进制形式。

请参见附录F:环境变量

A.4. 与管理有关的事宜

A.4.1. 如何复位根用户密码

如果你从未为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”。

应能使用新密码进行连接。

阅读(520) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~