0

0

MySQL系列:innodb引擎分析之文件IO_MySQL

php中文网

php中文网

发布时间:2016-06-01 13:04:25

|

1467人浏览过

|

来源于php中文网

原创

innodb作为数据库引擎,自然少不了对文件的操作,在innodb中所有需要持久化的信息都需要文件操作,例如:表文件、重做日志文件、事务日志文件、备份归档文件等。innodb对文件io操作可以是煞费苦心,其主要包括两方面,一个是对异步io的实现,一个是对文件操作管理和io调度的实现。在mysql-5.6版本的innodb还加入了direct io实现。做了这么多无非是优化io操作的性能。在innodb的文件io部分中,主要实现集中在os_file.*和fil0fil.*两个系列的文件当中,其中os_file*是实现基本的文件操作、异步io和模拟异步io。fil0fil.*是对文件io做系统的管理和space结构化。下面依次来介绍这两个方面的内容.

1.系统文件IO

在innodb中,文件的操作是比较关键的,innodb封装了基本的文件操作,例如:文件打开与关闭、文件读写以及文件属性访问等。这些是基本的文件操作函数封装。在linux文件的读写方面,默认是采用pread/pwrite函数进行读写操作,如果系统部支持这两个函数,innodb用lseek和read、write函数联合使用来达到效果. 以下是innodb文件操作函数: os_file_create_simple 创建或者打开一个文件 os_file_create 创建或者打开一个文件,如果操作失败会重试,直到成功 os_file_close 关闭打开的文件 os_file_get_size 获得文件的大小 os_file_set_size 设置文件的大小并以0填充文件内容 os_file_flush 将写的内容fsync到磁盘 os_file_read 从文件中读取数据 os_file_write 将数据写入文件 innodb除了实现以上基本的操作以外,还实现了文件的异步IO模型,在Windows下采用的IOCP模型来进行处理(具 体可以见网上的资料),在linux下是采用aio来实现的,有种情况,一种是通过系统本身的aio机制来实现,还有一种是 通过多线程信号模拟来实现aio.这里我们重点来介绍,为了实现aio,innodb定义了slot和slot array,具体数据结构如下:

typedef struct os_aio_slot_struct
{
     ibool	 is_read;                             /*是否是读操作*/
     ulint	 pos;                                    /*slot array的索引位置*/
     ibool	 reserved;                           /*这个slot是否被占用了*/
     ulint	 len;                                     /*读写的块长度*/
     byte*	 buf;                                   /*需要操作的数据缓冲区*/
     ulint	 type;                                   /*操作类型:OS_FILE_READ OS_FILE_WRITE*/
     ulint	 offset;                                 /*当前操作文件偏移位置,低32位*/
     ulint	 offset_high;                        /*当前操作文件偏移位置,高32位*/
     os_file_t	 file;                               /*文件句柄*/
     char*	 name;                               /*文件名*/
     ibool	 io_already_done;             /*在模拟aio的模式下使用,TODO*/
     void*	 message1;
     void*	 message2;
#ifdef POSIX_ASYNC_IO
     struct aiocb	control;                 /*posix 控制块*/
#endif
}os_aio_slot_t;

typedef struct os_aio_array_struct
{
 os_mutex_t	 mutex;          /*slots array的互斥锁*/
 os_event_t	 not_full;         /*可以插入数据的信号,一般在slot数据被aio操作后array_slot有空闲可利用的slot时发送*/
 os_event_t	 is_empty;       /*array 被清空的信号,一般在slot数据被aio操作后array_slot里面没有slot时发送这个信号*/

 ulint	 n_slots;                     /*slots总体单元个数*/
 ulint	 n_segments;             /*segment个数,一般一个对应n个slot,n = n_slots/n_segments,一个segment作为aio一次的操作范围*/
 ulint	 n_reserved;              /*有效的slots个数*/
 os_aio_slot_t*	slots;         /*slots数组*/

 os_event_t*	 events;         /*slots event array,暂时没弄明白做啥用的*/
}os_aio_array_t;

