广告
返回顶部
首页 > 资讯 > 数据库 >MySQL8.0 redo日志系统优化
  • 993
分享到

MySQL8.0 redo日志系统优化

MySQL8.0redo日志系统优化 2021-11-02 10:11:07 993人浏览 猪猪侠
摘要

背景 现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复。redo日志是物理日志,一般采用WAL(Write-Ahead-Logging)机制,所以也称redo日志为wal日

背景

现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复。redo日志是物理日志,一般采用WAL(Write-Ahead-Logging)机制,所以也称redo日志为wal日志,redo日志记录了所有数据的变更,undo日志是逻辑日志,记录了所有操作的前镜像,方便异常时进行回滚。用户在提交事务时,只要确保写redo日志成功即可,并不需要对应的数据页也实时落盘,这套机制的基本思想是利用空间换时间,用户事务的更新实际上在数据页和redo日志中记录了两份,传统的数据库存储引擎都是基于B+Tree来组织数据页,因此刷数据页是离散小块io,而写redo是顺序IO,对磁盘介质更友好,而且OLTP场景下,业务对RT(ResponseTime)也比较敏感,所以这套机制非常流行。

redo日志是保证数据不丢的关键因素,而且每个事务在提交时,都需要写redo日志,可想而知这块资源竞争是非常激烈的。这个问题是所有基于WAL机制的数据库系统个的共性问题,下文的讨论以Mysql为例,并以此说明mysql8.0在这块的优化

最初的redo日志机制

在Mysql的日志系统中,这里讨论的是InnoDB引擎,mtr(mini-transaction)是最小事务单位,一个用户事务会对应若干个mtr,mtr保证内部操作的原子性,比如B+Tree分裂操作,必需在一个mtr中。用户执行操作时,会同时更新数据页和写redo日志,mtr是redo日志的载体,存在每个会话的私有变量中。mtr提交时,会将本地redo日志拷贝到全局的log_buffer中,为了保证日志有序性,需要加来访问log_buffer,这把锁就是log_sys_t::mutex,所以这个锁竞争非常激烈。在这个锁保护下,除了要将本地日志拷贝到全局buffer,还需要将数据页加入了flush_list,供后台线程刷脏,辅助数据库检查点持续往前推进。检查点一方面能控制全局的redo日志文件大小,让日志具备循环复用的能力;另一方面,也能提高故障恢复速度。因为故障恢复的本质就是利用落盘的redo日志来恢复没有落盘的数据页。所以最开始(MySQL5.1)只有一把锁,大并发场景下,这个锁竞争非常激烈,MySQL在多核系统下也无法提升性能。

拆分log_sys_t::mutex

既然锁竞争压力大,那么最直观的想法就是拆锁。首先按功能拆分,刚刚说到,在mutex保护下,做了两件事,一件是拷贝本地日志到全局log_buffer;另一件事是将事务修改的page加入到flush_list。日志系统将这两件事解耦,引入了log_sys_t::flush_order_mutex,减少log_sys_t::mutex的持锁时间。将本地日志拷贝到log_buffer后,就可以释放log_sys_t::mutex,这样拷贝日志的线程和处理flush_list的线程就可以并发起来。

除了这个,日志系统还引入了双log_buffer机制,这个主要是为了解决全局log_buffer的读写并发问题。一个buffer用于拷贝日志到log_buffer,另一个log_buffer则用于读取,写入到日志文件。当需要读log_buffer时,则可以切换log_buffer的角色,这样就消除了写日志文件带来的访问log_buffer锁竞争。

但是,拆分完锁后,多个用户线程仍然需要在log_sys_t::mutex保护下,串行写log_buffer,由于memcpy操作比较重,所以这个锁竞争仍然非常激烈,需要优化。

消除log_sys_t::mutex

为了解决log_sys_t::mutex并发问题,MySQL 8.0引入了新的log_buffer机制,借助于lock_free的link_buf数据结构,利用原子变量来进行预占位,这样多个线程就能并发写redo,这种机制带来了一个空洞问题,因为写日志速度不一样,可能导致后占位(lsn较大)的线程先写完。但是我们写日志线程肯定是不能将带有空洞的buffer写到日志文件,因此会维护一个滑动窗口,即最小的连续的lsn:buf_ready_for_write_lsn。写日志线程会不断的检查 link_buf变量recent_written,然后写日志,推进buf_ready_for_write_lsn。

