MySQL架构

对于这个庞然大物,MySQL很难形成一套正式的定义和规范。大部分代码都是早期写的,当初并没有按照一个未来大系统的代码来写,而倾向于为了解决某写具体问题而编写。尽管如此,它写得足够优美足够长远,达到拥有足够优质的代码段来组装成一个数据库服务软件的程度。

内核模块 (Core Modules)

在本部分我努力尝试了确定系统的核心模块,不过,我申明一下,我只是尝试让现在存在的东西变得正式一些。 MySQL的开发者极少考虑这些术语,更确切地说,他们倾向思考文件、目录、类、结构体和函数等。“这出现在mi_open()”要比“这发生在MyISAM存在引擎层上”更常被听到。因为MySQL开发者对代码太了如指掌了,所以他们能够从函数、结构体及类这个层面考虑问题。他们会发现这部分中的抽象概念毫无用处。但这对于那些常常考虑模块和管理方面术语的人来说还帮助的。

就MySQL而言,我使用“模块”这个术语是相当的不严谨。不像大家常说的那种模块,在很多情况下,你并不能轻松地拔出并用另一种实现来替换。模块的代码散布在好几个文件之中,而且你会从同一个文件中找到不同模块的代码。老代码中尤为如此。新的代码与模块代码模式融合得更好一些。所以,在我们的定义中,模块就是一段在某些方面理论上属于一起,并在服务中提供某些关键功能表的代码。

我们可以在服务中确认以下的模块:

  • 服务初始化模块 (Server Initialization Module)
  • 连接管理器 (Connection Manager)
  • 线程管理器 (Thread Manager)
  • 连接线程 (Connection Thread)
  • 用户权限认证模块 (User Authentication Module)
  • 访问控制模块 (Access Control Module)
  • 语法解析器 (Parser)
  • 命令调度器 (Command Dispatcher)
  • 查询缓存模块 (Query Cache Module)
  • 优化器 (Optimizer)
  • 表单管理器 (Table Manager)
  • 表单更新模块 (Table Modification Module)
  • 表单维护模块 (Table Maintenance Module)
  • 状态报告模块 (Statud Reporting Module)
  • 抽象存储引擎接口/表处理器 (Abstracted Storage Engine Interface/Table Handler)
  • 存储引擎实现(Storage Engine Implementation: MyISAM, InnoDB, MEMORY, Berkeley DB)
  • 日志模块 (Logging Module)
  • 复制主库模块 (Replication Master Module)
  • 复制从库模块 (Replication Slave Module)
  • 客户端/服务器协议API (Client/Server Protocol API)
  • 低层网络I/O API (Low-Level Network I/O API)
  • 内核API (Core API)

内核的交互 (Interaction of the Core Modules)

当服务以命令行模式启动时,初始化模块开始起作用。它解析配置文件和命令行参数,申请全局的内存,初始化全局全量和结构体,加载访问控制表,并执行大量其它的初始化任务。一旦初始化的工作完成,初始化模块把控制权交给连接管理器,连接管理器开始用轮询的方式监控听从客端户过来的连接。

当一个客户端连接数据库服务器时,连接管理器执行一个低层网络协议的任务,然后把控制权交给线程管理器,它依次提供线程来处理连接(从现在开始我们把他称作连接线程了)。连接线程可能会被创建一个新的,或从线程缓存中重找一个并激。当连接线程拿到控制权,它首先调用用户权限模块。当前连接用户的身份得到证实,客户端就可以发出请求了。

连接线程把请求数据传递给命令调试器。有些在MySQL的代码中被称为命令的请求可以直接被命令调试器处理,而更复杂的请求需要转发到另外的模块。一个典型的命令可以是请求服务器执行一个查询,改变当前使用数据库(use),报告状态,发送一个复制更新的连续转储(也就是一组sql语句),或执行一些其它的操作。

