Mysql InnoDB 底层架构设计、功能、原理、源码系列合集

一、InnoDB 架构先导。【模块划分,各模块功能、源码位置、关键结构体/函数】

二、内存结构核心 - 缓冲池与性能加速器

三、日志系统 - 事务持久化的基石

四、事务引擎核心 - MVCC与锁机制

五、InnoDB 高阶机制与实战调优

六、架构全景图与最佳实践


前言

InnoDB作为MySQL的默认事务型存储引擎,其核心并发控制机制由MVCC(多版本并发控制)和锁系统共同构成。这两者相互配合,既保证了事务的隔离性与一致性,又提高了系统的并发性能。本文将从Undo Log与回滚段结构、MVCC实现原理、锁系统工作机制三个维度,深入剖析InnoDB事务引擎的核心设计与实现细节,帮助读者全面理解这一工业级存储引擎的并发控制机制。

一、Undo Log与回滚段

1.1 Undo Log结构与作用

Undo Log是InnoDB实现事务原子性和MVCC的核心数据结构。它采用逻辑日志形式,记录数据修改前的"前映像"(before image),而非物理页的修改。这种设计使得回滚操作更为高效,也便于构建多版本数据链。
每条记录在InnoDB中包含三个隐藏字段:

  • DB_TRX_ID:记录该行最新一次被修改的事务ID
  • DB_ROLL_ptr:回滚指针,指向该行在Undo Log中的上一个版本
  • DB_row_ID:隐藏的行ID,用于聚簇索引组织
    这些隐藏字段与Undo Log共同构成了多版本数据链。当事务修改数据时,会先将原数据写入Undo Log,然后修改当前数据。通过DB_ROLL_ptr,可以回溯到历史版本,实现事务的回滚和MVCC的版本控制。

1.2 回滚段物理结构

回滚段(Rollback Segment)是管理Undo Log的元数据结构。在InnoDB中,回滚段采用以下物理结构:

  1. 表空间组织:Undo Log存储在专门的undo tablespace中,由多个段(segment)组成。每个段由64个页 extent构成,页大小通常为16KB。
  2. 页结构:Undo页包含多个undo记录,每个记录对应一个事务的修改操作。页分为两种类型:
    • Insert undo页:仅用于回滚未提交的INSERT操作,在事务提交后可以立即释放
    • Update undo页:用于回滚UPDATE和DELETE操作,需要等到所有依赖该版本的事务完成后才能释放
  3. 段管理:回滚段通过rseg_history_len维护历史版本长度,协调线程根据此值触发purging操作。当事务提交时,会向回滚段注册,当事务回滚时,系统会根据回滚指针追溯并恢复数据。

这种结构设计使得事务回滚和MVCC版本控制变得高效,避免了对数据页的直接修改,减少了锁竞争,同时保证了事务的原子性。

1.3 Undo Log清理机制与长事务风险

Undo Log的清理由purge线程负责,其工作流程如下:

  1. 触发条件:当事务提交或回滚时,系统会调用srv_active_wake_master_thread()唤醒协调线程。
  2. 协调线程检测:协调线程srv_purge_coordinator_thread()会检查rseg_history_len是否变化。如果无新事务提交且历史长度未超过阈值(如5000),则进入无限期等待状态。
  3. 版本链遍历:当协调线程被唤醒后,工作线程会遍历版本链,根据ReadView的min_trx_id判断版本是否可清理。版本的DB_TRX_ID需小于min_trx_id,即对所有活跃事务都不可见时,才能被清理。
  4. 清理操作:清理操作包括删除标记记录、回收undo历史版本。系统会先从最新版本回溯,找到符合条件的版本后,将其从版本链中移除。

长事务对Undo Log的影响:长事务会阻碍undo log版本的回收,导致undo tablespace空间膨胀和查询性能下降。具体表现为:

  • 空间占用:长事务使undo log版本无法被清理,undo tablespace持续增长,可能导致磁盘空间不足
  • 版本链长度:长事务导致版本链过长,查询时需要遍历更多版本,增加CPU开销
  • Purge线程效率:当rseg_history_len持续增长时,purge线程的工作量增加,可能无法及时清理旧版本

官方建议:通过SHOW ENGINE INNODB STATUS监控undo log使用情况,设置合理的innodb_max undo_log_size参数限制undo tablespace大小,避免长事务阻塞系统清理。

二、MVCC实现原理

2.1 快照读与ReadView

MVCC的核心是通过ReadView实现快照读,使事务能够看到一致的数据视图,而不必等待其他事务释放锁。ReadView的生成规则如下:

  1. RC(读未提交)隔离级别:
  • 每次SQL读操作都会生成新的ReadView
  • ReadView仅包含当前系统最大事务ID(max_trx_id)
  • 可见性规则:DB_TRX_ID < max_trx_id,即读取最新已提交版本
  1. RR(可重复读)隔离级别
  2. 事务首次执行读操作时生成ReadView
  3. ReadView包含活跃事务列表(m_ids)、最小活跃事务ID(min_trx_id)、最大事务ID(max_trx_id)和创建事务ID(creator_trx_id)
  4. 可见性规则:
    • DB_TRX_ID < min_trx_idDB_TRX_ID == creator_trx_id
    • DB_TRX_ID不在活跃事务列表(m_ids)中

ReadView的生成时机与事务隔离级别密切相关,是MVCC实现一致性的关键。

2.2 隔离级别实现差异

RC与RR隔离级别的本质差异在于可见性判断机制和锁策略

隔离级别ReadView生成时机可见性判断规则幻读防护机制
RC每次读操作DB_TRX_ID < max_trx_id无间隙锁,依赖版本可见性规则
RR事务首次读操作DB_TRX_ID < min_trx_id且不在活跃列表使用间隙锁和临键锁防止幻读

在**RC隔离级别下,事务读取的是当前最新已提交版本**,不保证可重复读。每次读操作都生成新的ReadView,捕获当前系统最大事务ID(max_trx_id),版本的DB_TRX_ID小于该值即可见。

而在RR隔离级别下,事务读取的是事务开始时的快照,保证可重复读。事务首次读操作时生成ReadView,捕获所有活跃事务ID并记录最小值(min_trx_id)。后续读操作使用同一ReadView,只有版本的 DB_TRX_ID 小于min_trx_id 或等于事务自己的ID时才可见。

幻读防护:RR隔离级别通过间隙锁和临键锁防止幻读,而RC不使用此类锁,仅依赖版本可见性规则。

2.3 版本可见性判断算法

InnoDB的版本可见性判断算法是MVCC的核心逻辑,其实现如下:

  1. 获取当前版本:读取数据行的当前版本,检查其DB_TRX_IDDB删除标记
  2. 可见性判断
    • 如果版本的DB删除标记为已删除且DB删除TRX_ID ≤ 当前事务的min_trx_id,则该版本**不可见**
    • 如果版本的DB删除标记为已删除且DB删除TRX_ID > 当前事务的min_trx_id,则该版本**可见**
    • 如果版本的DB删除标记为未删除且DB创建TRX_ID > 当前事务的min_trx_id,则该版本**不可见**
    • 如果版本的DB创建TRX_ID < 当前事务的min_trx_id或等于事务自己的ID,则该版本**可见**
  3. 回溯历史版本:如果当前版本**不可见**,通过DB_ROLL_ptr回溯到上一个版本,重复可见性判断,直到找到可见版本或版本链结束。

这种基于版本号的可见性判断机制,使得读操作不需要加锁,极大提高了系统的并发性能。同时,通过ReadView维护活跃事务信息,确保了事务隔离性的实现。

三、锁系统剖析

3.1 行锁类型与实现机制

InnoDB的锁系统主要包含以下几种行锁类型:

  1. 记录锁(Record Locks)
    • 锁定单个索引记录
    • 依附于索引存在,未命中索引时升级为表锁
    • 用于防止其他事务修改同一行数据
    • 实现方式:在B+树的叶子节点上设置锁标记
  2. 间隙锁(Gap Locks)
    • 锁定索引记录之间的间隙
    • 不包含记录本身
    • 主要用于防止幻读
    • 实现方式:在B+树的非叶子节点上设置锁区间
  3. 临键锁(Next-Key Locks)
    • 结合记录锁和间隙锁
    • 锁定记录本身及其前面的间隙
    • RR隔离级别下的默认锁类型
    • 实现方式:通过组合记录锁和间隙锁的标志位
  4. 插入意向锁(Insert Intention Locks)
    • 间隙锁的一种特殊形式
    • 允许多个事务并发插入同一间隙区间的不同位置
    • 用于自增主键等场景的并发插入优化
  5. 意向锁(Intention Locks)
    • 表级锁,用于声明对表中行的加锁意图
    • 包括意向共享锁(IS)和意向排他锁(IX)
    • 用于快速判断表是否被锁,避免全表扫描

锁模式兼容性:InnoDB的锁模式遵循严格的兼容性规则:

XS
X不兼容不兼容
S不兼容兼容

共享锁(S)允许多个事务同时读取同一行数据,但阻止写入;排他锁(X)独占访问行数据,阻止其他事务读写 。

3.2 锁获取流程与数据结构

InnoDB的锁获取流程如下:

  1. 查询索引:通过B+树查找目标记录,根据查询条件确定需要锁定的范围。
  2. 判断锁类型
    • 等值查询:获取记录锁
    • 范围查询:获取临键锁或间隙锁
    • 插入操作:获取插入意向锁
  3. 检查锁兼容性:根据锁模式矩阵判断当前事务能否获取锁。
  4. 加锁操作
    • 如果兼容,直接加锁
    • 如果不兼容,进入等待状态,记录等待关系

锁在InnoDB中通过以下数据结构实现:

  • LOCK_rec_t:表示单个记录的锁信息,包含锁模式、事务ID等
  • LOCK_gap:表示间隙锁的信息
  • LOCK(ordinary):表示临键锁的信息
  • LOCK Insert Intention:表示插入意向锁的信息

锁信息存储在B+树的页中,每个页维护一个锁列表。对于记录锁,锁信息直接附加在记录上;对于间隙锁,锁信息存储在索引页的间隙区间中。

3.3 死锁检测机制

InnoDB的死锁检测基于等待图算法,其实现流程如下:

  1. 等待关系记录:当事务申请锁被阻塞时,系统会记录等待关系,形成等待图。
  2. 周期性检测:InnoDB定期检查等待图中是否存在环路。检测频率由innodb_deadlock_detect参数控制,可设置为offonsearch
  3. 环路检测算法:采用深度优先搜索(DFS)或广度优先搜索(BFS)算法遍历等待图,寻找环路。
  4. 死锁处理:一旦检测到死锁,系统会选择一个牺牲事务进行回滚。选择标准通常包括:
    • 事务持有锁的时间最短
    • 事务回滚成本最低
    • 随机选择避免偏向某些事务

等待图结构:InnoDB的等待图由多个节点和边组成。每个节点代表一个事务,边表示事务之间的等待关系。当事务A等待事务B释放锁,而事务B又等待事务A释放锁时,就形成了环路,系统会检测到死锁。

3.4 隔离级别与锁策略的协同

InnoDB的锁策略与事务隔离级别紧密协同:

  • RC隔离级别:主要依赖MVCC的版本可见性规则,读操作不加锁,写操作加排他锁
  • RR隔离级别:在MVCC基础上,增加间隙锁和临键锁机制防止幻读
    • 范围查询自动加临键锁
    • SELECT ... FOR UPDATE操作加临键锁
    • SELECT ... LOCK IN SHARE MODE操作加记录锁

这种协同设计使得InnoDB在保证事务隔离性的同时,最大限度地提高了并发性能。RC隔离级别牺牲了一定的隔离性换取更高的读性能,而RR隔离级别则在保证可重复读的基础上,通过间隙锁防止幻读。

四、性能特点与优化策略

4.1 MVCC与锁的性能权衡

InnoDB的并发控制机制在性能与隔离性之间做了精妙的权衡

  • 读操作性能:MVCC机制使得读操作不需要加锁,极大提高了读性能。RC隔离级别下读性能最高,但隔离性最低。
  • 写操作性能:写操作需要加排他锁,但MVCC机制减少了锁的持有时间。在事务提交时,锁被释放,其他事务可以立即访问数据。
  • 空间开销:MVCC机制需要额外存储历史版本数据,增加了存储空间开销。长事务会进一步加剧这一问题。
  • 版本链长度:频繁的更新操作会导致版本链过长,增加查询时的遍历开销。

最佳实践:根据业务场景选择合适的隔离级别,避免不必要的长事务,合理设置innodb_purge_threads参数提高清理效率。

4.2 高并发场景下的优化策略

在高并发场景下,InnoDB的并发控制机制可以通过以下策略优化:

  1. 锁拆分技术
    • 对热点数据采用分桶策略,将操作分散到不同行
    • 使用更细粒度的索引,减少锁的范围
  2. 避免间隙锁膨胀
    • 在RR隔离级别下,使用SELECT ... FOR UPDATE时尽量精确锁定范围
    • 考虑使用innodb_locks_unsafe_forbinlog参数减少间隙锁(需权衡隔离性)
  3. 优化事务设计
    • 减少事务持有时间,尽快提交或回滚
    • 避免在事务中执行长时间的查询或计算
    • 合理使用COMMITROLLBACK语句,而不是依赖自动提交
  4. 监控与调整
    • 使用SHOW ENGINE INNODB STATUS监控锁等待和事务状态
    • 调整innodb_lock Wait_timeout参数控制锁等待时间
    • 监控undo tablespace使用情况,及时清理或扩容

这些优化策略可以帮助系统更好地处理高并发场景,减少锁竞争和死锁风险,提高系统整体性能。

五、源码分析与关键函数

5.1 Undo Log相关源码

InnoDB的Undo Log实现主要集中在以下源码文件中:

  1. undo0undo.c
    • undo Log Create Space():创建undo表空间
    • undo Log Truncate():截断undo表空间
    • undo Log Apply():应用undo log进行回滚
  2. undo0roll.h
    • 定义undo记录结构
    • 实现undo链表遍历逻辑
  3. undo0rec.c
    • undo记录的读写操作
    • undo版本可见性判断

关键数据结构undo Log Spaceundo Segment管理undo log的物理存储,undo Page存储具体的undo记录,undo Record表示单个数据修改的前映像。

5.2 MVCC相关源码

MVCC的核心实现位于以下源码文件:

  1. row0mysql.c
    • row Is可见():判断版本是否可见的核心函数
    • row Read View():生成和管理ReadView的函数
  2. trx0view.h
    • 定义struct read_view:包含m_ids(活跃事务列表)、min_trx_id(最小活跃事务ID)、max_trx_id(最大事务ID)和creator_trx_id(创建事务ID)
  3. undo0undo.c
    • undo Log Get():获取历史版本数据

可见性判断函数row Is可见()是MVCC的核心函数,根据事务隔离级别和ReadView的属性,判断当前版本是否可见。在RC隔离级别下,该函数主要检查DB_TRX_ID < max_trx_id;在RR隔离级别下,则需要同时满足DB_TRX_ID < min_trx_id和不在活跃事务列表中。

5.3 锁系统相关源码

锁系统的实现主要位于以下源码文件:

  1. lock0lock.c
    • lock Acquire():获取锁的核心函数
    • lock死锁检测():死锁检测的核心算法
    • lock Wait():处理锁等待的逻辑
  2. lock0wait.c
    • lock Wait Graph Build():构建等待图的函数
    • lock Wait Graph Check():检查等待图中是否存在环路
  3. lock0btr.c
    • lock Btr Acquire():在B+树中获取锁的函数
    • lock Btr Release():释放B+树中锁的函数

关键数据结构LOCK Table表示表级别的锁信息,LOCK Index表示索引级别的锁信息,LOCK Rec表示记录级别的锁信息,LOCK Gap表示间隙锁的信息。

死锁检测函数lock死锁检测()函数通过遍历锁等待图,寻找是否存在环路。当检测到死锁时,系统会调用lock死锁处理()函数选择一个牺牲事务进行回滚。

六、总结与展望

InnoDB的事务引擎通过MVCC和锁系统的协同工作,实现了高性能的并发控制。Undo Log与回滚段构建了多版本数据链,支持事务的回滚和快照读;MVCC通过ReadView实现了不同隔离级别的可见性规则;锁系统则通过多种行锁类型和死锁检测算法,确保了事务的互斥和系统的一致性。

未来发展趋势可能包括:

  1. 更细粒度的锁机制:如基于列的锁或更智能的锁范围控制
  2. 更高效的MVCC实现:如减少版本链长度或优化可见性判断算法
  3. 分布式事务支持:如PolarDB-X等分布式数据库在InnoDB基础上的扩展

