MySQL架构,以及redo log、undo log和binlog的区别

编程入门 行业动态 更新时间:2024-10-24 01:49:13

MySQL<a href=https://www.elefans.com/category/jswz/34/1771112.html style=架构,以及redo log、undo log和binlog的区别"/>

MySQL架构,以及redo log、undo log和binlog的区别

一、Mysql的基本架构图

二、连接器

连接器负责跟客户端建立连接,获取权限、维持和管理连接:

  • 用户名密码验证;
  • 查询权限信息,分配对应的权限;
  • 可以使用show processlist查看现在的连接;
  • 如果太长时间没有动静,就会自动断开,通过wait_timeout控制,默认8小时;

连接可以分为两类:

  • 长连接:推荐使用,但是要周期性的断开长连接;
  • 短链接:

三、查询缓存

当执行查询语句的时候,会先去查询缓存中查看结果,之前执行过的sql语句及其结果可能以key-value的形式存储在缓存中,如果能找到则直接返回,如果找不到,就继续执行后续的阶段。

但是,不推荐使用查询缓存

  1. 查询缓存的失效比较频繁,只要表更新,缓存就会清空;
  2. 缓存对应新更新的数据命中率比较低

四、分析器

词法分析: Mysql需要把输入的字符串进行识别每个部分代表什么意思?

  • 把字符串 T 识别成 表名 T;
  • 把字符串 ID 识别成 列ID;

语法分析:
  根据语法规则判断这个sql语句是否满足mysql的语法,如果不符
合就会报错"You have an error in your SQL synta"

五、优化器

在具体执行SQL语句之前,要先经过优化器的处理:

  • 当表中有多个索引的时候,决定用哪个索引;
  • 当sql语句需要做多表关联的时候,决定表的连接顺序;
  • 等等;

不同的执行方式对SQL语句的执行效率影响很大:

  • RBO:基于规则的优化;
  • CBO:基于成本的优;

六、日志(redo、undo、binlog)