前面我们提到了系统中有两把锁,log_sys_t::mutex和log_sys_t::flush_order_mutex,通过占位方式,解决了写log_buffer的问题,那么如何解决将脏页有序加入到flush_list的问题呢?MySQL 8.0实现中仍然借助于link_buf数据结构,原来要求是加入flush_list的数据页的oldest_modification_lsn一定是递增的。这里顺便说下oldest_modification_lsn的含义,oldest_modification_lsn是指page第一次被修改后,mtr在log_sys_t中分配的lsn,即使这个page在flush下去之前,又在内存中被修改过N次,仍然以第一次修改的lsn为准,这样做的目的是,确保数据页内存的修改与检查点推进能对应上,避免检查点推进了,但对应的脏页可能还未刷盘,造成数据丢失问题。

由于是并发乱序写log_buffer,那么无法保证按lsn递增有序加入到flush_list,也就无法推进检查点。MySQL 8.0通过限制大于一定阀值L的lsn加入到flush_list做为权衡,假设当前flush_list的lsn最大值为M,那么只有在M值与当前线程lsn相差范围在L以内时,才将脏页写入flush_list。同样的,推进M,也依赖于link_buf变量recent_closed。这种策略本质上放宽了之前对于flush_list中对于LSN全局有序的限制到L范围内的有序。

除了日志系统变成lock free,MySQL8.0还将写日志线程从用户线程中拆分出来,有单独的log writer线程和log flusher后台线程来处理写日志和sync日志。原来的写日志方式是,大家随机group-commit,由一个线程负责write/flush日志,其它线程等待,这种模式下group的大小比较随机。拆分后,处理更灵活,batch大小也更好控制,而且对于flush_log_at_trx_commit!=1的场景,只需要等log writer的通知即可。

总结

从MySQL日志系统优化的演进过程来看,始终是围绕锁log_sys_t::mutex展开。 从最初的按功能拆分出log_sys_t::flush_order_mutex,到按读写拆分实现为双log_buffer,以及最新的MySQL 8.0利用无锁机制彻底去掉这把锁,显然MySQL的并发能力是越来越强的。这种优化“套路”其实是比较朴素通用的,对于一个新的系统,通过一把大锁能简化并发逻辑,优先保证正确性。在系统慢慢演进过程中,我们可以按功能拆分锁,缓解锁冲突压力;如果某把锁处于核心链路,而且又成为瓶颈,那么再想办法继续拆,或者实现为无锁,彻底解决并发冲突问题,目的只有一个就是充分利用多核CPU资源,然线程多干活,减少响应时间的同时,拉高吞吐量,而不是都等待空闲着。文章中并没有涉及更多关于MySQL8.0日志系统优化的细节,官方文档已经写地足够好,大家可以详细看看。

参考文档

https://mysqlserverteam.com/mysql-8-0-new-lock-free-Scalable-wal-design/

Http://mysql.taobao.org/monthly/2018/07/01/

https://yq.aliyun.com/articles/592215?utm_content=m_49932

您可能感兴趣的文档:

--结束END--

本文标题: MySQL8.0 redo日志系统优化

