关于ORACLE 和MYSQL INNODB 触发脏数据写的机制对比

首先要说明在ORACLE和INNODB触发checkpoint方面都采用LRU进行管理,并且都有全量检查点和增量检查点一说
在MYSQL中全量检查点叫做sharp checkpoint,增量检查点叫做FUZZY CHECKPOINT,

在ORACLE中更加细化,加入了LRUW链表,并且加入CHECKPOINT-Q列表,两者共同配合完成增量CHECKPOINT,在ORACLE
中DBWR写是按照CHECKPOINT-Q的顺序写的其是LRBA的链表,其触发条件受到MTTR的限制,如果ORACL估计能够达到INSTANCE
CRASH RECOVERY的时间就会不触发CHECKPOINT-Q写,而加入LRUW列表更是为了减轻按照CHECKPOINT-Q来写的负担,如果检查到
哪些每3秒访问少2次的脏块就会从LRU中拿下计入LRUW,等待DBWR3秒醒来触发写,对于3秒访问大于等于2次的脏块,依然按照
checkpoint-Q来写,因为很可能还会修改,写完后从CHECKPOINT-Q下摘下。这样LRUW基本就是为了那些修改次数少的脏块而生的,
目的在于优先写入修改次数少脏块减轻CHECKPOINT-Q增量检查点压力。
其实在ORACLE中LRU和LRUW都分为辅助和主列两个,关于这一点是为了加快扫描LRU的效率,详细参加吕海波ORACLE内核揭秘
这里给出ORACLE写脏块的机制(来自吕海波ORACLE内核揭秘)
1、DBWR 3秒写冷脏块上面说的3秒内访问一次的脏块
2、CHEKPOINT-Q 写入,他也是DBWR来判断的如果不能满足MTTR的设置就开始写,由CKPT修改CONTROLFILE里面的各种信息,重要的
就是LRBA,关于LRBA和脏块数量可能通过X$KCCCP来查看
3、服务器进程扫描LRU发现25%的脏块直接出发DBWR写,不需要等待3秒,从LRUW进行写,有隐含参数_db_large_dirty_queue控制默认25%
4、服务器进程扫描超过40%的BUFFER没有找到可用的BUFFER来缓存新的数据块,不需要等待3秒,从LRUW进行, 
   由隐含_db_block_max_scan_pct控制
5、各种全量检查点
   alter system checkpoint
   SHUTDOWN DATABASE非ABORT
   log switch
   表空间OFFLINE 表空间一级检查点
   DDL语句drop truncate等对象一级检查点

在MYSQL中一切其实差不多,但是从MYSQL内幕innodb存储引擎一书来看,所有的脏块和干净的块都在LRU列中,同时还存放了一份
在flush列表中(类似ORACLE的CHECKPOINT-q),同样MASTER进程也是用来读取FLUSH列表进行脏数据写的,但是MYSQL没有LRUW的
概念,所以所有的脏块正常情况下都是冲FLUSH列表中的脏块写入的。
这里给出MYSQL写脏块的机制(姜承晓MYSQL内幕innodb存储引擎)
FUZZY CHECKPOINT
1、MASTER进程每秒或者每10秒从FLUSH列表中按照顺序写入脏块
2、根据innodb_lru_scan_depth 参数设置默认5.6 1024,如果没有PAGE CLEANR 进程发现没有1024可用空闲页,刷出LRU链尾端的页
   如果有脏块触发脏块写show engine innodb status 来看及如下:
   Buffer pool size   70400
   Free buffers       32776--这里
   Database pages     34879
   Old database pages 12711
   Modified db pages  662
   
3、根据日志的使用情况,如果从show engine innodb status 来看及如下:
   Log sequence number 3100866076
   Log flushed up to   3100744765
   Pages flushed up to 3099998234
   Last checkpoint at  3099878300
   
   75%*日志量>Log sequence number-Last checkpoint at 不需要触发脏块写
   75%*日志量<Log sequence number-Last checkpoint at<90%*日志量触发异步写
   Log sequence number-Last checkpoint at>90%*日志量触发同步写

4、根据INNODB_MAX_DIRTY_PAGE_PCT设置默认75,当脏块数量达到75%进行脏数据库写
   Buffer pool size   70400
   Free buffers       32776
   Database pages     34879
   Old database pages 12711
   Modified db pages  662  ---这里
   
sharp checkpoint 只有在关闭数据库的时候触发并且INNODB_FAST_SHUTDOWN=1的情况下(默认设置)

由此来看ORACLE的第一条和第二条属于正常刷新他们对应了MYSQL第一条
ORACLE的第三条属于脏块过多刷新对应MYSQL的第四条
ORACLE的第四条属于没有可用的BUFFER BLOCK对应MYSQL的第二条
ORACLE虽然没有根据日志量的使用情况来判断是否需要写脏块,但是ORACLE实际每次SWITCH LOGFILE
都会触发检查点,那么也就不存在这样的问题了。
最后思考一个问题,ORACLE中实际上可能会出现脏数据写赶不上日志切换的速度会出现等待
Checkpoint not complete,这个时候可能要加大LOGFILE 组来满足,或者减少LOG生成量,我想
MYSQL INNODB中应该也会有同样的情况发生,但是没有模拟出来,也不知道怎么查看。
我这里对比只是为了更加加深两种不同数据库的CHECKPOINT和脏数据写机制,同时加入了自己的一些理解,可能有误
给出参考文献尊重原著

