您的位置:首页 > 科技 > IT业 > 千图网免费素材图库电脑版_网站设计知名企业_seo竞价推广_百度推广广告公司

千图网免费素材图库电脑版_网站设计知名企业_seo竞价推广_百度推广广告公司

2025/3/7 2:01:00 来源:https://blog.csdn.net/ningmengbaby/article/details/144996675  浏览:    关键词:千图网免费素材图库电脑版_网站设计知名企业_seo竞价推广_百度推广广告公司
千图网免费素材图库电脑版_网站设计知名企业_seo竞价推广_百度推广广告公司

事务隔离级别

  1. 读未提交(Read Uncommitted)

    • 定义:这是最低的隔离级别。在这个级别下,一个事务可以读取另一个未提交事务的数据。例如,事务 A 正在修改数据但尚未提交,事务 B 就可以读取事务 A 修改后的数据。这种情况可能会导致脏读(Dirty Read)。
    • 脏读示例:假设有一个银行账户表,事务 A 将账户余额从 1000 元修改为 2000 元,但尚未提交。此时事务 B 读取该账户余额为 2000 元。如果事务 A 由于某种原因回滚,账户余额恢复为 1000 元,那么事务 B 读取到的 2000 元就是脏数据,这种现象就是脏读。
    • 适用场景:这种隔离级别一般很少在实际应用中使用,因为数据的一致性很难保证。不过在某些对数据实时性要求极高,且允许一定程度的数据不一致的场景下,如某些实时数据统计系统,可能会考虑使用。
  2. 读已提交(Read Committed)

    • 定义:一个事务只能读取另一个已经提交事务的数据。这避免了脏读的问题。在这个隔离级别下,事务每次读取数据时都会获取最新的已提交数据。
    • 示例:沿用银行账户的例子,事务 A 提交了将账户余额从 1000 元修改为 2000 元的操作后,事务 B 才能读取到余额为 2000 元的数据。
    • 不可重复读问题:但是,读已提交隔离级别可能会出现不可重复读(Non - Repeatable Read)的情况。例如,事务 B 在两次读取同一账户余额时,第一次读取余额为 2000 元,在这期间事务 A 修改并提交了余额为 3000 元的操作,事务 B 再次读取时余额变为 3000 元,两次读取结果不同,这就是不可重复读。
    • 适用场景:适用于大多数对数据准确性要求较高,但对数据读取一致性要求不是特别严格的场景,如一些普通的查询系统或者网页应用的后台数据查询部分。
  3. 可重复读(Repeatable Read)

    • 定义:在这个隔离级别下,一个事务在执行期间多次读取同一数据时,结果是一致的,即使其他事务对该数据进行了修改并提交。MySQL 的 InnoDB 存储引擎默认的隔离级别就是可重复读。
    • 示例:事务 B 在读取账户余额为 2000 元后,在事务 B 结束之前,无论其他事务如何修改并提交账户余额,事务 B 再次读取账户余额时仍然是 2000 元。
    • 幻读问题:不过,可重复读隔离级别可能会出现幻读(Phantom Read)的情况。例如,事务 B 在查询所有账户余额大于 1000 元的账户列表时,得到了一个结果集。在事务 B 执行期间,事务 A 插入了一个新的账户余额大于 1000 元的账户并提交。当事务 B 再次查询时,会发现多了一个账户,就好像出现了 “幻影” 一样,这就是幻读。
    • 适用场景:适用于对数据一致性和准确性要求非常高的场景,如金融交易系统、订单处理系统等,在这些系统中,需要保证在一个事务过程中数据的稳定性。
  4. 可串行化(Serializable)

    • 定义:这是最高的隔离级别。在这个级别下,事务串行化执行,即多个事务依次执行,不会出现并发冲突。这完全避免了脏读、不可重复读和幻读的问题。
    • 示例:所有事务就像在单线程环境下一样,一个接一个地执行,不会出现多个事务同时操作同一数据的情况。
    • 性能问题:不过,可串行化隔离级别会导致系统性能大幅下降,因为它完全牺牲了并发性能。例如,在高并发的数据库应用场景中,如果采用可串行化隔离级别,数据库的吞吐量会显著降低。
    • 适用场景:适用于对数据一致性要求极高,并且并发访问量较小的场景,如一些对数据准确性要求极高的小型系统或者数据维护操作。 