在图中涉及三个日志: undo log(回滚日志)、redo log(重做日志) 、binlog (归档日志)

  • undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和MVCC。
  • redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复;
  • binlog (归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制;

6.1 redo、undo、binlog的区别

如上。

6.2 ACID以及实现方式

ACID:

  • A-原子性;原子性通过undo log实现;
  • C-一致性;通过原子性、隔离性、持久性实现的;
  • I-隔离性;隔离级别,通过锁实现;
  • D-持久性;通过redo log实现;

七、Buffer Pool(缓冲池)

  InnoDB存储引擎在处理客户端的请求时,如果需要访问某个页的数据,就会把完整的页中的数据全部加载到内存中,即使只访问页中的一条记录,也需要先把整个页的数据加载到内存中。将整个页加载到内存后就可以进行读写访问了,而且在读写访问之后并不着急把该页对应的内存空间释放掉,而是将其缓存起来,这样将来有请求再次访问该页面时,就可以剩下磁盘IO的开销了。

  为了缓存磁盘中的页,Innodb在MySQL服务器启动时就像操作系统申请了一片连续的内存,即Buffer Pool(缓冲池)。默认情况下,Buffer Pool的大小为128M。

  Buffer Pool对应的一片连续的内存被划分为若干个页面,页面大小与Innodb表空间用的页面大小一致,默认都是16kb,为了与磁盘中的页面区分开来,我们把这些Buffer Pool中的页面称为缓冲页。

  当我们修改了Buffer Pool中某个缓冲页的数据,它就与磁盘上的页不一致了,这样的缓冲页称为脏页。当然,我们可以每当修改完某个数据页时,就立即将其刷新到磁盘中对应的页上,但是频繁的往磁盘中写数据会严重的影响程序的性能,所以每次修改缓冲页后,我们并不着急立即将修改刷新到磁盘上,而是在某个时间点进行刷新。

  后台有专门的线程负责每隔一段时间就把脏页刷新到磁盘,这样就可以不影响用户线程处理正常的请求。

  总结:InnoDB存储引擎是以页为单位来管理存储空间的,在真正访问页面之前,需要先把磁盘中的页加载到内存中的Buffer Pool中,之后才可以访问,所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页以一定的频率刷新到磁盘(checkpoint机制),通过缓冲池来优化CPU和磁盘之间的鸿沟,这样就能保证整体的性能不会下降的太快。

八、redo log(重做日志,也叫事务日志)

8.1 什么是 WAL

  WAL(Write Ahead Log)预写日志,指的是 MySQL 的写操作并不是立刻更新到磁盘上,而是先记录在日志上,然后在合适的时间再更新到磁盘上。也是数据库系统中常见的一种手段,用于保证数据操作的原子性和持久性。

8.2 redo日志-innodb存储引擎的日志文件


  redo log(重做日志)是InnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。比如 MySQL 实例挂了或宕机了,重启时,InnoDB存储引擎会使用redo log恢复数据,保证数据的持久性与完整性。

什么是redo log?

   redo log就是重做日志的意思。它是记录事务产生的物理日志,即记录对那个数据页做了什么修改,对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新,每当执行一个事务就会产生这样的一条物理日志。


  MySQL 中数据是以页为单位,你查询一条记录,会从硬盘把一页的数据加载出来,加载出来的数据叫数据页,会放入到 Buffer Pool 中。后续的查询都是先从 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。

  更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool里更新。然后会把“在某个数据页上做了什么修改”记录到重做**日志缓存(redo log buffer)**里,接着刷盘到 redo log 文件里。

  理想情况,事务一提交就会进行刷盘操作,但实际上,刷盘的时机是根据策略来进行的。

小贴士:每条 redo 记录由“表空间号+数据页号+偏移量+修改数据长度+具体修改的数据”组成。

8.3 刷盘时机

首先redo log刷盘的机制:

  1. MySQL 正常关闭时;
  2. 当 redo log buffer 中记录的写入量大于 redo log buffer 内存空间的一半时,会触发落盘
  3. InnoDB 的后台线程每隔 1 秒,将 redo log buffer 持久化到磁盘;
  4. 每次事务提交时都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘(这个策略可由 innodb_flush_log_at_trx_commit 参数控制;

  从redo log刷磁的机制的第4点,我们知道,可以通过innodb_flush_log_at_trx_commit 参数来控制刷盘。首先我们了解一下默认的redo log 刷盘:

在执行更新语句的过程中,生成的 redo log 先写入到 redo log buffer 中,然后等事务提交的时候,再将缓存在 redo log buffer 中的 redo log 按组的方式「顺序写」到磁盘,这就是默认的redo log 刷盘。

8.3.1 redo log 的不同刷盘策略演示

  但是,我们应该了解更多的 innodb_flush_log_at_trx_commit 参数,是怎么样控制刷盘的。即innodb_flush_log_at_trx_commit有三个值:0、1、2,默认值为 1。这三个值的代表的策略如下:

  • innodb_flush_log_at_trx_commit = 0:延迟写,延迟刷。即每次事务提交时 ,还是将 redo log 留在 redo log buffer 中 ,该模式下在事务提交时不会主动触发写入磁盘的操作;
  • innodb_flush_log_at_trx_commit = 1:实时写,实时刷。即每次事务提交时,都将缓存在 redo log buffer 里的 redo log 直接持久化到磁盘,这样可以保证 MySQL 异常重启之后数据不会丢失。也是默认的模式;
  • innodb_flush_log_at_trx_commit = 2:实时写,延迟刷。即每次事务提交时,都只是缓存在 redo log buffer 里的 redo log 写到 redo log 文件,注意写入到「 redo log 文件」并不意味着写入到了磁盘,因为操作系统的文件系统中有个 Page Cache(操作系统的os cache)

可以通过下图更加详细的显示出来:

  所以,当innodb_flush_log_at_trx_commit 参数值不为1的时候,它应该通过redo log刷盘的机制的第3点来操作的,即InnoDB 的后台线程每隔 1 秒:

  1. innodb_flush_log_at_trx_commit = 0时,会把缓存在 redo log buffer 中的 redo log ,通过调用 write() 写到操作系统的 Page Cache,然后调用 fsync() 持久化到磁盘。所以该策略,MySQL 进程的崩溃会导致上一秒钟所有事务数据的丢失;
  2. innodb_flush_log_at_trx_commit = 2 时, 调用 fsync,将缓存在操作系统中 Page Cache 里的 redo log 持久化到磁盘。所以该策略,较innodb_flush_log_at_trx_commit = 0情况下更安全,因为 MySQL 进程的崩溃并不会丢失数据,只有在操作系统崩溃或者系统断电的情况下,上一秒钟所有事务数据才可能丢失;

  所以,innodb_flush_log_at_trx_commit参数不同值的安全性和写入性能,就不言而喻了:
数据安全性:1 > 2 > 0;
写入性能: 0 > 2> 1;

  所以说,鱼和熊掌不可兼得。即要不追求数据安全性,牺牲性能;要不追求性能,牺牲数据安全性。

8.4 比喻

有一个比喻相当好:

  • 酒店;
  • 账本(流水、欠账都记在这里);
  • 小黑板(记今天新增人的账本,晚上12点更新到账本里,然后把小黑板擦掉,重新写,这样效率最高);

redolog就是小黑板的作用;

问题:每秒异写到磁盘, 在这1s中间,能查询到还没有写到磁盘的内容吗?
——当然可以,数据是数据,日志是日志,这里讨论的都是日志,跟数据库能否查到的没有关系。
还是拿酒店做比方,卡里金额就是数据,跟你的账本里记得没关系。

8.5 疑惑-redo性能高原因

  • 顺序写;
  • 零拷贝(innodb_flush_log_at_trx_commit为2时);

kafka为什么效率高:

  1. 顺序写;
  2. 零拷贝,缺少了用户态和内核态数据的切换,增加整个读写的效率;

8.6 redo 日志文件组

  我们都知道一个文件总是有大小的,而 redo log文件的大小是由innodb_log_file_size参数控制的,默认是48M。那么问题就来了:

redo log 文件写满了怎么办?
  首先,默认情况下,InnoDB 存储引擎有 1 个重做日志文件组( redo log Group),【重做日志文件组】由有 2 个 redo log 文件组成,这两个 redo 日志的文件名:

  • ib_logfile0 和 ib_logfile1

      而且,在重做日志文件组中,每个文件大小固定而且一致的。它是以循环写的方式工作的,从头开始写,写到末尾就又回到开头,相当于一个环形。即先写 ib_logfile0 文件,写满了,就会切换到 ib_logfile1 文件,再写满了,就会再切换到ib_logfile0 文件从头开始写。如下:

      因为redo log 是为了防止Buffer Pool 中的脏页丢失而设计的,所以当Buffer Pool 的脏页刷新到了磁盘中,redo log 对应的记录也就没用了。所以重做日志文件组设计为循环写的原因。那么是怎么个循环写法呢?即重做日志文件组 相当于一个环形,在InnoDB 用 write pos 表示 redo log 当前记录写到的位置,用 checkpoint 表示当前要擦除的位置,如图:

    图解析说明:
  1. write pos 和 checkpoint 的移动都是顺时针方向;
  2. write pos ~ checkpoint 之间的部分(图中的红色部分),用来记录新的更新操作;
  3. check point ~ write pos 之间的部分(图中蓝色部分):待落盘的脏数据页记录;

  因为是一个环形,所以当 write pos 追上了 checkpoint,就意味着 redo log 文件满了,这时 MySQL 不能再执行新的更新操作,也就是说 MySQL 会被阻塞(因此所以针对并发量大的系统,适当设置 redo log 的文件大小非常重要),此时会停下来将 Buffer Pool 中的脏页刷新到磁盘中,然后标记 redo log 哪些记录可以被擦除,接着对旧的 redo log 记录进行擦除,等擦除完旧记录腾出了空间,checkpoint 就会往后移动(图中顺时针),然后 MySQL 恢复正常运行,继续执行新的更新操作。

  所以,一次 checkpoint 的过程就是脏页刷新到磁盘中变成干净页,然后标记 redo log 哪些记录可以被覆盖的过程。

8.4 redo log两阶段提交

8.4.1 redo log两阶段提交

执行流程:

  1. 执行器先从引擎中找到数据,如果在内存中直接返回,如果不在内存中,查询后返回;
  2. 执行器拿到数据之后会先修改数据,然后调用引擎接口重新吸入数据;
  3. 引擎将数据更新到内存,同时写数据到redo中,此时处于prepare阶段,并通知执行器执行完成,随时可以操作;
  4. 执行器生成这个操作的binlog;
  5. 执行器调用引擎的事务提交接口,引擎把刚刚写完的redo改成commit状态,更新完成;

8.4.2 如果不是两阶段提交会有什么问题

  • 先写redo log后写binlog:假设在redo log写完, binlog还没有写完的时候, MySQL进程异常重启。由于我们前面说过的, redo log写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行c的值是1。但是由于binlog没写完就crash了,这时候binlog里面就没有记录这个语句。因此,之后备份日志的时候,存起来的binlog里面就没有这条语句。然后你会发现,如果需要用这个binlog来恢复临时库的话,由于这个语句的binlog丢失,这个临时库就会少了这一次更新,恢复出来的这一行c的值就是0,与原库的值不同。
  • 先写binlog后写redo log:如果在binlog写完之后crash,由于redo log还没写,崩溃恢复以后这个事务无效,所以这一行c的值是0。但是binlog里面已经记录了“把c从0改成1”这个日志。所以,在之后用binlog来恢复的时候就多了一个事务出来,恢复出来的这一行c的值就是1,与原库的值不同。

无论先写哪个都会有问题,所以用两阶段提交。
可以这么理解,原先是写完redo或binlog中的其中一个就写磁盘了,两阶段提交是为了两个都写完了再写磁盘。

8.5 redo log总结

相信大家如上的解释和介绍都知道 redo log 的作用和它的刷盘时机、存储形式。

现在我们来思考一个问题:只要每次把修改后的数据页直接刷盘不就好了,还有 redo log 什么事?它们不都是刷盘么?差别在哪里?

  实际上,数据页大小是16KB,刷盘比较耗时,可能就修改了数据页里的几 Byte 数据,有必要把完整的数据页刷盘吗?而且数据页刷盘是随机写,因为一个数据页对应的位置可能在硬盘文件的随机位置,所以性能是很差。

  如果是写 redo log,一行记录可能就占几十 Byte,只包含表空间号、数据页号、磁盘文件偏移 量、更新值,再加上是顺序写,所以刷盘速度很快。
  所以用 redo log 形式记录修改内容,性能会远远超过刷数据页的方式,这也让数据库的并发能力更强。

其实内存的数据页在一定时机也会刷盘,我们把这称为页合并,讲 Buffer Pool的时候会对这块细说。

九、undo log(回滚日志)

  我们都知道在MYSQL的InnoDB引擎中,如果要执行一条“增删改”语句,即使我们没有输入 begin 开启事务和 commit 提交事务,其实这些语句也是按照事物来提交的,这就是MySQL 会隐式开启事务。而隐式开启事务的控制室通过autocommit 参数决定的,默认是开启。同时,我们也知道事务是可以回滚的。

那么问题来了,它是怎么回滚的呢?
答案:在每次执行事务过程中,会通过一个日志把所有回滚需要的信息记录下来,那么即使执行过程中MYSQL 崩溃了,也不用担心无法回滚到事务之前的数据,我们可以通过这个日志回滚到事务之前的数据。这就是undo log(回滚日志),它保证了事务ACID特征中的原子性(Atomicity)。

  undo log就是一种用于撤销回退的日志,里面的记录就是逻辑日志,比如执行delete时,undo log记录的是insert日志,反正亦然;当执行update时,undo log记录的是与update相反的记录。使用undo log实现事务回滚的过程如下:

从上图可以看出回滚事务是通过undo log来实现的,那么undo log都记录那些数据信息呢?

  1. 当插入一条记录时,undo log会把这条记录的主键值记录下来,当需要回滚的时候,会读取这条记录的主键值,然后执行删;
  2. 当删除一条记录时,undo log会把这条记录的全部内容都记录下来,当需要回滚的时候,会读取这条记录的全部内容并组成语句插入表中;
  3. 当更新一条记录时,undo log会把这条记录中更新列的旧值记录下来,当需要回滚的时候,会读取这条记录更新列的旧值,然后把旧值更新回去。

到这里可以知道,不同的操作,在undo log中记录的内容也是不一样的,所以操作不同,undo log中记录的格式也不同。有那些具体的不同可以查看InnoDB之UNDO LOG文章。

但是一条记录的每一次更新操作产生的 undo log 格式都有一个 roll_pointer 指针和一个 trx_id 事务id:

  • 通过 trx_id 可以知道该记录是被哪个事务修改的;
  • 通过 roll_pointer 指针可以将这些 undo log 串成一个链表,这个链表就被称为版本链;

 &emsp另外,undo log 还有一个作用,通过 ReadView + undo log 实现 MVCC(多版本并发控制)。有关这个作用可以阅读MYSQL 事务、事务隔离级别和MVCC,幻读文章;

十、binlog(归档日志)

 &emsp前面介绍了undo log 和 redo log 这两个日志都是 Innodb 存储引擎生成的。

 &emsp但是,我们也知道,MYSQL每次更新操作之后,在Server 层还会生成一条 binlog,等之后事务提交的时候,会将该事物执行过程中产生的所有 binlog 统一写 入 binlog 文件。所以,binlog 文件是记录了所有数据库表结构变更和表数据修改的日志,不会记录查询类的操作,比如 SELECT 和 SHOW 操作。

为什么有了 binlog, 还要有 redo log?
答:这个问题跟 MySQL 的时间线有关系。最开始 MySQL 里并没有 InnoDB 引擎,MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe(崩溃安全) 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用 redo log 来实现 crash-safe 能力。

Binlog是server层的日志,主要做mysql功能层面的事情
与redo日志的区别:

  1. redo是innodb独有的, binlog是所有引擎都可以使用的;
  2. redo是物理日志,记录的是在某个数据页上做了什么修改, binlog是逻辑日志,记录的是这个语句的原始逻辑(比如对 XXX 表空间中的 YYY 数据页 ZZZ 偏移量的地方做了AAA 更新);
  3. 写入方式不同: redo是循环写的,空间会用完, binlog是可以追加写的,不会覆盖之前的日志信息;
  4. 用途不同:binlog 用于备份恢复、主从复制,redo log 用于掉电等故障恢复;

binlog 有 3 种格式类型,分别是 STATEMENT(默认格式)、ROW、 MIXED,区别如下:

  • STATEMENT:每一条修改数据的 SQL 都会被记录到 binlog 中(相当于记录了逻辑操作,所以针对这种格式, binlog 可以称为逻辑日志),主从复制中 slave 端再根据 SQL 语句重现。但 STATEMENT 有动态函数的问题,比如你用了 uuid 或者 now 这些函数,你在主库上执行的结果并不是你在从库执行的结果,这种随时在变的函数会导致复制的数据不一致;
  • ROW:记录行数据最终被修改成什么样了(这种格式的日志,就不能称为逻辑日志了),不会出现 STATEMENT 下动态函数的问题。但 ROW 的缺点是每行数据的变化结果都会被记录,比如执行批量 update 语句,更新多少行数据就会产生多少条记录,使 binlog 文件过大,而在 STATEMENT 格式下只会记录一个 update 语句而已;
  • MIXED:包含了 STATEMENT 和 ROW 模式,它会根据不同的情况自动使用 ROW 模式和 STATEMENT 模式;

问题1: binlog是直接写入磁盘的吗?
当然不是的。在事务执行过程中,先把日志写到 binlog cache(Server 层的 cache),事务提交的时候,再把 binlog cache 写到 binlog 文件中。
MySQL 给 binlog cache 分配了一片内存,每个线程一个,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。如果超过了这个参数规定的大小,就要暂存到磁盘。

什么时候 binlog cache 会写到 binlog 文件?
在事务提交的时候,执行器把 binlog cache 里的完整事务写入到 binlog 文件中,并清空 binlog cache。如下图:

虽然每个线程有自己 binlog cache,但是最终都写到同一个 binlog 文件:

  • 图中的 write,指的就是指把日志写入到 binlog 文件,但是并没有把数据持久化到磁盘,因为数据还缓存在文件系统的 page cache 里,write 的写入速度还是比较快的,因为不涉及磁盘 I/O。
  • 图中的 fsync,才是将数据持久化到磁盘的操作,这里就会涉及磁盘 I/O,所以频繁的 fsync 会导致磁盘的 I/O 升高。

10.1 binlog的 刷盘 策略是通过sync_binlog 参数控制:

  1. sync_binlog = 0 的时候,表示每次提交事务都只 write,不 fsync,后续交由操作系统决定何时将数据持久化到磁盘。默认值;
  2. sync_binlog = 1 的时候,表示每次提交事务都会 write,然后马上执行 fsync;
  3. sync_binlog =N(N>1) 的时候,表示每次提交事务都 write,但累积 N 个事务后才 fsync

所以,sync_binlog 参数不同值的安全性和写入性能,就不言而喻了:

  • 数据安全性:1 > N > 0;
  • 写入性能: 0 > N > 1;

问题3: 如果不小心整个数据库的数据被删除了,能使用 redo log 文件恢复数据吗?
答:不可以使用 redo log 文件恢复,只能使用 binlog 文件恢复。因为 redo log 文件是循环写,是会边写边擦除日志的,只记录未被刷入磁盘的数据的物理日志,已经刷入磁盘的数据都会从 redo log 文件里擦除。而binlog 文件保存的是全量的日志,也就是保存了所有数据变更的情况,理论上只要记录在 binlog 上的数据,都可以恢复,所以如果不小心整个数据库的数据被删除了,得用 binlog 文件恢复数据。
上面也提到binlog的用途之一是主从复制,如果想了解更多主从复制相关的知识,可以看MYSQL主从复制文章

十一、疑问

11.1 问题1

有人也会问redo log文件也是在磁盘里面,数据文件也是在磁盘里面,这不是多余了吗?

答:当然不多余了。因为redo log是磁盘顺序写(即追加操作),数据刷盘是磁盘随机写(先找到位置,再写入),磁盘的顺序写比随机写高效的多。这也说明了WAL技术的另外一个优点:MySQL 的写操作从磁盘的「随机写」变成了「顺序写」。所以,为什么需要 redo log 的原因,总结起来如下:

  1. 实现事务的持久性,让 MySQL 有 crash-safe(崩溃恢复) 的能力,能够保证 MySQL 在任何时间段突然崩溃,重启后之前已提交的记录都不会丢失

  2. 将写操作从「随机写」变成了「顺序写」,提升 MySQL 写入磁盘的性能

11.2 问题2

被修改 Undo 页面,需要记录对应 redo log 吗?

答:当然需要。它是这样记录的:开启事务后,InnoDB 层更新记录前,首先要记录相应的 undo log,如果是更新操作,需要把被更新的列的旧值记下来,也就是要生成一条 undo log,undo log 会写入 Buffer Pool 中的 Undo 页面。不过,在修改该 Undo 页面前需要先记录对应的 redo log,所以先记录修改 Undo 页面的 redo log ,然后再真正的修改 Undo 页面。

11.3 问题3

redo log 和 undo log 区别?

这两种日志是属于 InnoDB 存储引擎的日志,区别如下:

  1. redo log 记录了此次事务「完成后」的数据状态,记录的是更新之「后」的值;
  2. undo log 记录了此次事务「开始前」的数据状态,记录的是更新之「前」的值;
  3. redo log 是保证事务四大特性中的持久性,undo log是保证事务四大特性中的原子性;

所以,事务提交之前发生了崩溃,重启后会通过 undo log 回滚事务,事务提交之后发生了崩溃,重启后会通过 redo log 恢复事务,如下图:

更多推荐

MySQL架构,以及redo log、undo log和binlog的区别

本文发布于:2024-03-11 16:58:35,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1729442.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:架构   区别   redo   MySQL   binlog

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!