设为首页 收藏本站
查看: 569|回复: 0

[经验分享] 思考mysql内核之初级系列6---innodb文件管理(摘自老杨)

[复制链接]

尚未签到

发表于 2016-10-23 05:42:02 | 显示全部楼层 |阅读模式
在上一篇里面,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;
DSC0000.gif

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表对应的表空间。

DSC0001.gif

Bingxi“我们先说到这里吧,内容还是很多的,建议将fil0fil.c中每个函数设置一个断点,然后通过语句调试的方式来掌握,比如往t1里面插数据,直到30M数据不够,要进行文件的扩展,然后跟踪进去看下如何进行文件的扩展等等。”
Alex:“是的,我们今天聊了表空间管理,那么后续就可以讨论系统表空间内是如何组织数据的了。”
Bingxi:“alex,先把基础的讲下,比如今天里面包含的两个常用结构:hash_table_t、UT_LIST_NODE_T。”
Alex:“嗯,可以的,我们下次聊这个。”

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-289909-1-1.html 上篇帖子: Mysql中如何设置日期字段默认值为当前日期 下篇帖子: MySQL空间数据库–查询点到多点间的最短路径
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表