




已阅读5页,还剩22页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Mysql 源代码分析系列 2 源代码结构 Mysql 源代码主要包括客户端程序代码 服务器端代码 测试工具和一些库构成 下面我们对比较重 要的目录做些介绍 BUILD 这个目录在本系列的上篇文章中我们仔细看过 内含各种平台的编译脚本 这里就不仔细说了 client 这个目录下有如下比较让人眼熟的文件 mysql cc mysqlcheck c mysqladmin cc mysqlshow c 等等 如果你编译一下就会发现那些眼熟的程序也出现了 比如 mysql 明白了吧 这个目录就是那 些客户端程序所在的目录 这个目录的内容也比较少 而且也不是我们阅读的重点 Docs 这个目录包含了文档 storage 这个目录包含了所谓的 Mysql 存储引擎 storage engine 存储引擎是数据库系统的核心 封装了 数据库文件的操作 是数据库系统是否强大最重要的因素 Mysql 实现了一个抽象接口层 叫做 handler sql handler h 其中定义了接口函数 比如 ha open ha index end ha create 等等 存储引擎需要实现这些接口才能被系统使用 这个接口定义超级复杂 有 900 多行 不过我们暂 时知道它是干什么的就好了 没必要深究每行代码 对于具体每种引擎的特点 我推荐大家去看 mysql 的在线文档 应该能看到如下的目录 innobase innodb 的目录 当前最流行的存储引擎 myisam 最早的 Mysql 存储引擎 一直到 innodb 出现以前 使用最广的引擎 heap 基于内存的存储引擎 federated 一个比较新的存储引擎 example csv 这几个大家可以作为自己写存储引擎时的参考实现 比较容易读懂 mysys 包含了对于系统调用的封装 用以方便实现跨平台 大家看看文件名就大概知道是什么情况了 sql 这个目录是另外一个大块头 你应该会看到 mysqld cc 没错 这里就是数据库主程序 mysqld 所在的 地方 大部分的系统流程都发生在这里 你还能看到 sql insert cc sql update cc sql select cc 等等 分别实现了对应的 SQL 命令 后面我们还要经常提到这个目录下的文件 大概有如下及部分 SQL 解析器代码 sql lex cc sql yacc yy sql yacc cc sql parse cc 等 实现了对 SQL 语句的 解析操作 handler 代码 handle cc handler h 定义了存储引擎的接口 item 代码 item func cc item create cc 定义了 SQL 解析后的各个部分 SQL 语句执行代码 sql update cc sql insert cc sql select cc sql show cc sql load cc 执行 SQL 对应的语句 当你要看 SELECT 的执行的时候 直接到 sql select cc 去看就 OK 了 辅助代码 net serv cc 实现网络操作 还有其他很多代码 vio 封装了 virtual IO 接口 主要是封装了各种协议的网络操作 plugin 插件的目录 目前有一个全文搜索插件 只能用在 myisam 存储引擎 libmysqld Mysql 连接库源代码 开源函数库目录 和所有的开源项目一样 Mysql 也使用了一些开源的库 在其代码库中我们能看到 dbug pstack strings zlib 等 多说无益 主要是对于 mysql 的代码目录有个概念 要找的时候也有个方向 万一要找某个东西找不 到了就只能 grep 了 Mysql 源代码分析系列 3 主要调用流程 引言 本文主要介绍 Mysql 主要的调用流程 将从代码的角度来看一个从用户发出的 select from test SQL 命令在服务器内部是如何被执行的 从我个人的经验来看 阅读理解大规模项目的代码最重要的 两个方面 一是了解主要的数据结构 二是了解数据流 在这里主要是调用流程 把这两个主线把握 住以后 大部分代码都是比较容易阅读的 Mysql 的源代码属于比较好读的类型 因为函数的调用关 系比较明确 难读的代码一般都充斥着大量的回调 异步调用 很可能你极难找到某个函数在哪里或 什么时候被调用了 当然 算法的实现代码也很难读 幸好 Mysql 不是那种难读的类型 所以我们也 不要害怕 大步向前吧 主要执行过程 从架构上来看 Mysql 服务器对于一条 SQL 语句的执行过程可以分成如下几部分 接受命令 包括用户验证 资源申请等 V 命令解析 解析 SQL 语句 生成语法树 V 寻找执行计划 根据解析出来的语法树 找到可能的执行计划 对于一条 SQL 语句 很可 能会有多种执行方案 特别是在 SQL 语句比较复杂的时候 这里需要对于各种可能的方案进行代价评 估 最快的找到最有的执行方案 V 优化执行计划 优化执行计划 这是 SQL 执行中最复杂的部分之一 据说全都是由数学博 士们写出来的 而且比较难懂 我目前还处于不懂的状态 V 执行 没啥可说的 只剩执行及返回结果了 系统启动 所有的程序都从 main 开始 mysqld 也不例外 打开 sql mysqld cc 稍加搜索 你就能看到熟悉的 main 函数 我们可以将其进行如下简写 int main int argc char argv logger init base init common variables MYSQL CONFIG NAME argc argv load default groups 解析配置文件和命令行参数 将配置文件中的内容转 行成命令行参数 init signals user info check user mysqld user set user mysqld user user info init server components 初始化服务器模块 network init 初始化网络模块 根据配置 打开 IP socket unix socket windows named pipe 来进行监听 start signal handler 开始接收信号 acl init 初始化 ACL Access Control List servers init 0 服务器初始化 init status vars 状态变量初始化 create shutdown thread 创建关闭线程 create maintenance thread 创建维护线程 sql print information 打印一些信息 handle connections sockets 0 主要的服务处理函数 循环等待并接受命令 进 行查询 返回结果 也是我们要详细关注的函数 wait for exit 服务要退出 cleanup exit 0 可以仔细的看看这个简写的 main 函数 逻辑很清楚 就算没有我的这些注释大部分人也能容易的理 解整个系统的执行流程 其实完整的 main 函数有接近 300 行 但是中心思想已经被包含在这里简短 的十几行代码中了 通过看这些代码 读者会发现 mysqld 是通过多线程来处理任务的 这点和 Apache 服务器是不一样的 等待命令 mysqld 等待和处理命令主要在 handle connections sockets 0 来完成 这里我们仔细看看这个函 数调用发生了什么 该函数也在 mysqld cc 中 也有大概 300 行 我们继续简写 为了方便分析 这里我们假定配置服务器通过 unix domain socket 来监听接受命令 其他方式类同 pthread handler t handle connections sockets void arg attribute unused FD ZERO FD SET unix sock unix socket 在 network init 中被打开 socket flags fcntl unix sock F GETFL 0 while abort loop abort loop 是全局变量 在某些情况下被置为 1 表示要退出 readFDs clientFDs 需要监听的 socket select int max used connection select 异步监听 当接收到时 间以后返回 sock unix sock flags socket flags fcntl sock F SETFL flags O NONBLOCK new sock accept sock my reinterpret cast struct sockaddr 接受请求 getsockname new sock thd new THD 创建 mysqld 任务线程描述符 它封装了一个客户端 连接请求的所有信息 vio tmp vio new new sock VIO TYPE SOCKET VIO LOCALHOST 网络操作抽象层 my net init 初始化任务线程描述符的网络操作 create new thread thd 创建任务线程 看到这里 大家应该已经基本清楚 mysqld 如何启动并进入监听状态 真正的命令处理就是在 create new thread 里面 看名字也知道就是创建一个新线程来处理任务 怎么样 是不是觉得 mysql 的代码很好懂呢 呵呵 更坚定了要继续读下去的信心 一条语句的执行 下面具体看看服务器如何执行语句 insert 语句的 上一节我们提到 create new thread 是所有处理的入口 这里我们仔细看看它到底干了什么 幸运的 是 它也在 mysqld cc 里面 我们不费吹灰之力就找他了它 static void create new thread THD thd NET net if connection count max connections 1 abort loop 看看当前连接数 是不是超过了系统配置允许的最大值 如果是就断开连接 close connection thd ER CON COUNT ERROR 1 delete thd connection count thread scheduler add connection thd 将新连接加入到 thread scheduler 的连接队 列中 现在看来关键还是在 thread scheduler 干了什么 现在打开 sql scheduler cc 文件 void one thread per connection scheduler scheduler functions func func max threads max connections func add connection create thread to handle connection func end thread one thread per connection end 再看 create thread to handle connection 它还是在 mysqld cc 中 哈哈 void create thread to handle connection THD thd if cached thread count wake thread thread cache append thd pthread cond signal else threads append thd pthread create 恩 看来先是看当前工作线程缓存 thread cache 中有否空余的线程 有的话 让他们来处理 否 则创建一个新的线程 该线程执行 handle one connection 函数 很好 继续往下看 到了 sql sql connection cc 中 pthread handler t handle one connection void arg thread scheduler init new connection thread setup connection thread globals thd for lex start thd login connection thd 进行连接身份验证 prepare new connection state thd do command thd 处理命令 end connection thd do command 在 sql sql parse cc 中 bool do command THD thd NET net packet length my net read net packet char net read pos command enum enum server command uchar packet 0 解析客户端穿过来 的命令类型 dispatch command command thd packet 1 uint packet length 1 再看 dispatch command bool dispatch command enum enum server command command THD thd char packet uint packet length NET net thd command command switch command case COM INIT DB case COM TABLE DUMP case COM CHANGE USER case COM QUERY alloc query thd packet packet length mysql parse thd thd query thd query length 进行 sql 语句解析 void mysql parse THD thd const char inBuf uint length const char found semicolon lex start thd if query cache send result to client thd char inBuf length lex 解析过后的 sql 语句的语法结构 TABLE LIST all tables lex query tables 该语句要访问的表的列表 switch lex sql command case SQLCOM INSERT insert precheck thd all tables mysql insert thd all tables lex field list lex many values lex update list lex value list lex duplicates lex ignore break case SQLCOM SELECT check table access thd lex exchange SELECT ACL FILE ACL SELECT ACL all tables UINT MAX FALSE 检查用户对数据表的访问权限 execute sqlcom select thd all tables 执行 select 语句 break Mysql 源代码分析系列 4 主要调用流程 续 在上一篇文章中我们讲到了的 mysql execute command 这个函数根据解析出来的 SQL 命令分别调用 不同的函数做进一步处理 我们这里先看 INSERT 命令的处理流程 其对应的处理函数是 mysql insert 在 sql sql insert cc 中 还是很长 大概 300 多行 bool mysql insert THD thd TABLE LIST table list 该命令要用到的表 List mysql prepare insert foreach value in values list write record 其实里面还有很多处理 trigger 错误 view 之类的 我们暂时都忽略 写数据记录 int write record THD thd TABLE table COPY INFO info if info handle duplicates DUP REPLACE info handle duplicates DUP UPDATE table file ha write row table record 0 table file ha update row table record 1 table record 0 else table file ha write row table record 0 不用说 这里我们还是省略了好多东西 要注意的是这里调用的 table file ha write row 和 table file ha update row 在 sql table h 可以看到 table 的定义 其中 file 被定义成 handler file 那 handler 是什么 对了 这就是我们前面提到的数据存储抽象层 所有的存储引擎都必须 事先这里定义的接口 才能被 mysql 使用 在这里使用的具体的接口操作是 ha write row 和 ha update row 这两个函数可以在 sql handler cc 中看到 比如 ha write row int handler ha write row uchar buf write row buf 调用具体的实现 binlog log row table 0 buf log func 写 binlog 下面我们看看在 myisam 中是怎么实现的文件操作 代码在 storage myisam ha myisam cc 中 先看 write row 723 int ha myisam write row uchar buf 724 725 ha statistic increment 726 727 If we have a timestamp column update it to the current time 728 if table timestamp field type 730 731 732 If we have an auto increment column and we are writing a changed row 733 or a new row then update the auto increment value in the record 734 735 if table next number field 738 if error update auto increment 739 return error 740 741 return mi write file buf 真正写文件 742 再看 mi write 函数 很好找 就在 storage myisam mi write c 我们就不再分析下去了 具体实现 和 myisam 使用的文件格式相关 有兴趣的可以参考 myisam 的相关文档 结语 写到这里 我们对于 mysql 执行 sql 语句的主要调用流程就有了大概的了解 但是真正的难点往往在 细节中 我也刻意逃避了这些细节 但是还是应该列一下相关的内容 Sql 语句的解析和相关数据结构 Sql 语句的描述数据结构 执行优化相关算法 数据存储殷勤抽象层的定义和交互 存储引擎的具体操作和文件格式 必须要提到的是 这些地方的代码都比较难懂 而且核心函数都很长 非常不便与理解 有需要的人 可以选一些方面具体深入 但要面面俱到就需要很多时间了 Mysql 源代码分析 5 Plugin 架构介绍 Mysql 现在很多模块都是通过 plugin 的方式连接到 Mysql 核心中的 除了大家熟悉的存储引擎都是 Plugin 之外 Mysql 还支持其他类型的 plugin 本文将对相关内容做一些简单介绍 主要还是以架构 性的介绍为主 具体细节会提到一点 但是肯定不会包括所有的细节 主要数据结构和定义 大部分的数据接口 宏和常量都定义在 include mysql plugin h 中 我们来慢慢看 先看 plugin 的类型 define MYSQL UDF PLUGIN 0 User defined function define MYSQL STORAGE ENGINE PLUGIN 1 Storage Engine define MYSQL FTPARSER PLUGIN 2 Full text parser plugin define MYSQL DAEMON PLUGIN 3 The daemon raw plugin type define MYSQL INFORMATION SCHEMA PLUGIN 4 The I S plugin type 开发者开发的 plugin 必须指定上述类型之一 类型包括用户自定义函数 存储引擎 全文解析 原 声 plugin 和 information schema plugin 最常见的是前三个 daemon plugin 一般用来在 mysqld 中启动一个线程 在某些时候干活儿 一个 plugin 的描述数据接口是 struct st mysql plugin int type the plugin type a MYSQL XXX PLUGIN value void info pointer to type specific plugin descriptor const char name plugin name const char author plugin author for SHOW PLUGINS const char descr general descriptive text for SHOW PLUGINS int license the plugin license PLUGIN LICENSE XXX int init void the function to invoke when plugin is loaded int deinit void the function to invoke when plugin is unloaded unsigned int version plugin version for SHOW PLUGINS struct st mysql show var status vars struct st mysql sys var system vars void reserved1 reserved for dependency checking 主要内容包括类型 名字 初始化 清理函数 状态变量和系统变量的定义等等 但是在使用的时候 一般不是直接使用这个数据结构 而是使用大量的宏来辅助 一个 plugin 的开始 define mysql declare plugin NAME MYSQL DECLARE PLUGIN NAME builtin NAME plugin interface version builtin NAME sizeof struct st plugin builtin NAME plugin plugin 定义结束 define mysql declare plugin end 0 0 0 0 0 0 0 0 0 0 0 0 MYSQL DECLARE PLUGIN 根据 plugin 是动态链接 plugin 还是静态链接 plugin 有不同的定义 ifndef MYSQL DYNAMIC PLUGIN define MYSQL DECLARE PLUGIN NAME VERSION PSIZE DECLS int VERSION MYSQL PLUGIN INTERFACE VERSION int PSIZE sizeof struct st mysql plugin struct st mysql plugin DECLS else define MYSQL DECLARE PLUGIN NAME VERSION PSIZE DECLS int mysql plugin interface version MYSQL PLUGIN INTERFACE VERSION int mysql sizeof struct st plugin sizeof struct st mysql plugin struct st mysql plugin mysql plugin declarations endif 特别要注意的是 ifndef MYSQL DYNAMIC PLUGIN 如果你要写的 plugin 是动态加载的话 需要 在编译的时候定义这个宏 总体而言 mysql declare plugin 申明了一个 struct st mysql plugin 数组 开发者需要在该宏之 后填写 plugin 自定义的 st mysql plugin 各个成员 并通过 mysql declare plugin end 结束这个数 组 看个例子 plugin daemon example daemon example cc 这是个动态 MYSQL DAEMON PLUGIN 类型的 plugin 注意到 plugin daemon example Makefile am 里面有 DMYSQL DYNAMIC PLUGIN 具体定义如 下 mysql declare plugin daemon example MYSQL DAEMON PLUGIN 这个定义经过 preprocess 被展开后定义为 int mysql plugin interface version MYSQL PLUGIN INTERFACE VERSION int mysql sizeof struct st plugin sizeof struct st mysql plugin struct st mysql plugin mysql plugin declarations MYSQL DAEMON PLUGIN 静态链接 plugin 也类似 只不过 plugin 宏展开出来的变量都有自己的名字 对于 myisam 生成了一 个叫 builtin myisam plugin 的 plugin 数组 plugin 可以定义自己的变量 包括系统变量和状态变量 具体的例子可以看看 storage innobase handler ha innodb cc 里面对于 innodb 插件的申明 结合 plugin h 还是比较 容易看懂的 在 mysql 的源代码里面 grep 一把 mysql declare plugin 看看都有哪些 plugin grep mysql declare plugin include cc rni plugin daemon example daemon example cc 187 mysql declare plugin daemon example sql ha partition cc 6269 mysql declare plugin partition sql log cc 5528 mysql declare plugin binlog sql ha ndbcluster cc 10533 mysql declare plugin ndbcluster storage csv ha tina cc 1603 mysql declare plugin csv storage example ha example cc 893 mysql declare plugin example storage myisam ha myisam cc 2057 mysql declare plugin myisam storage heap ha heap cc 746 mysql declare plugin heap storage innobase handler ha innodb cc 8231 mysql declare plugin innobase storage myisammrg ha myisammrg cc 1186 mysql declare plugin myisammrg storage blackhole ha blackhole cc 356 mysql declare plugin blackhole storage federated ha federated cc 3368 mysql declare plugin federated storage archive ha archive cc 1627 mysql declare plugin archive 呵呵 连 binlog 都是 plugin 哦 不过还是 storage plugin 占大多数 Plugin 初始化 在见面的介绍 main 函数的文章中我也提到了其中有个函数 plugin init 是初始化的一部分 这个东 东就是所有静态链接初始化 plugin 的初始化入口 该函数定义在 sql sql plugin cc 中 int plugin init int argc char argv int flags 初始化内存分配 pool init alloc root init alloc root hash 结构初始化 初始化运行时 plugin 数组 plugin dl array 用来保存动态加载 plugin plugin array 保存静 态链接 plugin 而且最多各自能有 16 个 plugin my init dynamic array my init dynamic array 初始化静态链接 plugin for builtins mysqld builtins builtins builtins 每一个 plugin 还可以有多个子 plugin 参见见面的 plugin 申明 for plugin builtins plugin info plugin register builtin plugin 初始化 plugin 调用 plugin 的初始化函数 将 plugin 的状态变量加入到状态变量列表中 将系统变量的 plugin 成员指向当前的活动 plugin 根据用户选项初始化动态加载 plugin if flags 根据配置加载制 定的 plugin 包括找到 dll 加载 寻找符号并设置 plugin 结构 if flags 加载系统 plugin table 中的 plugin 初始化剩下的 plugin for i 0 i state PLUGIN IS UNINITIALIZED if plugin initialize plugin ptr plugin ptr state PLUGIN IS DYING reap plugin ptr 这个函数执行结束以后 在 plugin array plugin dl array plugin hash 中保存了当前加载了的所 有的 plugin 到此 plugin 初始化结束 在 plugin initialize 函数里面 调用了每个 plugin 自己的 init 函数 参见前面的内容 特别要 提到的是对于各种不同类型的 plugin 初始化函数的参数也不一样 这是通过一个全局的 plugin type initialize 间接层来实现的 这个数组对于每种类型的 plugin 定义了一个函数 比如 对于 storage plugin 对应的是 ha initialize handlerton 对于 information scheme 对应的是 initialize schema table 然后在这些函数中再调用 plugin 的初始化函数 暂时对于其他类型的 plugin 没有定义这个中间层初始化函数 所以就直接调用了 plugin 的初始化函数 Mysql 源代码分析 6 Plugin 架构介绍 续 上篇文章我们分析了 Mysql 的 Plugin 接口以及 plugin 的初始化过程 这里我们继续看 plugin 怎么 被使用的 基本还是通过例子看问题 主要分析 myisam 如何通过 plugin 接口被调用的 myisam 是 mysql 最早的和默认的 storage engine 前面我们也看到在 plugin 初始化的时候是优先初 始化 myisam 然后才初始化其他的存储引擎 这里我们假定用户要对一个 myisam 的表做操作 具体 看看其中涉及的调用过程 myisam 的初始化 myisam plugin 的定义可以在 storage myisam ha isam cc 中找到 mysql declare plugin myisam MYSQL STORAGE ENGINE PLUGIN 初始化函数是 myisam init 在前面文章中提到 storage engine 类型的 plugin 均是通过 ha initialize handlerton 初始化 myisam init 的输入参数是 void p 实际上是 handlerton handlerton 在 mysql 中封装了访问一个存储引擎需要的接口 每个存储引擎在全局空 间有一个 handlerton 对象 保存在对应的内存中 plugin 结构的 data 域中 该结构具体定义可以在 sql handler h 中找到 myisam init 做的事情很简单 设置 handlerton 中的各个域 其中最重要的 域是 create 被指向了一个函数 myisam create handler 这个函数用来创建 handler 用来对于数 据库文件进行操作 打开一个表 数据库表是数据库中所有操作的基础 我们看看打开一个表需要做些什么 当一个 select 命令进来 的时候 sql parse cc 中的 execute sqlcom select 被执行 并被传入 parse 出来的所有该命令要用 的到表 它会调用 open and lock tables 来打开指定的表 然后调用 open and lock tables derived 再调用 open tables 再调用 open table sql base cc 一大堆 调用之后真正开始干实事儿的是 open unireg entry 名字很奇怪 但是确实就是它开始打开表了 我们仔细将仔细看这个函数 以及它调用的函数 这个函数很长 其实大部分都是在做错误处理 最 重要的就以下几行 static int open unireg entry THD thd TABLE entry TABLE LIST table list const char alias char cache key uint cache key length MEM ROOT mem root uint flags share get table share with create thd table list cache key cache key length OPEN VIEW table list i s requested object open table from share thd share alias get table share with create 是创建一个 table share 结构 包括了同一个类型的表公用的数据结 构 open table from share 则通过这个公用结构打开对应的要操作的表 TABLE SHARE get table share THD thd TABLE LIST table list share alloc table share table list key key length 分配内存 my hash insert 加入 cache 以后可以直接用 open table def thd share db flags 代开表的定义 需要读 frm 文件 open table def 是用来打开存储表定义的文件 mysql 中 每个表都有一个 frm 文件 存储了表的定 义 这个函数就是要打开表对应的 frm 文件 读入定义信息 填入 TABLE SHARE 结构 int open table def THD thd TABLE SHARE share uint db flags file my open path O RDONLY O SHARE MYF 0 open binary frm thd share head file open binary frm 读入二进制的 frm 文件信息 这个函数超长 但是我们暂时只是对与 plugin 相关的 部分感兴趣 因为每个表的 storage engine 信息就是从 frm 文件中读出来的 我们看相关的代码片 段 open binary frm plugin ref tmp plugin ha resolve by name thd name 就是 storage engine 的 名字 比如 myisam 这里根据名字找到对应的 plugin share db plugin my plugin lock NULL 保存 plugin 的引用 供以后使用 plugin 中的 data 域就是 handlerton 这将是主要的使用 plugin 的入口 好了 TABLE SHARE 设置好了 我们回到 open unireg entry 中 继续看 open table from share 这才是真正打开表的地方 这个函数还是在 sql table cc 中 这个函数还是超长 万幸的是我们 还是只想关注 plugin 相关的内容 TABLE 中有一个 file 结构 类型是 handler 我们以前提到过 handler 就是一个打开的表的引用 显然 open table from share 的责任之一就是要设置这个域 int open table from share THD thd TABLE SHARE share TABLE outparam outparam 是打开后的表信息 outparam file get new handler share 直奔主题 获取一个 handler share db type 返回 plugin 对应的 handlerton 其实就是将 plugin data 强制转换成 handlerton outparam file ha open outparam 调用 plugin 的 handler 定义的 open 函数 做自 定义的 open 操作 get new handler 负责根据 TABLE SHARE 的内容构造一个 handler 对象 这个函数在 sql handler cc 中 handler get new handler TABLE SHARE share MEM ROOT alloc handlerton db type file db type create db type share alloc 调用 plugin 的 create 函数 来创建 handler 成员 file init 前面我们提到过对于 myisam 对应的 create 函数是 myisam create handler 这个函数就是 new 了一 个 ha myisam 对象 而 ha myisam 又是从 handler 继承下来的 重载了 handler 对应的函数 这样一个对于应数据库表文件的 handler 就可以使用啦 它的第一个使用就是在 open table from share 中被调用 ha open ha open 在 handler cc 中定义 其实就是调用了重载后 了 open 函数 在 ha myisam 中 我们可以看到 open 函数的定义 这里我们就不仔细看了 实现细节 和 myisam 的文件结构相关 看到这里一个 SELECT from test 语句如何打开表的部分就基本清楚了 主要过程包括 从 frm 文件寻找 storage engine 的名字 并获取对应的 storage engine plugin 的 handlerton 调用 handlerton 的 create 函数生成 handler 通过 handler 重载的 open 函数打开表文件 挺清楚的 到了这里 我们就有了表的 handler 以后凡是涉及到存储引擎的操作 都通过这个接口调用来做 这样 storage engine plugin 就和 mysql 核心紧密结合到了一起 各司其事 共同完成复杂的 sql 操作 Mysql 源代码分析 7 MYISAM 的数据文件处理 好久没写分析文章了 一个是比较忙 另一个是因为余下的内容都是硬骨头 需要花时间慢慢理解 剩下的比较有意思的内容有 select 语句的执行和优化过程 大家关心数据库的查询性能 主要是对着部分比较感兴趣 特别是其 中的查询优化部分 Mysql 的 replication Mysql 的 master slave 架构是大部分使用 mysql 的高性能网站架构的不二选 择 replication 则是这个架构的基础 具体数据库引擎的实现 这部分也是很多关心 mysql 性能的人会比较感兴趣的部分 不过这个工作比 较复杂 特别是流行的 innodb 这个工作量尤其浩大 而且难度颇高 其中涉及到 transaction 的部 分 也是特别复杂 另外 我发现我写的文章被一些地方转摘了 感谢大家的阅读 但是我也希望转摘要注明出处 至少 给个原文链接吧 也不枉我幸苦一场 今天主要写写 Myisam 的数据文件的处理 Myisam 是最早实现的 Mysql 数据库引擎 也是人们心中的性能最好的引擎 虽然不是功能最强的 没 办法 现实往往要求性能和功能做权衡 这里选择分析它 主要原因是其实现还算比较简单明了 而且最近我对数据文件的格式比较感兴趣 特别是变长数据的处理 要注意的是本文不会介绍 myisam 的索引文件格式 基本知识 对于每一个以 Myisam 做数据引擎的表 在 目录下会有如下几个文件来保存 其相关信息 frm 文件 这个文件是跨引擎的 描述了该表的元信息 其中最重要的是表定义和表的数据库引擎 MYD 文件 这是我们要看的重点文件 包含了数据库 record 信息 就是数据库中的每个行 MYI 文件 索引文件 用来加速查找 而对于 MYD 中的每个 record 可以是 fixed dynamic 以及 packed 三种类型之一 fixed 表示 rec
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 集装箱道路运输与物流市场分析考核试卷
- 棉花供应链管理与优化考核试卷
- 油气仓储安全评价与监控考核试卷
- 陶瓷制作中的热工设备与节能技术考核试卷
- 临床常见急救救护流程规范
- 多重感染肺炎
- 胎儿窒息临床急救护理
- 子痫患者的麻醉管理
- AIDS合并口腔念珠菌感染诊疗体系
- 外科护理局部麻醉
- 施工组织设计施工方案报审表
- 雅马哈YS12编程手册
- 5G(UE)中PDU会话建立流程(消息)
- 组合数学(第二版)递推关系
- 酒水厂家授权书范本
- 产品供货质量保证措施方案
- 河南产业分析介绍课件
- 三病信息管理制度
- 湘教版七年级下册地理期末试卷-附答案
- 2023年副主任医师(副高)-中西医结合外科学(副高)考试历年真题荟萃带答案
- 教科版五年级下册科学知识点整理
评论
0/150
提交评论