参考:吕海波ORACLE内核揭秘
参考:姜承晓MYSQL内幕innodb存储引擎

时间: 2024-09-20 15:33:06

关于ORACLE 和MYSQL INNODB 触发脏数据写的机制对比的相关文章

多个数据库-c3p0同时配置Oracle和MySQL,JBDCUtil应如何写

问题描述 c3p0同时配置Oracle和MySQL,JBDCUtil应如何写 我想通过配置c3p0.xml文件在我需要时可以连接oracle或者MySQL数据库,但我不知道jdbcutil该怎么写

oracle 存储过程或函数怎么把数据写到硬盘上?

问题描述 想在 存储过程 或者 函数中将 一些数据写到硬盘上,最好中文不要乱码.哪位大侠能告诉我怎么做吗? 问题补充:mrliang 写道 解决方案 外网应该不太可能,局域网可以,如果是windows,可以设置共享目录,如果是linux,利用smbfs也可以设置共享目录解决方案二:Oracle中提供的一个utl_file的包可以将字符串读写到文件中1 修改INIT.ORA文件,加上UTL_FILE_PATH = <要创建文件的路径名>2 建立存储过程create or replace proc

MYSQL innodb buffer 状态数据的保存和载入

本文参考官方手册 原创转载请注明出处 版本:MYSQL 5.7 当数据库重启后,buffer中的数据需要重新预热,所谓预热就是等待常用数据通过用户调用SQL语句从磁盘载入到内存, 这个过程ORACLE中叫做物理读取,对于较大的平台这个预热过程往往需要较大的代价,典型的就是第一次运行一个select 语句很慢,过后再次执行就很快了. 对于这种情况innodb默认在关闭和启动的时候都会保存和加载状态数据,由参数 innodb_buffer_pool_load_at_startup 和 innodb_

MySQL InnoDB和MyISAM数据引擎的差别分析_Mysql

MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能. MyIASM是IASM表的新版本,有如下扩展: 二进制层次的可移植性. NULL列索引. 对变长行比ISAM表有更少的碎片. 支持大文件. 更好的索引压缩. 更好的键吗统计分布. 更好和更快的auto_increment处理. 以下是一些细节和具体实现的差别: 1.InnoDB不支持FULLTEXT类型的索引. 2.InnoDB 中不保存表的具体行数,也

MySQL InnoDB的两次写

今天我们来介绍InnoDB存储引擎的第二个特性 - 两次写(doublewrite),如果说插入缓冲是为了提高写 性能的话,那么两次写是为了提高可靠性,牺牲了一点点写性能. 部分写失效 想象这么一个 场景,当数据库正在从内存向磁盘写一个数据页时,数据库宕机,从而导致这个页只写了部分数据,这就是 部分写失效,它会导致数据丢失.这时是无法通过重做日志恢复的,因为重做日志记录的是对页的物理修改 ,如果页本身已经损坏,重做日志也无能为力. 两次写机制 从上面分析我们知道,在部分写 失效的情况下,我们在应

MySQL Innodb数据库性能实践——热点数据性能

对于大部分的应用来说,都存在热点数据的访问,即:某些数据在一定时间内的访问频率要远远高于其它数据. 常见的热点数据有"最新的新闻"."最热门的新闻"."下载量最大"的电影等. 为了了解MySQL Innodb对热点数据的支持情况,我进行了基准测试,测试环境如下: [硬件配置] 硬件 配置 CPU Intel(R) Xeon(R) CPU E5620 主频2.40GHz, 物理CPU 2个,逻辑CPU 16个 内存 24G(6块 * 4G  DDR

Oracle to MySQL Goldengate实现增量迁移

第一部分:安装和基本配置 一.环境 两台rhel 6.4虚拟机,分别异构oracle到mysql数据库同步测试 Ip:192.168.0.23 部署oracle 11.2.0.4,goldgate 12.1.2.1.0 for oracle Ip:192.168.0.25 部署mysql5.5.9,goldengate 12.1.2.1.0 for mysql 二.Oracle to Mysql需要注意的地方: 对MySQL支持的数据类型: CHAR|DATETIME|VARCHAR|TIMES

ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理区别

ORACLE 索引和MYSQL INNODB 辅助索引对NULL的处理 我们清楚ORACLE中的b+索引是对键值的NULL进行存储的,以致于我们 IS NULL这种肯定是用不到索引的, 当然这提及的ORACLE表为堆表,索引为单列B+树索引,(有一种优化方式为建立组合索引如create index xx on tab(a,'1') 这样来保证索引记录NULL值 这样DUMP出来为 ..... row#11[7886] flag: ------, lock: 2, len=12 col 0; NU

PHP将数据从Oracle向Mysql数据迁移实例

为什么要迁移? 首先从运营成本考虑,用Mysql可以节约不少的费用.另一方面,Mysql的稳定性及功能不断地提高与 增强,基本上可以满足客户的需求,如支持多 节点部署,数据分区等.还有就是Mysql使用方便,比 Oracle简单易用.故客户就要求将已有的Oracle数据表与内容迁移到Mysql来. 为什么要自己写脚本? 迁移的表与数据都蛮多的,有几百张表.因此手工完成不太方便.也尝试了一些免费的迁移工具, 如:MySQLMigrationTool等,发现转移 的字段类型不太符合要求(可能是原来的