MVCC

一、sql基本命令:

存储引擎:

1、查看系统支持的存储引擎

show engines;

2、查看表使用的存储引擎

a、show table status from db_name where name='table_name';

如果已经进入到一个数据库,可以使用 mysql> show table status like 'enterprise_stock_code' \G

b、show create table l_ability_base

(有人说用第二种方法不准确(http://guaniuzhijia.blog.163.com/blog/static/16547206920114129953533/)

如果关闭掉原先默认的Innodb引擎后根本无法执行show create table table_name指令,因为之前建的是Innodb表,关掉后默认用MyISAM引擎,导致Innodb表数据无法被正确读取。(没有测试))

3、修改表引擎方法

alter table table_name engine=innodb;

 

隔离级别:

1.查看当前会话隔离级别
select @@tx_isolation;
 
2.查看系统当前隔离级别
select @@global.tx_isolation;
 
3.设置当前会话隔离级别
set session transaction isolatin level repeatable read;
 
4.设置系统当前隔离级别
set global transaction isolation level repeatable read;

 

Mysql版本号:

select version();

 

二、MVCC是什么

MySql大多数『事务型存储引擎』的实现都不是简单的行级锁。基于提升并发性能的考虑,他们一般都同时实现了多版本并发控制(MVCC)

不仅是MySQL,包括Oracle, PostgreSQL等其他数据库系统也都实现了MVCC,但各自的实现机制不尽相同,因为MVCC没有一个统一的实现标准。
可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低虽然实现机制所有不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行

 

问题:什么是事务性存储引擎?还有什么其他类型的存储引擎?

有些存储引擎支持事务,比如InnoDB, 有些存储引擎不支持事务,比如MyIsam。当然还有其他的存储引擎


 

三、MVCC如何实现的

其实,MVCC是通过保存数据在某一时间点的快照来实现的。即,不管是否需要执行多长时间,同一个事务内看到的数据都是一致的。根据事务开始的时间不同,不通的事务对同一张表,同一时刻拿到的数据可能不一样。

MVCC只有在read commited和repeatable read的两个隔离级别下工作。read uncommitted总是读取最新的行数据,而不是符合当前事务版本的数据行。而serializable则会对所有读取的行都加锁。

 

3.1 undo log  

为了便于理解MVCC的实现原理,这里简单介绍一下undo log的工作过程

在不考虑redo log 的情况下利用undo log工作的简化过程为:

序号

动作

1开始事务
2记录数据行数据快照到undo log
3更新数据
4将undo log写到磁盘
5将数据写到磁盘
6提交事务

1)为了保证数据的持久性数据要在事务提交之前持久化,即2)

2)undo log的持久化必须在在数据持久化之前,这样才能保证系统崩溃时,可以用undo log来回滚事务

 

3.2、Innodb中的隐藏列

Innodb通过undo log保存了已更改行的旧版本的信息的快照。
InnoDB的内部实现中为每一行数据增加了三个隐藏列用于实现MVCC。

列名

长度(字节)

含义

作用

DB_TRX_ID6行的版本号插入或更新行的最后一个事务的事务标识符。(删除视为更新,将其标记为已删除)
DB_ROLL_PTR7行的删除版本号写入回滚段的撤消日志记录(若行已更新,则撤消日志记录包含在更新行之前重建行内容所需的信息)
DB_ROW_ID6 行标识(隐藏单调自增id)

结构

 

3.3 MVCC具体实现过程

(《高性能Mysql》的1.4节)

InnoDB的MVCC,是通过在每行纪录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间(DB_TRX_ID),一个保存了行的过期时间(DB_ROLL_PTR)(存储的并不是实际的时间值,而是系统版本号)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行纪录的版本号进行比较。在REPEATABLE READ隔离级别下,MVCC具体的操作如下:

 

