10bet网址
MySQL 8.0参考手册
相关的文档10bet官方网站 本手册下载
PDF (Ltr)- 41.5 mb
PDF (A4)- 41.6 mb
手册页(TGZ)- 262.1 kb
手册页(邮政编码)- 372.2 kb
信息(Gzip)- 4.0 mb
信息(邮政编码)- 4.0 mb
本手册节选

5.6.9.1锁定服务

MySQL发行版提供了一个锁接口,可以在两个级别上访问:

  • 在SQL级别,作为一组可加载函数,每个函数映射到对服务例程的调用。

  • 作为一个C语言接口,可作为一个插件服务从服务器插件或可加载函数调用。

关于插件服务的一般信息,请参见第5.6.9节,“MySQL插件服务”.有关可加载函数的一般信息,请参见添加一个可加载函数

锁定接口具有以下特点:

  • 锁有三个属性:锁命名空间、锁名称和锁模式:

    • 锁通过名称空间和锁名称的组合来标识。命名空间允许不同的应用程序使用相同的锁名称,而不会在不同的命名空间中创建锁,从而避免发生冲突。例如,如果应用程序A和B使用的名称空间为ns1而且ns2,每个应用程序都可以使用锁名lock1而且lock2不干扰其他应用程序。

    • 锁模式是读或写。读锁是共享的:如果一个会话在给定的锁标识符上有一个读锁,其他会话可以在同一标识符上获得一个读锁。写锁是互斥的:如果一个会话对给定的锁标识符有写锁,其他会话就无法获得对同一标识符的读或写锁。

  • 命名空间和锁名称必须为非-,非空,且最大长度为64个字符。指定为的命名空间或锁名称,空字符串或长度超过64个字符的字符串将导致ER_LOCKING_SERVICE_WRONG_NAME错误。

  • 锁定接口将名称空间和锁名视为二进制字符串,因此比较是区分大小写的。

  • 锁定接口提供获取锁和释放锁的函数。调用这些函数不需要特殊权限。权限检查是调用应用程序的职责。

  • 如果锁不是立即可用的,则可以等待。锁获取调用采用一个整数超时值,表示在放弃之前等待获得锁的秒数。如果在没有成功获取锁的情况下达到超时,则会触发ER_LOCKING_SERVICE_TIMEOUT发生错误。如果超时为0,则不需要等待,如果不能立即获得锁,则调用会产生错误。

  • 锁接口检测不同会话中的锁获取调用之间的死锁。在这种情况下,锁定服务选择一个调用者,并使用ER_LOCKING_SERVICE_DEADLOCK错误。此错误不会导致事务回滚。为了在死锁发生时选择一个会话,锁定服务优先选择持有读锁的会话,而不是持有写锁的会话。

  • 一个会话可以通过一个锁获取调用获得多个锁。对于给定的调用,获取锁是原子的:如果获得了所有锁,则调用成功。如果获取任何锁失败,调用将不获取锁并失败,通常使用ER_LOCKING_SERVICE_TIMEOUTER_LOCKING_SERVICE_DEADLOCK错误。

  • 会话可以为同一个锁标识符(名称空间和锁名称组合)获取多个锁。这些锁实例可以是读锁、写锁,或者两者兼而有之。

  • 通过调用释放锁函数显式地释放会话中获得的锁,或者在会话终止(正常或异常)时隐式地释放锁。事务提交或回滚时不会释放锁。

  • 在一个会话中,给定名称空间的所有锁在释放时一起释放。

锁服务提供的接口不同于GET_LOCK ()和相关的SQL函数(请参见第12.15节,“锁定函数”).例如,GET_LOCK ()不实现名称空间,只提供排他锁,而不提供不同的读写锁。

5.6.9.1.1服务C接口锁定

介绍锁定服务C语言接口的使用方法。要使用函数接口,请参见5.6.9.1.2节,“锁定服务功能接口”有关锁定服务接口的一般特征,请参见第5.6.9.1节,“锁定服务”.关于插件服务的一般信息,请参见第5.6.9节,“MySQL插件服务”

使用锁定服务的源文件应该包括这个头文件:

# include < mysql / service_locking.h >

要获得一个或多个锁,调用这个函数:

int mysql_acquire_locking_service_locks(MYSQL_THD opaque_thd, const char* lock_namespace, const char**lock_names, size_t lock_num, enum enum_locking_service_lock_type lock_type, unsigned long lock_timeout);

