MySQL redo 日志深度解析
MySQL redo 日志深度解析说过的话就一定要办到摘要ATM 机已经提示转账成功但服务器下一秒就挂了钱到底去哪了本文从 MySQL 为什么要发明 redo 日志讲起用生活化的比喻带你理解 redo 日志的格式、Mini-Transaction、log buffer、LSN、checkpoint 与崩溃恢复彻底搞懂 InnoDB 是如何做到说过的话一定要办到的持久性承诺。一、为什么需要 redo 日志假设你去 ATM 机转账机器已经吐出小票说转账成功你满意地走了。可就在那一瞬间银行服务器啪的一声——断电了。等工程师修好机器重启数据库问题来了你的转账到底生效了没有这就是数据库持久性Durability要解决的问题一旦事务提交即使系统随后崩溃数据修改也不能丢失。最简单粗暴的做法是事务提交时把修改过的所有数据页从内存刷到磁盘。但这个做法有两个致命问题1.1 问题一刷新完整页面太浪费InnoDB 以页默认 16KB为单位管理磁盘空间。你可能只修改了一个字节但刷盘时必须把整个 16KB 的页写回磁盘。只改1个字节却要刷16KB 内存中的数据页16KB -------------------------------- | | | | | | |★| | | | | | | | | | ← 只改了这1个字节 -------------------------------- | v 却要刷整个16KB到磁盘 浪费 16KB - 1字节 ≈ 16KB1.2 问题二随机 IO 太慢一个事务可能修改多个页面而且这些页面在磁盘上并不相邻。把分散在磁盘各处的页面一个个刷回去产生大量随机 IO对机械硬盘来说是噩梦。随机 IO vs 顺序 IO 随机 IO直接刷数据页 页A在磁道1 → 页B在磁道100 → 页C在磁道20 磁头来回奔波慢 顺序 IO写 redo 日志 所有日志追加写到文件末尾 磁头几乎不动快那怎么办MySQL 的答案是别刷整个页只把改了什么记下来。二、redo 日志的本质只记改动不刷全页redo 日志重做日志的核心思想极其简单既然我们只要保证事务提交后修改不丢失那完全没必要在提交时就把所有修改过的页面刷盘。只需要记录一下我改了什么将来崩溃恢复时按记录重新做一遍就行。redo 日志 vs 直接刷数据页 直接刷数据页 UPDATE balance100 → 把包含这行的整个16KB页刷到磁盘 → 事务提交成功 写 redo 日志 UPDATE balance100 → 记一条 redo 日志 表空间1第200页偏移量1024处把值从200改成100 → 把这条 redo 日志刷到磁盘很小顺序写 → 事务提交成功redo 日志相比直接刷数据页的优势对比项直接刷数据页写 redo 日志写入量整个页16KB几十到几百字节IO 类型随机 IO顺序 IO速度慢快对事务提交速度的影响大小三、redo 日志的格式物理日志与逻辑日志3.1 通用结构一条 redo 日志本质上记录了对哪个页做了什么修改基本结构如下redo 日志通用格式 ----------------------------------------------- | type | space ID | page num | data | ----------------------------------------------- | | | | | | | └─ 具体修改内容 | | └─ 页号 | └─ 表空间ID └─ redo日志类型MySQL 5.7有53种之多3.2 简单 redo 日志物理日志如果修改非常简单比如只是在页面的某个偏移量处改了几个字节redo 日志直接记录在哪个偏移量改了什么值。简单 redo 日志示例MLOG_8BYTE 场景更新 Max Row ID占8字节 redo 日志内容 type MLOG_8BYTE space ID 0系统表空间 page number 7 offset 某个偏移量 data 新的8字节值 含义在系统表空间第7页偏移量XXX处写入8字节的新值根据写入字节数不同分为MLOG_1BYTE写 1 字节MLOG_2BYTE写 2 字节MLOG_4BYTE写 4 字节MLOG_8BYTE写 8 字节MLOG_WRITE_STRING写一串数据带 len 字段3.3 复杂 redo 日志物理 逻辑但实际情况远比改几个字节复杂。比如向 B 树插入一条记录不仅要写入记录本身还要更新Page Directory 的槽信息Page Header 中的各种统计信息PAGE_N_DIR_SLOTS、PAGE_HEAP_TOP、PAGE_N_HEAP 等上一条记录的 next_record 指针可能还要做页分裂如果每个改动都记一条物理日志redo 日志量可能比整个页面还大如果记第一个改动的字节到最后一个改动的字节之间的所有数据又会包含大量未改动的数据依然浪费。于是 InnoDB 设计了更高级的 redo 日志类型比如MLOG_COMP_REC_INSERT插入一条紧凑行格式的记录MLOG_COMP_REC_DELETE删除一条记录MLOG_COMP_PAGE_CREATE创建一个新页面这些日志的特点是既包含物理信息哪个表空间的哪个页又包含逻辑信息调用哪个函数来恢复。复杂 redo 日志MLOG_COMP_REC_INSERT的含义 物理层面 → 指定了表空间ID和页号 逻辑层面 → 记录了插入记录所需的参数字段长度、偏移量等 → 崩溃恢复时调用插入记录函数传入这些参数 → 函数执行后Page Header、Page Directory 等自然就被恢复了 而不是直接记录 PAGE_N_DIR_SLOTS 5 PAGE_HEAP_TOP 0x2F0 ...那样太啰嗦了一句话总结简单 redo 日志是物理日志直接记录改哪几个字节复杂 redo 日志是逻辑日志记录调用什么函数、传什么参数。InnoDB 根据场景选择最合适的格式核心目标只有一个省空间。四、Mini-Transaction原子性的保证4.1 为什么需要原子性向 B 树插入一条记录有时只需要改一个叶子页乐观插入有时却需要分裂页面、新建页面、在内节点添加目录项记录悲观插入。无论哪种情况这些对页面的修改必须是原子的——要么全做完要么全没做。否则 B 树的结构就会被破坏。乐观插入 vs 悲观插入 乐观插入 页b有空位 ------------------ | 1 | 3 | 5 | | | | ← 插入10 ------------------ → 直接在页b里插入产生少量redo日志 悲观插入 页b满了 ------------------ | 1 | 3 | 5 | 7 | 9 | 11| ------------------ → 分配新页c → 把部分记录搬到页c → 在新页插入目标记录 → 修改链表指针 → 在内节点添加目录项 → 产生大量redo日志4.2 Mini-TransactionmtrInnoDB 把对底层页面的一次原子访问过程称为一个Mini-Transaction简称 mtr。一个 mtr 内产生的所有 redo 日志是一个不可分割的整体——崩溃恢复时要么全部恢复要么全部不恢复。如何实现这个原子性InnoDB 用了一个很聪明的办法多 redo 日志的情况在最后一 redo 日志后面加一条特殊的MLOG_MULTI_REC_END日志作为结束标记。恢复时只有看到这条结束标记才认为这组日志是完整的。mtr 的 redo 日志组 redo 日志1 redo 日志2 redo 日志3 ... redo 日志N MLOG_MULTI_REC_END ← 结束标记 崩溃恢复时 看到 MLOG_MULTI_REC_END → 整组恢复 ✅ 没看到结束标记 → 说明事务崩溃时没写完整组丢弃 ❌单条 redo 日志的情况利用 type 字段的第一个比特位。如果为 1表示这条日志本身就是一个完整的 mtr。事务、mtr、redo 日志的层级关系 事务Transaction | -- 语句1 | -- mtr_1 → redo日志组A | -- mtr_2 → redo日志组B | -- 语句2 | -- mtr_3 → redo日志组C | -- COMMIT 一个事务 多个语句 多个 mtr 多组 redo 日志五、redo log buffer日志先写内存5.1 redo log blockredo 日志在内存中以512 字节为单位组织成一个个block块就像这样redo log block 结构512 字节 ---------------------------------------------------------- | block header | block body | block trailer | | (12 字节) | (496 字节) | (4 字节) | ---------------------------------------------------------- | | | | | └─ 校验和 | └─ 真正存储 redo 日志的地方 └─ HDR_NO、DATA_LEN、FIRST_REC_GROUP、CHECKPOINT_NO字段含义LOG_BLOCK_HDR_NOblock 的唯一编号LOG_BLOCK_HDR_DATA_LEN已使用了多少字节初始 12写满为 512LOG_BLOCK_FIRST_REC_GROUP第一个 mtr 日志组在此 block 中的偏移量LOG_BLOCK_CHECKPOINT_NOcheckpoint 序号后面讲LOG_BLOCK_CHECKSUM校验和5.2 redo log buffer服务器启动时会申请一大片连续内存空间称为redo log buffer重做日志缓冲区默认大小16MB。它被划分成若干个连续的 512 字节 block。redo log buffer 结构 ------------------------------------------------------- | block 0 | block 1 | block 2 | block 3 | ... | block N | ------------------------------------------------------- ↑ | buf_free ← 全局变量指向下一个可写入的位置5.3 mtr 如何写入 log buffer关键点不是每产生一条 redo 日志就写一次 buffer而是等一个 mtr 结束时把整组日志一次性写入 log buffer。这样能保证 mtr 的日志在 buffer 中是连续的。不同事务的 mtr 可能是交替执行的所以 log buffer 里会交替出现不同事务的 mtr 日志log buffer 中的内容简化示意 -------------------------------------------------------- |mtr_T1_1|mtr_T2_1| mtr_T1_2跨3个block |mtr_T2_2| -------------------------------------------------------- 不同事务的 mtr 交替写入但同一个 mtr 的日志是连续的六、redo 日志刷盘与文件组6.1 什么时候刷盘log buffer 里的 redo 日志并不会一直在内存里待着以下情况会触发刷盘redo 日志刷盘时机 1. log buffer 满了约50%满时就开始刷 | 2. 事务提交时最重要为了保证持久性 | 3. 将某个脏页刷新到磁盘前 → 必须先保证该脏页对应的 redo 日志已经刷盘 | 4. 后台线程每秒刷一次 | 5. 正常关闭服务器时 | 6. 做 checkpoint 时后面详讲6.2 redo 日志文件组磁盘上的 redo 日志默认存储在数据目录下文件名为ib_logfile0、ib_logfile1。它们组成一个日志文件组循环使用。redo 日志文件组循环写 ib_logfile048MB ib_logfile148MB ---------------- ---------------- | 管理信息(2KB) | | 管理信息(2KB) | ---------------- ---------------- | redo日志... | ──→ | redo日志... | | | | | ---------------- ---------------- │ │ └───────────────────────┘ 写满后回到开头循环写 总容量 innodb_log_file_size × innodb_log_files_in_group 48MB × 2 96MB默认6.3 日志文件格式每个 redo 日志文件的前2048 字节4 个 block是管理信息block作用block 0log file header记录 redo 日志版本、起始 LSN、创建者等block 1checkpoint1记录 checkpoint 信息block 2未使用block 3checkpoint2和 checkpoint1 结构相同交替写入从第 2048 字节往后就是真正的 redo 日志 block 镜像了。七、LSNredo 日志的年龄7.1 什么是 LSNLSNLog Sequence Number是 InnoDB 用来标记已经产生了多少 redo 日志的全局变量可以理解为 redo 日志的累计年龄。初始值为8704。LSN 的增长 初始LSN 8704 mtr_1 产生 200 字节 redo 日志 → LSN 8704 12(block header) 200 4(block trailer) 8920 mtr_2 产生 1000 字节 redo 日志跨2个block → LSN 8920 1000 12×2 4×2 9944 注意LSN 增长量 实际日志字节 新占用的 block header/trailer7.2 flushed_to_disk_lsn与lsn对应还有一个flushed_to_disk_lsn表示已经刷新到磁盘的 redo 日志量。lsn vs flushed_to_disk_lsn 内存log buffer 磁盘redo日志文件 ------------------- ------------------- | mtr_1 日志 | ───已刷──→ | | | mtr_2 日志 | ───已刷──→ | | | mtr_3 日志 | ──未刷──→ | | ------------------- ------------------- lsn 10000已写入 buffer 的总量 flushed_to_disk_lsn 9948已刷盘的总量 差值 52还在 buffer 里没刷盘的日志当lsn flushed_to_disk_lsn时说明 log buffer 中的所有 redo 日志都已安全落盘。7.3 flush 链表中的 LSNBuffer Pool 中的脏页会按修改时间顺序挂在flush 链表中每个控制块记录两个重要属性属性含义oldest_modification第一次修改该页时的 LSNnewest_modification最近一次修改该页时的 LSNflush 链表与 LSN flush 链表按 oldest_modification 排序 头部 ← 页d(newest10000, oldest9948) ← 页c(9948, 8916) ← 页b(10000, 8916) ← 页a(8916, 8716) → 尾部 修改较晚 修改最早八、checkpoint空间不够了怎么办8.1 为什么需要 checkpointredo 日志文件组的容量是有限的比如默认只有 96MB不可能无限增长。当写到最后一个文件的末尾时必须回到第一个文件的开头继续写——这就是循环写。但如果直接覆盖就会丢失旧的 redo 日志。问题是这些旧的 redo 日志还需要吗如果某条 redo 日志对应的脏页已经刷新到磁盘了那么这条 redo 日志就没用了——因为崩溃恢复时可以直接从磁盘读取最新页面不需要 redo 日志来重建。所以 InnoDB 需要知道哪些 redo 日志可以安全地覆盖8.2 checkpoint 的原理checkpoint检查点的核心逻辑找到 flush 链表中最早修改的脏页尾节点读取它的oldest_modification所有 LSN 小于这个值的 redo 日志对应的脏页都已经刷盘了可以被覆盖把这个值记录为checkpoint_lsn并写入日志文件的管理信息checkpoint 过程 步骤1找到最早修改的脏页 flush 链表尾部 → 页aoldest_modification 8716 步骤2设置 checkpoint_lsn 8716 → LSN 8716 的 redo 日志都可以被覆盖 步骤3将 checkpoint 信息写入 ib_logfile0 的管理信息 → checkpoint_lsn 8716 → checkpoint_offset 该 LSN 对应的文件偏移量 → checkpoint_no 1 checkpoint_no 为偶数 → 写入 checkpoint1 checkpoint_no 为奇数 → 写入 checkpoint2双保险8.3 checkpoint 后的 LSN 关系checkpoint 后的 redo 日志文件状态 redo 日志文件组 可覆盖区 checkpoint_lsn 需保留区 ├──────────┤←──8716──┤←──────────────────────────→┤ ↑ 从这里开始恢复 | LSN 8716 之前的 redo 日志对应的脏页都已刷盘可以被覆盖 LSN 8716 之后的 redo 日志可能还有用必须保留8.4 查看系统 LSN 状态SHOWENGINEINNODBSTATUS\G-- 在输出中可以看到Log sequence number124476971-- 当前 lsnLog flushed upto124099769-- flushed_to_disk_lsnPages flushed upto124052503-- flush 链表尾 oldest_modificationLastcheckpointat124052494-- checkpoint_lsn九、持久性的取舍innodb_flush_log_at_trx_commit事务提交时刷 redo 日志到磁盘能保证持久性但也会带来性能开销。如果你愿意在极端情况下的数据安全和性能之间做取舍可以调整innodb_flush_log_at_trx_commit参数innodb_flush_log_at_trx_commit 三种模式对比 ┌──────────┬────────────────────────────────────────────────────────┐ │ 值 │ 行为 │ ├──────────┼────────────────────────────────────────────────────────┤ │ 0 │ 事务提交时不刷盘交给后台线程每秒刷一次 │ │ │ ⚠️ 崩溃时可能丢失最近1秒的数据 │ │ │ 性能最好 │ ├──────────┼────────────────────────────────────────────────────────┤ │ 1 │ 事务提交时立即调用 fsync 刷到磁盘默认 │ │ │ ✅ 完全保证持久性 │ │ │ 性能最差每次提交都要等磁盘IO │ ├──────────┼────────────────────────────────────────────────────────┤ │ 2 │ 事务提交时写到操作系统缓冲区但不强制刷盘 │ │ │ ⚠️ MySQL 挂了数据还在操作系统/机器挂了会丢失 │ │ │ ⚡ 性能较好 │ └──────────┴────────────────────────────────────────────────────────┘-- 查看当前设置SELECTinnodb_flush_log_at_trx_commit;-- 修改仅当前会话SETSESSIONinnodb_flush_log_at_trx_commit2;-- 修改全局SETGLOBALinnodb_flush_log_at_trx_commit2;生产建议对数据一致性要求高的场景金融、支付用1对性能要求高、可接受秒级数据丢失的场景日志、统计用2或0。十、崩溃恢复重启后如何重建数据redo 日志平时是个累赘但数据库崩溃时它就是救命稻草。10.1 确定恢复起点checkpoint_lsn重启时InnoDB 从 redo 日志文件组的管理信息中读取checkpoint1和checkpoint2比较两者的checkpoint_no取较大的那个代表最近的 checkpoint。从中得到checkpoint_lsn——这就是恢复的起点。确定恢复起点 checkpoint1: checkpoint_no 100, checkpoint_lsn 50000 checkpoint2: checkpoint_no 101, checkpoint_lsn 80000 ← 更新 恢复起点 80000checkpoint_lsn → 只需恢复 LSN 80000 的 redo 日志10.2 确定恢复终点redo 日志是顺序写的。最后一个 block 的LOG_BLOCK_HDR_DATA_LEN字段如果不等于 512说明这个 block 没有写满它就是恢复的终点。确定恢复终点 block N: DATA_LEN 512写满 block N1: DATA_LEN 340没写满← 恢复终点 block N2: DATA_LEN ???可能是空的不用管10.3 怎么恢复方法1用哈希表加速将需要恢复的 redo 日志按space IDpage number做哈希相同的页面日志放到同一个槽里用链表按 LSN 顺序连接。哈希表加速恢复 槽0 → 页a的redo日志LSN 80001 → 80015 → 80030 槽1 → 页b的redo日志LSN 80005 → 80020 槽2 → 页c的redo日志LSN 80010 | v 遍历哈希表逐个页面恢复 好处同一个页面的日志一次性处理减少随机IO方法2跳过已经刷盘的页面checkpoint_lsn 之后的 redo 日志对应的脏页可能已经被后台线程刷盘了。怎么判断每个数据页的File Header中有一个FIL_PAGE_LSN属性记录最近一次修改该页时的 LSN。如果FIL_PAGE_LSN redo 日志的 LSN → 说明该页在崩溃前已经刷盘这条 redo 日志不用重放如果FIL_PAGE_LSN redo 日志的 LSN → 说明该页没刷盘需要重放这条 redo 日志跳过已刷盘页面的判断 redo 日志页aLSN 85000把某值改为100 | v 读取磁盘上的页a查看 FIL_PAGE_LSN | ├── FIL_PAGE_LSN 90000 85000 │ → 页a在崩溃前已经刷盘跳过这条redo日志 ✅ | └── FIL_PAGE_LSN 80000 85000 → 页a没刷盘执行 redo 日志恢复 ✅十一、总结与实战速查11.1 redo 日志核心流程图完整的数据修改与 redo 日志流程 1. 执行 UPDATE/INSERT/DELETE | v 2. 在 Buffer Pool 中修改数据页 | v 3. 生成 redo 日志mtr 过程中暂存 | v 4. mtr 结束 → 将一组 redo 日志写入 log buffer | v 5. 事务提交 → 根据 innodb_flush_log_at_trx_commit 设置刷盘 | v 6. 后台线程持续将脏页刷到数据文件 | v 7. checkpoint → 标记可以覆盖的旧 redo 日志11.2 核心概念速查表概念一句话解释redo 日志记录对哪个页做了什么修改用于崩溃后恢复物理日志直接记录偏移量X处改为Y如 MLOG_8BYTE逻辑日志记录调用什么函数、传什么参数如 MLOG_COMP_REC_INSERTmtrMini-Transaction对页面的一次原子访问产生一组 redo 日志MLOG_MULTI_REC_ENDmtr 日志组的结束标记log bufferredo 日志的内存缓冲区默认 16MBlog block512 字节的 redo 日志存储单元ib_logfile0/1磁盘上的 redo 日志文件默认 2 个LSN日志序列号标记已产生的 redo 日志总量初始 8704flushed_to_disk_lsn已刷新到磁盘的 redo 日志量checkpoint_lsn可以安全覆盖的 redo 日志边界oldest_modification脏页第一次被修改时的 LSNnewest_modification脏页最近一次被修改时的 LSN11.3 关键参数速查参数名默认值含义innodb_log_buffer_size16MBredo log buffer 大小innodb_log_file_size48MB单个 redo 日志文件大小innodb_log_files_in_group2redo 日志文件个数innodb_flush_log_at_trx_commit1事务提交时 redo 刷盘策略11.4 常见面试题Q1redo 日志和 binlog 有什么区别Aredo 日志是 InnoDB 引擎层的物理/逻辑日志用于崩溃恢复binlog 是 MySQL Server 层的逻辑日志用于主从复制和 point-in-time 恢复。redo 日志是循环写的binlog 是追加写的。Q2为什么 redo 日志比刷数据页快A1redo 日志量小只记改动2redo 是顺序 IO追加写刷数据页是随机 IO页分散在磁盘各处。Q3事务提交时 redo 日志一定刷盘吗A取决于innodb_flush_log_at_trx_commit。为 1 时一定刷盘fsync为 0 时不刷盘靠后台线程为 2 时写到 OS 缓存但不保证刷盘。Q4checkpoint 是做什么的A解决 redo 日志文件空间有限的问题。把对应脏页已刷盘的 redo 日志标记为可覆盖实现循环使用。延伸阅读MySQL 官方文档InnoDB Redo Log

相关新闻

终极Windows右键菜单管理指南:5步轻松清理杂乱右键菜单

终极Windows右键菜单管理指南:5步轻松清理杂乱右键菜单

终极Windows右键菜单管理指南:5步轻松清理杂乱右键菜单 【免费下载链接】ContextMenuManager 🖱️ 纯粹的Windows右键菜单管理程序 项目地址: https://gitcode.com/gh_mirrors/co/ContextMenuManager 你是否经常被Windows右键菜单中那些用不到的选…

2026/8/13 8:13:40 阅读更多 →
二分答案算法精讲:从路标设置问题掌握最小化最大值求解

二分答案算法精讲:从路标设置问题掌握最小化最大值求解

1. 题目背景与核心思路拆解 看到“路标设置”这个标题,很多人的第一反应可能是物理世界的道路工程。但在算法竞赛的语境下,这其实是一道非常经典的“最小化最大值”问题,也叫“二分答案”的入门必刷题。我第一次在洛谷上刷到这道题时&#xf…

2026/8/13 8:12:40 阅读更多 →
AIOps实战:时序数据增强与语义日志解析提升运维精度与效率

AIOps实战:时序数据增强与语义日志解析提升运维精度与效率

1. 项目概述:当运维遇上AI,一场关于“精度”与“效率”的攻坚战最近在圈子里,大家讨论的热点除了大模型,就是如何让AI真正在运维这个“苦活累活”里落地生根。这不,阿里云在顶会上连发多项研究成果,核心就围…

