mysql存储引擎InnoDB


1,主体系结构:

默认7个后台线程,4个io thread(insert buffer、log、read、write),1个master thread(优先级最高),1个锁(lock)监控线程,1个错误监控线程。可以通过show engine innodb status来查看。新版本已对默认的read thread和write thread分别增大到4个,可通过show variables like 'innodb_io_thread%'查看。
存储引擎组成:

缓冲池(buffer pool)、重做日志缓冲池(redo log buffer)以及额外的内存池(additional memory pool).具体配置可由show variables like 'innodb_buffer_pool_size'、show variables like
'innodb_log_buffer_size'、show variables like 'innodb_additional_mem_pool_size'来查看。

缓冲池:

占最大块内存,用来存放各种数据的缓存包括有索引页、数据页、undo页、插入缓冲、自适应哈希索引、innodb存储的锁信息、数据字典信息等。工作方式总是将数据库文件按页(每页16k)读取到缓冲池,然后按最近最少使用(lru)的算法来保留在缓冲池中的缓存数据。如果数据库文件需要修改,总是首先修改在缓存池中的页(发生修改后即为脏页),然后再按照一定的频率将缓冲池的脏页刷新到文件。通过命令show engine innodb status;来查看。
日志缓冲:

将重做日志信息先放入这个缓冲区,然后按一定频率将其刷新到重做日志文件。mysql dba系统学习(21)mysql存储引擎InnoDB_第1张图片

innodb_buffer_pool_size 一般设置问机器的物理内存的80%

innodb_additional_mem_pool_size 一般是缓存数据字典和数据结构的信息,不宜太大



2,两次写:

它带来InnoDB数据的可靠性。如果写失效,可以通过重做日志进行恢复,但是重做日志中记录的是对页的物理操作,如果页本身损坏,再对其进行重做是没有意义的。所以,在应用重做日志前,需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewire。
恢复数据=页副本+重做日志





3,自适应哈希索引

InnoDB存储引擎提出一种自适应哈希索引,存储引擎会监控对表上索引的查找,如果观察到建立建立哈希索引会带来速度的提升,则建立哈希索引,所以称之为自适应的。自适应哈希索引只能用来搜索等值的查询,如select * from table where index_col='***', 此外自适应哈希是由InnoDB存储引擎控制的,我们只能通过innodb_adaptive_hash_index来禁用或启用,默认开启。


4,重做日志文件

实例和介质失败,重做日志文件就能派上用场,如数据库掉电,InnoDB存储引擎会使用重做日志恢复到掉电前的时刻,以此来保证数据的完整性。参数innodb_log_file_size指定了重做日志文件的大小;innodb_log_file_in_group指定了日志文件组中重做日志文件的数量,默认为2,innodb_mirrored_log_groups指定了日志镜像文件组的数量,默认为1,代表只有一个日志文件组,没有镜像;innodb_log_group_home_dir指定了日志文件组所在路径,默认在数据库路径下。
二进制日志和重做日志的区别:首先,二进制日志会记录所有与Mysql有关的日志记录,包括InnoDB、MyISAM、Heap等其他存储引擎的日志。而InnoDB存储引擎重做日志只存储有关其本身的事务日志;其次内容不同,不管将二进制日志文件记录的格式设为STATEMENT还是ROW,又或者是MIXED,其记录的都是关于一个事务的具体操作内容。而InnoDB存储引擎的重做日志文件记录的关于每个页的更改的物理情况 。此外,写入时间不同,二进制日志文件是在事务提交前进行记录的,而在事务进行的过程中,不断有重做日志条目被 写入重做日志文件中。


5,表空间文件

InnoDB默认的表空间文件为ibdata1,可通过show variables like 'innodb_file_per_table'查看每个表是否产生单独的.idb表空间文件。但是,单独的表空间文件仅存储该表的数据、索引和插入缓冲等信息,其余信息还是存放在默认的表空间中。每个文件都可以自动增长

mysql> show variables like "%file_path%";
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:10M:autoextend |
+-----------------------+------------------------+
1 row in set (0.00 sec)

innodb老提示我060809 16:49:11 [ERROR] InnoDB: syntax error in innodb_data_file_path

innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
一个指定数据文件的完全后缀包括文件名,它的尺寸和数个可选属性:
file_name:file_size[:autoextend[:max:max_file_size]]
autoextend属性和后面跟着的属性只可被用来对innodb_data_file_path行里最后一个数据文件。
如果你对最后的数据文件指定autoextend选项。如果数据文件耗尽了表空间中的自由空间,InnoDB就扩展数据文件。扩展的幅度是每次8MB。


6,mysql innodb中的锁
InnoDB存储引擎锁的实现和Oracle非常类似,提供一致性的非锁定读、行级锁支持、行级锁没有相关的开销,可以同时得到并发性和一致性。
InnoDB存储引擎实现了如下两种标准的行级锁:
共享锁(S Lock):允许事务读一行数据;
排他锁(X Lock):允许事务删除或者更新一行数据。
当一个事务已经获得了行r的共享锁,那么另外的事务可以立即获得行r的共享锁,因为读取没有改变行r的数据,我们称这种情况为锁兼容。但如果有事务想获得行r的排他锁,则它必须等待事务释放行r上的共享锁————这种情况称为锁不兼容。



在InnoDB Plugin之前,只能通过SHOW FULL PROCESSLIST,SHOW ENGINE INOODB STATUS等命令来查看当前的数据库请求,然后再判断当前事务中的锁的情况。新版本的InnoDB Plugin中,在INFORMATION_SCHEMA架构下添加了INNODB_TRX、INNODB_LOCKS、InnoDB_LOCK_WAITS。通过这三张表,可以更简单地监控当前的事务并分析可能存在的锁的问题。