Mysql源码学习笔记 偷窥线程

安装完Mysql后,使用VS打开源码开开眼,我嘞个去,这代码和想象中怎么差别这么大呢?

感觉代码有些凌乱,注释代码都写的比较随意,好像没有什么统一的规范,不同的文件中代码风格也有差异,可能Mysql经过了很多牛人的手之后,集众牛人之长吧。也可能是我见识比较浅薄,适应了自己的代码风格,井底之蛙了,总之还是怀着敬畏的心情开始咱的源码之旅吧。本人菜鸟,大神轻拍。

  Mysql可以启动起来了,应该怎么学习呢?总不能从main开始一步一步的看吧,Mysql作为比较底层的大型软件,涉及到数据库实现的方方面面,没有厚实的数据库理论基础和对Mysql各个模块相当的熟悉,从main开始势必会把自己引入某个死胡同啊,什么都看,最后啥也不会,咱伤不起。

  经过思考后,我想还是通过客户端来调试服务器,从而学习服务器代码比较现实。也就是通过客户端的动作,看服务器的反应。比如从客户端的登录动作来看SERVER如何进行通信、用户识别、鉴定以及任务分配的,通过CREATE TABLE,来看SERVER如何解析DDL语句以及针对不同的存储引擎采取的不同的物理存储方式,通过INSERT语句,来看SERVER如何进行Btree的操作。通过SELECT语句来看如何进行SQL语句语法树的创建和优化的,通过ROLL BACK,来看SERVER事务是如何实现的。这里主要是通过跟踪代码学习Mysql数据库实现的思想,对于具体的代码不去做过多的追究(主要是我对C++不是很熟悉),好读书,不求甚解,呵呵。
  由此,暂时准备了以下几条SQL语句,来有针对的进行SERVER的分析
代码如下:
1、 LOGIN(登录)
mysql.exe –uroot –p
2、 DDL(建表语句)
create table tb_myisam(c1 int, c2 varchar(256)) engine = myisam;
create table tb_innodb(c1 int, c2 varchar(256)) engine = innodb;
3、 INSERT
Insert into tb_myisam values(1 , ‘寂寞的肥肉’);
Insert into tb_innodb values(1 , ‘寂寞的肥肉’);
4、 SELECT
Select c1 from tb_myisam;
Select * from tb_innodb;
5、 ROLLBACK

大家都知道,mysql可以通过多个客户端,进行并发操作,当然也包括登录了。在别人登录的时候,其他的用户可能正在进行一些其它的操作,因此对于登录我们猜测应该有专门的线程负责客户端和服务器的连接的创建,以保证登录的及时性,对于每个连接的用户,应该用一个独立的线程进行任务的执行。
  首先介绍下mysql中创建线程的函数,创建线程的函数貌似就是_begin_thread,CreateThread,我们通过VS在整个解决方案中进行查找,bingo!在my_winthread.c中找到了调用_begin_thread的函数pthread_create,在os0thread.c中找到了调用CreateThread的函数os_thread_create,一个系统怎么封装两个系统函数呢??再仔细看下,发现my_winthread.c是在项目mysys下,而os0thread.c是在项目innobase下。innobase!!这不就是innodb的插件式存储引擎么,原来这是存储引擎自己的封装的底层函数,哥心中豁然开朗了。我想Mysql应用范围如此之广,除了开源之外,插件式的存储引擎功不可没啊,用户可以根据自己的实际应用采取不同的存储引擎,对于大公司,估计会开发自己的存储引擎。
  下面分析下pthread_create是如何调用_begin_thread的,先粗略看下源码。