在MySQL服务器的术语中,有两种客户端的请求:查询与命令。查询是要经过解析器的所有请求。而命令是不用调用解析器就能执行的请求。我们将在本书的内容中用到查询(query)这个术语,所以不仅仅是SELECT被叫做查询,DELETE或 UPDATE也被叫做查询。有时我们也把查询叫SQL语句。

如果所有的查询日志是打开的,命令调试器会要求日志模块在调度之前将查询和命令记录到纯文本日志中。所以在全日志配置的情况下所有的查询都将被记录下来,即使在语法错误根本没有并执行并随后立即返回一个错误这种情况下。

命令调度器经由查询缓存模块将请求转发给分析器。 查询缓存模块检查查询是否是可以被缓存的类型,并检查是否存在仍然有效的之前运算并缓存下来的结果。在命中的情况下,执行在此刻发生短路,被缓存的结果被返回给用户,连接线程接到控制权并开始准备处理另一个命令。如果查询缓存模块没有命中,查询将转到解析器,它将根据查询的类型判断控制权将如何跳转。

我们可以确认下列的几种模块可以接着继续前进:优化器,表更新模块,表维护模块,复制模块,状态报告模块。Select查询被转化到优化器;updates, inserts, deletes 和创建表及更改表结构的查询跳转到各自的表更新模块;检查, 修复,更新索引统计和整理表碎片的查询跳转到表维护模块;复制相关的语句跳转到复制模块;查询状态的语句跳转到状态报告模块。还有大量的表更新模块:Delete模块,Create模块,Update模块,Insert模块和Alter模块。

在这个时候,每个从解析器获得控制权的模块将查询中涉及到的表单列表传递给访问控制模块,然后在可以访问的情况下将列表传到表管理器,表管理器打开表并获取到必要的锁。现在表操作模块将继续进行它的任务并将向抽象存储引擎模块发送大量的请求以完成低层操作,如插入或更新一条记录,根据关键字获取记录行,或执行一个表级操作,例如修复表或更新索引统计信息。

抽象存储引擎模块将利用对象的多态性自动将请求转化为具体存储引擎的对应的方法。换句话说,在处理一个存储引擎对象时,调用者以为处理一个抽象类型,而实际上处理的是一个更具体的类型。换句话说,当处理一个存储引擎对象时,调用者以为在处理一个抽象类型,而实际上这个对象是更具体的类型:即给定表类型所对应的那个存储引擎对象。接口方法是个虚拟的,用来创建透明的效果。正确的方法将被调用,而调用者并不需要关心存储引擎的具体类型。

一旦查询或命令开始被处理,相关的模块可能会将一部分有效的结果发送到客户端。也有可能会发送一些警告信息或是一条错误信息。如果一个错误发生了,服务器端和客户端都会明白这个查询或命令失败了,并会采取合适的措施。客户端不会再接受任何与该查询的有关结果集、警告或错误消息,但当接服务器端发送错误(信号)之后还会一直接受对连接线程控制。注意当MySQL为了稳定性和扩展性而没有使用异常的话,在所有层级的所有调用都必须采用适当的传输控制手段来检查针对这种情况的错误。

如果低层的模块用某种方式更改了数据,并且二进制更新日志也是激活的话,这个模块也将负责请求日志模块将更新事件记录到二进制更新文件中去,除了MySQL开发者和高级用户把它叫作二进制日志外,有时它还叫复制日志。

一旦任务完成,执行流程将回到连接线程,连接线程执行必要的清理工作并等待另一个来自客户端的查询或命令。会话将会在一直保持,直到客户端发送退出命令。

除了与常规的客户端交互以外,服务器端还会从一个复制从服务器上接受连续读取二进制更新日志的命令。这个命令被复制主库模块处理。