2026/8/13 8:12:40 阅读更多 →

最新新闻

汽车遥控防盗系统技术解析:从滚动码到中继攻击的攻防演进

汽车遥控防盗系统技术解析:从滚动码到中继攻击的攻防演进

1. 从“滴滴”声到“无感”守护:现代汽车遥控防盗系统的演进与内核 十几年前,我们锁车时听到的那一声清脆的“滴滴”,是当时汽车防盗系统最直观的确认信号。那时的遥控钥匙,更像是一个简单的无线电开关,按下按钮&#…

2026/8/13 9:01:57 阅读更多 →
QMT量化交易:动态指标策略与多周期验证实战

QMT量化交易:动态指标策略与多周期验证实战

1. QMT交易系统中的指标策略概述 QMT(Quantitative Market Trading)作为国内主流量化交易平台,其核心价值在于为投资者提供可编程的交易策略实现能力。不同于传统交易软件的固定指标,QMT允许用户通过Python语言自定义技术指标&…

2026/8/13 9:01:57 阅读更多 →
信号频域分析:频率响应与滤波器特性详解

信号频域分析:频率响应与滤波器特性详解

在实际的信号处理、音频工程、通信系统乃至控制系统设计中,我们常常需要理解一个系统或设备对不同频率信号的“态度”。一个简单的放大器,对不同频率的正弦波放大倍数可能不同;一个音频均衡器,本质上就是在调整特定频段的增益&…