SELECT
InnoDB会根据以下两个条件检查每行纪录:

  1. InnoDB只查找版本(DB_TRX_ID)早于当前事务版本的数据行(行的系统版本号<=事务的系统版本号,这样可以确保数据行要么是在开始之前已经存在了,要么是事务自身插入或修改过的)
  2. 行的删除版本号(DB_ROLL_PTR)要么未定义(未更新过),要么大于当前事务版本号(在当前事务开始之后更新的)。这样可以确保事务读取到的行,在事务开始之前未被删除。

只有符合上述两个条件的纪录,才能作为查询结果返回。

 

INSERT
InnoDB为插入的每一行保存当前系统版本号作为行版本号。

 

DELETE
InnoDB为删除的每一行保存当前系统版本号作为行删除标识。

 

UPDATE
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时,保存当前系统版本号到原来的行作为行删除标识。

 

优点:
保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好。

缺点:
每行纪录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

 

四、总结

为了实现可串行化,同时避免锁机制存在的各种问题,我们可以采用基于多版本并发控制(Multiversion concurrency control,MVCC)思想的无锁事务机制。人们一般把基于锁的并发控制机制称成为悲观机制,而把MVCC机制称为乐观机制。这是因为锁机制是一种预防性的,读会阻塞写,写也会阻塞读,当锁定粒度较大,时间较长时并发性能就不会太好;而MVCC是一种后验性的,读不阻塞写,写也不阻塞读,等到提交的时候才检验是否有冲突,由于没有锁,所以读写不会相互阻塞,从而大大提升了并发性能。

我们可以借用源代码版本控制来理解MVCC,每个人都可以自由地阅读和修改本地的代码,相互之间不会阻塞,只在提交的时候版本控制器会检查冲突,并提示merge。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PostgreSQL的MVCC(多版本并发控制)是一种用于支持事务并维持数据一致性的同时,允许并发读写的机制。这种技术在数据库管理系统中非常关键,尤其是在处理事务性和并发操作时。 ### MVCC的工作原理 #### 时间戳隔离 在MVCC中,每一行数据都有一个称为“时间戳”的版本标识符。当一个事务开始时,它会获取一个时间点作为其活动的开始,这个时间点包含了所有已提交事务的时间戳信息。事务在其整个生命周期内,只能够访问和修改那些在这个时间点前或同时创建的数据。 #### 数据行和快照 在MVCC中,数据行不是直接存储其原始值,而是包含了一个额外的版本信息。每个查询或操作都会从数据库中加载一组所谓的“快照”,即特定时刻的所有活跃事务的状态。这些快照由一系列的版本(版本树)组成,其中每个节点表示一个事务的更新状态。 #### 写入与删除 写入操作会在现有数据上建立一个新的版本,并将旧版本标记为历史记录。如果需要,可以保留多个历史版本供日志和恢复使用。删除操作实际上是修改数据的一次写操作,将其标记为不可见而非物理删除,以便于保持查询性能。 ### 相关优势 1. **高并发性**:通过限制事务对数据的访问范围,使得多个事务可以在同一时间内运行而不相互干扰。 2. **冲突解决**:自动管理并发操作带来的冲突,减少了应用开发者在并发处理上的复杂度。 3. **安全性**:避免了死锁和其他并发问题,提高了系统的稳定性和可靠性。 4. **性能优化**:通过避免全表扫描等低效操作,提高查询效率。 ### 使用场景及限制 1. **多用户环境**:在大量并发用户同时请求的情况下,MVCC能有效减少锁定等待时间和提高系统吞吐量。 2. **数据完整性**:确保在高负载下仍能满足ACID(原子性、一致性、隔离性、持久性)属性的需求。 3. **复杂查询**:支持复杂的SQL查询,包括JOIN操作,而不会因为并发读写引起的问题。 然而,尽管有上述优点,MVCC也有其局限性: - 需要更多的磁盘空间来存储额外的版本数据。 - 对一些特殊的查询或需求可能不如其他并发控制策略高效。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值