内存结构关系图:
\

2.文件管理的内存结构

在innodb中定义三种文件类型:表空间文件(ibdata*)、重做日志文件(ib_logfile*)和归档文件(ib_arch_log*)。一般innodb在运行的过程中,会同时打开很多个文件,这就要求对文件进行系统的管理和控制。在innodb中定义了一套基于fil_system_t、fil_space_t和fil_node_t的内存管理结构。每个文件对应的是一个fil_node_t,fil_node是存储的最小单元,多个同一模块的fil_node组成一个fil_space_t,所有的space组成一个fil_system_t,在innodb引擎里,只有一个fil_system_t对象。

fil_system_t管理着全局的文件操作资源,例如:文件打开的数量、打开文件的信号控制、fil_space_t的管理和索引等。以下是fil_system_t的结构定义:

 

typedef struct fil_system_struct
{
     mutex_t	 mutex;              /*file system的保护锁*/
     hash_table_t*	spaces;     /*space的哈希表,用于快速检索space,一般是通过space id查找*/
     ulint	 n_open_pending;  /*当前有读写IO操作的fil_node个数*/
     ulint	 max_n_open;         /*最大允许打开的文件个数*/
     os_event_t	 can_open;    /*可以打开新的文件的信号*/
 
    UT_LIST_BASE_NODE_T(fil_node_t) LRU;       /*最近被打开操作过的文件,用于快速定位关闭的fil_node*/
    UT_LIST_BASE_NODE_T(fil_node_t) space_list;	 /*file space的对象列表*/
}fil_system_t;

值得注意的是space的哈希表和LRU,这里为什么会出现用hash table来索引space呢?因为在实际的数据库系统中,fil_space_t是会非常多的,用哈希表能快速定位到需要操作的fil_space_t。LRU是用于保存最近被打开和被操作过的fil_node,为了避免频发的关闭和打开文件,LRU保存一定数量(500)的最近打开过的文件,这样可以提高系统的效率。

 

fil_space_t是用于管理同一模块的file_node,上层模块操作文件不是以文件名来做操作关联的,而是用space_id,

也就是说,所有的文件操作是通过space为单位进行操作的。fil_space支持三种类型,分别是:
FIL_TABLESPACE 表空间space
FIL_LOG 重做日志space
FIL_ARCHI_LOG 归档日志space

fil_space_t的定义如下:

 

struct fil_space_struct
{
     char*	 name;                     /*space名称*/
     ulint	 id;                            /*space id*/
     ulint	 purpose;                 /*space的类型,主要有space table, log file和arch file*/
     ulint	 size;                         /*space包含的页个数*/
     ulint	 n_reserved_extents; /*预留的页个数*/
     hash_node_t	 hash;          /*chain node的HASH表*/
     rw_lock_t	 latch;               /*space操作保护锁,用于多线程并发*/
     ibuf_data_t*	ibuf_data;   /*space 对应的insert buffer*/
     ulint	 magic_n;                 /*魔法校验字*/

     UT_LIST_BASE_NODE_T(fil_node_t) chain;
     UT_LIST_NODE_T(fil_space_t)	 space_list;
};

fil_space通常是由一组文件组成,例如重做日志,一般是有3个文件组成一个group space用于重做日志记录。space通过成员latch可以支持多线程并发的。在innodb文件操作中,主要是通过space来做控制,以下是它的控制函数:
fil_space_create 创建一个fil_space
fil_space_free 销毁一个fil_space
fil_space_truncate_start 从space中删除fil_node,删除的总数据长度为trunc_len
fil_node_create 创建一个fil_node并加入到对应的space当中
fil_space_get_size 获得space的空间大小,以page为单位记
fil_io 指定space的io操作
fil_aio_wait aio异步方式的io操作等待,并根据完成状态更新space状态
fil_flush 指定space进行数据刷盘
fil_node_t是对单个文件进行管理,主要是管理文件的打开状态、文件句柄信息、文件的page数量和更新状态等。

 