2026/8/13 9:01:57 阅读更多 →
Nmap 使用教程:从入门到实战

Nmap 使用教程:从入门到实战

1. 引言 Nmap(Network Mapper)是一款开源的网络探测和安全审计工具,被广泛应用于网络发现、端口扫描、服务版本检测、操作系统识别以及安全漏洞评估。无论是网络管理员、安全工程师还是渗透测试人员,Nmap 都是必备的利器。 本教…

2026/8/13 9:01:57 阅读更多 →
OpenCV计算机视觉开发入门与实践<五>:VS2019下OpenCV开发环境测试

OpenCV计算机视觉开发入门与实践<五>:VS2019下OpenCV开发环境测试

1. OpenCV编译目录2.在程序中测试 OpenCV打开 VC 2019&#xff0c;新建一个控制台工程&#xff0c;工程名是 test。进行如下属性设置。1&#xff09; 混合图片#include <iostream> #include "opencv2/imgcodecs.hpp" #include "opencv2/highgui.hpp"…

2026/8/13 9:01:57 阅读更多 →
【AI Agent实战】构建可信 AI Agent:从系统消息框架到安全防护的完整指南——基于 Microsoft Agent Framework 的生产级安全实践

【AI Agent实战】构建可信 AI Agent:从系统消息框架到安全防护的完整指南——基于 Microsoft Agent Framework 的生产级安全实践

