MySQL:网络连接框架简析

2022-01-28  本文已影响0人  重庆八怪

一直对这部分不太了解,稍微看了一下,但由于知识储备有限,错误在所难免。


总的看起来MySQL在这部分依旧使用了常规的 reactor+线程池高并发网络模型,这里我们以poll为列,有如下特点:

貌似看起来大佬的手法都是通用的,都是按照一定模式写出来的。当然实际上涉及的东西还是非常多,但是这里我们仅仅了解网络框架部分,对于线程池\vio通信模块\net协议模块不做讨论,因为我也不了解,这里主要看看网络框架。

简要流程

main 
  ->mysqld_main 
    -> Connection_acceptor<Mysqld_socket_listener>::connection_event_loop 
       ->Mysqld_socket_listener::listen_for_connection_event 
          ->poll () 

对于用户会话线程通常叫做thread_one_connection,接着会调用thd_prepare_connection->login_connection将准备对连接fd进行ppoll的超时参数设置为connect_timeout指定的值,也就是言外之意connect_timeout是在处理连接请求的时候生效的参数。
然后thd_prepare_connection->login_connection->check_connection,在函数check_connection中完成主要任务是:

  1. ip_to_hostname函数:host_cache和ip相关的反解析动作,并且判断是否超过了max_connection_errors 参数,如果们设置 skip-host-cache skip-name-resolve就不会有这个动作。
  2. acl_check_host 函数:应该是对登陆网段等进行鉴定,是否符合登陆网段的需求,主要来自mysql.user表。
  3. acl_authenticate 函数:(Perform the handshake, authorize the client)这里应该就是要进行MySQL net的握手了,并且完成如密码认证等操作。如果是native password则调用native_password_authenticate进行密码验证。
  4. check_and_update_password_lock_state函数:主要完成对密码错误登陆次数/密码锁定天数的判定,如果不符合要求则报错Account is blocked for %s day(s) (%s day(s) remaining) due to %u consecutive failed logins. Use FLUSH PRIVILEGES or ALTER USER to reset."

在login_connection的末尾会将连接fd的ppoll的timeout参数设置为read_timeout/write_timeout。
最后接下来就是进行命令处理的环节了。也就是do_command。通常我们的会话就堵塞在这里等待客户端命令的到来如下:

#0  0x00007ffff5e2dcff in ppoll () from /lib64/libc.so.6
#1  0x00000000058bba82 in vio_io_wait (vio=0x7fffa801b990, event=VIO_IO_EVENT_READ, timeout=28800000) at /newdata/mysql-8.0.23/vio/viosocket.cc:847
#2  0x00000000058ba4c5 in vio_socket_io_wait (vio=0x7fffa801b990, event=VIO_IO_EVENT_READ) at /newdata/mysql-8.0.23/vio/viosocket.cc:105
#3  0x00000000058bc45b in vio_ssl_read (vio=0x7fffa801b990, buf=0x7fffa800e900 "\001", size=4) at /newdata/mysql-8.0.23/vio/viossl.cc:294
#4  0x00000000039bee83 in net_read_raw_loop (net=0x7fffa800d430, count=4) at /newdata/mysql-8.0.23/sql-common/net_serv.cc:1336
#5  0x00000000039bf1ef in net_read_packet_header (net=0x7fffa800d430) at /newdata/mysql-8.0.23/sql-common/net_serv.cc:1419
#6  0x00000000039c050a in net_read_packet (net=0x7fffa800d430, complen=0x7fffdc4fb9c8) at /newdata/mysql-8.0.23/sql-common/net_serv.cc:2010
#7  0x00000000039c0789 in net_read_uncompressed_packet (net=0x7fffa800d430, len=@0x7fffdc4fba08: 140736889600560) at /newdata/mysql-8.0.23/sql-common/net_serv.cc:2085
#8  0x00000000039c0a77 in my_net_read (net=0x7fffa800d430) at /newdata/mysql-8.0.23/sql-common/net_serv.cc:2161
#9  0x0000000003e23f6e in Protocol_classic::read_packet (this=0x7fffa801a780) at /newdata/mysql-8.0.23/sql/protocol_classic.cc:1404
#10 0x0000000003e25179 in Protocol_classic::get_command (this=0x7fffa801a780, com_data=0x7fffdc4fbb00, cmd=0x7fffdc4fbb2c) at /newdata/mysql-8.0.23/sql/protocol_classic.cc:2975
#11 0x00000000037f063d in do_command (thd=0x7fffa800b980) at /newdata/mysql-8.0.23/sql/sql_parse.cc:1266
#12 0x00000000039c5c91 in handle_connection (arg=0xbe8d880) at /newdata/mysql-8.0.23/sql/conn_handler/connection_handler_per_thread.cc:301
上一篇 下一篇

猜你喜欢

热点阅读