news 2026/6/21 0:36:55

【MySQL高阶】24.重做日志(2)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【MySQL高阶】24.重做日志(2)

文章目录

  • 6. InnoDB 磁盘文件
    • 6.9 重做日志 - Redo Log
      • 6.9.8 Redo Log对应磁盘上的文件是什么?
        • 6.9.8.1 这么多日志文件日志写到哪个文件中?
        • 6.9.8.2 什么是LSN?
      • 6.9.9 Redo Log日志文件的格式?
        • 6.9.9.1 Log Buffer中的Redo Log Block与磁盘中的Redo Log Block有哪些不同?
      • 6.9.9.2 重做日志文件管理区包含哪些信息?
        • 6.9.9.3 管理区中具体管理了什么信息?
      • 6.9.10 什么是CHECKPOINT - 检查点?
        • 6.9.10.1 哪些RedoLog可以被覆盖?
        • 6.9.10.2 如何记录可以覆盖的日志文件位置?
        • 6.9.10.3 如果没有小于 checkpoint_lsn 的日志时如何处理?
      • 6.9.11 重做日志还有哪些主要的配置项?
      • 6.9.12 如何查看重做日志的状态?
      • 6.9.13 如何根据RedoLog进行崩溃恢复?
        • 6.9.13.1 如何确定哪些日志需要恢复?
        • 6.9.13.2 如何获取最新的 checkpoint_lsn 和恢复的起点?
        • 6.9.13.3 如何确认恢复的终点?
        • 6.9.13.4 如何进行恢复?
        • 6.9.13.5 如何确定哪些日志在崩溃前已经落盘?

6. InnoDB 磁盘文件

6.9 重做日志 - Redo Log

6.9.8 Redo Log对应磁盘上的文件是什么?

  • 重做日志文件位于数据目录下的#innodb_redo目录中
  • 重做日志文件分为普通类型和备用类型,普通类型是正在使用的日志文件,备用是准备使用的日志文件,InnoDB共维护32个重做日志文件,每个文件的大小等于1/32 * innodb_redo_log_capacity
  • 重做日志文件使用#ib_redoN命名约定,其中N是重做日志文件编号,备用的重做日志文件使用_tmp为后缀。如下示例显示有21个活动(普通)重做日志文件和11个备用重做日志文件:
root@yudukai:/var/lib/mysql/#innodb_redo# ll total 102408 drwxr-x--- 2 mysql mysql 4096 May 29 09:08 ./ drwx------ 10 mysql mysql 4096 May 29 14:23 ../ -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo10_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo11_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo12_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo13_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo14_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo15_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo16_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo17_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo18_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo19_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo20_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo21_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo22_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo23_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo24_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo25_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo26_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo27_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo28_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo29_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo30_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo31_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo32_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo33_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo34_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo35_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo36_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo37_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo38_tmp' -rw-r----- 1 mysql mysql 3276800 May 12 10:28 '#ib_redo39_tmp' -rw-r----- 1 mysql mysql 3276800 May 29 09:08 '#ib_redo8' -rw-r----- 1 mysql mysql 3276800 May 29 09:10 '#ib_redo9' root@yudukai:/var/lib/mysql/#innodb_redo#

每个普通的重做日志文件都与一个特定的LSN取值范围相关联,用于崩溃恢时快速定位到要执行重做的日志,可以使用下面的查询显示活动重做日志文件的START_LSNEND_LSN值;

mysql> SELECT FILE_NAME, START_LSN, END_LSN FROM performance_schema.innodb_redo_log_files; +--------------------------+-----------+----------+ | FILE_NAME | START_LSN | END_LSN | +--------------------------+-----------+----------+ | ./#innodb_redo/#ib_redo8 | 26206208 | 29480960 | | ./#innodb_redo/#ib_redo9 | 29480960 | 32755712 | +--------------------------+-----------+----------+ 2 rows in set (0.00 sec) mysql>

总结:

  • 重做日志文件位于数据目录下的#innodb_redo目录中,在MySQL8.0InnoDB共维护32个重做日志文件,每个文件的大小等于1/32 * innodb_redo_log_capacity
  • 重做日志文件分为普通类型和备用类型,并且使用#ib_redoN命名约定,其中N是重做日志文件编号,备用的重做日志文件使用_tmp为后缀
  • 重做日志的总容量可以通过系统变量innodb_redo_log_capacity设置,8.0.308.0.33版本之间是128GB8.0.34版本开始最大为512GB

6.9.8.1 这么多日志文件日志写到哪个文件中?