代码如下:
int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
pthread_handler func, void *param)
{
HANDLE hThread;
struct pthread_map *map;
DBUG_ENTER(“pthread_create”);
if (!(map=malloc(sizeof(*map))))
DBUG_RETURN(-1);
map->func=func;
map->param=param;
pthread_mutex_lock(&THR_LOCK_thread);
#ifdef __BORLANDC__
hThread=(HANDLE)_beginthread((void(_USERENTRY *)(void *)) pthread_start,
attr->dwStackSize ? attr->dwStackSize :
65535, (void*) map);
#else
hThread=(HANDLE)_beginthread((void( __cdecl *)(void *)) pthread_start,
attr->dwStackSize ? attr->dwStackSize :
65535, (void*) map);
#endif
DBUG_PRINT(“info”, (“hThread=%lu”,(long) hThread));
*thread_id=map->pthreadself=hThread;
pthread_mutex_unlock(&THR_LOCK_thread);
if (hThread == (HANDLE) -1)
{
int error=errno;
DBUG_PRINT(“error”,
(“Can’t create thread to handle request (error %d)”,error));
DBUG_RETURN(error ? error : -1);
}
VOID(SetThreadPriority(hThread, attr->priority)) ;
DBUG_RETURN(0);
}

关键的代码是下面三句:
代码如下:
map->func=func;
map->param=param;
_beginthread((void( __cdecl *)(void *)) pthread_start,
attr->dwStackSize ? attr->dwStackSize :
65535, (void*) map);

从这可以看出,创建的新线程的名字是个固定的函数——pthread_start,而我们传进来的想创建的函数func是挂载在了map上了,函数的参数同样的挂载在map上了,这样我们就可以推理出在pthread_start函数中,肯定会出现这样的代码:
              map->func(map->param);
  mysql没有选择直接_beginthread(func, stack_size, param)的形式,而是进行了一次封装,不知道这样的好处是什么,可能牛人的思想不是我这样小菜鸟能顿悟的,跑题了~~
  至此,我们只在pthread_create函数上设置断点,调试启动mysqld,断点停下来,看下系统的线程状况:

我们第一次进入pthread_create,任何线程都没开始创建呢,按理说系统线程应该就只有一个主线程,可现在多了这么多,这些应该是innodb存储引擎创建的线程了(具体是在plugin_init)。根据线程的名称,结合注释,猜测了下这些线程的作用。
   Io_handler_thread:从名称可以知道这些是I/O线程,负责进行磁盘I/O。
Svr_error_monitor_thread:应该是服务器出错监控线程。
Svr_lock_timeout_thread:应该是和上锁相关的线程。
Svr_master_thread:
/*************************************************************************
The master thread controlling the server. */
服务器控制线程,应该是具体进行作业的线程。
Svr_monitor_thread:
/*************************************************************************
A thread prints the info output by various InnoDB monitors. */
监控线程,负责打印信息。

  淡然飘过吧,不去细究了,我们只关心pthread_create创建的线程。根据调试,发现多了几个线程同名的线程_threadstart,如下所示:

创建者:调用pthread_create进行创建线程的函数。

如知AI笔记 如知AI笔记

如知笔记——支持markdown的在线笔记,支持ai智能写作、AI搜索,支持DeepseekR1满血大模型

如知AI笔记 27 查看详情 如知AI笔记

应该是处理连接的线程了,从顺序上看,也应该是这样,只有系统中所有的其他必须的线程创建完毕后,才能创建监听线程(连接线程),即监听线程应该是系统最后创建的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/444071.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年11月7日 20:01:13
下一篇 2025年11月7日 20:07:41

