独占锁(X 锁)和共享锁(S 锁)是 InnoDB 的行级概念锁,用于确保对同一行记录的修改和删除的序列性,从而保证强一致性数据。它们适用于三种场景:记录锁、间隙锁和下一键锁。在高并发情况下,需要适当的配置以避免过多的死锁。
以下 SQL 语句可用于检查行锁等待情况。
返回参数 | 说明 |
---|---|
Innodb_row_lock_current_waits | 当前行锁等待的数量 |
Innodb_row_lock_time | 获取行锁所花费的总时间(以毫秒为单位) |
Innodb_row_lock_time_avg | 获取行锁的平均时间(以毫秒为单位) |
Innodb_row_lock_time_max | 获取行锁所花费的最大时间(以毫秒为单位) |
Innodb_row_lock_waits | 行锁等待发生的次数 |
当 MySQL 遇到过多并发请求时,由于对行锁的竞争,等待情况会出现。为了避免锁冲突,建议优化业务中的热门更新,并在处理大量数据时采用分页查询或分段查询等技术。这些方法可以防止在单个查询中锁定过多的数据行,从而降低锁冲突的风险,提高系统性能和响应速度。此外,可以调整 innodb_lock_wait_timeout
和 interactive_timeout
参数,以设置等待获取资源的最大时长。这有助于优化锁机制,提高系统可用性。
在死锁不频繁发生的情况下,可以设置 innodb_print_all_deadlocks=ON
以在错误日志中打印每次死锁发生的详细信息,以帮助分析死锁的成因。然而,如果业务中死锁频繁,为了维护错误日志和服务器性能,最好将 innodb_print_all_deadlocks
设置为 OFF,仅输出死锁的汇总信息。如果需要详细的死锁分析,可以暂时将该参数设置为 ON,以观察一段时间内的详细死锁信息,然后再关闭以最小化对服务器性能的影响。
为了避免 InnoDB 由于无法通过索引获取行锁而升到表级锁,建议尽可能使用索引进行数据检索。此外,添加索引时应尽量精确,以避免不必要的锁定,这会影响其他查询的性能。
为了避免由于范围检索(即间隙锁)而锁定不应锁定的记录,建议最小化范围查询的使用。此外,为了减少被锁定的资源和锁定时间,应控制事务的大小。关于事务的隔离级别,建议在可行的情况下使用较低的隔离级别,以降低与 MySQL 事务隔离处理相关的成本。