这些参数有以下含义:

  • opaque_thd:一个线程柄。如果指定为,则使用当前线程的句柄。

  • lock_namespace:以空结尾的字符串,表示锁命名空间。

  • lock_names:一个以空结束的字符串数组,提供了要获取的锁的名称。

  • lock_num中名称的数目lock_names数组中。

  • lock_type:锁定模式LOCKING_SERVICE_READLOCKING_SERVICE_WRITE分别获取读锁或写锁。

  • lock_timeout:在放弃之前等待获得锁的整数秒数。

要释放为给定名称空间获取的锁,调用这个函数:

int mysql_release_locking_service_locks(MYSQL_THD opaque_thd, const char* lock_namespace);

这些参数有以下含义:

  • opaque_thd:一个线程柄。如果指定为,则使用当前线程的句柄。

  • lock_namespace:以空结尾的字符串,表示锁命名空间。

锁定服务获得或等待的锁可以使用性能模式在SQL级别监视。有关详细信息,请参见锁定服务监控

5.6.9.1.2锁定业务功能接口

介绍锁服务的可加载函数提供的锁服务接口的使用方法。要使用C语言接口,请参见第5.6.9.1.1节,“锁定服务C接口”有关锁定服务接口的一般特征,请参见第5.6.9.1节,“锁定服务”.有关可加载函数的一般信息,请参见添加一个可加载函数

安装/卸载锁定业务功能接口

中描述的锁定服务例程第5.6.9.1.1节,“锁定服务C接口”不需要安装,因为它们内置在服务器中。而映射到服务例程调用的可加载函数则不是这样:函数必须在使用之前安装。本节将介绍如何操作。有关可加载函数安装的一般信息,请参见第5.7.1节,“安装和卸载可加载函数”

锁服务函数是在一个插件库文件中实现的,这个插件库文件位于plugin_dir系统变量。基础文件名为locking_service.每个平台的文件名后缀不同(例如,所以对于Unix和类Unix系统,. dll对于Windows)。

安装锁定业务功能,请使用创建函数声明中,调整所以根据需要为平台添加后缀:

CREATE FUNCTION service_get_read_locks返回INT SONAME 'locking_service.so'CREATE FUNCTION service_get_write_locks返回INT SONAME 'locking_service.so';CREATE FUNCTION service_release_locks返回INT SONAME 'locking_service.so';

如果在复制源服务器上使用该功能,请同时在所有复制服务器上安装该功能,以避免出现复制问题。

一旦安装,这些功能将一直处于安装状态,直到卸载为止。要删除它们,请使用删除函数声明:

下降函数service_get_read_locks;下降函数service_get_write_locks;下降函数service_release_locks;
使用锁定业务功能接口

在使用锁定服务功能之前,请按照说明安装安装/卸载锁定业务功能接口

要获得一个或多个读锁,调用这个函数:

mysql> SELECT service_get_read_locks('mynamespace', 'rlock1', 'rlock2', 10);+---------------------------------------------------------------+ | service_get_read_locks(‘mynamespace’,‘rlock1’,‘rlock2’,10 ) | +---------------------------------------------------------------+ | 1  | +---------------------------------------------------------------+

第一个参数是锁名称空间。最后一个参数是一个整数超时时间,表示在放弃之前需要等待多少秒来获得锁。中间的参数是锁名。

对于刚刚展示的示例,该函数获取带有锁标识符的锁(mynamespace rlock1)而且(mynamespace rlock2)

要获得写锁而不是读锁,调用这个函数:

mysql> SELECT service_get_write_locks('mynamespace', 'wlock1', 'wlock2', 10);+----------------------------------------------------------------+ | service_get_write_locks(‘mynamespace’,‘wlock1’,‘wlock2’,10 ) | +----------------------------------------------------------------+ | 1  | +----------------------------------------------------------------+

在本例中,锁标识符是(mynamespace wlock1)而且(mynamespace wlock2)

要释放一个命名空间的所有锁,使用这个函数:

mysql >选择service_release_locks(“mynamespace”);+--------------------------------------+ | service_release_locks(“mynamespace ') | +--------------------------------------+ | 1  | +--------------------------------------+

每个锁定函数返回非零表示成功。如果函数失败,就会出现错误。例如,由于锁名不能为空,会出现以下错误:

mysql> SELECT service_get_read_locks('mynamespace', ', 10);错误的锁服务锁名"。

一个会话可以为同一个锁标识符获取多个锁。只要不同的会话没有针对某个标识符的写锁,该会话就可以获得任意数量的读锁或写锁。每个对标识符的锁请求都会获得一个新锁。下面的语句获取三个具有相同标识符的写锁,然后获取三个具有相同标识符的读锁:

SELECT service_get_write_locks('ns', 'lock1', 'lock1', 'lock1', 0);SELECT service_get_read_locks('ns', 'lock1', 'lock1', 'lock1', 0);

如果你检查性能架构metadata_locks表中,您应该发现会话持有六个不同的锁,具有相同的锁(ns, lock1)标识符。(详情,请参阅锁定服务监控.)

因为会话至少持有一个写锁(ns, lock1),其他会话不能为它获取锁,无论是读还是写。如果会话只持有该标识符的读锁,那么其他会话可以获取该标识符的读锁,但不能获取写锁。

单个锁获取调用的锁是原子性获取的,但是原子性不会跨调用保持。因此,对于如下语句,其中service_get_write_locks ()在结果集中的每一行调用一次,原子性对每个单独的调用都有效,但对整个语句就不有效了:

SELECT service_get_write_locks('ns', 'lock1', 'lock2', 0) FROM t1 WHERE…;
谨慎

因为锁定服务会为每个成功请求给定锁标识符返回一个单独的锁,因此单个语句可能会获得大量锁。例如:

插入……选择service_get_write_locks (ns, t1。从t1开始;

这些类型的陈述可能有一定的不利影响。例如,如果语句部分失败并回滚,则在故障点之前获得的锁仍然存在。如果意图是在插入的行和获取的锁之间存在对应关系,那么这个意图是不满足的。另外,如果按一定的顺序授予锁很重要,请注意,结果集的顺序可能会因优化器选择的执行计划而不同。由于这些原因,最好将应用程序限制为每个语句只能调用一个锁获取调用。

锁定服务监控

锁定服务是使用MySQL Server元数据锁框架实现的,因此您可以通过检查Performance Schema来监控获取或等待的锁定服务锁metadata_locks表格

首先,启用元数据锁工具:

mysql >更新performance_schema。setup_instruments SET ENABLED = 'YES' -> WHERE NAME = 'wait/lock/metadata/sql/mdl';

然后获取一些锁并检查metadata_locks表:

mysql> SELECT service_get_write_locks('mynamespace', 'lock1', 0);+----------------------------------------------------+ | service_get_write_locks (' mynamespace ', ' lock1 ', 0 ) | +----------------------------------------------------+ | 1  | +----------------------------------------------------+ mysql >选择service_get_read_locks(“mynamespace”、“lock2”,0);+---------------------------------------------------+ | service_get_read_locks (' mynamespace ', ' lock2 ', 0 ) | +---------------------------------------------------+ | 1  | +---------------------------------------------------+ mysql >选择OBJECT_TYPE OBJECT_SCHEMA、OBJECT_NAME LOCK_TYPE LOCK_STATUS——从performance_schema >。metadata_locks——> OBJECT_TYPE = '锁定服务' \ G  *************************** 1。行  *************************** OBJECT_TYPE:锁定服务OBJECT_SCHEMA: mynamespace OBJECT_NAME: lock1 LOCK_TYPE:独家LOCK_STATUS:理所当然  *************************** 2。row *************************** OBJECT_TYPE:锁定服务OBJECT_SCHEMA: mynamespace OBJECT_NAME: lock2 LOCK_TYPE: SHARED LOCK_STATUS: GRANTED

锁定服务锁有一个OBJECT_TYPE的价值锁定服务.方法获得的锁是不同的GET_LOCK ()函数,其中有一个OBJECT_TYPE用户级锁

锁名称空间、名称和模式出现在OBJECT_SCHEMAOBJECT_NAME,LOCK_TYPE列。读写锁有LOCK_TYPE的值共享而且独家,分别。

LOCK_STATUS值是授予对于获得的锁,等待等待着一个锁。你可以期待看到等待如果一个会话持有写锁,而另一个会话试图获取具有相同标识符的锁。

锁定业务接口功能参考

锁定服务的SQL接口实现了本节中描述的可加载函数。有关用法示例,请参见使用锁定业务功能接口

这些功能具有以下特点:

  • 返回值为非零表示成功。否则将出现错误。

  • 命名空间和锁名称必须为非-,非空,且最大长度为64个字符。

  • 超时值必须是整数,指示在发生错误时放弃获取锁所需等待的秒数。如果超时为0,则不需要等待,如果不能立即获得锁,则函数会产生一个错误。

以下是可用的锁定服务功能: