mysql服务器是一个使用了大量内部锁和锁相关原语(例如mutex,rwlocks(包括prlocks和sxlocks),conditions,files)的多线程应用。在服务器内,与锁相关的对象随着新特性的实现和代码重构而改变,以提高性能。如同任何使用了锁原语的多线程应用一样,总会有一些风险,当多个锁同时被持有时会遇到死锁。对mysql来说,死锁的后果是灾难性的,会造成服务的完全丢失。
从MySQL 8.0.17开始,为了支持检测锁获取死锁并强制执行时释放死锁,MySQL支持LOCK_ORDER工具。这样就可以将锁顺序依赖关系图定义为服务器设计的一部分,并且服务器运行时的检查可以保证锁的获取是非循环的,并且执行路径符合该图。
这节提供了关于使用LOCK_ORDER工具的信息,但也仅是基本层面的使用。对于复杂的细节,请参见MySQL Server Doxygen文档的“锁定顺序”部分,该文档位于https://dev.mysql.com/doc/index-other.html。
LOCK_ORDER工具是用来调试服务器,而不是用于生产。
为使用LOCK_ORDER工具,请按照以下流程:
- 从源服务器构建MySQL,并使用-DWITH_LOCK_ORDER = ON CMake选项对其进行配置,以便该构建包括LOCK_ORDER工具。
注意:
启用WITH_LOCK_ORDER选项后,MySQL构建需要flex程序。 - 要在启用LOCK_ORDER工具的情况下运行服务器,请在服务器启动时启用lock_order系统变量。 也可以使用其他几个用于LOCK_ORDER配置的系统变量。
- 对于MySQL测试套件操作,mysql-test-run.pl具有–lock-order选项,该选项控制是否在测试用例执行期间启用LOCK_ORDER工具。
假设MySQL已使用了LOCK_ORDER工具构建mysql,则以下描述的系统变量将配置LOCK_ORDER工具的操作。 主要变量是lock_order,它指示是否在运行时启用LOCK_ORDER工具:
如果lock_order被禁用(默认选项),则其他LOCK_ORDER系统变量没有任何作用。
如果启用了lock_order,则其他系统变量将会配置要启用的LOCK_ORDER功能。
注意:
通常,可以通过使用–lock-order选项执行mysql-test-run.pl来配置LOCK_ORDER工具,并且mysql-test-run.pl可以将LOCK_ORDER系统变量设置为适当的值。
所有的LOCK_ORDER系统变量必须在服务器启动时设置。运行时这些值可见但是无法改变。
一些系统变量是成对存在的,比如lock_order_debug_loop和lock_order_trace_loop。对于此类对,当变量与之关联的条件发生时,将其区分如下:
如果启用了_debug_变量,将会raise一个debug assertion
如果启用了_trace_变量,会打印在日志中一个error.
表5.7 LOCK_ORDER系统变量概要
lock_order
是否在运行时启用LOCK_ORDER工具。如果禁用lock_order(默认设置),则其他LOCK_ORDER系统变量均无效。 如果启用了lock_order,则其他系统变量将配置要启用的LOCK_ORDER功能。
如果启用了lock_order,则如果服务器在获得锁时没有按照锁顺序图中的顺序,则会引发错误。
lock_order_debug_loop
当LOCK_ORDER工具遇到在锁顺序图中标记为循环的依赖项时,是否导致调试断言失败。
lock_order_debug_missing_arc
当LOCK_ORDER工具遇到在锁顺序图中没有声明的依赖项时,是否导致调试断言失败。
lock_order_debug_missing_key
当LOCK_ORDER工具遇到performance schema未能正确检测的对象时,是否导致调试断言失败。
lock_order_debug_missing_unlock
当LOCK_ORDER工具遇到持有期间被destory的锁是否导致调试断言失败。
lock_order_dependencies
lock_order_dependencies.txt文件的路径定义了服务器锁顺序依赖图。允许把它设置为无依赖。在这个场景中使用了空依赖图。
lock_order_extra_dependencies
包含锁定顺序依赖关系图的其他依赖的文件路径。这对修改在lock_order_dependencies.txt文件中定义的主服务器依赖关系图很有用,并带有描述第三方代码行为的其他依赖关系。 (另一种方法是修改lock_order_dependencies.txt本身,不鼓励这样做。)
如果未设置此变量,则不使用辅助文件。
lock_order_output_directory
LOCK_ORDER工具写日志到何处的目录。如果此变量未设置,默认是当前目录
lock_order_print_txt
LOCK_ORDER工具是否执行锁顺序图分析并打印文本报告。 该报告包括任何检测到的锁定获取周期。
lock_order_trace_loop
当LOCK_ORDER工具遇到在锁定顺序图中标记为循环的依赖项时,是否在日志文件中打印跟踪(strace)。
lock_order_trace_missing_arc
当LOCK_ORDER工具遇到在锁顺序图中未声明的依赖项时,是否在日志文件中打印跟踪。
lock_order_trace_missing_key
当LOCK_ORDER工具遇到未能正确检测performance schema的对象时,是否在日志文件中打印跟踪。
lock_order_trace_missing_unlock
当LOCK_ORDER工具遇到持有期间被销毁的锁时,是否在日志文件中打印跟踪。