在实际应用中,理解InnoDB的并发控制机制对于优化数据库性能至关重要。开发者应当根据业务场景合理选择隔离级别,设计高效的索引结构,避免长事务和锁竞争,才能充分发挥InnoDB事务引擎的性能优势。

通过本文的深入剖析,希望读者能够全面理解MySQL InnoDB事务引擎的核心工作机制,为实际应用中的性能优化和问题排查提供理论指导。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96779.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96779.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96779.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ pytorch ] 基于CLIP的zero-shot图像分类

论文&#xff1a;Learning Transferable Visual Models From Natural Language Supervision 地址&#xff1a;Learning Transferable Visual Models From Natural Language Supervision 一、关于CLIP 基于图文匹配的特征学习&#xff1a;该论文证明了预测哪个标题与哪个图像…

SP95N65CTO:一款高性能650V SiC MOSFET的全面解析

碳化硅&#xff08;SiC&#xff09;功率器件因其优异的性能&#xff0c;在高频、高温、高效率的应用中越来越受到重视。本文将以SP95N65CTO为例&#xff0c;详细介绍这款650V SiC MOSFET的关键特性、电气参数与应用场景。一、产品概述SP95N65CTO是一款采用TOLI&#xff08;TO-2…

week4-[二维数组]平面上的点

week4-[二维数组]平面上的点 题目描述 有 NNN 个二维平面上的点&#xff0c;每个点的坐标都是整数且坐标范围都在 0∼9990\sim 9990∼999 之间&#xff0c;求其中出现最频繁的点的出现次数及其坐标。 输入格式 第一行有一个整数 NNN&#xff0c;表示平面上点的个数。 接下来 NN…

领域专用AI模型训练指南:医疗、法律、金融三大垂直领域微调效果对比

领域专用AI模型训练指南&#xff1a;医疗、法律、金融三大垂直领域微调效果对比 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0…

在自动驾驶中ESKF实现GINS时,是否将重力g作为变量考虑进去的目的是什么?

在自动驾驶的ESKF中&#xff0c;是否将重力 g 作为估计变量&#xff0c;可以从多个维度来比较这两种方法的差异。对比维度不将重力 g 作为变量将重力 g 作为变量核心假设重力矢量 g 是已知且恒定的完美参考量。重力矢量 g 是需要被估计或校准的量&#xff0c;其值可能存在不确定…

Dify 从入门到精通(第 55/100 篇):Dify 的模型微调(进阶篇)

Dify 从入门到精通&#xff08;第 55/100 篇&#xff09;&#xff1a;Dify 的模型微调 Dify 入门到精通系列文章目录 第一篇《Dify 究竟是什么&#xff1f;真能开启低代码 AI 应用开发的未来&#xff1f;》介绍了 Dify 的定位与优势第二篇《Dify 的核心组件&#xff1a;从节点…

《Password Guessing Using Large Language Models》——论文阅读

1.研究背景LLM在文本生成和理解方面表现出色&#xff0c;但直接用于密码猜测存在以下问题&#xff1a;密码与自然语言的差异&#xff08;短、无语法、需精确匹配&#xff09;生成效率低、重复率高伦理限制&#xff08;如GPT-4拒绝生成大量密码&#xff09;2.本文研究提出PASSLL…

C# 使用OPCUA 与CODESYS进行标签通讯

目录 1.导出的标签 识别标签名称 2.引用OPCUA的包 3.读写方法的封装 4.完整的业务模块封装 1.导出的标签 识别标签名称 从CODESYS导出使用标签通讯的模块文档 大概是这样子的 <?xml version"1.0" encoding"utf-8"?> <Symbolconfiguratio…

C++ 中 `std::map` 的 `insert` 函数

1. 函数的概念与用途 std::map::insert 是 C 标准模板库&#xff08;STL&#xff09;中 map 容器的一个核心成员函数。它的核心任务很明确&#xff1a;向 map 中插入一个新的键值对&#xff08;key-value pair&#xff09;。 核心用途&#xff1a; 数据构建&#xff1a;初始化一…

【机器学习学习笔记】机器学习引言

前言本文章是拨珠自己的学习笔记&#xff0c;自用为主&#xff0c;学习请移步专门教程&#xff0c;若有错误请大佬轻喷&#xff0c;也欢迎同好交流学习。本文将阐述三个问题。什么是机器学习&#xff1f;监督学习、无监督学习到底在干什么&#xff1f;分类、回归、聚类又是怎么…

