Rootop 服务器运维与web架构

mysql连接类型与socket通信原理说明(转)

| 暂无评论

原文:http://blog.fity.cn/post/348/

MySQL连接类型中的localhost与127.0.0.1、IP区别:
localhost与127.0.0.1的区别是什么?相信有人会说是本地ip,曾有人说,用127.0.0.1比localhost好,可以减少一次解析。 看来这个入门问题还有人不清楚,其实这两者是有区别的。

NO.1 – 普通接说:
localhost也叫local ,正确的解释是:本地服务器
127.0.0.1在windows等系统的正确解释是:本机地址(本机服务器)

NO.2:
localhost(local)是不经网卡传输!这点很重要,它不受网络防火墙和网卡相关的的限制。
127.0.0.1是通过网卡传输,依赖网卡,并受到网络防火墙和网卡相关的限制。
一般设置程序时本地服务用localhost是最好的,localhost不会解析成ip,也不会占用网卡、网络资源。
有时候用localhost可以,但用127.0.0.1就不可以的情况就是在于此。猜想localhost访问时,系统带的本机当前用户的权限去访问,而用ip的时候,等于本机是通过网络再去访问本机,可能涉及到网络用户的权限。

NO.3 – MySQL被连接时主机类型:
1、 mysql -h 127.0.0.1 的时候,使用TCP/IP连接,
mysql server 认为该连接来自于127.0.0.1或者是”localhost.localdomain”
2、mysql -h localhost 的时候,是不使用TCP/IP连接的,而使用Unix socket;
此时,mysql server则认为该client是来自”localhost”

在mysql权限管理中的”localhost”有特定含义:
—— MySQL手册 5.6.4 ….. A Host value may be a hostname or an IP number, or ‘localhost’ to indicate the local host.

注意:虽然两者连接方式有区别,但当localhost 为默认的127.0.0.1时,两种连接方式使用的权限记录都是以下的记录(因为记录在前,先被匹配)
Host: localhost
User: root

MySQL连接类型证明:

# mysql -h 127.0.0.1  -u root -pfity.cn#123
ERROR 2003 (HY000): Can’t connect to MySQL server on ‘127.0.0.1’ (111)[需要指定端口,反之收到这个错误]

# mysql -h 127.0.0.1 -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1599
Current database:
Current user:           root@127.0.0.1
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             127.0.0.1 via TCP/IP  //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
TCP port:               3307
Uptime:                 5 hours 54 min 48 sec

Threads: 1  Questions: 5432  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.255
————–

# mysql -h 192.168.1.246  -u root -pfity.cn#123

ERROR 2003 (HY000): Can’t connect to MySQL server on ‘192.168.1.246’ (111)[需要指定端口,反之收到这个错误]

# mysql -h 192.168.1.246 -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1598
Current database:
Current user:           root@192.168.1.246
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             192.168.1.246 via TCP/IP    //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
TCP port:               3307
Uptime:                 5 hours 53 min 54 sec

Threads: 1  Questions: 5428  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.255
————–

# mysql -h localhost  -u root -pfity.cn#123[连接OK]

# mysql -h localhost -P 3307 -u root -pfity.cn#123

mysql> status;
————–
mysql  Ver 14.12 Distrib 5.0.95, for redhat-linux-gnu (i686) using readline 5.1

Connection id:          1600
Current database:
Current user:           root@localhost
SSL:                    Not in use
Current pager:          stdout
Using outfile:          ”
Using delimiter:        ;
Server version:         5.1.48-log Source distribution
Protocol version:       10
Connection:             Localhost via UNIX socket    //注意这里
Server characterset:    latin1
Db     characterset:    latin1
Client characterset:    latin1
Conn.  characterset:    latin1
UNIX socket:            /var/lib/mysql/mysql.sock
Uptime:                 5 hours 56 min 18 sec

Threads: 1  Questions: 5436  Slow queries: 1619  Opens: 72  Flush tables: 1  Open tables: 65  Queries per second avg: 0.254
————–

从这里看以看出,通过通过unix domain socket方式连接mysql时,你不需要特意指定端口,按照mysql官方所说通过unix domain socket方式连接mysql较快于TCP/IP方式。不过,如果通过socket方式连接mysql,当mysql.sock文件不再是默认的名称或存放路径时,你将会收到下面这个错误信息,当然,你可以需要在php代码config中声明一个变量指定unix domain socket路径或者在php.ini配置文件中定义也可。错误信息如下:
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)

默认情况下我们PHP实例和mysql通信是走TCP/IP的,但如果你加载了socket模块,默认会走sock文件连接,但如果你的linux主机上没有指定默认的socket文件,这样如果你使用mysql_connect连接的话,经常我们使用mysql_connect()或socket方式连接mysql时会收到错误:
No such file or directory、Can’t connect to local MySQL server through socket… ,如图:

然而此时mysql客户端可以正常使用,当然此刻你通过mysqli或pdo方式连接一般情况下也是不会有错误的,所以可以确定不是服务器的问题。

简而言之:主要区别是localhost是通过unix domain socket方式来连接,而127.0.0.1则是走的TCP协议方式连接
这是linux套接字网络的特性,win平台不会有这个问题

php.ini文件中如何定义mysql socket路径:
mysql.default_socket = mysql.sock //绝对路径就可以了
或者你可以在my.cnf文件中把mysql.sock路径指向/tmp/mysql.sock也可以

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

Socket简要通信机制与原理说明
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/2462.html

作者:Venus

专注于 服务器运维与性能优化 联系方式:https://www.rootop.org/about

发表评论