事务实现原理

  1. 事务的基本概念与 ACID 特性

    • 事务是一组数据库操作的逻辑单元,这些操作要么全部成功执行,要么全部不执行。事务具有 ACID 特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
    • 原子性:事务中的所有操作被视为一个不可分割的单元。例如,在银行转账事务中,从一个账户扣款和向另一个账户收款这两个操作必须同时成功或者同时失败。如果其中一个操作出错,整个事务就会回滚,就好像这个事务从未发生过一样。
    • 一致性:事务执行前后,数据库的完整性约束没有被破坏。比如在数据库中有一个账户余额不能为负数的约束,那么在转账事务执行后,账户余额依然要满足这个约束。
    • 隔离性:多个事务并发执行时,一个事务的执行不能被其他事务干扰。不同的隔离级别决定了事务之间相互影响的程度,如前面提到的读未提交、读已提交、可重复读和可串行化等隔离级别。
    • 持久性:一旦事务提交,它对数据库的修改就应该是永久性的。即使数据库系统出现故障,比如服务器突然断电,已经提交的事务数据也应该能够恢复。
  2. 事务的实现机制 - 日志(Redo Log 和 Undo Log)

    • Redo Log(重做日志)
      • 作用:用于在系统崩溃后恢复已提交的事务修改。当事务对数据库进行修改操作(如插入、更新、删除)时,这些修改操作会先记录在 Redo Log 缓冲中,然后按照一定的策略写入 Redo Log 文件。例如,当执行一个插入语句插入一条记录到表中时,插入操作的相关信息会先记录在 Redo Log 中。
      • 工作原理:在数据库正常运行时,事务提交后,Redo Log 中的记录用于保证数据的持久性。如果系统崩溃,在数据库重启后,会根据 Redo Log 中的记录重新执行已经提交的事务修改,从而将数据库恢复到崩溃前的状态。这就好比记录了一系列操作步骤的清单,系统崩溃后可以按照清单重新执行操作来恢复数据。
    • Undo Log(回滚日志)
      • 作用:用于撤销未完成事务的修改,保证事务的原子性。当事务开始执行时,数据库会为这个事务生成相应的 Undo Log。例如,事务在修改数据前,会先将原数据的副本记录在 Undo Log 中。
      • 工作原理:如果事务在执行过程中需要回滚,比如遇到错误或者执行了 ROLLBACK 语句,就可以根据 Undo Log 中的记录将数据恢复到事务开始之前的状态。这就像是给数据拍了一张 “快照”,如果事务出错,就可以根据这张 “快照” 把数据还原回去。
  3. 事务的并发控制 - 锁机制

    • 共享锁(S Lock)和排他锁(X Lock)
      • 共享锁:用于对数据进行读取操作。多个事务可以同时对同一数据加共享锁,因为读取操作一般不会相互冲突。例如,多个事务同时查询一个账户余额时,可以同时对账户余额数据加共享锁。
      • 排他锁:用于对数据进行写操作。当一个事务对数据加排他锁后,其他事务既不能对该数据加共享锁也不能加排他锁,直到持有排他锁的事务释放锁为止。比如,当一个事务在修改账户余额时,会对账户余额数据加排他锁,防止其他事务同时修改或读取该数据。
    • 锁的粒度与性能
      • 锁可以在不同的粒度上应用,如行级锁、表级锁等。行级锁只锁定表中的某一行数据,表级锁则锁定整个表。行级锁的并发性能更好,因为它允许不同事务同时操作同一表中的不同行数据。但是,行级锁的管理开销相对较大。表级锁管理开销小,但并发性能差,因为一个事务锁定整个表后,其他事务就不能对该表进行任何操作了。MySQL 的 InnoDB 存储引擎默认使用行级锁,但在某些情况下也会升级为表级锁,比如在事务对表中的大量行进行锁定操作时。
  4. 事务的启动与提交 / 回滚过程

    • 事务启动:在 MySQL 中,可以通过显式的语句(如START TRANSACTION)或者隐式的方式(如某些数据库引擎在执行某些特定的 SQL 语句,如INSERTUPDATEDELETE时自动开启一个事务)来启动一个事务。
    • 事务提交:当事务中的所有操作都成功执行,并且满足事务的完整性约束后,可以使用COMMIT语句来提交事务。提交事务后,Redo Log 中的记录会确保数据的持久性,并且释放事务中持有的锁。
    • 事务回滚:如果在事务执行过程中出现错误或者需要撤销事务的操作,可以使用ROLLBACK语句来回滚事务。回滚时,会根据 Undo Log 中的记录将数据恢复到事务开始之前的状态,并释放事务中持有的锁。

