构建千万级高可用企业级Node.js应用

355 阅读2分钟

download: 构建千万级高可用企业级Node.js应用

1 锁系统

在 MySQL 中 InnoDB 是常用的存储引擎,我们经常会遇到慢 sql 或者死锁,所以深入了解 DDL 和 DML 语句下锁机制是非常有必要的。

InnoDB 存储引擎的锁,按不同的维度可以进行不同的划分:

  • 按照锁粒度划分可以分为:表锁和行锁
  • 按照锁兼容性划可以分为:共享锁和排他锁

1.1 锁模式

1.1 意向锁

i 意向共享锁(LOCK_IS)
  • 表级锁,如需要在对应的记录行加共享锁时,必须先获取其对应表下对应的意向共享锁或者锁强度更高的表级锁
ii 意向排他锁(LOCK_IX)
  • 表级锁,如需要在对应的记录行加排他锁时,必须先获取其对应表下对应的意向排他锁或者锁强度更高的表级锁

常见的加意向锁,比如 SELECT ... FOR SHARE 会在对应记录行上加锁之前会先加表级意向共享锁,而 SELECT .. FOR UPDATE 则先加表级意向排他锁。

1.2 共享锁(LOCK_S)

共享锁的作用主要用于在事务中读取行记录后,不希望数据行不被其他的事务锁修改,但所有的读操作产生的 LOCK_S 锁不冲突的,来提高读读并发能力,常见的如

SELECT … IN SHARE MODE

普通查询在隔离级别为 SERIALIZABLE 会给记录加 LOCK_S 锁

对于普通的 INSERT/UPDATE,检查到 duplicate key(或者有一个被标记删除的 duplicate key ), 会加 LOCK_S 锁

1.3 排他锁(LOCK_X)

排他锁主要是为了避免对相同记录的并发修改控。其中常用的 UPDATE 或者 DELETE 操作,以及 SELECT … FOR UPDATE 操作,都会对记录加排他锁。只有拥有该锁的事务可以读取和修改数据行,其他事务进入阻塞状态,该锁是独占的,同一时间对于同一数据行只有一个事务可以拥有排他锁

1.4 自增锁(LOCK_AUTO_INC)

当插入的表中有自增列(AUTO_INCREMENT)的时候会触发自增锁。当插入表中有自增列时,数据库需要自动生成自增id,在生成之前会先为该表加 AUTO_INC 表锁,其他事务的插入操作阻塞,这样保证生成的自增值肯定是唯一的。AUTO_INC 的加锁逻辑和 InnoDB 的锁模式相关,自增锁模式通过参数 innodb_autoinc_lock_mode 来控制

1.2 行锁类型

行锁作用在聚簇索引和二级索引上,通过不同隔离级别的加锁方式来避免脏读,幻读