通过查看#innodb_redo目录,可以看到系统生成了32RedoLog文件,当RedoLog从内存刷到磁盘时,先从第一个日志文件开始写,第一个写满之后顺序写到第二个,以此类推;如果最后一个也写满了,就会重新从第一个文件开始写,也就是说重做日志文件可以循环使用,如图所示:

这里可能会出现一个问题,如果循环写入的话,那么后写入的日志会不会把之前写入的内容覆盖了?当然有这个可能,为了解决这个问题,InnoDB提出checkpoint的概念,关于checkpoint后面会详细介绍。

简单来说就是:如果之前对应的数据页都已落盘,那么就会在落盘的最后一个位置设下检查点,检查点之前的那些可以覆盖。


6.9.8.2 什么是LSN?
  • LSNLog Sequence Number的简写,称为日志序号;
  • MySQL在运行期间,只要执行DML操作就会修改数据页,意味着会不断的生成RedoLogInnoDB为了记录生成的日志总量(字节数),设计了一个只增不减的全局变量,这个全局变量就是LSN,起始值:16*512 = 8192 ,最大值 2^64 - 1 ;
  • 当一个MTR所包含的一组RedoLog被记录在Redo Log Block中时,实际是保存在Log Block Body区域,但是在统计LSN增量时,如果MTRBlock保存时,是按照实际写入的日志大小加上Log Block Header所占的12Byte和块尾Log Block Trailer所占4Byte
  • 示例:见下图
    1. 系统启动后初始化Log Buffer,buf_free指向第一个block偏移量为12Byte的位置,也就是block Header之后,此时LSN也会增加12,即8192 + 12 = 8204
    2. 假设MTR_1中包含的一组RedoLog大小为200Byte,那么LSN就会在原来的基础上加200,即:8204 + 200 = 8404
    3. 假设MTR_2中包含的一组RedoLog大小为1000Byte,这里当前的Block_1已经放不下这个MTR,于是日志顺序保存在后面的Block中,占满第二个Block后,直到使用了第三个Block的一部分空间,日志保存完成;这时LSN不但要记录MTR_2中日志的总大1000Byte,还要记录Block_1+Block_2Log Block TrailerBlock_2+Block_3Log Block Header,总大小为:1000 + 12 * 2 + 4 * 2 = 1032,此时LSN的值为:8404 + 1032 = 9436,如下图所示:


6.9.9 Redo Log日志文件的格式?

6.9.9.1 Log Buffer中的Redo Log Block与磁盘中的Redo Log Block有哪些不同?
  • 在内存中Log Buffer是一片连续的内存空间,被划分成了若干个512字节大小的Redo Log Block用来保存Redo Log,将Log Buffer中的Redo Log刷新到磁盘,本质就是把Redo Log Block的写入日志文件中,所以Redo Log对应的日志文件其实也是由若干个512字节大小的block组成。MySQL会根据配置生成一组撤销日志文件,每个文件的格式和大小都一样,由两部分组成:
    • 管理区:前2048个字节,也就是前4block存储一些日志文件的管理信息
    • 数据区:从第2048字节往后是用来存储Log Buffer对应的Redo Log Block
  • 也就是说真实的日志是从每个日志文件的第2048个字节开始写入,如图所示

  • 所以Log Buffer中的Redo Log Block与磁盘中的Redo Log Block在结构上是相同的,只不过在磁盘上多了用于文件管理的文件头信息

总结:

磁盘中RedoLog的格式与内存中的格式相同,在内存中Log Buffer是一片连续的内存空间,被划分成了若干个512字节大小的Redo Log Block用来保存Redo Log,将Log Buffer中的Redo Log刷新到磁盘,本质就是把Redo Log Block的写入日志文件中,所以Redo Log对应的日志文件其实也是由若干个512字节大小的block组成,只不过在磁盘上多了用于文件管理的文件头信息。


6.9.9.2 重做日志文件管理区包含哪些信息?

  • 关于Redo Log Block:的结构与内存结构相同,前2048字节 分为4Block分别为:
    • LOG_CHECKPOINT_1:第一个日志文件中日志头的第一个检查点信息
    • LOG_ENCRYPTION:日志文件头信息中的加密信息
    • LOG_CHECKPOINT_2:第一个日志文件中日志头的第二个检查点信息
    • LOG_FILE_HDR_SIZE:日志文件头信息