相关推荐

  • PHP中安全高效地将JSON数据导入MySQL数据库

    本文旨在解决PHP将JSON数据导入MySQL时遇到的不一致问题,尤其当JSON内容包含特殊字符时,数据插入失败的根本原因在于未正确处理SQL注入风险。教程将深入分析问题成因,并提供使用mysqli预处理语句的安全解决方案,确保数据导入的稳定性和安全性。 1. 问题描述与初步分析 在将JSON文件数…

    2025年12月10日
    000
  • JSON数据导入数据库:解决PHP中JSON文件加载与SQL注入的隐患

    本文旨在解决PHP从JSON文件加载数据到MySQL数据库时遇到的不一致性问题。通过深入分析,揭示了看似随机的失败实则源于SQL注入漏洞,即未转义的特殊字符导致SQL语法错误。教程将详细阐述这一安全隐患,并提供使用MySQLi和PDO预处理语句的专业解决方案,确保数据导入的稳定性和安全性,避免潜在的…

    2025年12月10日
    000
  • Laravel 查询中获取唯一(Distinct)字段或行数据的策略

    本教程探讨在 Laravel 复杂多表连接查询中,如何精确获取指定字段的唯一值或基于特定字段的唯一行数据。文章将详细介绍 select()->distinct() 和 groupBy() 两种核心方法,并通过代码示例和注意事项,帮助开发者避免常见陷阱,高效处理数据去重需求。 理解多表连接查询中…

    2025年12月10日
    000
  • php中的PDO是什么以及如何使用?PDO扩展介绍与使用教程

    PDO通过预处理和参数绑定将SQL语句与数据分离,确保用户输入不被当作代码执行,从而有效防止SQL注入;使用try-catch处理异常、设置正确字符集、管理数据库凭证安全,并利用debugDumpParams等工具调试,提升开发效率与安全性。 PDO就是PHP操作数据库的一个统一接口,它能让你用一套…

    2025年12月10日
    000
  • PHP如何实现用户登录和注册_PHP构建用户登录注册系统的流程与实践

    答案:PHP实现用户登录注册需围绕数据安全与用户体验平衡,通过数据库设计、密码哈希、会话管理等步骤构建系统。首先创建包含id、username、email、password_hash等字段的users表;注册时进行前端输入校验与后端严格验证,使用password_hash()处理密码并用预处理语句存…

    2025年12月10日
    000
  • 掌握Laravel查询:Distinct与GroupBy在多表联接中的正确用法

    本文深入探讨了在Laravel中进行多表联接查询时,如何精确地获取期望的唯一ID或唯一记录。针对distinct()方法在无明确select()时的默认行为,文章提供了两种核心解决方案:通过select()与distinct()组合来获取特定列的唯一值,以及利用groupBy()方法获取每组的完整唯…

    2025年12月10日
    000
  • MySQL创建表1064错误解析:数值类型与数据精度选择

    本文针对MySQL创建表时常见的1064语法错误,特别是由于DOUBLE类型精度定义不当引发的问题,提供了详细的解决方案。文章解释了DOUBLE和DECIMAL数据类型的差异,强调了在处理金融或需要精确计算的数据时,应优先选用DECIMAL(M,D)类型,并给出了正确的CREATE TABLE语句示…

    2025年12月10日
    000
  • PHP与数据库时间戳比较:实现高效数据检索与通知

    本教程旨在解决PHP中日期(如date(“Y-m-d”))与数据库中完整时间戳(如DATETIME或TIMESTAMP类型)进行有效比较的常见问题。我们将探讨如何利用SQL的内置函数如NOW()或CURDATE(),实现高效、精确的日期时间范围查询,以识别最新数据或特定日期的…

    2025年12月10日
    000
  • 使用PHP函数填充HTML Select元素

    本教程详细介绍了如何利用PHP函数动态生成并填充HTML (下拉列表或ListBox)元素。通过一个可复用的PHP函数,您可以高效地从后端数据源获取数据,并将其转换为结构化的HTML选项,实现灵活的数据展示与用户交互,同时提供了示例代码和使用注意事项。 动态生成HTML下拉列表的需求 在Web开发中…

    2025年12月10日
    000
  • 动态填充HTML下拉列表:PHP函数式实现指南

    本文详细介绍了如何使用PHP函数动态生成并填充HTML下拉列表(元素),以替代硬编码选项。通过一个可重用的PHP函数,您可以高效地从后端数据源获取数据,并将其转换为结构化的HTML选项,支持自定义ID、名称及默认选中功能,从而实现前端界面的灵活数据展示。 动态填充HTML下拉列表的需求 在web开发…

    2025年12月10日
    000
  • PHP与数据库时间戳的高效比较:基于NOW()函数实现数据筛选

    本文旨在探讨在PHP应用中,如何高效且准确地比较PHP date()函数生成的日期与数据库中存储的时间戳。通过深入解析SQL的NOW()函数,我们将展示一种简洁而强大的方法,用于筛选出当前或近期的数据,并提供实用的代码示例和专业建议,以优化您的数据查询逻辑。 场景分析:PHP日期与数据库时间戳的比较…

    2025年12月10日
    000
  • php如何执行mysql查询_php执行sql查询语句的方法

    使用mysqli或PDO执行MySQL查询需连接数据库、执行SQL、处理结果并关闭连接;为防止SQL注入,应使用预处理语句将SQL结构与数据分离;优化性能可采用索引、避免SELECT *、使用LIMIT、优化SQL语句、启用缓存等手段;若遇“Access denied”错误,需检查用户名、密码、主机…

    2025年12月10日
    000
  • php如何实现一个基本的用户登录系统?php用户认证与登录系统开发步骤

    答案:实现PHP登录系统需设计用户表,通过注册页面收集并安全存储用户信息,登录时验证凭证并维护会话,受保护页面检查会话状态,注销则销毁会话;使用预处理语句防SQL注入,password_hash()和password_verify()安全处理密码,session_start()管理会话数据。 实现一…

    2025年12月10日
    000
  • 在Laravel Eloquent中创建条件性自定义列的多种策略

    本文探讨在Laravel Eloquent中根据条件合并多个字段(如title和original_title)生成自定义列的多种策略。我们将详细介绍利用DB::raw进行数据库层面处理、使用模型访问器实现应用层封装,以及区分自定义列选择与条件筛选的不同场景,旨在提供高效、可维护的解决方案。 问题解析…

    2025年12月10日
    000
  • php如何实现一个简单的MVC框架 php从零构建MVC框架核心步骤

    实现PHP MVC框架需分离数据、逻辑与展示,通过路由解析URL并调用对应控制器方法,模型处理数据,视图渲染页面;依赖注入通过容器管理对象依赖,ORM将数据库表映射为类并封装CRUD操作,模板引擎解析变量与控制结构实现视图渲染。 实现一个简单的PHP MVC框架,核心在于分离数据、逻辑和展示,让代码…

    2025年12月10日
    000
  • 基于复选框的MySQL数据过滤与状态回显实践指南

    本教程详细介绍了如何利用HTML复选框与PHP及MySQL数据库进行交互。我们将探讨两种核心应用场景:一是根据用户选择的复选框条件来动态过滤和显示数据库数据;二是如何根据数据库中存储的布尔值(1或0)来正确显示复选框的选中状态。通过具体的代码示例和实践指导,帮助开发者高效实现基于复选框的数据管理功能…

    2025年12月10日
    000
  • PHP如何从数据库获取数据_PHP从数据库查询与获取数据全流程

    选择合适的PHP数据库扩展需权衡mysqli的性能与PDO的灵活性及安全性,优先推荐PDO;优化查询性能应从索引、SQL语句、缓存、分页策略入手,并考虑连接池与预计算;处理连接错误需结合try-catch、日志记录、友好提示、重试机制与监控告警,保障系统稳定。 PHP从数据库获取数据,核心在于建立连…

    2025年12月10日
    000
  • Eloquent 中实现条件字段选择与搜索:告别原始 SQL 的优雅之道

    本文探讨在 Laravel Eloquent 中如何优雅地实现条件字段选择,即根据 title 和 original_title 字段的值动态生成一个新字段。我们将介绍两种主要方法:利用 Eloquent Accessor 进行模型层面的处理,以及在必要时使用 DB::raw 进行数据库层面的计算。…

    2025年12月10日
    000
  • PHPMaker 2019中实现复杂数据过滤与联接:自定义视图的实践指南

    在PHPMaker 2019中处理涉及复杂联接和高级过滤逻辑的数据时,直接在Recordset_Selecting事件中实现往往受限。本文详细阐述了如何通过创建数据库自定义视图来解决此类问题,特别是针对需要结合多表信息进行去重和条件筛选的场景。教程涵盖了视图的创建、在PHPMaker中集成视图以及如…

    2025年12月10日
    000
  • 迁移 Laravel 项目:从 MS SQL Server 到 MySQL

    本文旨在指导开发者将基于 Laravel 框架且使用 MS SQL Server 数据库的项目迁移到 MySQL 数据库。文章将详细介绍在不迁移数据以及需要迁移数据两种情况下的具体步骤,包括数据库配置、缓存清理、路由测试以及数据库结构重建等操作,并提供必要的代码示例和注意事项,帮助开发者顺利完成迁移…

    2025年12月10日
    000

发表回复

登录后才能评论
关注微信