技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> MySQL --> mysql innodb 文件相关的三个重要结构体

mysql innodb 文件相关的三个重要结构体

浏览:2062次  出处信息

我们使用mysql,常使用innodb存储引擎,它包括两种,一种是innobase,另外一种是innodb plugin。今天主要介绍innodb plugin的file I/O操作,innodb plugin存储引擎的文件操作主要包括下面三个重要的结构体:

  • fil_node_struce   一个node对应着一个文件
  • fil_space_struct  一个space对应着一个tablespace
  • fil_system_struct  innodb tablespace memory cache

下面分别简单介绍三个结构体,这三个结构体的一些成员变量可以标示这三个结构体所构成的关系,它们是如何关联在一起的。

第一个重要的结构体,node是数据文件在内存中对应的一个管理结构

/** File node of a tablespace or the log data space */
struct fil_node_struct {

 //指向这个node所在的tablespace
 fil_space_t* space;

 //这个文件的名字,包含了路径 

 char*  name; /*!< path to the file */

 //这个node是否处于打开状态,这个依附于下面的成员变量hanlde的值
 ibool  open; /*!< TRUE if file open */

 //文件打开的句柄
 os_file_t handle; /*!< OS handle to the file, if file open */

 //这个node所对应的文件,是否使用raw disk
 ibool  is_raw_disk;

 //文件大小,多少个页

 ulint  size; /*!< size of the file in database pages, 0 if
    not known yet; the possible last incomplete
    megabyte may be ignored if space == 0 */

 //多少个pending i/o,mysql有自己的异步I/O机制,接下来三个参数也都与此有关
 ulint  n_pending;
    /*!< count of pending i/o's on this file;
    closing of the file is not allowed if
    this is > 0 */
 ulint  n_pending_flushes;
    /*!< count of pending flushes on this file;
    closing of the file is not allowed if
    this is > 0 */
 ib_int64_t modification_counter;/*!< when we write to the file we
    increment this by one */
 ib_int64_t flush_counter;/*!< up to what
    modification_counter value we have
    flushed the modifications to disk */

 //这是一个结构体,表示双向链表中的一个field,通过它可以知道前一个node,后一个node,这些node都属于同一个表空间
 UT_LIST_NODE_T(fil_node_t) chain;
    /*!< link field for the file chain */
//这是一个结构体,表示LRU双向链表中的一个field,通过它可以知道前一个node,后一个node,这些node可能属于不同的表空间,这个LRU的base node存在fil_system_struct中。

 UT_LIST_NODE_T(fil_node_t) LRU;
    /*!< link field for the LRU list */

 ulint  magic_n;/*!< FIL_NODE_MAGIC_N */
};

 

第二个重要的结构体,表空间space,从逻辑上讲,一个表空间space包含一个node,或者多个node

/** Tablespace or log data space: let us call them by a common name space */
struct fil_space_struct {
 char*  name; /*!< space name = the path to the first file in it */

//每个表空间都有唯一的一个ID
 ulint  id; /*!< space id */

 //表空间的version
 ib_int64_t tablespace_version;
 ibool  mark; /*!< this is set to TRUE at database startup if
    the space corresponds to a table in the InnoDB
    data dictionary; so we can print a warning of
    orphaned tablespaces */

//这个表空间停止新的i/o操作,比如文件改名操作
 ibool  stop_ios;
 ibool  stop_ibuf_merges;
    /*!< we set this TRUE when we start
    deleting a single-table tablespace */

//是否正在被删除
 ibool  is_being_deleted;
    /*!< this is set to TRUE when we start
    deleting a single-table tablespace and its
    file; when this flag is set no further i/o
    or flush requests can be placed on this space,
    though there may be such requests still being
    processed on this space */
//这个表空间的用途,主要有三种FIL_TABLESPACE, FIL_LOG, or FIL_ARCH_LOG

 ulint  purpose;

//双向链表的基结点,管理这个表空间所有的nodes
 UT_LIST_BASE_NODE_T(fil_node_t) chain;
    /*!< base node for the file chain */

//这个表空间的大小
 ulint  size; /*!< space size in pages; 0 if a single-table
    tablespace whose size we do not know yet;
    last incomplete megabytes in data files may be
    ignored if space == 0 */
 ulint  flags; /*!< compressed page size and file format, or 0 */
 ulint  n_reserved_extents;
    /*!< number of reserved free extents for
    ongoing operations like B-tree page split */

 //这个表空间的pending flushes个数,如果这个值>0,这个表空间不允许删除。
 ulint  n_pending_flushes; 

 //mysql特有的insert buffer,你还记得它的作用是什么吗?它存在什么地方?

