精华内容
下载资源
问答
  • 2021-01-19 14:37:12

    昨天看了InnoDB的双写缓冲,书上说的不太详细,网上也人云亦云。想了一段时间,终于有一些头绪。

    首先需要说一下为什么需要双写缓冲?由于InnoDB和操作系统的页大小不一致,InnoDB页大小一般为16k,操作系统页大小为4k,导致InnoDB回写dirty数据到操作系统中,一个页面需要写4次,写入过程出现问题无法保持原子性。写的过程如果崩溃或者断电,可能导致只有一部分写回到操作系统文件系统中,整个数据只是部分成功,其实数据是损坏的。

    如果需要保证数据成功,又不采用双写缓冲,也有比较笨的办法,redo日志中记录整个变更的页数据,回写的时候从redo日志中拷贝页数据到文件系统中,这样会导致redo日志非常大,可能给系统性能带来很大问题。

    采用双写缓冲,redo日志只需要记录很少的变更信息,原数据还是存在原来的文件系统中,写入到doublewrite buffer中时,根据redo日志和元数据信息计算得到新数据,先写入到doublewrite buffer中。如果这时系统崩溃,恢复以后InnoDB可以计算校验位,知道数据不正确,重新根据redo日志和元数据计算生成数据覆盖doublewrite buffer中的损坏数据。当doublewrite buffer中的数据全部成功写入以后,此时doublewrite buffer会将数据写入到文件系统中,如果此时系统崩溃,只需要遍历doublewrite buffer,重新将数据写入文件系统,覆盖损坏数据即可。

    由于书里和网上一直语焉不详,一直思考为什么需要doublewrite buffer,如果没有是不是也是可行的,答案是没有也可行,但是这样就需要redo日志记录所有变更的页数据,会导致redo日志特别大。如果redo日志只记录变化是否可行?这样会有问题,因为如果直接写入到文件系统中,如果数据损坏,原数据已经被覆盖,单独根据只含有变化信息的redo日志没法计算出新的正确数据。所以doublewrite buffer相当于承担存储中间状态的介质,这样可能会导致多一些IO,但是由于doublewrite buffer是顺序写入,应该影响不太大,数据正确性和redo日志大小得到控制,利大大大于弊。

    更多相关内容
  • 双写缓冲区是InnoDB的大特性之一,还有两个是 Buffer Pool简称BP、自适应Hash索引。doublewrite缓冲区是一个存储区,在该存储区中,在InnoDB将页面写入InnoDB数据文件中的适当位置之前,先从缓冲池中刷新页面。如果...

        双写缓冲区是InnoDB的三大特性之一,还有两个是 Buffer Pool简称BP、自适应Hash索引。doublewrite缓冲区是一个存储区,在该存储区中,InnoDB将页面写入InnoDB数据文件中的适当位置之前,先从缓冲池中刷新页面 。如果在页面写入过程中存在操作系统,存储子系统或意外的mysqld进程退出,则InnoDB可以在崩溃恢复期间从doublewrite缓冲区中找到页面的良好副本。注意:系统恢复后,MySQL 可以根据redolog 进行恢复,而mysql在恢复的过程中是检查page的checksum,checksum就是pgae的最后事务号,发生partial page write 问题时,page已经损坏,找不到该page中的事务号,就无法恢复。

        为什么需要双写?个人理解宏观上还是与InnoDB需要支持事务(ACID)特性有关,而底层的原因是为了解决Partial Write Page问题

        之前在分析Mysql - InnoDB引擎对事务ACID的实现原理分析时个人认为已经透彻的分析了事务的实现过程,而为了实现事务InnoDB引入了比较多的组件,设计的特别复杂,InnoDB级别包括:(行锁、临建锁、间隙锁)锁和加锁规则、MVCC、redo log、undo log、视图(Read View)。而官方文档也在隔离型和持久性上面明确指向了数据双写机制,如下图

        InnoDB的页大小默认为16K,可以使用参数innodb_page_size设置, 可设置的值有: 64KB,32KB,16KB(默认),8KB和4KB。并且在数据校验时也针对页进行计算,即他们是一个整个对待,包括把数据持久化到磁盘的操作。而计算机的硬件和操作系统在极端情况下(比如断电、系统崩溃)时,刚写入了4K或8K数据,那么就不能保证该操作的原子性,称为部分页面写问题(Partial Write Page)

        此时就引入了双写缓存区的机制,当发生极端情况时,可以从系统表空间的Double Write Buffer【磁盘上】进行恢复,下面是InnoDB的架构图、双写和恢复流程图。为了方便对比,将组件放在了相同的位置:

        这样在极端情况下也能解决 Partial Write page问题了,但是如果我自己的系统本身数据要求没有那么高(比如日志数据库),这样的话毕竟双写是有一定的性能开销的。可以通过参数innodb_doublewrite = 0进行关闭,设置为1表示开启。官方认为,尽管需要写入两次数据,但是写缓冲区不需要两次的 io开销或操作,因为只需要调用一次操作系统的fsync() 就可以将批量数据顺序写入磁盘 -> 系统表空间的Double Write Buffer(如上图),这里是顺序写而不是随机写(性能可以保证),当然前提是配置刷盘策略参数innodb_flush_method为默认的O_DIRECT。其实还有一点就是真正提交的时候会使用组提交,我们可以用参数控制:binlog_group_commit_sync_delay:组提交执行fsync() 延迟的微妙数,延迟时间越长批量数据越多,磁盘io越少性能越高。binlog_group_commit_sync_no_delay_count:组提交执行fsync的批个数。


    Mysql - 知识图谱总览

    Mysql - 配置大全(my.cnf)

    Mysql - Mysql架构图

    Mysql - MySQL索引(复合索引、覆盖索引、索引下推、前缀索引)

    Mysql - 优化器阶段的索引选择过程

    Mysql - 争取一文讲清楚Mysql中的锁(全局锁、表级锁、行级锁)和加锁规则

    Mysql - InnoDB引擎对事务ACID的实现原理分析

    Mysql - binlog日志、主从复制过程

    Mysql - InnoDB三大特性之Buffer Pool缓冲池

    Mysql - InnoDB三大特性之双写缓冲区(Double Write Buffer)

    Mysql - InnoDB三大特性之自适应Hash索引(从数据结构角度分析Mysql中的Hash索引)

    Mysql - 普通索引与唯一索引之间性能差别change buffer

    Mysql - 大表全表查询过程(分析底层的数据流转过程)

    Mysql - delete、重建表过程以及内部的锁状态变化

    Mysql - count(字段)<count(主键 id)<count(1)≈count(*)

    Mysql - join类型和实现的效果

    Mysql - join(索引和非索引)的实现原理和优化手段

    Mysql - order by执行原理

    Mysql - 深度分页问题的解决方案

    Mysql - 范围查询过程分析底层的锁实现机制(解决幻读、版本读的不可重复读问题)

    Mysql - 不同级别数据恢复问题

    Mysql - 脏页刷新机制

    Mysql - 慢查询和执行计划

     

    展开全文
  • 文章目录1 问题背景2 回顾3 双写缓冲区 1 问题背景 前面研究了InnoDB磁盘架构之表空间,今天来研究双写缓冲区。 2 回顾 InnoDB架构如下图所示: 3 双写缓冲区 原文 The doublewrite buffer is a storage area ...

    在这里插入图片描述

    1 问题背景

    前面研究了InnoDB磁盘架构之表空间,今天来研究双写缓冲区。

    2 回顾

    InnoDB架构如下图所示:

    在这里插入图片描述

    3 双写缓冲区

    原文
    The doublewrite buffer is a storage area where InnoDB writes pages flushed from the buffer pool before writing the pages to their proper positions in the InnoDB data files. If there is an operating system, storage subsystem, or unexpected mysqld process exit in the middle of a page write, InnoDB can find a good copy of the page from the doublewrite buffer during crash recovery.

    双写缓冲区是一个存储区域,在InnoDB将页写到InnoDB数据文件的正确位置之前,InnoDB将页从缓冲池写到该区域(双写缓冲区)。如果在页面写入的过程中存在操作系统,存储子系统或者意外的mysqld进程退出,InnoDB可以在崩溃恢复期间从双写缓冲区找到一个完整的页面副本。

    原文
    Although data is written twice, the doublewrite buffer does not require twice as much I/O overhead or twice as many I/O operations. Data is written to the doublewrite buffer in a large sequential chunk, with a single fsync() call to the operating system (except in the case that innodb_flush_method is set to O_DIRECT_NO_FSYNC).

    即使数据被写了两次,双写缓冲区不需要两倍的I/O开销或者两倍的I/O操作。数据以大顺序块的形式被写进双写缓冲区中,只需fsync()调用一次操作系统(innodb_flush_method被设置成O_DIRECT_NO_FSYNC的情况除外)。

    原文
    Prior to MySQL 8.0.20, the doublewrite buffer storage area is located in the InnoDB system tablespace. As of MySQL 8.0.20, the doublewrite buffer storage area is located in doublewrite files.

    在 MySQL 8.0.20 之前,双写缓冲区存储区位于InnoDB系统表空间中。从 MySQL 8.0.20 开始,双写缓冲区存储区域位于双写文件中。

    双写缓冲区详情配置见Doublewrite Buffer

    展开全文
  • (1)MySQL数据存储包含内存与磁盘两个部分;(2)内存缓冲池(buffer pool)以页为单位,缓存最热的数据页(data page)与索引页(index ...问题来了,那请求呢?情况一假如要修改页号为4的索引页,而这个页正好在缓冲池内...

    92a674683f28

    (1)MySQL数据存储包含内存与磁盘两个部分;

    (2)内存缓冲池(buffer pool)以页为单位,缓存最热的数据页(data page)与索引页(index page);

    (3)InnoDB以变种LRU算法管理缓冲池,并能够解决“预读失效”与“缓冲池污染”的问题;

    毫无疑问,对于读请求,缓冲池能够减少磁盘IO,提升性能。问题来了,那写请求呢?

    情况一

    假如要修改页号为4的索引页,而这个页正好在缓冲池内。

    92a674683f28

    如上图序号1-2:

    (1)直接修改缓冲池中的页,一次内存操作;

    (2)写入redo log,一次磁盘顺序写操作;

    这样的效率是最高的。

    画外音:像写日志这种顺序写,每秒几万次没问题。

    是否会出现一致性问题呢?

    并不会。

    (1)读取,会命中缓冲池的页;

    (2)缓冲池LRU数据淘汰,会将“脏页”刷回磁盘;

    (3)数据库异常奔溃,能够从redo log中恢复数据;

    什么时候缓冲池中的页,会刷到磁盘上呢?

    定期刷磁盘,而不是每次刷磁盘,能够降低磁盘IO,提升MySQL的性能。

    画外音:批量写,是常见的优化手段。

    情况二

    假如要修改页号为40的索引页,而这个页正好不在缓冲池内。

    92a674683f28

    此时麻烦一点,如上图需要1-3:

    (1)先把需要为40的索引页,从磁盘加载到缓冲池,一次磁盘随机读操作;

    (2)修改缓冲池中的页,一次内存操作;

    (3)写入redo log,一次磁盘顺序写操作;

    没有命中缓冲池的时候,至少产生一次磁盘IO,对于写多读少的业务场景,是否还有优化的空间呢?

    这即是InnoDB考虑的问题,又是本文将要讨论的写缓冲(change buffer)。

    画外音:从名字容易看出,写缓冲是降低磁盘IO,提升数据库写性能的一种机制。

    什么是InnoDB的写缓冲?在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。

    它是一种应用在非唯一普通索引页(non-unique secondary index page)不在缓冲池中,对页进行了写操作,并不会立刻将磁盘页加载到缓冲池,而仅仅记录缓冲变更(buffer changes),等未来数据被读取时,再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。

    InnoDB加入写缓冲优化,上文“情况二”流程会有什么变化?

    假如要修改页号为40的索引页,而这个页正好不在缓冲池内。

    92a674683f28

    加入写缓冲优化后,流程优化为:

    (1)在写缓冲中记录这个操作,一次内存操作;

    (2)写入redo log,一次磁盘顺序写操作;

    其性能与,这个索引页在缓冲池中,相近。

    画外音:可以看到,40这一页,并没有加载到缓冲池中。

    是否会出现一致性问题呢?

    也不会。

    (1)数据库异常奔溃,能够从redo log中恢复数据;

    (2)写缓冲不只是一个内存结构,它也会被定期刷盘到写缓冲系统表空间;

    (3)数据读取时,有另外的流程,将数据合并到缓冲池;

    不妨设,稍后的一个时间,有请求查询索引页40的数据。

    92a674683f28

    此时的流程如序号1-3:

    (1)载入索引页,缓冲池未命中,这次磁盘IO不可避免;

    (2)从写缓冲读取相关信息;

    (3)恢复索引页,放到缓冲池LRU里;

    画外音:可以看到,40这一页,在真正被读取时,才会被加载到缓冲池中。

    还有一个遗漏问题,为什么写缓冲优化,仅适用于非唯一普通索引页呢?

    InnoDB里,聚集索引(clustered index)和普通索引(secondary index)的异同

    如果索引设置了唯一(unique)属性,在进行修改操作时,InnoDB必须进行唯一性检查。也就是说,索引页即使不在缓冲池,磁盘上的页读取无法避免(否则怎么校验是否唯一?),此时就应该直接把相应的页放入缓冲池再进行修改,而不应该再整写缓冲这个幺蛾子。

    除了数据页被访问,还有哪些场景会触发刷写缓冲中的数据呢?

    还有这么几种情况,会刷写缓冲中的数据:

    (1)有一个后台线程,会认为数据库空闲时;

    (2)数据库缓冲池不够用时;

    (3)数据库正常关闭时;

    (4)redo log写满时;

    画外音:几乎不会出现redo log写满,此时整个数据库处于无法写入的不可用状态。

    什么业务场景,适合开启InnoDB的写缓冲机制?

    先说什么时候不适合,如上文分析,当:

    (1)数据库都是唯一索引;

    (2)或者,写入一个数据后,会立刻读取它;

    这两类场景,在写操作进行时(进行后),本来就要进行进行页读取,本来相应页面就要入缓冲池,此时写缓存反倒成了负担,增加了复杂度。

    什么时候适合使用写缓冲,如果:

    (1)数据库大部分是非唯一索引;

    (2)业务是写多读少,或者不是写后立刻读取;

    可以使用写缓冲,将原本每次写入都需要进行磁盘IO的SQL,优化定期批量写磁盘。

    画外音:例如,账单流水业务。

    上述原理,对应InnoDB里哪些参数?

    有两个比较重要的参数。

    92a674683f28

    参数:innodb_change_buffer_max_size

    介绍:配置写缓冲的大小,占整个缓冲池的比例,默认值是25%,最大值是50%。

    画外音:写多读少的业务,才需要调大这个值,读多写少的业务,25%其实也多了。

    参数:innodb_change_buffering

    介绍:配置哪些写操作启用写缓冲,可以设置成all/none/inserts/deletes等。

    展开全文
  • InnoDB双写缓冲

    2020-04-11 19:46:27
    先简单解释下什么是双写缓冲。InnoDB使用了一种叫做doublewrite的特殊文件flush技术,在把pages写到date files之前,InnoDB先把它们写到一个叫doublewrite buffer的连续区域内,在写doublewrite buffer完成后,...
  • 传输速度的提升使得USB设备控制器的设计指标也随之提高,虽然协议中对于缓冲区的设计要求并没有本质上的改变,但是由于总线带宽与传输速度的提高,各个芯片供应商均推出了自己的缓冲区设计方案。为了提高USB接口的...
  • 什么是缓冲区?有什么作用?2.单缓冲3.缓冲4.单缓冲和双缓冲通信时的区别5.循环缓冲区6.缓冲池 0.思维导图 1.什么是缓冲区?有什么作用? 2.单缓冲 T>C时的例子: T<C时: 3.缓冲 T>C+M时: T...
  • 双缓冲区

    千次阅读 2016-08-27 23:15:21
    双缓冲区今天看大规模分布式存储系统,看到缓冲这一部分内容,加之之前项目中应用到缓冲思想,故总结缓冲知识如下,其中程序是参看stackoverflow的,具体网址找不到了,故未标注在参看文献中。 简介 双缓冲区...
  • 最近在使用C#做项目的时候发现在加载一个具有大量控件和复杂...一般需要使用双缓冲区的地方都是由于“生产者”和“消费者”供需不一致所造成的。这样的情况在很多地方后可能会发生,使用多缓冲可以很好的解决。我举几
  • 一般需要使用双缓冲区的地方都是由于“生产者”和“消费者”供需不一致所造成的。这样的情况在很多地方后可能会发生,使用多缓冲可以很好的解决。我举几个常见的例子:例 1.在网络传输过程中数据的接收,有时可能...
  • Java双缓冲技术详细讲解,适合初学者,简单易懂,代码
  • 缓冲双缓冲

    千次阅读 2021-07-30 21:13:39
    因为缓冲区是临界资源,不能同时对它进行读/。由于只有一个缓冲区,发送者只有等到接收者将数据取走后,才能再往缓冲区中送数据,否则会覆盖掉原有数据。而接收者也只有等发送者输入数据才能取走,否则会重复取出...
  • 现在,我需要创建一个虚拟的、看不见但是可以在上面画图(比如说画点、线)的OSD层,我称之为offscreen(后台缓冲区)。简洁的说,“屏幕缓冲”是指在内存中建立一个“图形设备上下文的缓存”,所有的绘图操作都在...
  • c语言双缓冲缓冲机制

    2021-04-12 08:12:56
    这里自定义目录标题 1:code: 代码转载于:(部分错误已经修改) 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:...
  • 现在,我需要创建一个虚拟的、看不见但是可以在上面画图(比如说画点、线)的OSD层,我称之为offscreen(后台缓冲区)。简洁的说,“屏幕缓冲”是指在内存中建立一个“图形设备上下文的缓存”,所有的绘图操作都在...
  • TCP的发送缓冲区

    千次阅读 2020-12-20 08:16:46
    当应用进程调用write往套接口数据时,内核从应用进程缓冲区中拷贝所有数据到套接口的发送缓冲区,如果套接口发送缓冲区容不下应用程序的所有数据,或者是应用进程的缓冲区大于套接口的发送缓冲区,或者是套接口的...
  • MapReduce环形缓冲区底层实现

    千次阅读 2022-01-31 18:11:03
    MapOutputBuffer内部使用了一个缓冲区暂时存储用户输出数据,当缓冲区使用率达到一定阈值后,再将缓冲区中的数据到磁盘上。 数据缓冲区的设计方式直接影响到Map Task的效率,而现有多种数据
  • 存储系统双缓冲设计模式

    千次阅读 多人点赞 2019-05-19 12:18:27
    文章目录前言单缓冲模式单缓冲模式改进: 双缓冲模式 前言 在存储系统数据的过程中,出于性能上的考虑,新的数据并不是每次都flush到目标存储中的,而是先放入到一个buffer空间里,等到buffer空间满了,再做一次...
  • minigui框架提供了窗口双缓冲区机制,利用这个机制可以实现窗口显示特效。不是所有的窗口都可以利用双缓冲区实现显示特效,窗口必须具备WS_EX_AUTOSECONDARYDC扩展窗口风格。所以下面的函数中首先就是判断窗口是否有...
  • ringbuff | 通用FIFO环形缓冲区实现库

    千次阅读 2020-06-06 10:58:39
    设计思想解读 关于环形缓冲区背后的设计实现,请阅读这篇文章,的非常棒: STM32进阶之串口环形缓冲区实现 5. 项目工程源码获取和问题交流 目前我将ringbuff源码、我移植到小熊派STM32L431RCT6开发板的工程源码...
  • 缓冲区有很多种(粗略分类),像输入缓冲区、输出缓冲区、文件缓冲区、键盘缓冲区、输出缓冲区等等。有时候叫buf 缓冲区本质是一段连续的空间,比如char a[10],a为一段连续的20字节的空间 按照其功能来...
  • 多图详解缓冲区溢出问题

    万次阅读 多人点赞 2020-11-18 23:43:21
    缓冲区溢出一个常见的后果是:黑客利用函数调用过程中程序的返回地址,将存放这块地址的指针精准指向计算机中存放攻击代码的位置,造成程序异常中止。为了防止发生严重的后果,计算机会采用栈随机化,利用金丝雀值...
  • 双缓冲技术讲解

    万次阅读 多人点赞 2017-05-15 17:49:17
    当更改完成时,交换操作会立即交换下一个缓冲区和当前缓冲区,以便新的缓冲区现在公开显示。 旧的当前缓冲区现在可以重新用作新的下一个缓冲区。 与较大的架构模式不同,缓冲存在于较低的实施级别。 因此,对...
  • 交换指针的安全保证让缓冲的方式避免了单缓冲方式在动态内容显示中的问题,增加的一个缓冲区也在一定程度上提高了 gui 绘制的效率,这种方式的使用十分广泛。 三缓冲 三缓冲的工作原理与缓冲类似,只是缓冲...
  • 架构设计:生产者/消费者模式[4]:双缓冲区 文章目录 ★为啥要双缓冲区?★双缓冲区的原理★双缓冲区的几种状态★可能的并发问题★应用场景  “双缓冲区”是一个应用很广的手法。该手法用得最多的地方想必是屏幕...
  • python双缓冲, double buffer
  • 双缓冲绘图算法C++例子实现

    千次阅读 2021-11-13 22:26:04
    文章目录前言一、双缓冲绘图算法?二、使用步骤1.准备环境2.创建项目3. 创建小球类4. 在view文件中设置所需参数及函数1. 需要添加一个小球对象,还需要添加小球移动的距离变量;2. 需要添加一个定时器,用以更新小球...
  • MFC双缓冲绘图

    2017-09-02 14:53:12
     所谓双缓冲技术,百度百科的解释:双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。    当我们看...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 97,134
精华内容 38,853
关键字:

双写缓冲区