如果服务器被配置为复制从库,初始化模块将调用复制从库模块,它将依次起动两个线程,SQL线程和I/O线程。它们负责将主库上发生的更新传递到从库上。一台机器有可能被同时定义为主库和从库。 带有客户端的网络通信将会通过客户端/服务器协议模块,它负责对数据按一定的格式打包,并根据连接设置进行压缩。客户端/服务器协议依次使用低层的网络I/O模块,网络I/O模块可以在不同的平台之间在socket级接发数据。当连接设置了安全相关参数时,客户端/服务器协议也负责用OpenSSL包对数据进行加密。 当在执行各模块任务的时候,核心组件严重依赖核心API。核心API提供丰富的函数集,包括文件I/O、内在管理、字符串操作、各种数据结构与算法的实现以及很多其它有用的功能。应该鼓励MySQL开发者避免直接调用libc包,而是使用核心API使得将来的平台移植及代码优化变得更容易。

图1-1 阐明了核心模块与其它模块的交互

"高层MySQL模块视图" 图1-1 高层MySQL模块视图

详述内核模块

现在,我们将更近距离地接触每个组件。讨论的目的之是把之前提到的概念与实际的代码关联起来。另外,我们将会提及每个组件的部分历史并试着评估其将来的发展之路。

经常提到的源码将会被编译,其实你会发现将提及的文件用文本编辑器打开并定位到函数引用的位置是很有帮助的。调试器也会做同样的事,第3章会提到,那章也会告诉你如何拿到源码。

服务初始化模块

服务初始化模块负责服务在启动时的初始化工作,大多数代码可以在sql/mysqld.cc中找到。入口就是C/C++程序员所期望的:main()。下面是其它一些有趣的函数。如果所有文件没有标明,就在sql/mysqld.cc中。

  • init_common_variables()
  • init_thread_environment()
  • init_server_components()
  • grant_init() 在sql/sql_acl.cc
  • init_slave() 在sql/slave.cc
  • get_options()

虽然这些代码在3.22版中被创建之后就再也没有被从头重写过,但它被很具有意义地重构为将其做为新功能加入到MySQL中。一个大的初始化代码的变化是过去在main()下的函数在代码的生命周期中渐渐被重组为大量的辅助函数了。此外,当4.0版本的核心模块API模块的选项解析功能有效时,命令行和配置文件选项的解析也从GUN的getopt()转换为MySQL的核心API选项解析了。

在5.1版本中,一个具有重大意义的初始化插件的功能加到init_server_components()中。 总体来说,这段代码是相当稳定的。基于过去的历史,我们可以预言:将来在启动时需要特殊的初始化工作时,这段代码将要加入新的特性。无论如何,要重写这段代码是不太可能的。

连接管理器

连接管理器监听来自客户端的连接,分派这些请求到线程管理器。该模块也就是sql/mysqld.cc中的一个函数:handle_connections_sockets()。尽管如些,由于它在服务运行中担当的决定性的角色,值得被划分为一个单独的模块。大量的#ifdef指令昭示着将网络代码移植到种种操作系统上的挑战。

随着时间的推移,这段代码或多或少都在慢慢进化以适应不同操作系统下的奇奇怪怪的网络系统的调用。将来更多的更改可能是尝试新的移植,或是不同的操作系统供应商引进新的接口到新版的产品中。

线程管理器

线程管理器负责保持跟踪线程并保证一个线程被分派去处理客户端连接。这是另一个小的模块。大多数代码在sql/mysqld.cc中。入口是create_new_thread()。另一个有意思的函数是同一文件中的start_cached_thread()。

要注意的是在sql/sql_class.sh中定义了THD类并在sql/sql_class_cc中实现了它,成为了这个模块中的一部分。THD类型的对象是线程描述符(THead Descriptor),在大多数的服务模块中是至关重要的。很多函数将第一个参数设置为THD的指针。

线程管理器的代码在3.23的版本中加入了线程缓存后进行了大量的重写,自那时起代码就没有被明显改动过。将来不愿再对代码做任何明显的改动自在情理之中。

然而在我的概念中,关于将THD类当成这个模块的一个部分这个改动还有另外一个不同的故事。诸如预编译语句(prepared statements)、服务器端的游标以及存储过程等新加的、特性导致了4.1版和5.0版中THD类代码的大量重写。它现在是Query_arena、Statement和Open_tables_state类的父类,这些类也被定义在sql/sql_class.h中。

连接线程模块

连接线程是在已建立的连接上处理客户端请求的重点。这个模块也相当的小。它只由一个函数组成:在sql/sql_parse.cc中的handle_one_connection()。尽管如此,不考虑它的大小,见于它在服务中起扮演的角色,它也值得被归类为一个模块。

代码随时间进化,当各种调用THD变量的初始化工作被移至THD类之后,它渐渐变得简洁且易读。这段代码在将来不要做太多修改的愿望也是合情合理的。

用户权限认证模块

用户权限认证模块验证来连接的用户并初始化该用户所在权限级别的结构体及变量。该模块的入口是sql/sql_parse.cc中的check_connection()。但这个功能的其它部分在sql/sql_acl.cc和sqlpassword.cc中。一些有意思的检查的函数包括:

  • acl_check_host() sql/sql_acl.cc中
  • check_random_string() sql/password.cc中
  • check_user() sql/sql_parse.cc中
  • acl_getroot() sql/sql_acl.cc中

代码只在4.1版本中被明显地重写过一次。由于这个改动可能会带来影响,MySQL开发者为更新需要一个更安全的认证机制的协议耽误过一阵子。

自那以后,他们没有对代码做太多的改动。但是,随着5.1版中plug-in新功能的加入,MySQL开发者打算加入可插拔的认识与角色功能,这将引起代码的改动。

访问控制模块

访问控制模块来验证客户端的用户是否有足够的权限来执行请求的操作。大多数代码都在sql/sql_acl.cc中,一个非常常用的函数check_access()却在sql/sql_parse.cc中。下面列了其它一些我们关心的函数,除了特别指出的外,都能在sql/sql_acl.cc中找到。

  • check_gran()
  • check_table_access() sql/sql_parse.cc
  • check_grant_column()
  • acl_get()

自从3.22版本之后这些代码就没怎么动过。但在4.0版中加入过新的权限类型,这稍微改变了其它代码的使用方法。MySQL开发者打算加入角色的支持,这也会起对该模块大的改动。

解析器

解析器负责解析请求并构造一颗解析树。模块的入口是sql/sql_parse.cc中的mysql_parse(),它执行一些初始化工作,然后调用sql/sql_yacc.cc中由GNU Bison生成的yypaser(),GNU Bison在sql/sql_yacc.yy中,包含了MySQL所能理解的SQL语言集合的定义。要注意的是,不像其它很多的开源项目,MySQL用自己的语法扫描器代替lex(一个词法分析器生成工具)。关于MySQL语法扫描器会在第九章详细谈到。除了刚刚提到的之外,另外一些相关的文件还包括:

  • sql/gen_lex_hash.cc
  • sql/lex.h
  • sql/lex_symbol.h
  • sql/lex_hash.h(生成的文件)
  • sql/sql_lex.h
  • sql/sql_lex.cc
  • sql/目录下以item_开头的,以.h或.cc为后缀的一件文件

当有新的SQL的特征增加时,解析器要同步变更以适应新的情况。当然,解析器的核心结构相当稳定,到目前为止还是能适应增长。预计当有新的元素加入时,核心代码不会变动太多。MySQL的开发者曾经,其实有时一直在讨论将核心代码重写并移出yacc/Bison以提高速度。就这样,他们已经讨论了至少7年了,到目前还没有被列为优先解决的问题。

命令调度器

命令调度器负责将请求分派到知道该如何处理它们的低层的模块中。它由sql/sql_parse.cc中的do_command()和dispatch_command()两个函数组成。

随着可被支持的命令的增加,这个模块也在变大。将来代可能会发生小幅的增大,但核心结构不太可能有变动。

查询缓存模块

