百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

分布式之系统底层原理(上)(底层分布式技术)

mhr18 2025-06-23 20:39 5 浏览 0 评论

作者:allanpan,腾讯 IEG 高级后台工程师

导言

分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务以及分布式系统最核心的底层原理逐一进行剖析,内容包括但不限于 BASE 原则两阶段原子提交协议三阶段原子提交协议Paxos/Multi-Paxos 分布式共识算法的原理与证明Raft 分布式共识算法分布式事务的并发控制等内容。

事务

事务是访问并可能更新各种数据项的一个程序执行单元(unit)。事务由一个或多个步骤组成,一般使用形如 begin transactionend transaction 语句或者函数调用作为事务界限,事务内的所有步骤必须作为一个单一的、不可分割的单元去执行,因此事务的结果只有两种:1. 全部步骤都执行完成,2. 任一步骤执行失败则整个事务回滚。

事务最早由数据库管理系统(database management systemDBMS)引入并实现,数据库事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。数据库事务严格遵循 ACID 原则,属于刚性事务,一开始数据库事务仅限于对单一数据库资源对象的访问控制,这一类事务称之为本地事务 (Local Transaction),后来随着分布式系统的出现,数据的存储也不可避免地走向了分布式,分布式事务(Distributed Transaction)便应运而生。

刚性事务

刚性事务(如单一数据库事务)完全遵循 ACID 规范,即数据库事务的四大基本特性:

  • Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。
  • Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。
  • Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。
  • Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
  • 刚性事务也能够以分布式 CAP 理论中的 CP 事务来作为定义

    柔性事务

    在电商领域等互联网场景下,传统的事务在数据库性能和处理能力上都遇到了瓶颈。因此,柔性事务被提了出来,柔性事务基于分布式 CAP 理论以及延伸出来的 BASE 理论,相较于数据库事务这一类完全遵循 ACID 的刚性事务来说,柔性事务保证的是 “基本可用,最终一致”,CAP 原理相信大家都很熟悉了,这里我们讲一下 BASE 原则:

  • 基本可用(Basically Available):系统能够基本运行、一直提供服务。
  • 软状态(Soft-state):系统不要求一直保持强一致状态。
  • 最终一致性(Eventual consistency):系统需要在某一时刻后达到一致性要求。
  • 柔性事务(如分布式事务)为了满足可用性、性能与降级服务的需要,降低一致性(Consistency)与隔离性(Isolation)的要求,遵循 BASE 理论,传统的 ACID 事务对隔离性的要求非常高,在事务执行过程中,必须将所有的资源对象锁定,因此对并发事务的执行极度不友好,柔性事务(比如分布式事务)的理念则是将锁资源对象操作从本地资源对象层面上移至业务逻辑层面,再通过放宽对强一致性要求,以换取系统吞吐量的提升。

    此外,虽然柔性事务遵循的是 BASE 理论,但是还需要遵循部分 ACID 规范:

  • 原子性:严格遵循。
  • 一致性:事务完成后的一致性严格遵循;事务中的一致性可适当放宽。
  • 隔离性:并行事务间不可影响;事务中间结果可见性允许安全放宽。
  • 持久性:严格遵循。
  • 本地事务

    本地事务(Local Transaction)指的是仅仅对单一节点/数据库资源对象进行访问/更新的事务,在这种事务模式下,BASE 理论派不上用场,事务完全遵循 ACID 规范,确保事务为刚性事务。

    分布式事务

    在分布式架构成为主流的当下,系统对资源对象的访问不能还局限于单节点,多服务器、多节点的资源对象访问成为刚需,因此,本地事务无法满足分布式架构的系统的要求,分布式事务应运而生。

    访问/更新由多个服务器管理的资源对象的平面事务或者嵌套事务称之为分布式事务(Distributed Transaction),分布式事务是相对于本地事务来说的。

    平面事务:单一事务,访问多个服务器节点的资源对象,一个平面事务完成一次请求之后才能发起下一个请求。

    嵌套事务:多事务组成,顶层事务可以不断创建子事务,子事务又可以进一步地以任意深度嵌套子事务。

    对于分布式事务来说,有两个最核心的问题:

    1. 如何管理分布式事务的提交/放弃决定?如果事务中的一个节点在执行自己的本地事务过程中遇到错误,希望放弃整个分布式事务,与此同时其他节点则在事务执行过程中一切顺利,希望提交这个分布式事务,此时我们应该如何做决策?
    2. 如何保证并发事务在涉及多个节点上资源对象访问的可串行性(规避分布式死锁)?如果事务 T 对某一个服务器节点上的资源对象 S 的并发访问在事务 U 之前,那么我们需要保证在所有服务器节点上对 S 和其他资源对象的冲突访问,T 始终在 U 之前。

    问题 1 的解决需要引入一类分布式原子提交协议的算法如两阶段提交协议等,来对分布式事务过程中的提交或放弃决策进行管理,并确保分布式提交的原子性。而问题 2 则由分布式事务的并发控制机制来处理。

    原子提交协议

    原子性是分布式事务的前置性约束,没有原子性则分布式事务毫无意义。

    原子性约束要求在分布式事务结束之时,它的所有操作要么全部执行,要么全部不执行。以分布式事务的原子性来分析,客户端请求访问/更新多个服务器节点上的资源对象,在客户端提交或放弃该事务从而结束事务之后,多个服务器节点的最终状态要么是该事务里的所有步骤都执行成功之后的状态,要么恢复到事务开始前的状态,不存在中间状态。满足这种约束的分布式事务协议则称之为原子提交协议。

    当一个分布式事务结束时,事务的原子特性要求所有参与该事务的服务器节点必须全部提交或者全部放弃该事务,为了实现这一点,必须引入一个协调者(Coordinator)的角色,从参与事务的所有服务器节点中挑选一个作为协调者,由它来保证在所有服务器节点上最终获得同样的结果。协调者的工作原理取决于分布式事务选用的协议。

    一般来说,分布式事务中包含的两个最基础的角色就是:

  • Coordinator -- 协调者
  • Participants -- 参与者
  • 单阶段原子提交协议

    单阶段原子提交协议(one-phase atomic commit protocol, 1APC)是最简单的一种原子提交协议,它通过设置一个协调者并让它不断地向所有参与者发送提交(commit)或放弃(abort)事务的请求,直到所有参与者确认已执行完相应的操作。

    1APC 协议的优点是简单易用,对一些事务不复杂的场景比较合适,但在复杂事务场景则显得捉襟见肘,因为该协议不允许任何服务器节点单方面放弃事务,事务的放弃必须由协调者来发起,这个设计会导致很多问题:首先因为只有一次通信,协调者并不会收集所有参与者的本地事务执行的情况,所以协调者决定提交还是放弃事务只基于自己的判断,在参与者执行事务期间可能会遇到错误从而导致最终事务未能真正提交,错误一般与事务的并发控制有关,比如事务执行期间对资源对象加锁,遇到死锁,需要放弃事务从而解开死锁,而协调者并不知道,因此在发起下一个请求之前,客户端完全不知道事务已被放弃。另一种情况就是利用乐观并发控制机制访问资源对象,某一个服务器节点的验证失败将导致事务被放弃,而协调者完全不知情。

    两阶段提交协议

    定义

    两阶段提交协议(two-phase commit protocol, 2PC)的设计初衷是为了解决 1APC 不允许任意一个服务器节点自行放弃它自己的那部分本地事务的痛点,2PC 允许任何一个参与者自行决定要不要放弃它的本地事务,而由于原子提交协议的约束,任意一个本地事务被放弃将导致整个分布式事务也必须放弃掉。

    两阶段提交协议基于以下几个假设:

  • 存在一个节点作为协调者(Coordinator),分布式事务通常由协调者发起(当然也可以由参与者发起),其余节点作为参与者(Participants),且节点之间可以自由地进行网络通信,协调者负责启动两阶段提交流程以及决定事务最终是被提交还是放弃。
  • 每个节点会记录该节点上的本地操作日志(op logs),日志必须持久化在可靠的存储设备上(比如磁盘),以便在节点重启之后需要恢复操作日志。另外,不记录全局操作日志。
  • 所有节点不能发生永久性损坏,也就是说节点就算是损坏了也必须能通过可靠性存储恢复如初,不允许出现数据永久丢失的情况。
  • 参与者对协调者的回复必须要去除掉那些受损和重复的消息。
  • 整个集群不会出现拜占庭故障(Byzantine Fault)-- 服务器要么崩溃,要么服从其发送的消息。
  • 原理

    两阶段提交协议,顾名思义整个过程需要分为两个阶段:

    1. 准备阶段(Prepare Phase)
    2. 提交阶段(Commit Phase)

    在进行两阶段提交的过程中,协调者会在以下四种状态间流转:

    1. init
    2. preparing
    3. committed
    4. aborted

    而参与者则会在以下三种状态间流转:

    1. working
    2. prepared
    3. committed

    阶段 I(投票表决阶段)

    1. 任意一个参与者发起分布式事务 T 并执行本地事务成功,接着将一条 <ready T> 记录追加到本地日志 buffer 中并 flush 到可靠性存储设备如磁盘上,从 working 状态进入 prepared 状态,然后向协调者发送 prepare T 消息;
    2. 收到参与者发来的 prepare T 消息后,协调者将一条 <prepare T> 记录追加到日志中,然后从 init 状态进入 preparing 状态,紧接着向分布式事务的其他参与者发出 canCommit? 消息,发起事务表决过程;
    3. 当参与者收到 canCommit? 请求后,除了发起事务的那一个之外,其他还在working 状态的参与者会先尝试执行本地事务,如果本地事务执行成功,则会往本地日志 buffer 写入一条 <ready T> 记录并 flush 到可靠性存储中,但不提交事务,进入 prepared 状态,然后回复一条 ready T 消息对此事务投 YES 票;如果本地事务执行失败,则参与者会往本地日志 buffer 写入一条 <don't commit T> 记录并 flush 到可靠性存储中,然后回复一条 don't commit T 消息投 NO 票。

    阶段 II(收集投票结果完成事务)

    1. 协调者收集所有的投票(包括它自己的投票);(a) 如果所有的投票都是 ready T,则表示没有故障发生,那么协调者决定提交该事务,首先它会在其本地日志中追加一条 <commit T> 记录,从 preparing 状态进入committed 状态,然后向所有的参与者发送 doCommit 请求消息,要求参与者提交它们的本地事务;(b) 如果有任一个投票是 No,则协调者决定放弃掉该事务,首先它会往本地日志中追加一条记录,从 preparing 状态进入 aborted 状态,然后发送 doAbort 请求消息给所有的参与者,通知它们回滚各自的本地事务。
    2. 投了 YES 票的参与者阻塞等待协调者给它发来 doCommitdoAbort 消息,如果接收到的是 doCommit 消息则提交本地事务并在此过程中记录日志 <commit T>,然后进入 committed 状态,最后回复一个 haveCommitted 的消息通知协调者本地事务已经成功提交;反之,如果收到的是 doAbort 消息则回滚本地事务并写入日志<abort T>,然后进入 aborted状态。

    上面的过程是一种更通用的流程,即由任意的参与者发起一个分布式事务,而在实践中一般把分布式事务的发起交给协调者来做,减少事务发起者确认该事务已被提交所需等待的网络消息延迟:

    性能

    网络 I/O 开销

    假设两阶段提交过程一切运行正常,即协调者和参与者都不出现崩溃和重启,网络通信也都正常。那么假设有一个协调者和 N 个参与者,两阶段提交过程中将会发送如下的消息:

  • 任意一个参与者从 working 状态进入 prepared 状态并发送 Prepared 消息给协调者,1 条消息。
  • 协调者收到消息后,向其他参与者发送 canCommit? 请求消息,N - 1 条消息。
  • 收到 canCommit? 消息的参与者各自回复协调者投票消息,N - 1 条消息。
  • 协调者统计投票情况之后,发送 doCommit 消息给其他参与者,N 条消息。
  • 所以,事务发起者在经过 4 条网络消息延迟之后确认该分布式事务已被提交,而整个过程共计发送 3N - 1 条网络消息(因为 haveCommitted 在 2PC 仅仅是用于最后通知协调者而已,属于可有可无的一次网络消息,2PC 在该消息缺省的情况下也能正常运行,因此 haveCommitted 一般不计入网络延迟成本中)。

    前面我们提到,在实践中一般是由协调者来发起事务,如果考虑这种情况的话,事务发起者 -- 协调者在经过 3 条网络消息延迟之后确认该分布式事务已经被提交,而整个过程实际发送的网络消息则变成 3N 条。

    总而言之,两阶段提交协议的网络通信开销和集群节点的数量成 3 倍正比。

    本地存储设备 I/O 开销

    基于前文中叙述的两阶段提交协议的基本假设之一:每个节点会通过日志来记录在本地执行的操作,以便在节点发生故障并重启节点之后能利用日志恢复到故障前的状态,因此两阶段提交过程中除了网络 I/O 的开销之外,还有本地存储设备 I/O 的开销:

  • 发起事务的参与者执行本地事务,1 次写操作。
  • 其余参与者执行各自的本地事务,N - 1 次写操作。
  • 协调者统计投票结果并决定提交事务,1 次写操作。
  • 所以事务发起者在经过 3 次本地存储设备 I/O 延迟之后确认该事务已被提交,整个过程总计有 N + 1 次本地存储设备 I/O,而如果由协调者来发起事务的话,则还是需要 N + 1 次本地存储设备 I/O,但是只需要经过 2 次本地存储设备 I/O 延迟即可确认事务已被提交。

    恢复

    在分布式事务中,所有的参与者节点都可能发生故障,所以我们需要保证在该故障节点恢复时发生的一切都和分布式事务 T 的全局决策保持一致。节点在恢复的时候会读取 T 的最后一个本地日志记录并作出相应的操作:

    1. 如果 T 的最后一条日志记录是 <commit T>,那么说明协调者在节点发生故障时的全局决策是提交 T,根据本地事务所使用的日志方式,在该节点上可能需要执行 redo T
    2. 如果 T 的最后一条日志记录是 <abort T>,那么说明协调者在节点发生故障时的全局决策是中止 T,根据本地事务所使用的日志方式,在该节点上可能需要执行 undo T
    3. 如果 T 的最后一条日志记录是 <don't commit T>,则和第 2 中情况类似,执行 undo T
    4. 如果 T 的最后一条日志记录是 <ready T>,这种情况比较麻烦,因为恢复节点无法确认在它故障之后协调者发出的最终全局决策是什么,因此它必须要和集群中其余至少一个节点取得联系,询问 T 的最终结果是什么:恢复节点先尝试询问协调者,如果此时协调者正在工作,则告知恢复节点 T 的最终结果,如果是提交就执行 redo T,中止就执行 undo T;如果协调者因故不在工作,则恢复节点可以要求其他某一个参与者节点去查看本地日志以找出 T 的最终结果并告知恢复节点。在最坏的情况下,恢复节点无法和集群中其他所有节点取得联系,这时恢复节点只能阻塞等待,直至得知 T 的最终结果是提交还是中止。
    5. 如果本地日志中没有记录任何关于 T 在两阶段提交过程中的操作,那么根据前面的两阶段提交流程可知恢复节点还没来得及回复协调者的 canCommit? 请求消息就发生了故障,因此根据两阶段算法,恢复节点只能执行 undo T

    缺陷

    1. 同步阻塞:两阶段提交协议是一个阻塞的协议,在第二阶段期间,参与者在事务未提交之前会一直锁定其占有的本地资源对象,直到接收到来自协调者的 doCommitdoAbort 消息。
    2. 单点故障:两阶段提交协议中只有一个协调者,而由于在第二阶段中参与者在收到协调者的进一步指示之前会一直锁住本地资源对象,如果唯一的协调者此时出现故障而崩溃掉之后,那么所有参与者都将无限期地阻塞下去,也就是一直锁住本地资源对象而导致其他进程无法使用。
    3. 数据不一致:如果在两阶段提交协议的第二阶段中,协调者向所有参与者发送 doCommit 消息之后,发生了局部网络抖动或者异常,抑或是协调者在只发送了部分消息之后就崩溃了,那么就只会有部分参与者接收到了 doCommit 消息并提交了本地事务;其他未收到 doCommit 消息的参与者则不会提交本地事务,因而导致了数据不一致问题。

    XA 标准接口

    2PC 两阶段提交协议本身只是一个通用协议,不提供具体的工程实现的规范和标准,在工程实践中为了统一标准,减少行业内不必要的对接成本,需要制定标准化的处理模型及接口标准,国际开放标准组织 Open Group 定义了分布式事务处理模型 DTP(Distributed Transaction Processing)Model,现在 XA 已经成为 2PC 分布式事务提交的事实标准,很多主流数据库如 Oracle、MySQL 等都已经实现 XA。

    两阶段事务提交采用的是 X/OPEN 组织所定义的 DTP Model 所抽象的 AP(应用程序), TM(事务管理器)和 RM(资源管理器) 概念来保证分布式事务的强一致性。 其中 TM 与 RM 间采用 XA 的协议进行双向通信。 与传统的本地事务相比,XA 事务增加了准备阶段,数据库除了被动接受提交指令外,还可以反向通知调用方事务是否可以被提交。 TM 可以收集所有分支事务的准备结果,并于最后进行原子提交,以保证事务的强一致性。

    Java 通过定义 JTA 接口实现了 XA 模型,JTA 接口中的 ResourceManager 需要数据库厂商提供 XA 驱动实现, TransactionManager 则需要事务管理器的厂商实现,传统的事务管理器需要同应用服务器绑定,因此使用的成本很高。 而嵌入式的事务管器可以以 jar 包的形式提供服务,同 Apache ShardingSphere 集成后,可保证分片后跨库事务强一致性。

    通常,只有使用了事务管理器厂商所提供的 XA 事务连接池,才能支持 XA 的事务。Apache ShardingSphere 在整合 XA 事务时,采用分离 XA 事务管理和连接池管理的方式,做到对应用程序的零侵入。

    三阶段提交协议

    由于前文提到的两阶段提交协议的种种弊端,研究者们后来又提出了一种新的分布式原子提交协议:三阶段提交协议(three-phase commit protocol, 3PC)。

    三阶段提交协议是对两阶段提交协议的扩展,它在特定假设下避免了同步阻塞的问题。该协议基于以下两个假设:

    1. 集群不发生网络分区;
    2. 故障节点数不超过 K 个(K 是预先设定的一个数值)。

    基于这两个假设,三阶段提交协议通过引入超时机制和一个额外的阶段来解决阻塞问题,三阶段提交协议把两阶段提交协议的第一个阶段拆分成了两步:1) 评估,2) 资源对象加锁,最后才真正提交:

    1. CanCommit 阶段:协调者发送 CanCommit 请求消息,询问各个参与者节点,参与者节点各自评估本地事务是否可以执行并回复消息(可以执行则回复 YES,否则回复 NO),此阶段不执行事务,只做判断;
    2. PreCommit 阶段:协调者根据上一阶段收集的反馈决定通知各个参与者节点执行(但不提交)或中止本地事务;有两种可能:1) 所有回复都是 YES,则发送 PreCommit请求消息,要求所有参与者执行事务并追加记录到 undo 和 redo 日志,如果事务执行成功则参与者回复 ACK 响应消息,并等待下一阶段的指令;2) 反馈消息中只要有一个 NO,或者等待超时之后协调者都没有收到参与者的回复,那么协调者会中止事务,发送 Abort 请求消息给所有参与者,参与者收到该请求后中止本地事务,或者参与者超时等待仍未收到协调者的消息,同样也中止当前本地事务。
    3. DoCommit 阶段:协调者根据上一阶段收集到的反馈决定通知各个参与者节点提交或回滚本地事务,分三种情况:1) 协调者收到全部参与者回复的 ACK,则向所有参与者节点广播 DoCommit 请求消息,各个参与者节点收到协调者的消息之后决定提交事务,然后释放资源对象上的锁,成功之后向协调者回复 ACK,协调者接收到所有参与者的 ACK 之后,将该分布式事务标记为 committed;2) 协调者没有收到全部参与者回复的 ACK(可能参与者回复的不是 ACK,也可能是消息丢失导致超时),那么协调者就会中止事务,首先向所有参与者节点广播 Abort 请求消息,各个参与者收到该消息后利用上一阶段的 undo 日志进行事务的回滚,释放占用的资源对象,然后回复协调者 ACK 消息,协调者收到参与者的 ACK 消息后将该分布式事务标记为 aborted;3) 参与者一直没有收到协调者的消息,等待超时之后会直接提交事务。

    事实上,在最后阶段,协调者不是通过追加本地日志的方式记录提交决定的,而是首先保证让至少 K 个参与者节点知道它决定提交该分布式事务。如果协调者发生故障了,那么剩下的参与者节点会重新选举一个新的协调者,这个新的协调者就可以在集群中不超过 K 个参与者节点故障的情况下学习到旧协调者之前是否已经决定要提交分布式事务,若是,则重新开始协议的第三阶段,否则就中止该事务,重新发起分布式事务。

    在最后的 DoCommit 阶段,如果参与者一直没有收到协调者的 DoCommit 或者Abort 请求消息时,会在等待超时之后,直接提交事务。这个决策机制是基于概率学的:当已经进入第三阶段之后,说明参与者在第二阶段已经收到了 PreCommit 请求消息,而协调者发出 PreCommit 请求的前提条件是它在第二阶段开头收集到的第一阶段向所有参与者发出的 CanCommit 请求消息的反馈消息都是 YES。所以参与者可以根据自己收到了 PreCommit 请求消息这一既定事实得出这样的一个结论:其他所有参与者都同意了进行这次的事务执行,因此当前的参与者节点有理由相信,进入第三阶段后,其他参与者节点的本地事务最后成功提交的概率很大,而自己迟迟没有收到 DoCommitAbort 消息可能仅仅是因为网络抖动或异常,因此直接提交自己的本地事务是一个比较合理的选择

    三阶段提交协议主要着重于解决两阶段提交协议中因为协调者单点故障而引发的同步阻塞问题,虽然相较于两阶段提交协议有所优化,但还是没解决可能发生的数据不一致问题,比如由于网络异常导致部分参与者节点没有收到协调者的 Abort 请求消息,超时之后这部分参与者会直接提交事务,从而导致集群中的数据不一致,另外三阶段提交协议也无法解决脑裂问题,同时也因为这个协议的网络开销问题,导致它并没有被广泛地使用,有关该协议的具体细节可以参阅本文最后的延伸阅读一节中的文献进一步了解,这里不再深入。

    明天发布的(下)篇将继续讲解Paxos/Multi-Paxos 分布式共识算法的原理与证明Raft 分布式共识算法分布式事务的并发控制等内容,敬请期待。

    相关推荐

    【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库

    如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...

    Pure Storage推出统一数据管理云平台及新闪存阵列

    PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...

    对Java学习的10条建议(对java课程的建议)

    不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...

    SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!

    官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...

    JDK21有没有什么稳定、简单又强势的特性?

    佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...

    「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了

    在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...

    Java面试题及答案最全总结(2025版)

    大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...

    数据库日常运维工作内容(数据库日常运维 工作内容)

    #数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...

    分布式之系统底层原理(上)(底层分布式技术)

    作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...

    oracle 死锁了怎么办?kill 进程 直接上干货

    1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...

    SpringBoot 各种分页查询方式详解(全网最全)

    一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...

    《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略

    《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...

    LoadRunner(loadrunner录制不到脚本)

    一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...

    Redis数据类型介绍(redis 数据类型)

    介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...

    RMAN备份监控及优化总结(rman备份原理)

    今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

    取消回复欢迎 发表评论: