Mysql note

温故知新,mysql都到5.8了,重新拿起来看看。

Mysql随着版本的升级,存储引擎也从MyISAM变成了InnoDB,锁从表锁变成了行锁🔐。

MyISAM不支持事务,InnoDB支持事务。表锁虽然开销小,锁表快,但高并发下性能低。

行锁虽然开销大,锁表慢,但高并发下相比之下性能更高。事务和行锁都是在确保数据准确的基础上提高并发的处理能力。

TIPS:

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁。并且该索引不能失效,否则都会从行锁升级为表锁。

行锁的加锁方式:自动加锁 对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁;对于普通SELECT语句,InnoDB不会加任何锁;当然我们也可以显示的加锁:

共享锁(也称读锁,多用于判断数据是否存在,多个读操作可以同时进行而不会互相影响。当如果事务对读锁进行修改操作,很可能会造成死锁):

1
select * from tableName where ... + lock in share more

排他锁(也称写锁,独占锁,当前写操作没有完成前,它会阻断其他写锁和读锁):

1
select * from tableName where ... + for update 

以下命令可以分析行锁定:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
mysql> show status like 'innodb_row_lock%';

| Variable_name                 | Value |
| Innodb_row_lock_current_waits | 0     |
| Innodb_row_lock_time          | 0     |
| Innodb_row_lock_time_avg      | 0     |
| Innodb_row_lock_time_max      | 0     |
| Innodb_row_lock_waits         | 0     |

innodb_row_lock_current_waits: 当前正在等待锁定的数量
innodb_row_lock_time: 从系统启动到现在锁定总时间长度;非常重要的参数,
innodb_row_lock_time_avg: 每次等待所花平均时间;非常重要的参数,
innodb_row_lock_time_max: 从系统启动到现在等待最常的一次所花的时间;
innodb_row_lock_waits: 系统启动后到现在总共等待的次数;非常重要的参数。直接决定优化的方向和策略。

行锁优化的一些优化:

1、尽可能让所有数据检索都通过索引来完成,避免无索引行或索引失效导致行锁升级为表锁。 2、尽可能避免间隙锁带来的性能下降,减少或使用合理的检索范围。 3、尽可能减少事务的粒度,比如控制事务大小,而从减少锁定资源量和时间长度,从而减少锁的竞争等,提供性能。 4、尽可能低级别事务隔离,隔离级别越高,并发的处理能力越低。