查询缓存模块缓存查询结果,每当有缓存结果时,通过返回已经缓存的结果集来缩短查询周期。该模块的实现在sql/sql_cache.cc中。一些用到的方法包括:

Query_cache::store_query()
Query_cache::send_result_to_client()

该模块是在4.0版中被加入的。除了修正一些bug之外,将来很少会被改动。

优化器

优化器负责生成响应查询的最佳策略,执行并将结果返回给客户端。这可能是MySQL代码中最复杂的一个模块了。入口是sql/sql_select.cc中mysql_select()函数。这个函数将会在第九章中进行讨论。其它一些用到的函数和方法都在sql/sql_select.cc中,包括: * JOIN:prepare() * JOIN:optimize() * JOIN:exce() * make_join_statistics() * find_best_combination() * optimize_cond()

当你深入到优化器的深度时,你会发现这是一个值得一观的洞穴。范围优化器(range optimizer)是一个单独存放在sql/opt_range.cc中的完全与优化器隔离开并足够复杂的优化器,负责优化使用索引来检索位于一个或多个给定的范围内的值。范围优化器的入口是SQL_SELECT::test_quick_select()

优化器一直处理更改的状态。4.1版中在另一个复杂的层中加入了子查询。5.0中加入了贪婪搜索(greedy search)来优化表的关联顺序,并让每个表能用到多个索引(索引合并)。预计将来会有大量的修改。一个期待已久的改变就是子查询优化。

表单管理器

表单管理器负责创建、读取更新表定义文件(.frm后缀的)、维护被叫做table cache的表单描述符的缓存和管理表级锁。大多数据代码在sql/sql_ base.cc、sql/table.cc、sql/unireg.cc和sql/lock.cc中。这个模块将在第9章中详解。一些被用到的函数包括:

  • openfrm() sql/table.cc中
  • mysql_create_frm() sql/unireg.cc中
  • open_table() sql/sql_base.cc中
  • open_tables() sql/sql_base.cc中
  • open_ltable() sql/sql_base.cc中
  • mysql_lock_table() sql/lock.cc中

这些代码自3.22版之后就没怎么动过,除了4.1版本中加入新的表格式外。在过去,Monty曾表达过对这些低效的table cache代码的不满并打算重写。但此后并没有列入到最重要的事中。尽管如此,一些改进在5.1版中有所体现。

表单更新模块

这一系列模块负责对表的create/delete/rename/drop/update/insert等操作,在代码上也有着明显的区别,篇幅所限,恕不详叙。尽管如此,一旦你对其它的代码熟悉了,你可以阅读源码并通过以下的入口毫不费力地进行调试并找出它们之间的区别:

  • mysql_update()和mysql_multi_update() sql/sql_update.cc中
  • mysql_insert() sql/sql_insert.cc中
  • mysql_create_table() sql/sql_table.cc中
  • mysql_alter_table() sql/sql_table中
  • mysql_rm_table() sql/sql_table中
  • mysql_delete() sql/sql_delete.cc中

Update和Delete模块在4.0版中因加入多表更新和删除而做了大量改动。为了支持4.1版的预编译语句(prepared statement)和5.1中触发器,Update、Insert和Delete模块也做了一些重组。除了时不时有一些极小的性能提升外无其它太大的动作。将来很大的一部分代码将会保持原貌。

表单维护模块

表单维护模块负责如check、repair、backup、restore、optimize(defragment)和analyze(更新关键字分布统计)等操作。代码可以在sql/sql_table.cc中找到。核心函数是mysql_admin_table()以及下面的好使的封装: * mysql_check_table() * mysql_repair_table() * mysql_backup_table() * mysql_restore_table() * mysql_optimize_table() * mysql_analyze_table() * mysql_admin_table()将请求进一步转发给相应的存储引擎的方法。大量的工作产生在存储储引擎级别。

