MySQL InnoDB文件相关的三个重要结构体

日期: 2011-08-22 作者:zhaolinjnu 来源:TechTarget中国 英文

  我们使用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,这是一件挺有意思的事。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