 ulint  n_pending_ibuf_merges;/*!< this is positive
    when merging insert buffer entries to
    a page so that we may need to access
    the ibuf bitmap page in the
    tablespade: dropping of the tablespace
    is forbidden if this is positive */

//两个hash表,提供两种快速访问node,或者table的方法
 hash_node_t hash; /*!< hash chain node */
 hash_node_t name_hash;/*!< hash chain the name_hash table */
#ifndef UNIV_HOTBACKUP

//定义的一个latch,来控制这个space结构体的并发操作
 rw_lock_t latch; /*!< latch protecting the file space storage
    allocation */
#endif /* !UNIV_HOTBACKUP */

//双向链表的一个field,通过这个成员变量,可以找到前一个unflushed space,以及下一个unflushed space,双向链表的基结点存在于fil_system_struce的unflushed_spaces里
 UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
 ibool  is_in_unflushed_spaces; /*!< TRUE if this space is
    currently in unflushed_spaces */
//双向链表的一个field,这个双向链表保存整个系统所有的tablespace,这个双向链表的基结点存在于fil_system_struct的space_list中

 UT_LIST_NODE_T(fil_space_t) space_list;
    /*!< list of all spaces */
 ulint  magic_n;/*!< FIL_SPACE_MAGIC_N */
};

/** Value of fil_space_struct::magic_n */
#define FIL_SPACE_MAGIC_N 89472

 

第三个重要的结构体tablespace memory cache,它是一个入口,通过它可以找到所有的spaces,node的LRU链表,待刷新的unflushed spaces

/** The tablespace memory cache */
typedef struct fil_system_struct fil_system_t;

/** The tablespace memory cache; also the totality of logs (the log
data space) is stored here; below we talk about tablespaces, but also
the ib_logfiles form a 'space' and it is handled here */

struct fil_system_struct {
#ifndef UNIV_HOTBACKUP

//定义一个mutex,用来保护对此结构的并发访问
 mutex_t  mutex;  /*!< The mutex protecting the cache */
#endif /* !UNIV_HOTBACKUP */

//hash表,根据space_id能快速定位space
 hash_table_t* spaces;  

//hash表,根据space_name能快速定位到space

 hash_table_t* name_hash; 

//所有打开的,并且没有pending i/o的文件node,都会放入到LRU链表中进行淘汰,系统表空间,以及日志的文件不会放入到此LRU链表当中
 UT_LIST_BASE_NODE_T(fil_node_t) LRU;
     /*!< base node for the LRU list of the
     most recently used open files with no
     pending i/o's; if we start an i/o on
     the file, we first remove it from this
     list, and return it to the start of
     the list when the i/o ends;
     log files and the system tablespace are
     not put to this list: they are opened
     after the startup, and kept open until
     shutdown */

 //所有发生了数据改写的space,都会入到unflushed_spaces,如果想知道哪些spaces需要刷i/o,只需要遍历此链表即可
 UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
     /*!< base node for the list of those
     tablespaces whose files contain
     unflushed writes; those spaces have
     at least one file node where
     modification_counter > flush_counter */

//当前打开文件的个数
 ulint  n_open;  /*!< number of files currently open */

//系统允许打开的文件个数,这是一个软限制,不是一个硬限制,如果是单表空间,这个成员变量所对应的innodb_open_files参数需要设大
 ulint  max_n_open; /*!< n_open is not allowed to exceed
     this */
 ib_int64_t modification_counter;/*!< when we write to a file we
     increment this by one */
 ulint  max_assigned_id;/*!< maximum space id in the existing
     tables, or assigned during the time
     mysqld has been up; at an InnoDB
     startup we scan the data dictionary
     and set here the maximum of the
     space id's of the tables there */
 ib_int64_t tablespace_version;
     /*!< a counter which is incremented for
     every space object memory creation;
     every space mem object gets a
     'timestamp' from this; in DISCARD/
     IMPORT this is used to check if we
     should ignore an insert buffer merge
     request */

//双向链表的基结点,管理着全部的spaces
 UT_LIST_BASE_NODE_T(fil_space_t) space_list;
     /*!< list of all file spaces */
};

/** The tablespace memory cache. This variable is NULL before the module is
initialized. */
static fil_system_t* fil_system = NULL;

 

这几个结构体里的UT_LIST_BASE_NODE_T(),UT_LIST_NODE_T(),可以看一下宏定义,以增强大家对以上三个结构体三者之间关系的理解。

#define UT_LIST_BASE_NODE_T(TYPE)\
struct {\
 ulint count; /*!< count of nodes in list */\
 TYPE * start; /*!< pointer to list start, NULL if empty */\
 TYPE * end; /*!< pointer to list end, NULL if empty */\
}\

 

#define UT_LIST_NODE_T(TYPE)\
struct {\
 TYPE * prev; /*!< pointer to the previous node,\
   NULL if start of list */\
 TYPE * next; /*!< pointer to next node, NULL if end of list */\
}\    

 

在Fil0fil.c文件里定义上如上的三个重要的结构体,里面还有很多函数,都是围绕着这三个结构体展开,这些函数完成innodb 的文件i/o操作。平时应多读读代码,在代码结构里,更容易去理解mysql innodb plugin的运行原理,对代码的理解,如果碰到一些bug,也可以知道怎么样绕开这个bug,这是一件挺有意思的事。

建议继续学习:

  1. C语言结构体里的成员数组和指针    (阅读:4590)
  2. 结构体初始化的方法    (阅读:2317)
  3. c、cpp中使用匿名结构体、类定义数组    (阅读:2122)
  4. 根据成员地址获取结构体变量    (阅读:1651)
  5. HAProxy几个重要的结构体    (阅读:1484)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1