程序设计---状态机

在软件工程、嵌入式开发、自动化控制等领域&#xff0c;状态机&#xff08;State Machine&#xff09;是一种描述系统行为的强大工具。它通过抽象“状态”“事件”“转换”和“动作”四大核心要素&#xff0c;将复杂的逻辑流程转化为可视化、可验证的状态流转规则&#xff0c;广…

GaussDB 数据库架构师修炼(十八) SQL引擎-分布式计划

1 分布式架构GaussDB基于MPP &#xff08;Massively Parallel Processing&#xff09; 并行架构Streaming流式计算框架2 分布式计划CN轻量化&#xff08;light proxy&#xff09; FQS&#xff08; fast query shipping &#xff09; STREAM计划 XC计划计划类型场景原理CN…

微前端架构核心要点对比

1. 样式隔离 常见的隔离方式有以下几种,还是根据自身业务来确定: 1.1. shadowDOM 目前相对来说使用最多的样式隔离机制。 但shadowDOM并不是银弹,由于子应用的样式作用域仅在 shadow 元素下,那么一旦子应用中出现运行时“翻墙”跑到外面构建 DOM 的场景,必定会导致构建…

VMware 17.6安装包下载与保姆级图文安装教程!

软件下载 [软件名称]&#xff1a;VMware 17.6 [软件大小]&#xff1a;226.66MB [系统环境]&#xff1a;win 7/8/10/11或更高&#xff0c;64位操作系统 VMware合集&#xff0c;软件下载&#xff08;夸克网盘需手机打开&#xff09;&#xff1a;&#xff1a;VMware合集丨夸克网…

关于微服务下的不同服务之间配置不能通用的问题

问题引入现有两个服务&#xff0c;一个是 A 服务&#xff0c;一个是 B 服务&#xff0c;并且这两个服务都需要使用 mysql。现 B 服务中引入了 A 服务的依赖&#xff0c;在 A 服务中添加了 mysql 的相关配置&#xff0c;那么这时就有一个问题&#xff1a;既然 B 已经引入了 A 的…

【机器学习项目 心脏病预测】

文章目录心脏病预测导入数据集数据集介绍理解数据数据处理机器学习K近邻分类器逻辑回归支持向量分类器&#xff08;SVC&#xff09;决策树分类器随机森林分类器结论心脏病预测 在这个机器学习项目中&#xff0c;我们使用UCI心脏病数据集 UCI &#xff0c;并将使用机器学习方法…

【论文阅读 | arXiv 2025 | WaveMamba:面向RGB-红外目标检测的小波驱动Mamba融合方法】

论文阅读 | arXiv 2025 | WaveMamba&#xff1a;面向RGB-红外目标检测的小波驱动Mamba融合方法​​1&&2. 摘要&&引言3. 方法3.1. 预备知识3.2. WaveMamba3.3. WaveMamba融合块&#xff08;WMFB&#xff09;3.3.1. 低频Mamba融合块&#xff08;LMFB&#xff09;…

DevExpress发布PowerPoint Presentation API库,支持跨平台与 PDF 导出

DevExpress专注于为 .NET、JavaScript、VCL 等多种平台提供高性能 UI 控件、报表工具、数据可视化组件及开发框架&#xff0c;产品覆盖桌面、Web、移动及跨平台应用开发领域。凭借稳定的性能、丰富的功能与优质的技术支持&#xff0c;DevExpress 的解决方案已广泛应用于金融、制…

Vue3使用 DAG 图(AntV X6)

参考文档 AntV X6 文档 可自定义设置以下属性 容器宽度&#xff08;width&#xff09;&#xff0c;类型&#xff1a;number | string&#xff0c;默认 ‘100%’容器高度&#xff08;height&#xff09;&#xff0c;类型&#xff1a;number | string&#xff0c;默认 ‘100%’…

【数据结构】跳表的概率模型详解与其 C 代码实现

文章目录介绍关键组成部分读者可以比对这张图片去理解跳表 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c5704b6276a14c3f9facdc3e55015bcc.jpeg#pic_center) 核心操作原理算法的概率模型跳表的 C代码实现初始化跳跃表的节点、跳跃表本身跳表插入节点查找元素更新…