Innodb存储引擎4大特性


Innodb存储引擎特性:

DoubleWrite

Insert/Change Buffer

Adaptive Hash Index

Flush neighbor page

 

DoubleWrite:

(root@DB)[information_schema]> showvariables like '%double%'

    -> ;

+--------------------+-------+

| Variable_name      | Value |

+--------------------+-------+

| innodb_doublewrite | ON    |

+--------------------+-------+

1 row in set (0.01 sec)

 

目的:数据写入页的可靠性(默认开启)

 

主要解决以下问题:

  Partial write(部分写):一个页只写了部分的内容,这时数据库宕机了

  16K的页只写入了4k,6k,8k,12K的情况

不可以通过redo log进行恢复,因为页的数据不完整,页已损坏

  Like Oracle media corrupt

保证redo的数据是完整的,一致的,doublewrite就是用来保证redo页的完整


工作原理

  doublewrite固定存放在ibdate共享表空间中

存在一个段对象doublewrite中

  2M大小(both fileand memory),不可修改,由两个区组成

页在刷新时首先顺序写入到doublewrite

然后再刷新回磁盘

  doublewrite采用覆盖写,本次的写入会覆盖上次的数据,2M数据是覆盖写入的,先写doublewrite,再写数据文件。一份数据写两份,有个保障,其中一份如果页有损坏,可以用另一份来恢复页的数据


如果写数据页时,共享表空间的页损坏了,mysql就会以数据文件中的页为准

如果写数据页时,数据文件中的页损坏了,mysql就会以共享表空间中的页为准

 

性能开销:

  doublewrite 写入是顺序的

性能开销取决于写入量

通常5%-25%

       slave服务器不能关闭doubelwrite

 

可关闭doublewrite的条件:

  1.atomic write

磁盘

      Fusion-IO  #支持原子写

文件系统

      ZFS(solaries操作系统的文件系统) ,#linux系统不可用

      btrfs   #linux系统不可用 

  --skip-innodb-doublewrite  #关闭doublewrite

 

 

Insert/Change Buffer

Insert buffer

用来提高辅助索引的插入性能,减少随机IO,一次性合并插入

  nono unique secondary index

  Insert Buffer对象在共享表空间中,在ibdata文件中,写insert buffer时也会写redo日志

原理:

先把插入二级索引的值先缓存起来,放到Insert buffer对象中,如果要查询到二级索引时,再将Insert buffer对象中的页再一次性合并到原表中

先判断插入的非聚集索引页码是否在缓冲池中,若中,则直接插入

若不在,则先放入到一个Insert buffer对象中

      insert buffer 也是一颗B+树

每次最多缓存2K的记录

当读取辅助索引页码到缓冲池,将Insert Buffer中该页的记录合并到辅助索引页

 

(root@DB)[information_schema]> show variables like'%change%'

    -> ;

+-------------------------------+-------+

| Variable_name                | Value |

+-------------------------------+-------+

| innodb_change_buffer_max_size | 25    | #insert buffer大小最大为bufferpool的25%

| innodb_change_buffering       |all   |  #默认值是打开的

| session_track_state_change    |OFF   |

+-------------------------------+-------+

3 rows in set (0.00 sec)

create table t (

  a int auto_increment,

  b varchar(30),

  primary key(a)

)

 

create table t(

  a int auto_increment,

  b varchar(30),

  primary key(a),

  key(b)

)

Insert buffer用于提升b列的插入性能,通过空间换时间来提高 


 

 

潜在问题

最大可以使用1/2缓冲池内存

    --innodb-change-buffer-max-size=25

  shutdown 不进行insert buffer记录合并

  insert buffer开始进行合并时插入性能开始下降

 

(root@DB)[information_schema]> show engine innodbstatus\G;

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 1, free list len 0, seg size 2, 0 merges

merged operations:

insert 0, delete mark 0, delete 0

discarded operations:

insert 0, delete mark 0, delete 0

 

seg size:占用页的数量,这个占用了2个页

merges:合并了多少个页

insert:插入了多少条记录

discarded operations:当表的数据插入到insert buffer之后,这张表被删除了,那insert buffer里面的数据就没有用了,discarded表示丢弃的页记录

 

 

Change Buffer:

  insert buffer:只能对insert进行缓存,change buffer可以对所有的操作进行cache

  insert

  Delete-marking

  Purge

  -- innodb_change_buffering

  all

  None

  inserts

  Deletes

  Changes=(insert & delete-marking)

  Purges

 

(root@DB)[(none)]> show engine innodb status\G;

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 1, free list len 0, seg size 2, 0 merges

merged operations:

insert 2323233, delete mark 4234234, delete4213

discarded operations:

insert 0, delete mark 0, delete 0

 

 

Adaptive Hash Index

  5.6以上的版本建议关闭Adaptive Hash Index

    CPU占用会高,但性能没有提升

查找buffer pool中页是否是活跃的页,如果是活跃的页,则mysql会自动对页进行hash,不需要手动干预

搜索时间复杂度

    B+树  #只能查找以页,不能找出页中的记录

哈希表  #可以直接找出页中的记录


(root@DB)[(none)]> show variables like'%innodb_adaptive%';

+----------------------------------+--------+

| Variable_name                   | Value  |

+----------------------------------+--------+

| innodb_adaptive_flushing        | ON     |

| innodb_adaptive_flushing_lwm     |10     |

| innodb_adaptive_hash_index       |ON     |

| innodb_adaptive_hash_index_parts | 8     |  #分片,这里是8个分片

| innodb_adaptive_max_sleep_delay  | 150000 |

+----------------------------------+--------+

5 rows in set (0.00 sec)

(root@DB)[(none)]> show engine innodb status\G;

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

Hash table size 34673, node heap has 0 buffer(s)

0.00 hash searches/s, 0.00 non-hash searches/s

 

 

 

Flush neighbor page

目的:将随机的访问,转换为顺序的访问

  Flush Neighbor Page(FNP)

试图刷新页所在区中的所有脏页

传统机载磁盘有效

  SSD关闭此功能,配置值为0

  MYSQL 5.6

    --innodb_flush_neighbors=1|0

(root@DB)[(none)]> show variables like'%neighbor%'

    -> ;

+------------------------+-------+

| Variable_name          | Value|

+------------------------+-------+

| innodb_flush_neighbors | 1     |

+------------------------+-------+

1 row in set (0.01 sec)

参数值: 

0:表示关闭

1表示打开

2表示只刷新连续的页

 

可以在线修改:

(root@DB)[(none)]> set globalinnodb_flush_neighbors=0;

Query OK, 0 rows affected (0.00 sec)

分割线
感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS