查看文章
 
innodb体系结构(下)
2012-02-13 20:13
版本3:
void master_thread(){
     loop:
          begin 1秒to 10秒
               日志缓存刷新至磁盘的干活
               if 上次IO次数<5
                    最多执行5次合并插入缓冲的干活
               if 脏页比例>最大脏页比率阈值
                    磁盘同步刷新这100页脏页的干活
               if 没有用户活动
                    切换至后台模式
          end:
     if 上一次执行的IO操作<200次
          将100个脏页刷新至磁盘
     合并插入缓冲
     日志缓存刷新至磁盘
     
     do 清理任务
          if 脏页率>70%
               将100个脏页刷新至磁盘
          else
               将10个脏页刷新至磁盘
     end

     do 检查点执行清理
     goto loop:
     后台模式loop:
          干点活
          goto loop:     
}
无用户活动或者数据库关闭会触发切换至后台模式
该模式下 系统表示压力不大 于是:
删除无用的undo页(总是)
合并20个插入缓冲(总是)
跳回主干循环(总是)
不断刷新100个页 直到符合某种条件(作为资本家的人类不能让电脑闲着)
版本4:
void master_thread(){
     loop:
          begin 1秒to 10秒
               日志缓存刷新至磁盘的干活
               if 上次IO次数<5
                    最多执行5次合并插入缓冲的干活
               if 脏页比例>阈值
                    磁盘同步刷新这100页脏页的干活
               if 没有用户活动
                    切换至后台模式
          end:
     if 上一次执行的IO操作<200次
          将100个脏页刷新至磁盘
     合并插入缓冲
     日志缓存刷新至磁盘
     
     do 清理任务
          if 脏页率>70%
               将100个脏页刷新至磁盘
          else
               将10个脏页刷新至磁盘
     end

     do 检查点执行清理
     goto loop:
     后台模式loop:
          进行清理动作
          执行20个合并缓冲
          if 非空闲
               goto loop:
          else
               goto flush loop:

          flush loop:
               将100个脏页刷新至磁盘
               if 脏页比率>最大脏页比率阈值(通常是90%) 
                    goto flush loop
               goto 闲置模式
          闲置模式:
               线程挂起,打酱油,等待事件发生
          goto loop:     
}
潜在问题:
(1)对IO的硬限制,忽视硬件带来的性能提升(例:每秒执行100次脏页磁盘同步)
解决方法:可配置,按IO吞吐率的百分比来刷新和合并,IO吞吐率可配,一般默认是200(工程师需要根据自身实际的硬件条件来进行针对性配置)
在合并插入缓冲时,合并插入缓冲数量为IO吞吐的5%
刷新脏页时,单词全量的脏页处理数位IO吞吐。
(2) 最大脏页比率阈值
     太大,当服务器压力增大或者是大内存时,性能反而下降
     太小,频繁的磁盘操作带来硬件的压力
     目前公认比较优的一个值是75%
版本5:
void master_thread(){
     loop:
          begin 1秒to 10秒
               日志缓存刷新至磁盘的干活
               if 上次IO次数<5%io_capacity
                    最多执行5%io_capacity 次合并插入缓冲的干活
               if 脏页比例>阈值
                    磁盘同步刷新这100%io_capacity 页脏页的干活
               else if 当前各资源满足刷新脏页条件
                    执行期望数量的脏页刷新
               if 没有用户活动
                    切换至后台模式
          end:
     if 上一次执行的IO操作<IO吞吐量
          将100%io_capacity个脏页刷新至磁盘
     5%io_capacity合并插入缓冲
     日志缓存刷新至磁盘
     
     do 清理任务
          if 脏页率>70%
               将100%io_capacity个脏页刷新至磁盘
          else
               将10%io_capacity个脏页刷新至磁盘
     end

     do 检查点执行清理
     goto loop:
     后台模式loop:
          进行清理动作
          执行100%io_capacity个合并缓冲
          if 非空闲
               goto loop:
          else
               goto flush loop:

          flush loop:
               将100%io_capacity个脏页刷新至磁盘
               if 脏页比率>最大脏页比率阈值(通常是90%) 
                    goto flush loop
               goto 闲置模式
          闲置模式:
               线程挂起,打酱油,等待事件发生
          goto loop:     
}

至此innodb主要的核心操作均介绍完了
该存储引擎有三大特性:
(1)插入缓冲 已讲解 (性能提升)
(2)两次写  (数据可靠性
当数据库宕机时,一个页只写了一部分,部分写失效造成数据丢失(场景:断电,操作系统将一个写操作切分成多个写操作)
重做日志恢复可行否?必须不可行啊,其对页物理操作,若该页损坏,重做没意义
也就是说需要在重做日志前,增加一个页的副本,当写失效时,先用副本还原,再重做这就是两次写的机制。
两次写实体数据两部分组成,一个是内存池中的两次写内存(大小为2MB),另一个是物理磁盘上连续128个页(为毛要连续的),当缓冲池脏页进行刷新时,不直接写磁盘,而是先将脏页数据拷贝到两次写内存池中,然后分成两次,每次写入1MB到共享表空间物理磁盘上,然后马上调用fsync函数同步磁盘(写操作立刻执行到磁盘等待IO执行结束再返回,有兴趣的可以了解下fsync与sync的区别以及io的缓存队列机制
http://hi.baidu.com/cxmsee/blog/item/c8988db1a783ee5809230280.html 《unix高级环境编程》第三章)。这过程是顺序写。完成第一次写后,再执行第二次写,此时页是离散的,性能稍差。
若本身系统的文件系统(ZFS)支持部分写失效的防范机制,则可将两次写人为关闭,减少不必要的性能开销。
(3)自适应哈希索引
innodb存储引擎会监控表上索引的查找,若观察发现建立哈希索引可以带来性能提升,则建立之。其通过缓冲池的B+树构造出来,注意不是全表建立,
此外存储引擎会根据当前的模式和访问频率来未某些页建立哈希索引,默认是开启构建哈希索引的。
关闭重启
innodb_fast_shutdown参数影响着关闭数据库时的行为,可取值为0,1,2
0表示全量数据清理合并刷新都将执行
1标示仅将脏页刷新至磁盘
2标示将日志写入日志文件,等到下次启动时执行恢复操作
innodb_force_recovery影响数据库恢复时的行为

类别:默认分类||添加到搜藏 |分享到i贴吧|浏览(67)|评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu