InnoDB中的锁与事务—理论+实战

一、InnoDB中的锁与事务

InnoDB中是支持事务的。

首先InnoDB中不只有行锁,也是有表锁的。

二、pt-online-schema-change

我们在修改表结构的时候,上的就是表的写锁,所以修改表结构,尤其是大表时,要尤其注意。

pt-online-schema-change可以在不阻塞写入的情况下改动数据表,其原理如下:

  1. 首先创建一个和你要执行的alter操作的表一样的空的表结构。
  2. 执行我们赋予的表结构的修改,然后copy原表中数据到新表里面。
  3. 在原表上创建一个触发器在数据copy的过程中,将原表的更新数据的操作全部更新到新的表中来。这个理特别注意,如果原表中已经定义了触发器,那么工具就不能工作了,因为工具使用的数据库的触发器。
  4. copy完成之后,用rename table新表来代替原表,默认删除原表。

三、事务的特性

ACID,原子性,一致性,隔离性,持久性。

四、并发事务带来的问题

  1. 更新丢失。ABA问题。
  2. 脏读:读到了其他事务未提交的内容。不符合一致性。
  3. 不可重复度:事务中前后读到的内容不一致。不符合隔离性。
  4. 幻读:事务中,后来读到的内容比之前的内容多。不符合隔离性。

五、事务的隔离级别

隔离级别脏读不可重复读幻读
未提交读可能可能可能
已提交读不可能可能可能
可重复读不可能不可能可能
序列化不可能不可能不可能

五、查看与设置事务的隔离级别

#常看当前数据库的事务隔离级别
show variables like 'tx_isolation';

#查看当前会话隔离级别 
select @@tx_isolation;

#设置为读未提交
set tx_isolation='read-uncommitted';

#设置为读已提交
set tx_isolation='read-committed';

#设置为可重复读
set tx_isolation='REPEATABLE-READ';

#设置为串行化
set tx_isolation='SERIALIZABLE';

六、不可重复读中的机制

开启两个事务,一个事务更改并提交后的数据,在另一个事务中查询不到,但是如果在这个事务中更改却是会以最新的数据为依据的,且在更改后,在本事务中继续查询,就可以查到新的数据了,

这是使用MVCC机制,也就是快照的模式:

  • select不会更新版本号,是快照读(历史版本)。
  • insert、update、delete会更新版本号,是当前读(当前版本)。

关于幻读,并不是开启两个事务,一个事务中提交的新增记录一定会体现在另一个事务中,而是只有在这个事务需要修改这条新增记录时,这个事务才会查出来这条新增记录。

关于幻读,可以通过间隙锁的方式间接解决,就是当我们不想要我们的数据被别的事务新增时,那么我们就把我们的数据加上间隙锁,从而让其他的事务无法新增数据。

七、行锁分析命令

通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况:

show status like 'innodb_row_lock%';

查询出来的变量的意义如下:

  • Innodb_row_lock_current_waits:当前正在等待锁定的数量
  • Innodb_row_lock_time:从系统启动到现在锁定总时间长度
  • Innodb_row_lock_time_avg:每次等待所花平均时间
  • Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花时间
  • Innodb_row_lock_waits:系统启动后到现在总共等待的次数

八、上升表锁的情况

for update,或者是增删改的条件有以下情况发生:

  • 我们在索引上操作是行锁。
  • 在无索引的字段上操作上的是表锁。
  • 索引字段上的范围查询,以及模糊查询给表上的都是表锁。

我们一定要注意,避免行锁上升为表锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值