6.9.9.3 管理区中具体管理了什么信息?
  • 管理区各字段中的信息随着MySQL版本迭代变化非常大,这里主要介绍一些关键信息
  • LOG_CHECKPOINT_1LOG_CHECKPOINT_2:主要是记录CHECKPOINT操作时对应的LSNLSN会交替写入到LOG_CHECKPOINT_1LOG_CHECKPOINT_2中,具体写入规则后面介绍。LOG_ENCRYPTIONLOG_FILE_HDR_SIZE中的加密信息,不做过多讨论
  • LOG_FILE_HDR_SIZE:主要记录日志文件的一些信息,主要包括:
    • LOG_HEADER_FORMAT:占4字节,日志的格式标识,和MySQL版本相关,有重大更新的版本才设置相应的值,在MySQL5.7.9之前一直都是0
    • LOG_HEADER_START_LSN:占8字节,日志文件中第一个和最后一个LSN编号
    • LOG_HEADER_CREATOR:占32字节,记录日志的创建者,正常生成的日志一般为"MEB"+MySQL的版本号,如果是运行mysqlbackup程序,在备份过程中生成的日志,则记录MySQL的版本号

6.9.10 什么是CHECKPOINT - 检查点?

RedoLog从内存刷到磁盘上的日志文件使用循环写入的方式,也就是从第一个日志文件顺序写到最后一个日志文件,当最后一个日志文件写满时又重新写第一个日志文件,那么就可能出现日志被覆盖的情况,那么哪些日志可以被覆盖哪些不能被覆盖呢?


6.9.10.1 哪些RedoLog可以被覆盖?

首先回顾一下RedoLog的作用,RedoLog是用作崩溃后恢复没有完成落盘的事务,也就是说当Buffer Pool中的脏页写入RedoLog,但数据页还没有落盘时发生的崩溃,当服务器重启之后可以根据RedoLog进行恢复,这也是RedoLog的应用时机,所以这种状态下的RedoLog不能被覆盖,如下图所示:

如果缓冲池中的脏页在记录RedoLog之后,也完成了真正的落盘操作,那么相应的RedoLog就没有用了,所以这部分RedoLog就可以被覆盖,如下图所示:

经过分析可以看出,判断日志文件中的RedoLog是否可以覆盖的依据是它对应的数据页是否已经刷新到磁盘。


6.9.10.2 如何记录可以覆盖的日志文件位置?

前面介绍过InnoDB使用LSN是来记录RedoLog总字节数,在这个基础上InnoDB采用一个全局变量checkpoint_lsn来记录当前系统中可以被覆盖日志总量是多少,也就是说checkpoint_lsn记录已落盘脏页对应的日志结束时LSN的值,此时LSN小于checkpoint_lsnRedoLog就可以被覆盖,如图所示:

  • 当脏页刷新到磁盘之后,重新计算checkpoint_lsn的操作,称为一次CHECKPOINT操作,也可以说是重置一次检查点,系统会用一个checkpoint_no变量记录发生CHECKPOINT操作的次数,每做一CHECKPOINT操作checkpoint_no就会加1
  • 由于RedoLog文件的大小是固定的,在系统启动时已经分配好了对应的Redo Log Block,所以很容易就可以根据checkpoint_lsn计算写入位置在日志文件中的偏移量
  • 关于检查点相关的checkpoint_nocheckpoint_lsn以及写入偏移量的信息会被记录在第一个日志文件的管理区,同时InnoDB规定,当checkpoint_no的值是偶数时写到checkpoint1中,是奇数时写到checkpoint2中。

总结:

CHECKPOINT也称为检查点,由于RedoLog文件是可以循环使用的,当最后一个文件写满时又会从第一个文件开始写入,这必将导致老的日志被覆盖,CHECKPOINT是标记已被刷新到磁盘的脏页刷对应的RedoLog可以被覆盖的一种操作,当日志的LSN小于已落盘脏页对应的LSN都可以被覆盖。


6.9.10.3 如果没有小于 checkpoint_lsn 的日志时如何处理?

如果日志文件中没有小于checkpoint_lsn的日志时,表明日志文件已经使用完了,这时原来的日志不能被覆盖,InnoDB会先优先刷新脏页到磁盘,再做CHECKPOINT操作,之后再继续进行日志记录。


6.9.11 重做日志还有哪些主要的配置项?

重做日志在磁盘上所占的空间可以通过系统变量innodb_redo_log_capacity控制,变量值以字节为单位,最大值549755813888,表示512GB,可以在选项文件或在运行时使用SET GLOBAL语句进行设置,如下所示:

# 将RedoLog的最大容量设置为8GB SET GLOBAL innodb_redo_log_capacity = 8589934592;

重做日志的目录可以通过系统变量innodb_log_group_home_dir进行设置,如果没有指定则日志文件位于数据目录的#innodb_redo目录中,如果定义了innodb_log_group_home_dir变量,则日志文件存放在该目录下的#innodb_redo目录中;

# 默认数据目录 root@yudukai:/var/lib/mysql# ll total 93888 # ... 省略 drwxr-x--- 2 mysql mysql 4096 May 29 09:08 '#innodb_redo'/ # ... 省略

根据实际应用场景通过配置对应的系统变量来指定Redo Log在磁盘上所占的空间的大小、所在目录等属性。


6.9.12 如何查看重做日志的状态?

通过状态变量innodb_redo_log_capacity_resized显示当前重做日志容量限制:

mysql> SHOW STATUS LIKE 'Innodb_redo_log_capacity_resized'; +----------------------------------+-----------+ | Variable_name | Value | +----------------------------------+-----------+ | Innodb_redo_log_capacity_resized | 104857600 | # 100MB +----------------------------------+-----------+ 1 row in set (0.00 sec) mysql>

可以通过查询performance_schema.innodb_redo_log_files表来查看活动重做日志文件的信息

mysql> SELECT * FROM performance_schema.innodb_redo_log_files\G *************************** 1. row *************************** FILE_ID: 8 FILE_NAME: ./#innodb_redo/#ib_redo8 START_LSN: 26206208 END_LSN: 29480960 SIZE_IN_BYTES: 3276800 IS_FULL: 1 CONSUMER_LEVEL: 0 *************************** 2. row *************************** FILE_ID: 9 FILE_NAME: ./#innodb_redo/#ib_redo9 START_LSN: 29480960 END_LSN: 32755712 SIZE_IN_BYTES: 3276800 IS_FULL: 0 CONSUMER_LEVEL: 0 2 rows in set (0.00 sec) mysql>

通过使用SHOW ENGINE InnoDB STATUS访问InnoDB标准监视器输出中LOG部分查看有关Redo Log的信息

mysql> SHOW ENGINE INNODB STATUS\G *************************** 1. row *************************** Type: InnoDB Name: Status: ===================================== ... # 省略 --- LOG --- Log sequence number 21737291 # 当前的LSN Log buffer assigned up to 21737291 # Log buffer中已分配的LSN Log buffer completed up to 21737291 # Log buffer中已使用完成的LSN Log written up to 21737291 # 已写入操作缓存的LSN Log flushed up to 21737291 # 已刷新到日志文件的LSN Added dirty pages up to 21737291 # 已添加的脏页对应的LSN Pages flushed up to 21737291 # 最新添加到刷新链表页对应的LSN Last checkpoint at 21737291 # 最后一次做checkpoint的LSN Log minimum file id is 6 # 日志文件最小的编号 Log maximum file id is 6 # 普通日志文件的最大编号 24 log i/o's done, 0.00 log i/o's/second # 写入数据和速度 ... # 省略

6.9.13 如何根据RedoLog进行崩溃恢复?

MySQL正常运行时,RedoLog不仅发挥不了它的作用而且还会对服务器的性能造成影响,但是服务器一旦崩溃,在重新启动时,就可以根据RedoLog中的记录把数据页恢复到崩溃前的状态


6.9.13.1 如何确定哪些日志需要恢复?

前面我们介绍过每一次CHECKPOINT操作都会重新计算checkpoint_lsncheckpoint_lsn之前的日志表示已经被刷到磁盘数据页所生成的RedoLog,既然已被刷到磁盘,也就没有必要进行恢复,所以需要恢复的是checkpoint_lsn之后的日志


6.9.13.2 如何获取最新的 checkpoint_lsn 和恢复的起点?

RedoLog文件组中的第一个文件的管理信息中有两个block checkpoint1checkpoint2,其中都存储了checkpoint_lsncheckpoint_no信息,每次做CHECKPOINT操作时,会在这两个block中交替写入CHECKPOINT信息,只要需要把这两个block中保存的checkpoint_no值比较一下,哪个值大就表示哪个block存储的就是最近的一次checkpoint信息。这样我们就能拿到最近发生的checkpoint对应的checkpoint_lsn值以及它在RedoLog文件组中的偏移量checkpoint_offset


6.9.13.3 如何确认恢复的终点?

我们用之前已经掌握的内容分析一下这个问题,首先RedoLog是顺序写入的,当一个block写满了之后再写下一个,而每一个blocklog block header中都有一个名为LOG_BLOCK_HDR_DATA_LEN的属性,该属性记录了当前block使用了多少字节,对于写满的block来说,该值一定是512,所以找到第一个LOG_BLOCK_HDR_DATA_LEN的值不为512,就可以确定恢复扫描的最后一个block,这个block中的最后一条日志就是恢复的终点。


6.9.13.4 如何进行恢复?

