A.2.2. 无法连接到[local] 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秒)。

·         退出注册表编辑器。

·         重新引导机器。

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

关注编程学问公众号