在3.23版本中引入该模块以提供表单维护的SQL接口,在此之前表单维护必须在线下执行。在4.1版本中对网络协议模块进行了大量的修改以支持预编译语句。它影响了所有的对客户端有回馈的模块,包括表单维护模块。其它方面自引入以来就没有太多的更动,将来也不会有。

状态报告模块

状态报告模块负责响应服务器配置、性能跟踪变量、表结构信息、复制(replication)进程及table cache的状态等等相关的请求。它处理以show开头的查询。大多数代码在sql/sql_show.cc中。一些有趣的函数除了指明的外都在sql/sql_show.cc中: * mysqld_list_processes() * mysqld_show() * mysqld_show_create() * mysqld_show_fields() * mysqld_show_open_tables() * mysqld_show_warnings() * show_master_info() sql/slave.cc中 * show_binlog_info() sql/sql_repl.cc中

该模块被持续地改进。加了新的状态报告功能,就会加入新的函数,这种模式会一直延续。

抽象存储引擎接口(表处理器)

该模块其实就是一个叫handler抽象类和一个叫handlerton的结构体。handerton结构体是在5.1中为plug-in集成加入的,它提供了一个标准化的接口来执行低层的存储与检索操作。

表处理器在sql/handler.h中定义,部分在sql/handler.cc中实现。从它派生的具体的存储引擎类必须实现所有父类的纯虚函数。这将在第9章更详细地讨论。

该模块在3.23版本为了帮助集成BerkeleyDB的表而引入。它产生了非常深远的影响:现在各种各样的低层的存储引擎可以相当轻易地放到MySQL下。在集成InnoDB的过程中,代码也得到了很好的提炼。在将来该模块在很大程序上依赖于什么样的存储引擎将被集成进来以及已经存在的存储引擎变化。比如,有时下面的一些存储引擎的新特性要求添加新接口使得对高层的模块可用。

存储引擎实现(MyISAM, InnoDB, MEMORY, Berkeley DB)

每一种存储引擎都通过继承前面提到的handler类提供了一个标准操作接口。继承类的方法依据具体存储引擎的低层调用定义了标准操作接口。这部分过程与单独的存储引擎将会在第10章中详解。为一睹为快起见,你可以先看一眼下面的少数有意思的文件与文件夹:

  • sql/ha_myisam.h与sql/ha_myisam.cc
  • sql/ha_innodb.h与sql/ha_innodb.cc
  • sql/ha_heap.h与sql/ha_heap.cc
  • sql/ha_ndbcluster.h与sql/ha_ndbcluster.cc
  • myisam/
  • innobase/
  • heap/
  • ndb/

自打在3.23版中存储引擎被第一次抽象后,只有三个完整的引擎:MyISAM,ISAM(老版的MyISAM)和MEMORY。(注意MEMORY存储引擎早期叫HEAP,在源码中一些文件和文件夹中还能反映出早期名字的痕迹)。然而随着BerkeleyDB,MERGE,InnoDB以及近期涌显出来的NDB MySQL集群等引擎的加入,这个列表飞速增大。大多数存储引擎仍然在开发阶段,我们将来会看到更多的新的引擎加入。

日志模块

日志模块负责维护更高层的(逻辑层)的日志。一个存储引擎出于自身目的可以另外管理自身更低层的(物理层或逻辑层)的日志,但日志模块不涉及这些,而由存储引擎自己掌管。这里所指的逻辑日志乃是二进制更新日志(也可用来做复制)、命令日志(用来系统监视与应用调试)和慢查询(用来跟踪不优化的查询)。

5.1版本之前,该模块大部分在MYSQL_LOG这个类中,该类在sql/sql_class.h中定义,在sql/log.cc中实现。5.1版对该模块进行了重写。现在有一系各层级的管理类,MYSQL_LOG是TC_LOG的父类,它们都在sql/log.h中。

当然,绝大多数日志的工作是在记录二进制复制日志。用来记录事件的创建与读取二进制复制日志的类在sql/log_event.h中定义,在sql/log_event.cc中实现。复制主库模块与复制从库模块也在很大程度上依赖日志模块的功能。

