最近看了slave IO的源码,发现slave IO的写relay log貌似是单线程单连接的,这让我有点小失望。
slave IO的主函数是handle_slave_io,处理流程如下:
图1 handle_slave_io处理流程
我们这次主要要完成safe_connect以及try_to_reconnet用到的核心函数 mysql_real_connect流程的探索。
一、mysql_real_connect流程
在这之前我们需要弄明白连接mysql需要那几步操作,参考自官网的文档(http://dev.mysql.com/doc/internals/en/plain-handshake.html),据说连接时需要以下操作:
图2 mysql_real_connect操作流程
1.建立与mysql的连接
对于需要连接的建立一个监听端口,然后建立与链表中的所有服务端建立连接,并绑定到监听端口
1 if (!net->vio && 2 (!mysql->options.protocol || 3 mysql->options.protocol == MYSQL_PROTOCOL_SOCKET) && 4 (unix_socket || mysql_unix_port) && 5 (!host || !strcmp(host,LOCAL_HOST))) 6 { 7 my_socket sock= socket(AF_UNIX, SOCK_STREAM, 0); 8 DBUG_PRINT("info", ("Using socket")); 9 if (sock == SOCKET_ERROR) 10 { 11 set_mysql_extended_error(mysql, CR_SOCKET_CREATE_ERROR, 12 unknown_sqlstate, 13 ER(CR_SOCKET_CREATE_ERROR), 14 socket_errno); 15 goto error; 16 } 17 18 net->vio= vio_new(sock, VIO_TYPE_SOCKET, 19 VIO_LOCALHOST | VIO_BUFFERED_READ); 20 if (!net->vio) 21 { 22 DBUG_PRINT("error",("Unknow protocol %d ", mysql->options.protocol)); 23 set_mysql_error(mysql, CR_CONN_UNKNOW_PROTOCOL, unknown_sqlstate); 24 closesocket(sock); 25 goto error; 26 } 27 28 host= LOCAL_HOST; 29 if (!unix_socket) 30 unix_socket= mysql_unix_port; 31 host_info= (char*) ER(CR_LOCALHOST_CONNECTION); 32 DBUG_PRINT("info", ("Using UNIX sock '%s'", unix_socket)); 33 34 memset(&UNIXaddr, 0, sizeof(UNIXaddr)); 35 UNIXaddr.sun_family= AF_UNIX; 36 strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1); 37 38 if (vio_socket_connect(net->vio, (struct sockaddr *) &UNIXaddr, 39 sizeof(UNIXaddr), get_vio_connect_timeout(mysql))) 40 { 41 DBUG_PRINT("error",("Got error %d on connect to local server", 42 socket_errno)); 43 set_mysql_extended_error(mysql, CR_CONNECTION_ERROR, 44 unknown_sqlstate, 45 ER(CR_CONNECTION_ERROR), 46 unix_socket, socket_errno); 47 vio_delete(net->vio); 48 net->vio= 0; 49 goto error; 50 } 51 mysql->options.protocol=MYSQL_PROTOCOL_SOCKET; 52 }