文章目录 一、为什么可信度是 AI Agent 的生命线? 1.1 从"能用"到"值得信赖"的跨越 1.2 本课学习目标 二、安全基础:构建系统消息框架(System Message Framework) 2.1 为什么系统提示词对 Agent 至关重要? 2.2 系统消息框架的四步法 Step 1:创建 Met…

2026/8/13 9:00:57 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者&#xff0c;或者正准备踏入这个领域&#xff0c;那么Visual Studio&#xff08;后面简称VS&#xff09;绝对是你绕不开的伙伴。但有时候&#xff0c;这个伙伴会跟你开一个不大不小的玩笑&#xff1a;你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南&#xff1a;RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑&#xff1a;baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码&#xff08;维护中 rm repo&#xff09; 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片&#xff1a;Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/12 1:11:09 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身&#xff0c;而应重视模型外的系统搭建&#xff0c;即Harness。提出AgentModelHarness的实用公式&#xff0c;详细介绍Harness的四个层次&#xff1a;持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/12 1:11:08 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速&#xff1a;macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/11 17:09:45 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南&#xff1a;3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗&#xff1f;ncmdump解密工具帮你轻松解决这个困…

2026/8/12 1:11:10 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片&#xff1a;为英语学习 App 打造桌面级学习助手适用平台&#xff1a;HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0&#xff08;API 26 Beta&#xff09;新增了 AgentCard 智能体卡片能力&#xff0c;这是继 HMAF&#xff08;鸿蒙智能体框架&#x…

2026/8/11 17:09:45 阅读更多 →