目录
一、mysql存储引擎
1、什么是mysql存储引擎?
mysql存储引擎是mysql底层软件的一个组件
存储引擎就是存储数据,建立索引,更新查询数据源等等数据源的实现方式
它可以按特定的方式把数据存入磁盘和读取磁盘上的数据,不同的存储引擎使用的方式都不同。
2、存储引擎的类型
mysql中可以通过show engines 命令来查询mysql支持的存储引擎的类型
现在mysql 默认的存储引擎为InnoDB,支持事务
InnoDB:支持事务、外键、行锁、崩溃后可安全恢复
MyISAM:表锁、支持全文索引
CSV
memory
页是InnoDB管理磁盘存储空间的基本单位,也是最小单位,一个页的大小一般是16KB
二、mysql事务(transaction)
1、定义
一个数据库事务由一条或者多条sql语句构成,它们形成一个逻辑的工作单元。这些sql语句要么全部执行成功,要么。全部执行失败,MySQL 事务主要用于处理操作量大,复杂度高的数据。
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。
2、事务的四个(ACID)属性
- 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成。
- 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
- 隔离性:一个事务的执行不能被其他事务干扰。
- 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
3、事务控制语句
begin或者start transaction:可以显式的开起一个事务
commit:提交事务,并使已对数据库进行的所有修改成为永久性的
rollback:回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;
savepoint identifier A:,SAVEPOINT 允许在事务中创建一个保存点A,一个事务中可以有多个 SAVEPOINT;
rollback to identifier A:把事务回滚到标记点
使用set 可以改变mysql的自动提交模式
set autocommit=0 进制自动提交
set autocommit=1 开起自动提交
DDL和DCL不受autocommit这个变量的影响
start transaction 后去操作表的时候,加的是表锁
三、并发事务的四个问题
1、脏读:读取到了未提交数据
脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
2、不可重复读(前后多次读取,数据内容不一致):
是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
3、幻读:(前后多次读取,数据总量不一致)
假设事务1查询t1表中name=chen的用户,没有的话则插入,事务2就往表中插入一条name=chen的用户,由于事务查到name=chen的数据不存在,因此往表中插入一条name=chen的数据,这时就会发生冲突,这里的事务1就是发生了幻读,意思就是本来刚刚还是没有的,突然一下右有了,好像产生了幻觉一样。
幻读和不可重复读很相似,不可重复读的重点在于修改了数据(update),而幻读的重点在于新增了或者删除数据(delete、insert)
4、丢失更新(lost update)
丢失更新就是两个事务读入同一个数据并进行了修改,但是事务2提交的结果覆盖了事务1,导致了事务1修改的结果丢失了。
四、mysql事务的四个隔离级别
- read uncommitted(读未提交):事务1和事务2,事务1写入了数据,但是还没有提交,也可以被事务2给读到,读取到的数据就是脏数据,这种隔离级别最低
- read committed(读已提交):事务1和事务2,事务1提交了的数据才能被事务2读和写,这种隔离级别会导致不可重复读,Oracle默认隔离级别
- repeatable read (可重复读):事务1提交的数据,事务2只能读,不能写,这样避免了不可重复读和脏读,但是有可能会出现幻读,mysql的默认隔离级别
- serializable(可串行化):提供严格的事务隔离。它要求事务串行化执行,事务只能一个接着一个地执行,但不能并发执行。很少使用,效率太低。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
五、锁
共享锁(读锁)
被共享锁锁定的资源可以被其他用户读取,但是其他用户不能不能修改它,通常在执行select语句时会给操作对象(表、数据)加上共享锁,执行完后就会被释放
排他锁(写锁)
当前用户可以读写表,但是其它用户既不能读也不能写,在执行insert、update、delete等语句时会使用排他锁,但当对象上有其它锁存在时,无法对其加排他锁。
按锁的颗粒度分
表级锁:锁定整张表,其他用户无法对该表进行操作
行级锁:锁定一行数据,其他用户还是可以访问同一个表的其他数据。
乐观锁
总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,乐观锁机制避免了长事务中的数据库加锁开销(操作员 A和操作员 B 操作过程中,都没有对数据库数据加锁),大大提升了大并发量下的系统整体性能表现
悲观锁
悲观锁,正如其名,具有强烈的独占和排他特性,每次读取数据的时候总会认为数据会被其他用户更改,所以都会加锁,当其他用户想要访问数据的时候都会被挂起。
六、事务实现的原理
1、redo log 和 undo log
redo log (持久性):
重做日志,由重做日志缓冲和重做日志文件组成,前者在内存中,后者在磁盘中,当事务提交之后,会把所有修改信息都会存到该日志中
redo log是用来恢复数据的,用于保障,已提交事务的持久化特性
undo log (原子性):
回滚日志,用于记录数据被修改前的信息,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。
undo log是用来回滚数据的用于保障 未提交事务的原子性
2、锁和MVCC基础
锁:事务的隔离性可以通过加读写锁来实现的
MVCC:多版本并发控制
实现原理:版本链、undo log ,read view
mvcc用来解决读—写冲突的无锁并发控制,就是为事务分配单项增长的时间戳
。为每个数据修改保存一个版本
,版本与事务时间戳相关联,
读操作只读取
该事务开始前
的数据库快照
MVCC在mysql中的实现依赖的是undo log 和read view
undo log :记录某行数据的多个版本的数据
read view:判断当前版本数据的可见性