mysql 锁分类
- 表级锁:开销小,加锁快,并发度最低,无死锁
- 行锁:开销大,加锁慢,并发度最高,会出现死锁
- 页面锁:开销介于表级锁和行锁之间,并发度一般,会出现死锁
事务的四个特性
- 原子性:要么都执行要么都不执行
- 一致性:事务开始和结束都保持一直状态(例如B树索引和数据的一致)
- 隔离性:事务的中间状态其他线程不感知
- 持久性:数据修改是永久性的,即使发现故障,也能够保持正确数据
mysql并发问题
- 并发更新丢失-防止更新丢失是应用的责任-乐观锁
- 脏读
- 不可重复读
- 幻读
查看mysql的行锁竞争情况
show status like ‘innodb_row_lock%’
更新库存:
update tb_inventory set store=store-1 where store-1>=0;
监控
Standard Monitor:
CREATE TABLE innodb_monitor (a INT) ENGINE=INNODB;
DROP TABLE innodb_monitor;
SHOW ENGINE INNODB STATUS\G;
Lock Monitor:
CREATE TABLE innodb_lock_monitor (a INT) ENGINE=INNODB;
DROP TABLE innodb_lock_monitor;
set GLOBAL innodb_status_output=ON;
set GLOBAL innodb_status_output_locks=ON;
锁模式
SELECT * FROM table_name WHERE … LOCK IN SHARE MODE(共享锁)
SELECT * FROM table_name WHERE …FOR UPDATE(x=排他锁)
自动提交设置后,构造死锁的例子
set autocommit=0;
自动提交后,其他事务可见
| sessiong1 | session2|
|select * from talbe lock in share mode|select * from table lock in share mode|
|update set |update set |
加锁模式
mysql执行加锁是加在索引项上面的,而不是加载数据项的
类型转换可能导致走不走索引,这一点特别注意
间隙锁
- 间隙锁是为了防止幻读
- 间隙所示范围锁
- 间隙所的例子select for update where id>1 ||update where id 不存在
注意:尽量使用相等条件来访问记录,不要使用范围条件
*mysql日志-
mysql-binlog录制执行的语句
mysql-主从结构不断的执行binlog日志实现主从复制