本文链接: https://www.lsjlt.com/news/2035.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL8.0 redo日志系统优化
    背景 现在主流的数据库系统的故障恢复逻辑都是基于经典的ARIES协议,也就是基于undo日志+redo日志的来进行故障恢复。redo日志是物理日志,一般采用WAL(Write-Ahead-Logging)机制,所以也称redo日志为wal日...
    99+
    2021-11-02
    MySQL8.0 redo日志系统优化
  • MySQL日志系统bin log、redo log和undo log
    MySQL日志系统bin log、redo log和undo log       今人不见古时月,今月曾经照古人。   简介:日志是MySQL数据库的重要组成部分,记录着数据库运行期间各种状态信息,主要包括错误日志、查询日志、慢查询日志、...
    99+
    2019-07-22
    MySQL日志系统bin log redo log和undo log
  • mysql日志系统redo log和bin log介绍
    首先,我们先来看看一次查询/更新语句流程图 本文会将重点放在执行器<->存储引擎之间的交互。 mysql不是每次数据更改都立刻写到磁盘,而是会先将修改后的结果暂存在内存中,当一段时间后,再一次性将多个修改写...
    99+
    2022-08-25
  • 添加redo日志组和添加日志组多元化
    查看redo日志组的状态和日志的位置. SQL> select * from v$log;     GROUP#  &n...
    99+
    2022-10-18
  • MySQL8.0 redo log优化概述和线程模型介绍
    本篇内容介绍了“MySQL8.0 redo log优化概述和线程模型介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能...
    99+
    2022-10-18
  • Oracle产生redo日志量大小统计
    在Oracle中,对于数据库的修改操作都会记录redo,那么不同的操作会产生多少redo呢?可以通过以下一些方式来查询来统计产生的redo日志量。 (1)SQL*Plus中使用AUTOT...
    99+
    2022-10-18
  • Java日志系统如何优化并发处理?
    日志系统是现代软件开发中必不可少的一部分,它能够记录系统运行时的各种信息,如错误日志、调试信息、性能指标等。在Java应用程序中,日志系统通常是通过Log4j、Logback等第三方库实现的。 然而,在高并发环境下,日志系统的性能会成为一...
    99+
    2023-09-25
    日志 并发 大数据
  • 如何使用 Python 缓存 API 优化日志系统?
    Python 是一门流行的编程语言,它被广泛地应用于 Web 开发、数据分析、人工智能等领域。在这些应用中,日志系统是非常重要的一环。在大规模系统中,日志系统的性能往往成为瓶颈,这时候就需要使用缓存 API 来优化日志系统。本文将介绍如何使...
    99+
    2023-08-24
    日志 缓存 api
  • 分布式系统中如何优化 Python 日志性能?
    在分布式系统中,日志记录是非常重要的,它可以帮助我们了解系统的运行情况,以便及时发现和解决问题。然而,日志记录也会对系统的性能产生一定的影响,特别是在分布式系统中。在本文中,我们将探讨如何优化 Python 日志性能以提高分布式系统的效率...
    99+
    2023-07-22
    日志 分布式 函数
  • 日志系统(2)
    redo log redo log:重做日志。每当有操作时,在数据变更之前将操作写入redo log,这样当发生掉电之类的情况时系统可以在重启后继续操作 undo log:称为撤销日志,当一些变更执行到一半无法完成时,可以根据撤销...
    99+
    2015-12-02
    日志系统(2)
  • Linux系统日志记录:如何优化Java并发性能?
    在开发高并发系统时,如何优化Java并发性能是一项非常关键的任务。在这个过程中,Linux系统日志记录是一个不可忽略的因素。本文将介绍如何使用Linux系统日志记录来优化Java并发性能。 1.了解Linux系统日志记录 Linux系统日...
    99+
    2023-10-28
    并发 linux 日志
  • Python 日志系统:如何使用缓存 API 优化性能?
    Python 是一种高级语言,它的灵活性和多样性使得它成为了许多项目的首选语言。然而,Python 也有一些缺点,其中之一就是性能问题。当你的 Python 代码运行缓慢时,你需要考虑如何优化它。Python 日志系统是一个非常有用的工具...
    99+
    2023-08-24
    日志 缓存 api
  • 如何实现MySQL底层优化:日志系统的优化与性能提升
    MySQL是目前最流行的关系型数据库管理系统之一,作为网站及应用程序后端的核心组件,其性能优化显得尤为关键。其中,日志系统是MySQL的重要组成部分,其性能对数据库的整体性能影响极大。因此,本文将深入讨论MySQL日志系统的优化和性能提升。...
    99+
    2023-11-08
    MySQL 优化 日志
  • Mysql优化-慢sql日志
    一.开启慢sql日志捕获慢sql 查询mysql是否开启慢sql捕获:show variables like ‘%slow_query_log%’; 默认为OFF,开启:set global slow_query_log=1; 查看慢...
    99+
    2018-11-19
    Mysql优化-慢sql日志
  • Rsyslog+H3C日志系统
    一、交换机发送日志到linux主机[9F-3600V2-EI]info-center loghost 192.168.11.36[9F-3600V2-EI]info-center enable 二、linux下配置   1.建立日志文件路径...
    99+
    2023-01-31
    系统 日志 Rsyslog
  • JavaScript 是否可以优化 PHP 日志系统的查询速度?
    随着互联网和大数据时代的到来,日志系统在各个领域中扮演着非常重要的角色。PHP作为一种流行的服务器端编程语言,其日志系统也是相当重要的。然而,在实际应用中,由于日志系统的查询效率存在一定问题,导致查询速度变慢,影响了系统的整体性能。在这种情...
    99+
    2023-07-28
    日志 大数据 javascript
  • Linux系统中,如何使用Python来优化缓存和日志?
    在Linux系统中,Python是一种非常流行的编程语言,它可以帮助我们优化缓存和日志。在本文中,我们将会介绍一些使用Python来优化缓存和日志的技巧,并提供一些示例代码。 一、缓存优化 缓存是一种常用的技术,它可以帮助我们提高应用程序的...
    99+
    2023-10-10
    linux 缓存 日志
  • 怎么在Linux系统下安装ccze美化系统日志
    这篇文章主要介绍“怎么在Linux系统下安装ccze美化系统日志”,在日常操作中,相信很多人在怎么在Linux系统下安装ccze美化系统日志问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么在Linux系统下...
    99+
    2023-06-12
  • laravel日志优化的案例
    小编给大家分享一下laravel日志优化的案例,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!日志浏览扩展地址:arcanedev/log-viewer安装扩展composer require arcan...
    99+
    2023-06-14
  • Centos 6.5 ----日志系统Rsyslog
                     &...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作