初始化
函数原型:
MYSQL *mysql_init(MYSQL *mysql)
复制
函数描述: 分配或初始化适合mysql_real_connect()的MYSQL对象。如果mysql是NULL指针,则该函数分配,初始化并返回新对象。否则,将初始化该对象并返回该对象的地址。如果mysql_init()分配了一个新对象,则在调用mysql_close()关闭连接时将释放该对象。
在非多线程环境中,mysql_init()根据需要自动调用mysql_library_init()。但是,mysql_library_init()在多线程环境中不是线程安全的,因此mysql_init()也不是。在调用mysql_init()之前,可以在生成任何线程之前调用mysql_library_init(),或者使用互斥锁来保护mysql_library_init()调用。这应该在任何其他 Client 端库调用之前完成。
函数内部实现:mysql_init( )函数内部主要执行客户端初始化工作(包括错误信息、客户端插件、默认端口设置、fred Fish()调试库使用、信号设置等),MYSQL数据结构空间申请和相关的初始参数设置,如图1所示。
图1 mysql_init()内部实现
连接属性设置
函数原型:
int mysql_options(MYSQL *mysql, enum mysql_option option, const void *arg)
复制
函数描述:可用于设置额外的连接选项并影响连接的行为。可以多次调用此功能以设置多个选项。在mysql_init()之后和mysql_connect()或mysql_real_connect()之前致电mysql_options()。option参数是您要设置的选项; arg参数是选项的值。如果该选项是整数,则将指向整数值的指针指定为arg参数。
MySQL可支持设置的选项有多个,常用的有:
①用作默认字符集的字符集的名称:
MYSQL_SET_CHARSET_NAME(参数类型:char *);
复制
② 如果发现连接丢失,则启用或禁用与服务器的自动重新连接:MYSQL_OPT_RECONNECT(参数类型:my_bool *);
③ 每次尝试从服务器读取的超时时间(以秒为单位):MYSQL_OPT_READ_TIMEOUT(参数类型:unsigned int *),如有必要,可以重试,因此总有效超时值是选项值的三倍;
④ 连接超时(以秒为单位):MYSQL_OPT_CONNECT_TIMEOUT(参数类型:unsigned int *);
⑤ 连接到 MySQL 服务器时要执行的 SQL 语句:MYSQL_INIT_COMMAND(参数类型:char *),如果发生重新连接,则自动重新执行。
除此之外,还有众多参数,此处不一一列举。
函数内部实现:该函数内部实际调用mysql_optionsv(),接收可变参数,函数内部采用switch…case语句进行参数的设置,如图2所示。
图2 mysql_option()内部实现
连接数据库
函数原型:
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag)
复制
功能描述:mysql_real_connect()尝试构建与在host上运行的 MySQL 服务器的连接。在执行需要有效MYSQL连接处理程序结构的任何其他 API 函数之前,Client 端程序必须成功连接到服务器。值得注意的是,不能在调用mysql_real_connect()之前尝试对密码进行加密;密码加密由 Client 端 API 自动处理。
函数内部实现:在mysql_real_connect函数内部,真正执行连接的是mthd_my_real_connect()函数,该函数大致可分为三个模块,分别是连接前属性检查、连接与用户认证,其整体流程如图3所示。
图3 mysql_real_connect()内部实现
在连接参数检查模块,其所作的工作主要是:
① 设置一些默认的连接属性:ma_set_connect_attrs:主要调用mysql_options与mysql_optionsv,返回值为mysql_options与mysql_optionsv的返回值总和;
② 判断连接状态:mysql->net->vio参数不为0,则连接已经建立,直接设置错误消息,返回;
③ set_sigpipe:设置客户端标志client->flag是否忽略SIGPIPE信号;
④ 如果有相关的配置文件,即my_cnf_file或者my_cnf_group为真,读取默认配置:mysql_read_default_options:读取配置文件,一次设置配置文件中的配置参数,my_free()释放my_cnf_file与my_cnf_group,mysql->options.my_cnf_file与mysql->options.my_cnf_group赋值为0
⑤ 空字符串检测:主要包含host/user/passwd/port/unix_socket;
⑥ 设置mysql->server_status=SERVER_STATUS_AUTOCOMMIT。
在连接建立模块,其所作的工作如图4所示:
MySQL主要的连接协议有TCP/IP和Unix套接字文件两种。TCP/IP传输支持到本地或者远程MySQL服务器的连接,适用于任何平台,套接字文件传输仅支持与本地MySQL服务器的连接,可以是TLS/SSL加密的,仅用于Linux或者Unix平台。在连接方式上,Unix套接字文件是通过文件系统中的文件进行连接,默认为/tmp/mysql.sock,其速度比TCP/IP更快。
MySQL.sock文件是一种特殊的文件,在MySQL服务器和客户端之间进行通信时使用,其中包含了MySQL服务器的socket信息,包括端口号、地址、网卡信息等。主要用于客户端软件与MySQL服务器之间的数据传输,是成功运行MySQL必须具备的文件之一。在Linux系统中,MySQL.sock文件通常被保存在/tmp目录下。
图4 MySQL建立连接
值得注意的是,在采用TCP/IP方式连接时,MySQL是按照处理多个连接的思路进行设计的,因此在客户端创建套接字文件socketfd之后和执行connect()连接操作之前,执行bind()函数绑定每个连接的员IP地址。
用户认证模块:连接完成之后,需要在MYSQL结构中保存数据库服务器的相关版本信息,并针对指定的用户和数据库开展连接认证。这一阶段已经开始数据库与客户端之间的通信,客户端读取服务器发过来的连接信息数据包,数据库服务器接收客户端发送的用户名、密码和数据库名称的信息数据包。其中,连接密码加密在客户端完成,如图5所示。
图5 连接认证模块