确定了需要扫描哪些日志进行崩溃恢复之后,接下来就是怎么进行恢复了,假设现在的日志文件中有RedoLog,如图所示:

  • 第一条日志在checkpoint_lsn之前,表示已经落盘不用恢复;
  • checkpoint_lsn之后的日志可以通过顺序扫描的方式,根据日志记录的内容依次恢复对应的数据页
  • InnoDB在顺序读取日志进行恢复的过程中采用了一些优化措施:首先根据日志的Space IdPage No计算出散列值,以这个散列值为KEY,把Space IdPage No相同的日志放到哈希表的同一个槽里,如果有多个Space IdPage No相同的日志,那么按照日志生成的先后顺序使用链表连接起来,如下图所示:

  • 组织好日志后,通过遍历哈希表,就可以一次把一个数据页中的修改全部恢复好,减少了读取数据页时的随机I/O次数

6.9.13.5 如何确定哪些日志在崩溃前已经落盘?
  • checkpoint_lsn之后的日志有可能就根本没有落盘,也有可能已经落盘但没有来的及做CHECKPOINT,在恢复时如何区分呢?
  • 在页结构章节介绍过,磁盘上的每个页都包含一个File Header信息,其中又包含已被刷到磁盘的LSNFIL_PAGE_FILE_FLUSH_LSN信息,在恢复时就可以通过当前日志对应的LSNFIL_PAGE_FILE_FLUSH_LSN进行比较,如果日志的LSN小于等于已刷新到磁盘的LSN,那就证明日志对应的数据在崩溃之前已经落盘,直接跳过即可

总结:

恢复的过程主要分为以下几步:

  1. 通过checkpoint_lsn和第一个没有写满的日志页确定需要恢复日志的起始和结束位置;
  2. 遍历日志并把Space IdPage No相同的日志组织在一起,以便一次性恢复完相应数据页的所有内容;
  3. 日志的LSN小于磁盘数据页文件记录的已刷新LSN时,表示这些数据在崩溃之前已落盘,跳过即可。

小结

  • RedoLog用于在数据库崩溃后恢复已提交事务还没有来的及落盘的数据,在保证事务的持久性和一致性方面起到了至关重要的作用
  • RedoLog的写入时候,在UndoLog之后,脏页落盘之前
  • RedoLog的结构:TypeSpace IDPage nodata
  • 用来组织RedoLog的数据结构是Redo页,页的大小是512B,由Log Block HeaderLog Block BodyLog Block Trailer组成,日志内容保存在Log Block Body
  • Log Buffer和日志文件中Redo页的格式相同并且都是顺序排列的
  • RedoLog在磁盘上所占的空间可以通过系统变量innodb_redo_log_capacity控制,变量值以字节为单位,最大512GB
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 5:46:45

DeepSeek大模型架构与生产部署深度解析

1. 这不是又一个“大模型介绍”,而是一份工程师视角下的DeepSeek AI技术解剖报告我第一次在内部技术分享会上看到DeepSeek-V2的推理延迟数据时,下意识核对了三遍测试环境配置——单卡A100上7B模型端到端响应压到380ms以内,这个数字在2023年Q4…

作者头像 李华
网站建设 2026/6/11 11:48:52

终极指南:ModTheSpire模组管理器,让《杀戮尖塔》无限扩展

终极指南:ModTheSpire模组管理器,让《杀戮尖塔》无限扩展 【免费下载链接】ModTheSpire External mod loader for Slay The Spire 项目地址: https://gitcode.com/gh_mirrors/mo/ModTheSpire ModTheSpire是《杀戮尖塔》最强大的外部模组加载器&am…

作者头像 李华
网站建设 2026/6/9 5:43:08

STC89C52四路防盗报警系统:蜂鸣器+窗磁+PIR+红外对射全功能设计包

本文还有配套的精品资源,点击获取 简介:基于STC89C52等经典51单片机搭建的家用级防盗报警系统,支持四种独立触发机制:本地蜂鸣器声光报警、干簧管窗磁开关检测门窗开合状态、HC-SR501热释电红外传感器识别人体移动、红外对射或…

作者头像 李华
网站建设 2026/6/9 5:43:00

MC9S12E128时钟系统配置:从PLL到外设时钟的嵌入式开发实战

1. 项目概述与核心价值在嵌入式开发的江湖里,MCU的时钟系统就像是整个系统的“心跳”和“节拍器”。它决定了CPU能以多快的速度执行指令,也决定了SPI、SCI、PWM这些外围模块能否精准地收发数据、生成波形。很多新手工程师在项目初期,往往把精…

作者头像 李华