思考mysql内核之初级系列6---innodb文件管理
在上一篇里面,bingxi和alex思考了information_schema,这个一直在innodb外围打转。没有进入到innodb的内部。在后续的文章中,以innodb的为主,逐个思考。Bingxi和alex今天了解了fil文件管理。
对应的文件为:
D:\mysql-5.1.7-beta\storage\innobase\fil\fil0fil.c
D:\mysql-5.1.7-beta\storage\innobase\include\fil0fil.h
1)所谓的tablespace
Bingxi:“alex,配置项有一个选项innodb_file_per_table,也就是每个表有一个自己的tablespace。
以下是代码片段: 14.2.3.1. Using Per-Table Tablespaces You can store each InnoDB table and its indexes in its own file. This feature is called “multiple tablespaces” because in effect each table has its own tablespace. |
”
Alex:“是的,bingxi。不过tablespace这个概念我们借鉴了oracle中的命名:表空间。在oracle中,tablespace表示表的集合,也就是很多个表放到同一个逻辑整体里面。”
Bingxi:“是的,相比myisam,每个myisam表对应三个文件。而innodb可以将很多表放到一个文件或者多个文件里面,这个叫共享表空间。另外,如果innodb_file_per_table加到配置文件,则每个新建的innodb表则使用独立表空间。”
Alex:“bingxi,那什么叫独立表空间呢?我们需要来debug一下代码。假设我们使用系统默认的参数启动,则会有两个tablespace,第一个tablespace包括一个文件ibdata1,这个也可以称为系统表空间,另外一个space包括两个日志文件。”
Bingxi:“是的,我们参考了oracle的系统表空间就知道系统表空间里面会存放很多字典信息。这里我们先不说那么远,先说下如果我们需要将系统表空间的文件数量增加,应该怎么填写?因为我们是debug环境下,我们在D:\mysql-5.1.7-beta目录下创建一个my.ini,在其中写入两行参数:
以下是引用片段: [mysqld] innodb_data_file_path = ibdata1:10M;ibdata2:20M:autoextend |
这表示系统表空间里面就会有两个文件,其中第一个文件ibdata1是10M,第二个文件大小是是20M,并且可以进行自动扩展。
”
Alex:“好吧,我们现在先配置下文件,然后看看系统内部是如何管理这些文件的。先看看文件系统的定义。
以下是代码片段: //文件系统管理结构 typedef struct fil_system_struct fil_system_t; struct fil_system_struct { …… //下面两个表空间用于快速查找space,fil_system_t结构用于整个fil的管理。 //注意:这里的最低粒度是文件 hash_table_t* spaces; //根据space id进行hash的space hash_table_t* name_hash; //根据space name进行hahs的space …… //file space的链表,比如这里有两个space,一个是系统表空间,一个是log space UT_LIST_BASE_NODE_T(fil_space_t) space_list; }; |
从上面的结构中,我们可以看到fil_system_t与fil_space_t是一对多的关系。
以下是代码片段: /* Tablespace or log data space: let us call them by a common name space */ struct fil_space_struct { char* name; //space name = 该space的第一个文件名 ulint id; //space id …… //该space包含的文件结点链表 UT_LIST_BASE_NODE_T(fil_node_t) chain; //文件链表 …… //指向下一个space UT_LIST_NODE_T(fil_space_t) space_list; …… }; |
从这个结构中我们也可以看出,fil_space_struct与fil_node_t也是一对多的关系,也就是一个space下面可以包含多个文件。从我们的my.ini中可以得知我们的系统表空间是对应两个文件:ibdata1、ibdata2。我们来具体看看fil_node_t的定义。
以下是代码片段: /* File node of a tablespace or the log data space */ struct fil_node_struct { fil_space_t* space; //所属的space char* name; //文件路径 ibool open; //文件是否打开 os_file_t handle; //文件句柄 ulint size; //文件大小 …… UT_LIST_NODE_T(fil_node_t) chain; //文件结点链表 …… }; |
启动后的图如下图1
以下是代码片段: //file space的链表,比如这里有两个space,一个是系统表空间,一个是log space UT_LIST_BASE_NODE_T(fil_space_t) space_list; |
”
Bingxi:“是的,我们看下系统表空间这个space里的size这个字段,里面的size为1920,等于对应的两个文件大小的相加,640+1280。这个640是怎么计算的呢,文件页的大小为16k,而ibdata1的大小为10M,因此对应的页数为640页。因此这里的值为640。同样的ibdata2的页数为20M/16k=1280。”
Alex:“好的,我们可以看到这里仅仅是将结点生成了,还需要将日志文件以及系统表空间的的文件打开,保持打开直到数据库shut down。
以下是代码片段: int innobase_start_or_create_for_mysql(void) { …… //打开所有的日志文件以及系统表空间中的文件,保持打开直到数据库shut down fil_open_log_and_system_tablespace_files(); …… } |
在开始进一步之前,我们先看下独立表空间。目前正在使用的是系统表空间,执行语句,往系统表空间里面插入数据。执行后将数据库shut down。然后往my.ini里面增加一行配置用于使用独立表空间。
以下是引用片段: [mysqld] innodb_data_file_path = ibdata1:10M;ibdata2:20M:autoextend innodb_file_per_table = 1 |
重启后执行如下语句
以下是引用片段: mysql> use test; Database changed mysql> create table t2(id int) engine=innodb; Query OK, 0 rows affected (0.02 sec) |
执行语句后,我们可以发现test生成了两个文件:t2.frm以及t2.ibd。同时,我们测试下,能不能在配置为独立表空间的情况下,执行查询语句,发现还是可以使用共享表空间(和系统表空间一个意思)的数据。
以下是代码片段: mysql> select * from t1; +------+-------+ | id | name | +------+-------+ | 1 | name1 | | 2 | name2 | +------+-------+ 2 rows in set (0.02 sec) |
同理,我们重新修改my.ini,去掉独立表空间的配置项,也能使用之前创建的t2表。然后看下文件系统的space_list的数量为3了。也就是t2表对应的表空间。
”
Bingxi“我们先说到这里吧,内容还是很多的,建议将fil0fil.c中每个函数设置一个断点,然后通过语句调试的方式来掌握,比如往t1里面插数据,直到30M数据不够,要进行文件的扩展,然后跟踪进去看下如何进行文件的扩展等等。”
Alex:“是的,我们今天聊了表空间管理,那么后续就可以讨论系统表空间内是如何组织数据的了。”
Bingxi:“alex,先把基础的讲下,比如今天里面包含的两个常用结构:hash_table_t、UT_LIST_NODE_T。”
Alex:“嗯,可以的,我们下次聊这个。”
建议继续学习:
- Innodb IO优化-配置优化 (阅读:6627)
- Innodb分表太多或者表分区太多,会导致内存耗尽而宕机 (阅读:6135)
- Innodb 表和索引结构 (阅读:4774)
- InnoDB线程并发检查机制 (阅读:4085)
- Innodb如何使用内存 (阅读:4002)
- 快速预热Innodb Buffer Pool的方法 (阅读:3961)
- Innodb文件表空间结构 (阅读:3705)
- InnoDB的缓存替换策略及其效果 (阅读:3638)
- 多版本并发控制:PostgreSQL vs InnoDB (阅读:3632)
- InnoDB之Dirty Page、Redo log (阅读:3418)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:yzyangwanfu 来源: 杨万富的专栏
- 标签: innodb mysql内核 文件管理
- 发布时间:2010-07-25 20:15:09
- [67] Oracle MTS模式下 进程地址与会话信
- [65] 如何拿下简短的域名
- [65] Go Reflect 性能
- [59] 图书馆的世界纪录
- [59] 【社会化设计】自我(self)部分――欢迎区
- [59] android 开发入门
- [58] IOS安全–浅谈关于IOS加固的几种方法
- [53] 视觉调整-设计师 vs. 逻辑
- [47] 读书笔记-壹百度:百度十年千倍的29条法则
- [47] 界面设计速成