其结构定义如下:

久久企业网站后台管理系统1.0
久久企业网站后台管理系统1.0

一、功能简介本软件完全适应大、中、小型网站建设需要,让您用很便宜的虚拟主机空间也可以开通4个独立的网站!久久企业网站后台管理系统各种版本开发基础架构均为php+mysql+div+css+伪静态,迎合搜索引擎排名的喜好。另外值得一提的是本站特色的TAG系统可为您的网站做出无限分类,不用任何设置全站ULR伪静态!本建站系统除了有产品发布、新闻(软文)发布、订单管理系统和留言反馈等一些最基本的功能之外

下载

 

struct fil_node_struct
{
     char*	 name;                         /*文件路径名*/
     ibool	 open;                         /*文件是否被打开*/
     os_file_t	handle;                  /*文件句柄*/
     ulint	 size;                             /*文件包含的页个数,一个页是16K*/
     ulint	 n_pending;                 /*等待读写IO操作的个数*/
     ibool	 is_modified;               /*是否有脏也存在,flush是根据这个标志进行刷盘的*/
     ulint	 magic_n;                     /*魔法校验字*/
     UT_LIST_NODE_T(fil_node_t) chain;
     UT_LIST_NODE_T(fil_node_t) LRU;
};

值得注意的是当外部调用了fil_flush时,判断一个fil_node是否需要刷盘的必要条件是:
文件必须是打开的 open = TRUE
文件存在内存和硬盘数据不一致 is_modified = TRUE

 

 

了解了他们三者的基本定义后,那他们之间的关系是怎么的?不用文字叙述,看下面的内存结构关系图:

 

\

 

在了解了他们之间的基本关系后,那么一个io操作是怎么进行的?在这个模型里,一个io操作提交和被运行是比较复杂的。具体流程如下: 1.外部模块提交一个fil_io, 先会进行基本的io操作类型的判断和文件打开方式的判断。 2.然后进行对正在进行io操作的计数做判断,如果正在进行的io数量 > 最大文件打开数量的四分之三,唤醒所有aio的操作线程进行io处理,并进行sleep等待。 3.如果正在进行的io数量 = 最大文件打开数量,唤醒所有的aio操作线程进行io处理,并等待fil_system_t的can_open信号。 4.如果不满足2和3,找到需要受理io操作的space和node,并打开node对应的文件,打开文件时会对打开文件数量限制做判断,如果当前打开文件操作io的数量 + LRU里已经打开文件的数量>= 最大文件打开数量时,会取出LRU中最后一个fil_node进行文件关闭。然后在对新的io操作的fil_node文件进行打开。 5.fil_node文件打开后,调用os_aio进行io操作提交,然后等待io操作完成 6. io操作完成后,将完成io操作的fil_node放入LRU的第一个位置,并更改对应的fil_system/fil_space/fil_node的状态,最后触发一个fil_system的can open信号。 7.监听can_open的线程收到这个信号后,会跳到第4步进行自己的io操作提交。 流程图如下: \

 

3总结

总体来说,innodb的文件IO涉及到知识面很多,可以能短时间无法完全理解透彻,一般在阅读源码的时候可以做一些基本的单元测试,这样有助于理解。弄清楚innodb的文件IO操作是非常有必要的,因为文件IO操作模块直接影响对innodb的日志系统的理解、表空间系统的理解。而且Innodb在文件IO模块的改进还是比较大的,尤其是引入Direct IO后。Direct IO很多数据库都在用这个技术,除了innodb,oracle和淘宝的oceanbase都使用了这个技术, 关于Direct IO网络上资料很多,可以自行结合MySQL-5.6的innodb来做研究。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

【李炎恢】ThinkPHP8.x 后端框架课程
【李炎恢】ThinkPHP8.x 后端框架课程

共50课时 | 4.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号