Mysql 的事务操作问题
什么是数据库事务?
一组 sql 语句组成的数据库逻辑处理单元,在这组的 sql 操作中,要么全部执行成功,要么全部执行失败。
事务支持是在引擎层实现的。MySQL 原生的 MyISAM 引擎不支持事务,这也是 MyISAM 被 InnoDB 取代的重要原因之一。
你能说一说 Redo/Undo 机制吗?
Redo/Undo 机制比较简单,它们将所有对数据的更新操作都写到日志中。
Redo log 用来记录某数据块被修改后的值,可以用来恢复未写入 data file 的已成功事务更新的数据;Undo log 是用来记录数据更新前的值,保证数据更新失败能够回滚。
假如数据库在执行的过程中,不小心崩了,可以通过该日志的方式,回滚之前已经执行成功的操作,实现事务的一致性。
例子:假如某个时刻数据库崩溃,在崩溃之前有事务 A 和事务 B 在执行,事务 A 已经提交,而事务 B 还未提交。当数据库重启进行 crash-recovery 时,就会通过 Redo log 将已经提交事务的更改写到数据文件,而还没有提交的就通过 Undo log 进行 roll back。
那回滚日志什么时候删?
当系统里没有比这个回滚日志更早的 read-view 的时候。
InnoDB 的 MVCC 实现机制 MVCC 可以认为是行级锁的一个变种,它可以在很多情况下避免加锁操作,因此开销更低。MVCC 的实现大都都实现了非阻塞的读操作,写操作也只锁定必要的行。InnoDB 的 MVCC 实现,是通过保存数据在某个时间点的快照来实现的。一个事务,不管其执行多长时间,其内部看到的数据是一致的,也就是事务在执行的过程中不会相互影响。
简述一下 MVCC 在 InnoDB 中的实现:
InnoDB 的 MVCC,通过在每行记录后面保存两个隐藏的列来实现:一个保存了行的创建时间,一个保存行的过期时间(删除时间),当然,这里的时间并不是时间戳,而是系统版本号,每开始一个新的事务,系统版本号就会递增。在 RR 隔离级别下,MVCC 的操作如下:
select 操作:InnoDB 只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录。行的删除版本要么未定义,要么大于当前事务版本号。可以确保事务读取的行,在事务开始之前未删除。insert 操作:将新插入的行保存当前版本号为行版本号。delete 操作:将删除的行保存当前版本号为删除标识。update 操作:变为 insert 和 delete 操作的组合,insert 的行保存当前版本号为行版本号,delete 则保存当前版本号到原来的行作为删除标识。由于旧数据并不真正的删除,所以必须对这些数据进行清理,innodb 会开启一个后台线程执行清理工作,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫做 purge。
例子
事务的四大特征:
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。持久性:当事务提交或回滚后,数据库会持久化的保存数据。隔离性:多个事务之间,相互独立。一致性:事务操作前后,数据总量不变
评论