当复制引入进来后模块被大量修改过。5.0中分布式事务导致一些修改。5.1版中加入了像操作SQL表单那样搜索日志的功能,这导致了大量代码重构。二进制日志部分也做了大量的修改以适应基于行的复制。此时些刻很难预估这些代码将来会有什么改变。

复制主库模块

复制主库模块负责主库上的复制功能。该模块最常用的功能就是发送持续的复制日志事件反馈到请求的从库。大部分代码在sql/sql_repl.cc中。核心函数是mysql_binlog_send()。

该模块在3.23版中加入,它除了一次将大量代码从函数中隔离出的的彻底的清理外没有经历任何大的更动。起初,这些代码都有着雄心勃勃的自动防止故障的开发计划。但是当这些计划要实施的时候,MySQL从爱立信拿到了NDB集群的代码,并开始走上自动故障处理终极目标的另一条路。根据那些开发情况,此时本地的MySQL在复制如何发展这一点上还不明朗。

这个模块将会在12章中进行更详细的讲解。

复制从库模块

复制从库模块负责从库上的复制功能。从库的职责就是从主库上获取更新,然后在从库上再应用一遍。在4.0版中,从库起动两个线程。网络I/O线程向主库请求并接收持续的更新反馈,并将他它记录为本地中继日志。SQL线程将在将他们从中继日志中读出来之后再应用。这些代码在sql/slave.cc中。要学习的最重要的函是handle_slave_io()和handle_slave_sql()。

该模块在3.23中与复制主库模块一同加入。在4.0中在一起的从库线程分解为SQL线程与I/O线程时这部分代码经过一次大量的改动。

该模块将在第12章有更详细的讨论。

客户端/服务器协议API

MySQL客户端/服务器通信协议在协议栈中位于操作系统协议(TCP/IP或本地socket)之上。该模块实现了跨平台创建、读到、解读和发送协议包的API。代码在sql/protocol.cc,sql/protocol.h和sql/net_serv.cc中

sql/protocol.h和sql/protocol.cc定义和实现了一系列的类。Protocol是基类,Protocol_simple、Protocol_prep和Protocol_cursor继承了他。模块中一些有趣的函数如下:

  • my_net_read() 在sql/net_serv.cc中
  • my_net_write() 在sql/net_serv.cc中
  • net_store_data() 在sql/protocol.cc中
  • send_ok() 在sql/protocol.cc中
  • send_error() 在sql/protocol.cc中

4.0版中该模块为支持4GB的包而被修改过,在此之前,包的上限是24MB。该模块的类层次结构是在4.1中为处理预编译语句而加入的。看起来该层面的大多数问题已经被解决了,将来也不会有太多的代码改动。但开发者在考虑加入消息支持。

该模块会在第5章做更详细的讨论。

低层网络I/O API

低层网络I/O API提供一个低层网络I/O和SSL会话的抽象。代码在vio/文件夹下,该模块的甩的函数都是在vio_开头了。 在需要支持SSL连接的需求刺激下,该模块在3.23中被引入。抽象低层的网络I/O也更方便了往新操作系统上的移植与维护老的端口。

核心API

核心API是MySQL的瑞士军刀。它提供了可移植的文件I/O、内存管理、字符串操作、文件系统导航、格式化打印,一个数据结构与算法的集合和大量的其它的功能。如果遇到一个问题,经常会在核心API中能找到解决方法,如果没有,那它正在开发中。该模块在很大程度上是Monty能力的体现,也不是为了仅仅去解决一个问题,它可能是MySQL神器的核心组件。

代码在mysys/和strings/文件夹下。大多数核心API的函数是my_开头。 这个模块已经在壮大与提高的路上。当有新的功能加入时,关注点是保持它的稳定性及高层的性能上。这种风格将一如既往。

该模块会在第3章详述。

发表评论