MySQL服务器连接过程浅析

mysqld是MySQL服务器端主进程,可以说mysqld是MySQL的真正核心,一切工作都是围绕mysqld进程进行的。所以要解剖mysql这个庞然大物,mysqld的代码是最好的突破口。

一切都是从熟悉的main()函数开始的,其实是从mysqld_main()函数开始的。这些代码都在mysqld.cc。mysqld_main()随后调用了win_main)()。win_main()函数主要是做了一些初始化的工作。

初始化工作完成之后,MySQL已经做好准备接受连接了。然后我们的主角Handle_connections_methods()函数登场了。这个函数的主要工作是新建3个子进程,他们分别接受TCP/IP、命名管道以及共享内存这三种方式的连接。一般情况下客户都是用TCP/IP(socket)来连接MySQL服务器的,这是最有弹性的通信方式。但是在嵌入式软件的应用环境中,需要采用后两种通信方式。

简化后的handle_connections_methods()函数:

代码如下:

static void handle_connections_methods()
{
  mysql_mutex_lock(&LOCK_thread_count);
  mysql_cond_init(key_COND_handler_count, &COND_handler_count, NULL);
  handler_count=0;
  handler_count++;
  mysql_thread_create(key_thread_handle_con_namedpipes, &hThread, &connection_attrib, handle_connections_namedpipes, 0));
  handler_count++;
  mysql_thread_create(key_thread_handle_con_sockets, &hThread, &connection_attrib, handle_connections_sockets_thread, 0));
  handler_count++;
  mysql_thread_create(key_thread_handle_con_sharedmem, &hThread, &connection_attrib, handle_connections_shared_memory, 0))
  while (handler_count > 0)
    mysql_cond_wait(&COND_handler_count, &LOCK_thread_count);
  mysql_mutex_unlock(&LOCK_thread_count);
}

新建了3个线程之后,handle_connectins_methods()函数进入一个长时间循环,直到3个连接线程全部退出后才退出。这里我主要看看socket的连接线程,我们的研究对象就是这个handle_connections_sockets_thread。这个线程把自己初始化之后,就直接调用了handle_connections_sockets();

handle_connections_sockets()函数使用select()调用监听mysqld的端口,然后等待客户端的连接。等到一个客户端连接后,这个函数中会新建一个THD类型的变量,这个变量是一个“交际花”,从连接建立开始,到SQL语法分析、查询执行、结果返回等等。这个变量一直都在,总之这是一个非常重要的变量。

还有struct st_vio这个结构体,这个结构体是一个命令的中转站。在“交际花”THD中也定义了一个vio类型的结构体。这个结构体的功能就是从储存从套接字中读取通信内容,然后又把自己的值赋给THD的vio变量。VIO类型中详细的描述了一次请求,包括请求的内容、时间、请求的套接字地址等等。之后发生的事情就是把这个“交际花”传递到服务线程,create_thread_to_handle_connection()实现这个功能。

以下是删减后的代码

代码如下:

void create_thread_to_handle_connection(THD *thd)
{
  if (cached_thread_count > wake_thread)
  {
    mysql_cond_signal(&COND_thread_cache);
  }
  else
  {
    mysql_thread_create(key_thread_one_connection, &thd->real_id, &connection_attrib, handle_one_connection, (void*) thd)));   
  }
}

这个函数会查看有没有闲置的缓存线程(MySQL不会把断开连接后的服务线程立即销毁掉,而是缓存了起来),如果有就是用缓存线程,如果没有就新建一个线程来服务连接。至此,一个连接就进入了服务线程,连接线程返回继续等待连接。

后边的内容就都是在服务线程中实现的,《深入理解MySQL》中有很详细的代码跟踪,感兴趣的同学可以看看。我把函数调用顺序附上,供参考。

代码如下:

handle_one_connection()
mysql_thread_create()
handle_one_connection()
do_handle_one_connection()
init_new_connection_thread()
init_new_connection_handler_thread()
do_command()
dispatch_command()
mysql_parse()
mysql_execuate_command()

(0)

相关推荐

  • 在Ubuntu或Debian系统的服务器上卸载MySQL的方法

    对于有的vps,系统默认安装了mysql.我们需要从我们的服务器.vps上卸载(移除)默认的mysql.那么如何(怎样)在ubuntu\Debian上卸载mysql? 通常情况下,下列mysql软件包会被安装到 Debian .Ubuntu中: mysql-client - The latest version of MySQL database client(最新版的mysql数据库客户端). mysql-server - The latest version of MySQL databas

  • MySQL数据库InnoDB引擎下服务器断电数据恢复方法

    说明: 线上的一台MySQL数据库服务器突然断电,造成系统故障无法启动,重新安装系统后,找到之前的MySQL数据库文件夹. 问题: 通过复制文件的方式对之前的MySQL数据库进行恢复,发现在程序调用时找不到数据库中的表,造成网站无法正常访问. 分析: 1.MySQL数据库,使用拷贝文件方式来恢复数据库,只支持MyISAM引擎: 2.如果有数据库或数据表使用了InnoDB引擎,恢复的时候,必须连同MySQL数据库目录下的ibdata1文件一起拷贝过来. 解决办法: 1.停止MySQL服务 serv

  • Windows服务器MySQL中文乱码的解决方法

    我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B. 如果你也遇到了这个问题,咱先不谈原因,在PC自带的cmd中(或者是mysql安装版安装后的Command Line客户端,又或者是工作用的SecureCRT)试试效果.进入mysql环境,从头开始操作.假设你的客户端编码是gbk或者utf8(这么说太不严谨了,怎么能假设呢,但是一般来说假如安装后没动过,cmd是gbk编码,m

  • 使用MySQL语句来查询Apache服务器日志的方法

    Linux 有一个显著的特点,在正常情况下,你可以通过日志分析系统日志来了解你的系统中发生了什么,或正在发生什么.的确,系统日志是系统管理员在解决系统和应用问题时最需要的第一手资源.我们将在这篇文章中着重讲解 Apache HTTP web server 生成的 Apache access 日志. 这次,我们会通过另类的途径来分析 Apache access 日志,我们使用的工具是 asql.asql 是一个开源的工具,它能够允许使用者使用 SQL 语句来查询日志,从而通过更加友好的格式展现相同

  • 抛弃 PHP 代价太高

    前言 我初次尝试编程使用的语言是php,并且在数个使用php作为主要开发语言的公司工作过.但是,我并不会对其他语言视而不见,并且现如今php已经不是我主要的开发语言了. 我认为我是一个可以因为"不需要过度担心语言设计"与"尽可能轻松地快速地赚钱.完成工作"就会很快乐的人.我最近刚从一个主要以php作为前端开发的全职工作岗位中离职. 最近我通读了那篇虽然已经陈旧但仍勾起如此真实的痛苦,以至于我无法再忽视的博文<Eevee.PHP:糟糕的设计带来的碎片 >.

  • 解决Mysql服务器启动时报错问题的方法

    一.概述 文章主要介绍因为启动mysql服务报错引发的问题:"ERROR! The server quit without updating PID file (/var/lib/mysql/localhost.localdomain.pid)",顺带扩充一些其它的知识点,当前版本是red hat 6,mysql 5.6. 二.步骤 报错的源头 问题解决 1.权限 报错的源头就是它了,一般这种问题首先会想到的就是权限问题,就是/var/lib/mysql该文件夹的权限 上图可以看到my

  • 防止服务器宕机时MySQL数据丢失的几种方案

    对于多数应用来说,MySQL都是作为最关键的数据存储中心的,所以,如何让MySQL提供HA服务,是我们不得不面对的一个问题.当master当机的时候,我们如何保证数据尽可能的不丢失,如何保证快速的获知master当机并进行相应的故障转移处理,都是需要我们好好思考的.这里,笔者将结合这段时间做的MySQL proxy以及toolsets相关工作,说说我们现阶段以及后续会在项目中采用的MySQL HA方案. Replication 要保证MySQL数据不丢失,replication是一个很好的解决方

  • win2008 R2服务器下修改MySQL 5.5数据库data目录的方法

    说明: 操作系统:Windows Server 2008 R2 MySQL版本:5.5.25a MySQL程序安装目录:D:\Program Files\MySQL\MySQL Server 5.5 MySQL数据库默认目录:C:\ProgramData\MySQL\MySQL Server 5.5\data\ 需求:修改MySQL数据库目录为D:\Program Files\MySQL\MySQL Server 5.5\data 具体操作: 一.停止MySQL 开始-cmd net stop

  • MySQL服务器连接过程浅析

    mysqld是MySQL服务器端主进程,可以说mysqld是MySQL的真正核心,一切工作都是围绕mysqld进程进行的.所以要解剖mysql这个庞然大物,mysqld的代码是最好的突破口. 一切都是从熟悉的main()函数开始的,其实是从mysqld_main()函数开始的.这些代码都在mysqld.cc.mysqld_main()随后调用了win_main)().win_main()函数主要是做了一些初始化的工作. 初始化工作完成之后,MySQL已经做好准备接受连接了.然后我们的主角Hand

  • mySQL服务器连接,断开及cmd使用操作

    通过mysql命令实现连接MySQL服务器.在MySQL服务器启动后,选择"开始"→"运行"命令,在弹出的"运行"窗口中输入"cmd"命令,按Enter键后进入DOS窗口,在命令提示符下输入连接MySQL服务器.测试网址 www.dc3688.com 连接MySQL服务器需要输入用户名.密码.MySQL服务器所在地址 >mysql-uroot-h127.0.0.1-ppassword 断开连接 连接到MySQL服务器后,

  • MySQL服务器的启动和关闭

    本章的说明只用于UNIX 系统.如果正在运行Windows 系统,可以跳过本章,因为附录A"获得和安装软件"一节中包含了所有需要的启动和关闭命令.      调用本章给出的命令      为了简洁,在大多数情况中,诸如mysqla d m i n.mysqldump 等程序在本章中没有给出任何- h.- u或- p选项.笔者假定您将会用连接服务器所需的任何选项调用这些程序. 用无特权的用户账号运行MySQL服务器 在讨论如何启动服务器之前,考虑一下在服务器启动时应该运行哪个账号.服务器

  • Mysql服务器的启动与停止(一)

    在讨论如何启动MySQL服务器之前,让我们考虑一下应该以什么用户身份运行MySQL服务器.服务器可以手动或自动启动.如果你手动启动它,服务器以你登录Unix(Linux)的用户身份启动,即如果你用paul登录Unix并启动服务器,它用paul运行:如果你用su命令切换到root,然后运启动服务器,则它以root运行.然而,大多数情况下你可能不想手动启动服务器,最有可能是你安排MySQL服务器在系统引导时自动启动,作为标准引导过程的一部分,在Unix下,该引导过程由系统的Unix用户root执行,

  • 浅析mysql交互式连接&非交互式连接

    交互式操作:通俗的说,就是你在你的本机上打开mysql的客户端,就是那个黑窗口,在黑窗口下进行各种sql操作,当然走的肯定是tcp协议. 非交互式操作:就是你在你的项目中进行程序调用.比如一边是tomcat web服务器,一边是数据库服务器,两者怎么通信?在java web里,我们通常会选择hibernate或者是jdbc来连接.那么这时候就是非交互式操作. 在之前,我基本上不关系这两个属性,都是用的是mysql服务商推荐的默认值,就是8小时. 但是,从昨天开始,由于在新网租用了一个空间,而他的

  • vscode ssh远程连接服务器的思考浅析

    目录 过往经验总结 关于vscode 与ssh有关的两个配置文件 报错解决:ssh连接时提示管道不存在 问题 解决方案 方案一:使用git中的ssh作为替代 方案二:修改私钥文件权限 各方式远程连接项目文件的性能对比 现象 原因分析 过往经验总结 注:笔者写本文的目的不是完整细致地描述连接的全过程,而是记录当中遇到的现象.问题,及为什么会产生这个问题的分析.所以部分过程会省略,或者默认读者都是很熟悉各种操作的. 使用ssh远程连接,要获知目标主机的ip地址,并使用正确的密码或密钥. 笔者之前曾尝

  • 使用Memcache缓存mysql数据库操作的原理和缓存过程浅析

    对于大型网站如facebook,ebay等网站,如果没有Memcache做为中间缓存层,数据访问不可能吃得消,对于一般网站,只要具备独立的服务器,完全可以通过配置Memcache提高网站访问速度和减少数据库压力,这里主要讨论一下Memcache和MySQL数据库交互过程的流程关系,了解Memcache的中间缓存层作用,从而深入了解Memcache机制原理. Memcache和MySQL交互流程图 如上图,传统的查询方法是直接查询数据库,数据库将结果返回给查询语句,而当有Memcache中间缓存层

  • mysql设置更改root密码、mysql服务器的连接、mysql常用命令的图解

    1.设置更改root密码 查看mysql 启动与否,若没启动就运行:/usr/local/mysql56/bin/mysql ps aux |grep mysql 或 netstat -tulnp |grep 3306 运行mysql 命令,会出现: -bash: mysql: command not found 就把mysql 添加到环境变量: 临时添加:PAHT=$PATH:/usr/local/mysql56/bin 永久添加:echo "export PATH=$PATH:/usr/lo

  • 解决mysql服务器在无操作超时主动断开连接的情况

    我们在使用mysql服务的时候,正常情况下,mysql的设置的timeout是8个小时(28800秒),也就是说,如果一个连接8个小时都没有操作,那么mysql会主动的断开连接,当这个连接再次尝试查询的时候就会报个"MySQL server has gone away"的误,但是有时候,由于mysql服务器那边做了一些设置,很多情况下会缩短这个连接timeout时长以保证更多的连接可用.有时候设置得比较变态,很短,30秒,这样就需要客户端这边做一些操作来保证不要让mysql主动来断开.

  • Navicat出现无法远程连接MySql服务器问题的解决办法

    Navicat无法远程连接MySql服务器问题的解决方法写在前面: 操作系统:中标麒麟4.0: 数据库:MySQL5.7.26: JDK:采用中标麒麟系统自带的openjdk: 客户端工具:Navicat: 前置条件: MySQL服务安装完毕: 情景: 安装好mysql,本地访问正常,但同一个局域网内的机器都无法访问该服务器上的mysql数据库: 原因: mysql默认是不可以通过远程机器访问的,只允许本地访问,通过下面的配置可以开启远程访问: 排查思路: mysql设置远程访问主要从以下三个方

随机推荐