Undolog和Redolog 写入的区别 

  1. 写入目的不同

    • Redo Log(重做日志)
      • 写入目的主要是为了保证事务的持久性。当事务提交后,即使数据库系统发生故障(如服务器断电、软件崩溃等),通过 Redo Log 中的记录能够将已提交事务对数据库所做的修改重新执行,从而使数据库恢复到事务提交后的状态。例如,一个事务成功更新了用户表中的用户年龄信息,Redo Log 会记录这个更新操作,确保这个更新操作在系统故障后可以被重做。
    • Undo Log(回滚日志)
      • 主要用于保证事务的原子性。它记录了事务在修改数据之前的数据状态,以便在事务需要回滚时,能够撤销已经执行的操作,将数据恢复到事务开始之前的状态。比如,事务在执行插入操作之前,会把插入位置的原有数据状态记录在 Undo Log 中,当事务回滚时,就可以根据这些记录把数据恢复如初。
  2. 写入时机不同

    • Redo Log
      • 在事务执行过程中,对数据库的修改操作(如插入、更新、删除)会先记录在 Redo Log 缓冲中。这些缓冲中的记录会在一定条件下(如缓冲满了、事务提交等)按照一定的顺序写入 Redo Log 文件。一般来说,为了提高性能,Redo Log 采用的是一种预写式日志(Write - Ahead Logging,WAL)的方式,即先写日志,再修改数据。例如,当执行一个更新语句时,首先将更新操作记录到 Redo Log 缓冲,然后才对数据库中的数据进行实际更新。
    • Undo Log
      • 通常在事务开始修改数据之前就会开始记录相关的回滚信息。当事务执行一个修改操作时,数据库会先生成对应的 Undo Log 记录,然后再进行实际的数据修改。例如,在执行删除操作时,会先将被删除的数据备份到 Undo Log 中,然后再从数据库中删除该数据。
  3. 内容记录方式不同

    • Redo Log
      • 记录的是事务对数据库进行的修改操作本身。这些记录包含足够的信息来重新执行修改操作,如操作类型(插入、更新、删除)、操作的数据对象(表名、行标识等)以及新的数据值(对于更新操作)等。例如,对于一个更新用户年龄的操作,Redo Log 可能会记录类似 “更新用户表中用户 ID 为 123 的年龄为 30 岁” 这样的信息。
    • Undo Log
      • 记录的是数据修改之前的原始状态。对于插入操作,记录的是插入位置的原有数据;对于更新操作,记录的是更新前的数据值;对于删除操作,记录的是被删除的数据本身。例如,对于更新用户年龄的操作,Undo Log 会记录 “用户 ID 为 123 的年龄原来是 20 岁” 这样的信息。
  4. 与事务提交的关系不同

    • Redo Log
      • 事务提交后,Redo Log 中的记录会在后续的恢复过程中起到关键作用,用于保证数据的持久性。如果事务没有提交,Redo Log 缓冲中的记录可能会因为事务回滚而被丢弃(具体情况取决于数据库的实现)。
    • Undo Log
      • 事务提交后,Undo Log 中的记录并不会立即删除。因为在某些情况下(如数据库使用了多版本并发控制,MVCC),这些记录可能仍然用于支持并发事务的读取操作。只有当确定这些记录不再需要时(如所有可能需要读取旧版本数据的事务都结束了),才会清除 Undo Log 中的相应记录。如果事务回滚,Undo Log 中的记录会被用来将数据恢复到事务开始之前的状态。

Redo Log和Undo Log是如何配合工作的?

  1. 事务执行阶段的配合

    • 数据修改前的准备
      • 当事务开始对数据进行修改时,首先会生成 Undo Log。例如,在一个更新操作中,数据库会将被更新数据的原始值记录到 Undo Log 中。这就像是在修改数据之前先拍一张 “快照”,以便后续需要时能够恢复原始状态。假设要将表中某用户的年龄从 20 岁更新为 30 岁,此时会把年龄为 20 岁这个原始值记录到 Undo Log 中。
    • 数据修改与 Redo Log 记录
      • 在记录 Undo Log 之后,事务对数据的实际修改操作会被记录到 Redo Log 中。Redo Log 记录的是如何将数据修改到新状态的操作信息。对于上述更新用户年龄的例子,Redo Log 会记录更新操作的详细信息,如更新的表、行标识以及新的年龄值 30 岁等内容,以便在系统故障后能够重做这个更新操作。
    • 保证原子性和持久性的协同操作
      • 通过这种方式,Undo Log 和 Redo Log 协同保证了事务的原子性和持久性。原子性通过 Undo Log 实现,因为如果事务需要回滚,可以利用 Undo Log 中的原始数据来撤销已经执行的修改操作。持久性通过 Redo Log 实现,一旦事务提交,即使系统出现故障,也可以根据 Redo Log 中的记录重新执行修改操作,确保数据的修改被持久化。
  2. 事务回滚阶段的配合

    • 利用 Undo Log 回滚操作
      • 当事务需要回滚时,例如因为遇到错误或者执行了 ROLLBACK 语句,系统会根据 Undo Log 中的记录来撤销事务对数据所做的修改。按照之前记录的原始数据,将数据恢复到事务开始之前的状态。以之前更新用户年龄的例子来说,如果事务回滚,就会将用户年龄从 30 岁恢复为 20 岁,这个恢复操作是依据 Undo Log 中的记录进行的。
    • Redo Log 在回滚过程中的处理
      • 在回滚过程中,Redo Log 中与该回滚事务相关的未提交部分可能会被清理或者标记。因为回滚操作意味着这个事务对数据的修改不应该被持久化,所以相应的 Redo Log 记录如果还没有用于其他目的(如支持其他事务的持久性恢复),就可以进行清理,以保持日志文件的一致性。
  3. 事务提交后的配合

    • Redo Log 保证持久性
      • 事务提交后,Redo Log 的作用变得更加关键。它会确保事务对数据的修改能够持久化。在提交过程中,数据库会将 Redo Log 缓冲中的记录写入磁盘上的 Redo Log 文件(可能通过一系列的刷盘操作),使得这些修改操作在系统故障后能够被重新执行。例如,在一个高并发的数据库系统中,当多个事务同时提交时,数据库会按照一定的策略将它们的 Redo Log 记录安全地写入磁盘。
    • Undo Log 的后续处理
      • 对于 Undo Log,在事务提交后并不会立即删除。因为在一些情况下,如数据库采用多版本并发控制(MVCC)技术时,Undo Log 中的记录可能还需要用于支持其他事务的读取操作。这些事务可能需要读取在这个事务提交之前的数据版本,此时 Undo Log 中的记录就可以提供相应的数据。只有当确定这些记录不再需要时,才会清理 Undo Log 中的相应记录。例如,在一个长时间运行的事务读取历史数据版本时,数据库会利用 Undo Log 来提供这些数据,直到所有可能需要这些历史数据的事务都结束后,才会清除相关的 Undo Log 记录。

Redolog与Binlog是如何保证一致的 

  1. Redo Log 和 Binlog 的基本概念与作用

    • Redo Log:主要用于在数据库系统崩溃后恢复已提交事务的修改,保证事务的持久性。它记录的是对数据库数据页的物理修改操作,采用预写式日志(WAL)的方式,即先写日志再修改数据。例如,在更新数据库表中的某条记录时,Redo Log 会记录如何将这条记录更新到新状态的物理操作信息。
    • Binlog:用于数据库的备份和恢复、主从复制等功能。它记录的是数据库的逻辑操作,例如 SQL 语句的形式。比如,对于上述的记录更新操作,Binlog 可能会记录一条类似 “UPDATE table_name SET column_name = new_value WHERE condition” 的 SQL 语句。
  2. 两阶段提交(2PC)机制保证一致性

    • 准备阶段(Prepare)
      • 当事务开始提交时,首先进入准备阶段。在这个阶段,InnoDB 存储引擎(以 MySQL 的 InnoDB 为例)会将 Redo Log 的事务记录从内存缓冲区写入磁盘的 Redo Log 文件,但此时这些记录还处于 “prepare” 状态,事务尚未真正提交。同时,会生成 Binlog 记录,将这个事务的逻辑操作(如 SQL 语句)写入 Binlog 文件缓冲区。
      • 这一步的关键在于,Redo Log 和 Binlog 的写入操作是在一个原子操作单元内进行的,保证了这两个日志对于这个事务的记录要么都成功,要么都失败。如果在这个阶段出现故障,例如写入 Binlog 时失败,那么整个事务可以通过回滚机制(利用 Redo Log 中的信息)来撤销之前的操作。
    • 提交阶段(Commit)
      • 如果在准备阶段,Redo Log 和 Binlog 的记录都成功写入各自的缓冲区,那么事务进入提交阶段。在这个阶段,InnoDB 存储引擎会将 Redo Log 文件中这个事务的记录状态从 “prepare” 修改为 “commit”,标志着这个事务真正提交。此时,事务对数据库的修改就可以通过 Redo Log 来保证持久性,并且 Binlog 中的记录也完整地记录了这个事务的逻辑操作,用于备份、恢复和主从复制等功能。
      • 这个两阶段提交机制确保了 Redo Log 和 Binlog 在事务提交过程中的一致性。因为只有当两个日志都成功记录了事务的相关信息后,事务才会被真正提交,避免了因日志不一致而导致的数据问题。
  3. 崩溃恢复过程中的一致性处理

    • 检查 Redo Log 和 Binlog 状态
      • 当数据库系统崩溃后重新启动时,会检查 Redo Log 和 Binlog 的状态来恢复数据并保证一致性。首先会查看 Redo Log 中的事务记录,对于那些处于 “prepare” 状态的事务记录,会检查 Binlog 中是否有对应的完整事务记录。
    • 根据检查结果处理事务
      • 如果 Binlog 中有对应的完整事务记录,说明这个事务在崩溃前已经成功完成了两阶段提交的准备阶段,只是还没来得及将 Redo Log 中的记录状态修改为 “commit”。此时,会将这些事务在 Redo Log 中的记录状态修改为 “commit”,并根据 Redo Log 中的记录来恢复事务对数据库的修改,从而保证数据的一致性和事务的持久性。
      • 如果 Binlog 中没有对应的完整事务记录,说明这个事务在两阶段提交过程中出现了问题,可能是 Binlog 写入失败等情况。此时,会根据 Redo Log 中的信息将这些事务回滚,撤销它们对数据库的修改,同样保证了数据的一致性。

Redo Log和Binlog在两阶段提交中的具体作用是什么?

  1. Redo Log 在两阶段提交中的作用

    • 第一阶段(Prepare):数据持久性的初步保障

      • 当事务进入提交流程的第一阶段时,Redo Log 会将事务相关的修改操作从内存缓冲区写入磁盘文件,但此时这些记录处于 “prepare” 状态。这一步是基于预写式日志(WAL)原则,其核心作用是为事务修改的数据提供初步的持久性保障。
      • 例如,在更新数据库中某条记录的事务中,Redo Log 会记录更新操作对应的物理信息,如数据页的修改位置和新的数据值等。这样,即使在后续的提交过程中出现故障,这些已经写入磁盘的 “prepare” 状态的 Redo Log 记录可以用于恢复事务的修改操作,确保数据不会丢失。
    • 第二阶段(Commit):最终确认事务的持久性

      • 在两阶段提交的第二阶段,如果事务能够顺利进行到这一步,Redo Log 中该事务记录的状态会从 “prepare” 修改为 “commit”。这一操作标志着事务对数据库的修改被最终确认,使得这些修改能够真正持久化到数据库中。
      • 系统故障恢复时,数据库可以根据 Redo Log 中处于 “commit” 状态的记录来重演事务的修改操作,将数据库恢复到事务提交后的状态,从而保证了事务的持久性这一关键特性。
  2. Binlog 在两阶段提交中的作用

    • 第一阶段(Prepare):记录事务的逻辑操作

      • 在第一阶段,Binlog 与 Redo Log 几乎同时开始记录。Binlog 记录的是事务的逻辑操作,通常以 SQL 语句的形式呈现。例如,对于插入、更新或删除操作,Binlog 会分别记录对应的 INSERT、UPDATE 或 DELETE 语句及其相关参数。
      • 这些逻辑操作记录的重要性在于,它们为数据库的逻辑恢复、主从复制等功能提供了基础。在主从复制场景中,从库需要根据主库的 Binlog 来重现事务的逻辑操作,以保持与主库数据的一致性。
    • 第二阶段(Commit):支持数据备份、恢复和复制等功能的持久化记录

      • 在第二阶段,虽然 Binlog 的写入动作在第一阶段已经开始(写入缓冲区),但此时它的作用更加凸显。如果 Binlog 记录成功从缓冲区刷盘到磁盘文件,那么这些记录就成为了数据库备份、恢复以及主从复制等操作的可靠依据。
      • 例如,在数据恢复过程中,可以通过回放 Binlog 中的逻辑操作来重建数据库状态;在主从复制环境下,从库通过读取主库的 Binlog 来执行相同的逻辑操作,从而实现数据的同步复制。Binlog 的存在确保了数据库在不同层次的操作(如备份、复制等)能够按照事务的逻辑顺序正确执行,维护了数据的一致性和完整性。
  3. Redo Log 和 Binlog 协同作用

    • 通过两阶段提交机制,Redo Log 和 Binlog 相互配合,共同保证了事务的原子性、一致性和持久性。在第一阶段同时记录两种日志,确保事务的物理修改和逻辑操作都有记录;在第二阶段,通过对 Redo Log 状态的更新和 Binlog 的持久化(如果需要),使得事务在数据库内部的修改和在外部功能(如复制、备份)所需的逻辑操作都能正确完成,避免了数据不一致和丢失的风险。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com