空心|Aurora,万字详文:腾讯数据库专家深度探索Amazon( 三 )


Aurora提供了一个“自动恢复”缓冲预热的功能 , 其官方宣称如下:
“自动恢复”缓存预热
当数据库在关闭后启动或在发生故障后重启时 , Aurora将对缓冲池缓存进行“预热” 。 即 , Aurora会用内存页面缓存中存储的已知常用查询页面预加载缓冲池 。 这样 , 缓冲池便无需从正常的数据库使用“预热” , 从而提高性能 。
Aurora页面缓存将通过数据库中的单独过程进行管理 , 这将允许页面缓存独立于数据库进行“自动恢复” 。 在出现极少发生的数据库故障时 , 页面缓存将保留在内存中 , 这将确保在数据库重新启动时 , 使用最新状态预热缓冲池 。
源自:
“在出现极少发生的数据库故障时 , 页面缓存将保留在内存中” , 这句话很重要 , 一是其表明数据不用很耗时地重新加载了 , 二是数据库实例崩溃前的数据内存状态被保留着 , 三是数据库崩溃重启不必再执行“故障恢复”的过程即使用REDO日志重新回放以保障数据的一致性了(事务的ACID中的C特性) 。
那么 , 页面缓冲是一直保留在哪个节点的内存中?是存储节点还是计算节点?如果是位于计算节点 , 那么备机节点发生数据库故障时 , 这样的机制不会对备机节点起到保护作用 。 如果是位于存储节点 , 则存储作为一个服务 , 服务了一主多备的多个节点 , 则能更好的发挥“自动恢复”缓冲预热的功效(存储节点的caching一直存在 , 向上层计算节点的caching提供数据批量加载服务 , 但也许不是这样 , 而是提供一个接口 , 能够向计算层的caching提供高速读数据的服务 , 论文没有更多的重要细节披露 , 权做推测) 。 由此看来 , “Caching”层的两层设计 , 当是有价值的(价值点是“自动恢复”缓冲预热 , 由存储层提供此项服务) , 与预写日志功能从事务层剥离是关联的设计 。
这就又回到前面引用的论文中的那段英文 , 其表明:Aurora的设计 , 把REDO日志、持久化存储、系统故障恢复、物理备份与物理恢复这些功能模块 , 归属到了存储层 。 由此就引出了Aurora的另外一个重要话题---存储层的设计(如下的第二部分和下一节内容) 。
对于计算层的“Caching” , 其实现将被大为简化 。 脏数据不再被写出 , 脏页面不再需要复杂的淘汰策略进行管理 , 消除了后台的写任务线程 , 同时也消除了checkpoint线程的工作 , 数据缓冲区的管理大为简化 , 即降低了系统的复杂度又减少了时间的消耗、还避免了因执行后台写等任务带来的性能抖动 , 解耦带来的功效确实宜人 。 Aurora额外需要做的一项新工作是:onlypageswithalongchainofmodificationsneedtoberematerialized 。 而计算层的“Caching”变成单向的读入 , 此时需要解决的 , 仅仅是什么样的数据可以(从存储层的Caching)被读入的问题 , 而论文原文描述:
Theguaranteeisimplementedbyevictingapagefromthecacheonlyifits“pageLSN”(identifyingthelogrecordassociatedwiththelatestchangetothepage)isgreaterthanorequaltotheVDL.
VDL是存储层的最小一致点(参见3.1节) , 标识了可用日志的最低范围 , 比VDL还老的数据页不再可用 , 所以显然如上的论文原文是错误的 。 如果有比当前数据页还新的数据页被从日志中恢复 , 则其LSN一定更大 , 所以页面换入的条件是:存储层Caching中存在页面的LSN值更大的;页面被换出的条件是:Caching中的页面的LSN小于等于VDL 。 而且 , 这一定是发生在备机需要更新其计算层的Caching时刻 , 而不是主机需要更新其计算层的Caching时刻 。 存在此种情况 , 其原因已经很明显 , 主机修改数据 , 形成脏页 , 这样的脏页(数据的后像)才能作为REDO日志的一部分被主机刷出;而主机不会刷出脏页 , 所以被修改后的数据页应该一直在内存中 , 而被修改过的数据页如果反复被修改 , 则意味着主机Caching中的相应脏页数据一定是最新的 , 没有必要从存储层的Caching中读入“绕道恢复后的数据页” 。 如果以上猜想不成立 , 除非Aurora生成REDO日志时 , 存于REDO日志中的数据页部分采取先复制然后其上的数据项被修改这样的方式 。 可是多做一次复制 , 又有何必要呢?


推荐阅读