MySQL服务器版本令牌插件
MySQL包括版本令牌,该功能可用于创建服务器令牌并围绕服务器令牌进行同步,应用程序可使用该服务器令牌来防止访问不正确或过时的数据。
版本令牌接口具有以下特征:
- 版本令牌是由用作密钥或标识符的名称以及一个值组成的对。
- 版本令牌可以被锁定。应用程序可以使用令牌锁来向其他合作应用程序指示令牌正在使用中,不应进行修改。
- 每个服务器都建立了版本令牌列表(例如,用于指定服务器分配或操作状态)。此外,与服务器通信的应用程序可以注册自己的令牌列表,这些令牌指示需要服务器进入的状态。该应用程序发送到未处于必需状态的服务器的SQL语句会产生错误。这是向应用程序发出的信号,它应在所需状态下寻求其他服务器以接收SQL语句。
以下各节描述了版本令牌的组件,讨论了如何安装和使用它,并提供了其组件的参考信息。
版本令牌插件
版本令牌基于实现以下组件的插件库:
- 一个名为的服务器端插件
version_tokens
保存与服务器关联的版本令牌列表,并订阅有关语句执行事件的通知。该version_tokens
插件使用审核插件API监视来自客户端的传入语句,并将每个客户端的特定于会话的版本令牌列表与服务器版本令牌列表进行匹配。如果存在匹配项,则插件将允许该语句通过,服务器将继续对其进行处理。否则,插件会向客户端返回错误,并且语句失败。 - 一组用户定义函数(UDF)提供了一个SQL级API,用于处理和检查由插件维护的服务器版本令牌的列表。必须具有
VERSION_TOKEN_ADMIN
或SUPER
特权才能调用任何版本令牌UDF。 - 当
version_tokens
插件加载时,它定义了VERSION_TOKEN_ADMIN
动态特权。可以向UDF的用户授予此特权。 - 系统变量使客户端可以指定注册所需服务器状态的版本令牌列表。如果客户端发送语句时服务器具有不同的状态,则客户端会收到错误。
安装或卸载版本令牌
注意如果安装了版本令牌,则会涉及一些开销。为避免这种开销,除非计划使用它,否则不要安装它。
本节介绍如何安装或卸载版本令牌,该版本令牌是在包含插件和用户定义函数(UDF)的插件库文件中实现的。有关安装或卸载插件和UDF的一般信息,请参见“MySQL服务器插件”和“安装和卸载用户定义的功能”。
要由服务器使用,插件库文件必须位于MySQL插件目录(由plugin_dir
系统变量命名的目录)中。如有必要,通过设置plugin_dir
服务器启动时的值来配置插件目录位置。
插件库文件的基本名称为version_tokens
。每个平台的文件名后缀都不同(例如,.so
对于Unix和类似Unix的系统,.dll
对于Windows)。
要安装版本令牌插件和UDF,请使用INSTALL PLUGIN
和CREATE FUNCTION
语句(.so
根据需要调整平台的后缀):
INSTALL PLUGIN version_tokensSONAME 'version_token.so';CREATE FUNCTION version_tokens_setRETURNS STRING SONAME 'version_token.so';CREATE FUNCTION version_tokens_showRETURNS STRING SONAME 'version_token.so';CREATE FUNCTION version_tokens_editRETURNS STRING SONAME 'version_token.so';CREATE FUNCTION version_tokens_deleteRETURNS STRING SONAME 'version_token.so';CREATE FUNCTION version_tokens_lock_sharedRETURNS INTSONAME 'version_token.so';CREATE FUNCTION version_tokens_lock_exclusiveRETURNS INTSONAME 'version_token.so';CREATE FUNCTION version_tokens_unlockRETURNS INTSONAME 'version_token.so';
您必须安装UDF来管理服务器的版本令牌列表,但还必须安装插件,因为没有它,UDF将无法正常工作。
如果插件和UDF在主复制服务器上使用,请在所有从属服务器上也安装它们,以避免复制问题。
如前所述安装后,插件和UDF将保持安装状态,直到被卸载。要删除它们,请使用UNINSTALL PLUGIN
nd DROP FUNCTION
语句:
UNINSTALL PLUGIN version_tokens;DROP FUNCTION version_tokens_set;DROP FUNCTION version_tokens_show;DROP FUNCTION version_tokens_edit;DROP FUNCTION version_tokens_delete;DROP FUNCTION version_tokens_lock_shared;DROP FUNCTION version_tokens_lock_exclusive;DROP FUNCTION version_tokens_unlock;
使用版本令牌
在使用版本令牌之前,请根据“安装或卸载版本令牌”中提供的说明进行安装。
使用版本令牌的情况是,系统访问一个MySQL服务器集合,但需要通过监视它们并根据负载变化调整服务器分配来管理它们以实现负载平衡。这样的系统包括以下组件:
- 要管理的MySQL服务器的集合。
- 与服务器进行通信并将其组织为高可用性组的管理或管理应用程序。组具有不同的用途,每个组中的服务器可能具有不同的分配。特定组中服务器的分配可以随时更改。
- 访问服务器以检索和更新数据的客户端应用程序,根据分配给它们的目的选择服务器。例如,客户端不应将更新发送到只读服务器。
版本令牌允许根据分配来管理服务器访问,而无需客户端重复查询服务器有关其分配的信息:
管理应用程序执行服务器分配,并在每个服务器上建立版本令牌以反映其分配。应用程序将缓存此信息,以为其提供中央访问点。
如果某个时候管理应用程序需要更改服务器分配(例如,将其从允许写入更改为只读),它将更改服务器的版本令牌列表并更新其缓存。
- 为了提高性能,客户端应用程序从管理应用程序获取缓存信息,从而使它们避免必须检索有关每个语句的服务器分配的信息。根据要发出的语句的类型(例如,读取还是写入),客户端选择适当的服务器并连接到该服务器。
另外,客户端向服务器发送自己的客户端特定版本令牌,以注册其所需的服务器分配。对于客户端发送到服务器的每个语句,服务器会将自己的令牌列表与客户端令牌列表进行比较。如果服务器令牌列表包含客户端令牌列表中存在的所有具有相同值的令牌,则存在匹配项,服务器将执行该语句。
另一方面,也许管理应用程序已更改服务器分配及其版本令牌列表。在这种情况下,新的服务器分配现在可能与客户端要求不兼容。服务器和客户端令牌列表之间的令牌不匹配,服务器返回错误以回复该语句。这指示客户端从管理应用程序缓存中刷新其版本令牌信息,并选择要与之通信的新服务器。
用于检测版本令牌错误和选择新服务器的客户端逻辑可以通过以下方式实现:
- 客户端可以自行处理所有版本令牌注册,不匹配检测和连接切换。
- 这些动作的逻辑可以在管理客户端和MySQL服务器之间连接的连接器中实现。这样的连接器可能会处理不匹配错误检测并重新发送自身的语句,或者可能会将错误传递给应用程序,然后将其留给应用程序以重新发送语句。
以下示例以更具体的形式说明了前面的讨论。
当版本令牌在给定服务器上初始化时,该服务器的版本令牌列表为空。令牌列表维护通过调用用户定义函数(UDF)来执行。该VERSION_TOKEN_ADMIN
或SUPER
权限才能调用任何版本令牌的UDF,所以令牌列表修改预期由具有相应权限的管理或行政程序来完成。
假设管理应用程序与客户端查询的一组服务器进行通信,以访问员工和产品数据库(分别命名为emp
和prod
)。允许所有服务器处理数据检索语句,但只允许其中一些进行数据库更新。为了在特定于数据库的基础上处理此问题,管理应用程序在每个服务器上建立一个版本令牌列表。在给定服务器的令牌列表中,令牌名称表示数据库名称,令牌值取决于read
或write
取决于是否必须以只读方式使用数据库,或者是否可以进行读写操作。
客户端应用程序通过设置系统变量来注册它们要求服务器匹配的版本令牌的列表。变量设置是基于特定于客户端的,因此不同的客户端可以注册不同的需求。默认情况下,客户端令牌列表为空,与任何服务器令牌列表匹配。当客户端将其令牌列表设置为非空值时,匹配可能成功还是失败,具体取决于服务器版本的令牌列表。
要定义服务器的版本令牌列表,管理应用程序将调用version_tokens_set()
UDF。(还有用于修改和显示令牌列表的UDF,如后所述。)例如,应用程序可能会将这些语句发送到三个服务器组成的一组:
服务器1:
mysql>SELECT version_tokens_set('emp=read;prod=read'); +------------------------------------------ + | version_tokens_set('emp=read;prod=read') | +------------------------------------------ + | 2 version tokens set. | +------------------------------------------ +
服务器2:
mysql>SELECT version_tokens_set('emp=write;prod=read'); +------------------------------------------- + | version_tokens_set('emp=write;prod=read') | +------------------------------------------- + | 2 version tokens set. | +------------------------------------------- +
服务器3:
mysql>SELECT version_tokens_set('emp=read;prod=write'); +------------------------------------------- + | version_tokens_set('emp=read;prod=write') | +------------------------------------------- + | 2 version tokens set. | +------------------------------------------- +
在每种情况下,令牌列表都指定为以分号分隔的对列表。结果令牌列表值将导致以下服务器分配:name=value
- 任何服务器都接受对任一数据库的读取。
- 仅服务器2接受
emp
数据库更新。 - 仅服务器3接受
prod
数据库更新。
除了为每个服务器分配版本令牌列表之外,管理应用程序还维护反映服务器分配的缓存。
在与服务器通信之前,客户端应用程序联系管理应用程序并检索有关服务器分配的信息。然后,客户端根据这些分配选择服务器。假设客户端要在emp
数据库上执行读取和写入操作。根据前面的分配,只有服务器2合格。客户端连接到服务器2并通过设置其version_tokens_session
系统变量在其中注册其服务器要求:
mysql>SET @@SESSION.version_tokens_session = 'emp=write';
对于客户端发送到服务器2的后续语句,服务器将自己的版本令牌列表与客户端列表进行比较,以检查它们是否匹配。如果是这样,则语句将正常执行:
mysql>UPDATE emp.employeeSET salary = salary * 1.1WHERE id = 4981; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql>SELECT last_name, first_nameFROM emp.employeeWHERE id = 4981; +----------- +------------ + | last_name | first_name | +----------- +------------ + | Smith | Abe | +----------- +------------ + 1 row in set (0.01 sec)
服务器和客户端版本令牌列表之间的差异可以通过两种方式发生:
- 该
version_tokens_session
值中的令牌名称不在服务器令牌列表中。在这种情况下,将ER_VTOKEN_PLUGIN_TOKEN_NOT_FOUND
发生错误。 - 值中的令牌值
version_tokens_session
与服务器令牌列表中相应令牌的值不同。在这种情况下,将ER_VTOKEN_PLUGIN_TOKEN_MISMATCH
发生错误。
只要服务器2的分配没有更改,客户端就会继续使用它进行读取和写入。但是,假设管理应用程序想要更改服务器分配,以便emp
必须将数据库的写操作发送到服务器1而不是服务器2。为此,它用于version_tokens_edit()
修改emp
两个服务器上的令牌值(并更新其服务器缓存)作业):
服务器1:
mysql>SELECT version_tokens_edit('emp=write'); +---------------------------------- + | version_tokens_edit('emp=write') | +---------------------------------- + | 1 version tokens updated. | +---------------------------------- +
服务器2:
mysql>SELECT version_tokens_edit('emp=read'); +--------------------------------- + | version_tokens_edit('emp=read') | +--------------------------------- + | 1 version tokens updated. | +--------------------------------- +
version_tokens_edit()
修改服务器令牌列表中的命名令牌,并使其他令牌保持不变。
客户端下一次向服务器2发送一条语句时,其自己的令牌列表不再与服务器令牌列表匹配,并且发生错误:
mysql>UPDATE emp.employeeSET salary = salary * 1.1WHERE id = 4982; ERROR 3136 (42000): Version token mismatch for emp. Correct value read
在这种情况下,客户端应联系管理应用程序以获取有关服务器分配的更新信息,选择新服务器,然后将失败的语句发送到新服务器。
注意每个客户端必须通过仅根据其在给定服务器中注册的令牌列表发送语句来与版本令牌合作。例如,如果客户端注册的令牌列表
'emp=read'
,则“版本令牌”中没有任何内容可阻止客户端发送emp
数据库更新。客户本身必须避免这样做。
对于从客户端收到的每个语句,服务器将隐式使用锁定,如下所示:
- 为客户端令牌列表(即
version_tokens_session
值)中命名的每个令牌获取共享锁 - 执行服务器和客户端令牌列表之间的比较
- 根据比较结果执行语句或产生错误
- 释放锁
服务器使用共享锁,因此可以在不阻塞的情况下进行多个会话的比较,同时防止任何在尝试操纵服务器令牌列表中相同名称的令牌之前尝试获取排他锁的会话的令牌更改。
前面的示例仅使用了Version Tokens插件库中包含的一些用户定义,但还有其他一些。一组UDF允许操作和检查服务器的版本令牌列表。另一组UDF允许版本令牌被锁定和解锁。
这些UDF允许创建,更改,删除和检查服务器的版本令牌列表:
version_tokens_set()
完全替换当前列表并分配一个新列表。参数是用分号分隔的对列表。name=value
version_tokens_edit()
可以对当前列表进行部分修改。它可以添加新令牌或更改现有令牌的值。参数是用分号分隔的对列表。name=value
version_tokens_delete()
从当前列表中删除令牌。参数是用分号分隔的标记名称列表。version_tokens_show()
显示当前令牌列表。不用争论。
这些函数中的每个函数(如果成功)都将返回一个二进制字符串,指示发生了什么操作。以下示例建立服务器令牌列表,通过添加新令牌对其进行修改,删除一些令牌,然后显示结果令牌列表:
mysql>SELECT version_tokens_set('tok1=a;tok2=b'); +------------------------------------- + | version_tokens_set('tok1=a;tok2=b') | +------------------------------------- + | 2 version tokens set. | +------------------------------------- + mysql>SELECT version_tokens_edit('tok3=c'); +------------------------------- + | version_tokens_edit('tok3=c') | +------------------------------- + | 1 version tokens updated. | +------------------------------- + mysql>SELECT version_tokens_delete('tok2;tok1'); +------------------------------------ + | version_tokens_delete('tok2;tok1') | +------------------------------------ + | 2 version tokens deleted. | +------------------------------------ + mysql>SELECT version_tokens_show(); +----------------------- + | version_tokens_show() | +----------------------- + | tok3=c; | +----------------------- +
如果令牌列表格式错误,则会出现警告:
mysql>SELECT version_tokens_set('tok1=a; =c'); +---------------------------------- + | version_tokens_set('tok1=a; =c') | +---------------------------------- + | 1 version tokens set. | +---------------------------------- + 1 row in set, 1 warning (0.00 sec) mysql>SHOW WARNINGS \G *************************** 1. row *************************** Level : Warning Code : 42000 Message : Invalid version token pair encountered. The list provided is only partially updated. 1 row in set (0.00 sec)
如前所述,版本令牌是使用分号分隔的对列表定义的。考虑以下调用:name=value
version_tokens_set()
mysql>SELECT version_tokens_set('tok1=b;;; tok2= a = b ; tok1 = 1\'2 3"4') +--------------------------------------------------------------- + | version_tokens_set('tok1=b;;; tok2= a = b ; tok1 = 1\'2 3"4') | +--------------------------------------------------------------- + | 3 version tokens set. | +--------------------------------------------------------------- +
版本令牌将参数解释如下:
- 名称和值周围的空格将被忽略。名称和值中允许使用空格。(对于
version_tokens_delete()
,它使用没有值的名称列表,名称周围的空格将被忽略。) - 没有报价机制。
- 令牌的顺序并不重要,除非令牌列表包含给定令牌名称的多个实例,最后一个值优先于较早的值。
根据这些规则,前面的version_tokens_set()
调用将生成一个带有两个标记的标记列表:tok1
具有的值1'2 3"4
和tok2
具有的值= b
。要验证这一点,请致电version_tokens_show()
:
mysql>SELECT version_tokens_show(); +-------------------------- + | version_tokens_show() | +-------------------------- + | tok2=a = b;tok1=1'2 3"4; | +-------------------------- +
如果令牌列表包含两个令牌,为什么version_tokens_set()
返回该值3 version tokens set
?发生这种情况是因为原始令牌列表包含的两个定义tok1
,而第二个定义替换了第一个定义。
版本令牌令牌操作UDF将这些约束放在令牌名称和值上:
- 令牌名称不能包含
=
或个;
字符,并且最大长度为64个字符。 - 令牌值不能包含
;
字符。值的长度受max_allowed_packet
系统变量的值约束。 - 版本令牌将令牌名称和值视为二进制字符串,因此比较区分大小写。
版本令牌还包括一组UDF,使令牌可以被锁定和解锁:
version_tokens_lock_exclusive()
获取独占版本令牌锁。它包含一个或多个锁名称和超时值的列表。version_tokens_lock_shared()
获取共享版本令牌锁。它包含一个或多个锁名称和超时值的列表。version_tokens_unlock()
释放版本令牌锁(独占和共享)。不用争论。
每个锁定函数返回非零值即可成功。否则,将发生错误:
mysql>SELECT version_tokens_lock_shared('lock1', 'lock2', 0); +------------------------------------------------- + | version_tokens_lock_shared('lock1', 'lock2', 0) | +------------------------------------------------- + | 1 | +------------------------------------------------- + mysql>SELECT version_tokens_lock_shared(NULL, 0); ERROR 3131 (42000): Incorrect locking service lock name '(null)'.
建议使用“版本令牌”锁定功能进行锁定。申请必须同意合作。
可以锁定不存在的令牌名称。这不会创建令牌。
注意版本令牌锁定功能基于“锁定服务”中描述的锁定服务,因此对于共享锁定和互斥锁定具有相同的语义。(版本令牌使用服务器中内置的锁定服务例程,而不使用锁定服务UDF接口,因此不需要安装这些UDF即可使用版本令牌。)版本令牌获得的锁使用的锁定服务命名空间
version_token_locks
。可以使用性能模式监视锁定服务锁,因此对于版本令牌锁也是如此。有关详细信息,请参见“锁定服务监视”。
对于版本令牌锁定功能,令牌名称参数的使用与指定的完全相同。周围的空格不会被忽略,=
并且;
允许使用字符。这是因为版本令牌只是将要锁定的令牌名称照原样传递给锁定服务。
版本令牌参考
以下讨论可作为对这些版本令牌组件的参考:
- 版本令牌功能
- 版本令牌系统变量
版本令牌功能
版本令牌插件库包括几个用户定义的函数。一组UDF允许操作和检查服务器的版本令牌列表。另一组UDF允许版本令牌被锁定和解锁。该VERSION_TOKEN_ADMIN
或SUPER
权限才能调用任何版本令牌UDF。
以下UDF允许创建,更改,删除和检查服务器的版本令牌列表。如“使用版本标记”所述,对参数进行解释name_list
和解释token_list
(包括空白处理),该节提供了有关指定标记的语法的详细信息以及其他示例。
version_tokens_delete(name_list)
使用
name_list
参数从服务器的版本令牌列表中删除令牌,并返回指示操作结果的二进制字符串。name_list
是要删除的版本令牌名称的列表,以分号分隔。mysql>
SELECT version_tokens_delete('tok1;tok3'); +------------------------------------ + | version_tokens_delete('tok1;tok3') | +------------------------------------ + | 2 version tokens deleted. | +------------------------------------ +参数
NULL
被视为空字符串,这对令牌列表没有影响。version_tokens_delete()
删除其参数中命名的标记(如果存在)。(删除不存在的令牌不是错误。)要完全清除令牌列表而不知道列表中有哪些令牌,请将NULL
或不包含令牌的字符串传递给version_tokens_set()
:mysql>
SELECT version_tokens_set(NULL); +------------------------------ + | version_tokens_set(NULL) | +------------------------------ + | Version tokens list cleared. | +------------------------------ + mysql>SELECT version_tokens_set(''); +------------------------------ + | version_tokens_set('') | +------------------------------ + | Version tokens list cleared. | +------------------------------ +version_tokens_edit(token_list)
使用
token_list
参数修改服务器的版本令牌列表,并返回指示操作结果的二进制字符串。token_list
是用分号分隔的成对列表,用于指定要定义的每个令牌的名称及其值。如果令牌存在,则将其值更新为给定值。如果令牌不存在,则会使用给定值创建令牌。如果参数是或不包含令牌的字符串,则令牌列表保持不变。name=value
NULL
mysql>
SELECT version_tokens_set('tok1=value1;tok2=value2'); +----------------------------------------------- + | version_tokens_set('tok1=value1;tok2=value2') | +----------------------------------------------- + | 2 version tokens set. | +----------------------------------------------- + mysql>SELECT version_tokens_edit('tok2=new_value2;tok3=new_value3'); +-------------------------------------------------------- + | version_tokens_edit('tok2=new_value2;tok3=new_value3') | +-------------------------------------------------------- + | 2 version tokens updated. | +-------------------------------------------------------- +version_tokens_set(token_list)
用
token_list
参数中定义的标记替换服务器的版本标记列表,并返回指示操作结果的二进制字符串。token_list
是用分号分隔的成对列表,用于指定要定义的每个令牌的名称及其值。如果参数是或不包含令牌的字符串,则清除令牌列表。name=value
NULL
mysql>
SELECT version_tokens_set('tok1=value1;tok2=value2'); +----------------------------------------------- + | version_tokens_set('tok1=value1;tok2=value2') | +----------------------------------------------- + | 2 version tokens set. | +----------------------------------------------- +version_tokens_show()
以二进制字符串形式返回服务器的版本令牌列表,该二进制字符串包含以分号分隔的对列表。
name=value
mysql>
SELECT version_tokens_show(); +-------------------------- + | version_tokens_show() | +-------------------------- + | tok2=value2;tok1=value1; | +-------------------------- +
以下UDF允许版本令牌被锁定和解锁:
version_tokens_lock_exclusive(token_name[,token_name]...,timeout)
获取一个或多个版本令牌的排他锁,这些令牌由名称指定为字符串,如果未在给定的超时值内获取锁,则会超时并出错。
mysql>
SELECT version_tokens_lock_exclusive('lock1', 'lock2', 10); +----------------------------------------------------- + | version_tokens_lock_exclusive('lock1', 'lock2', 10) | +----------------------------------------------------- + | 1 | +----------------------------------------------------- +version_tokens_lock_shared(token_name[,token_name]...,timeout)
获取一个或多个版本令牌的共享锁,这些共享令牌由名称指定为字符串,如果未在给定的超时值内获取锁,则会超时并显示错误。
mysql>
SELECT version_tokens_lock_shared('lock1', 'lock2', 10); +-------------------------------------------------- + | version_tokens_lock_shared('lock1', 'lock2', 10) | +-------------------------------------------------- + | 1 | +-------------------------------------------------- +version_tokens_unlock()
使用
version_tokens_lock_exclusive()
和释放当前会话中获得的所有锁version_tokens_lock_shared()
。mysql>
SELECT version_tokens_unlock(); +------------------------- + | version_tokens_unlock() | +------------------------- + | 1 | +------------------------- +
锁定功能具有以下特征:
- 成功返回值非零。否则,将发生错误。
- 令牌名称是字符串。
- 与操纵服务器令牌列表的UDF的参数处理相反,令牌名称参数周围的空格不会被忽略,
=
并且;
允许使用字符。 - 可以锁定不存在的令牌名称。这不会创建令牌。
- 超时值是非负整数,表示错误超时之前等待获取锁的时间(以秒为单位)。如果超时为0,则没有等待,如果无法立即获取锁,该函数将产生错误。
- 版本令牌锁定功能基于“锁定服务”中所述的锁定服务。
版本令牌系统变量
版本令牌支持以下系统变量。除非安装了版本令牌插件,否则这些变量不可用(请参见“安装或卸载版本令牌”)。
系统变量:
version_tokens_session
属性 值 命令行格式 --version-tokens-session=value
系统变量 version_tokens_session
范围 Global, Session 动态 是 SET_VAR
提示适用没有 类型 string 默认值 NULL
此变量的会话值指定客户端版本令牌列表,并指示客户端会话要求服务器版本令牌列表具有的令牌。
如果
version_tokens_session
变量是NULL
(默认值)或具有空值,则任何服务器版本令牌列表都匹配。(实际上,空值将禁用匹配要求。)如果
version_tokens_session
变量具有非空值,则其值与服务器版本令牌列表之间的任何不匹配都会导致会话发送到服务器的任何语句出错。在以下情况下会发生不匹配:- 该
version_tokens_session
值中的令牌名称不在服务器令牌列表中。在这种情况下,将ER_VTOKEN_PLUGIN_TOKEN_NOT_FOUND
发生错误。 - 值中的令牌值
version_tokens_session
与服务器令牌列表中相应令牌的值不同。在这种情况下,将ER_VTOKEN_PLUGIN_TOKEN_MISMATCH
发生错误。
服务器版本令牌列表包括未在
version_tokens_session
值中命名的令牌,这并非不匹配。假设管理应用程序已按如下所示设置服务器令牌列表:
mysql>
SELECT version_tokens_set('tok1=a;tok2=b;tok3=c'); +-------------------------------------------- + | version_tokens_set('tok1=a;tok2=b;tok3=c') | +-------------------------------------------- + | 3 version tokens set. | +-------------------------------------------- +客户端通过设置其
version_tokens_session
值来注册它要求服务器匹配的令牌。然后,对于客户端发送的每个后续语句,服务器将根据客户端version_tokens_session
值检查其令牌列表,如果不匹配,则会产生错误:mysql>
SET @@SESSION.version_tokens_session = 'tok1=a;tok2=b'; mysql>SELECT 1; +--- + | 1 | +--- + | 1 | +--- + mysql>SET @@SESSION.version_tokens_session = 'tok1=b'; mysql>SELECT 1; ERROR 3136 (42000): Version token mismatch for tok1. Correct value第一个
SELECT
成功,因为客户端令牌tok1
和tok2
存在于服务器令牌列表中,并且每个令牌在服务器列表中具有相同的值。第二个SELECT
失败,因为尽管tok1
它存在于服务器令牌列表中,但其值与客户端指定的值不同。此时,除非服务器令牌列表更改为再次匹配,否则客户端发送的任何语句都会失败。假设管理应用程序更改服务器令牌列表,如下所示:
mysql>
SELECT version_tokens_edit('tok1=b'); +------------------------------- + | version_tokens_edit('tok1=b') | +------------------------------- + | 1 version tokens updated. | +------------------------------- + mysql>SELECT version_tokens_show(); +----------------------- + | version_tokens_show() | +----------------------- + | tok3=c;tok1=b;tok2=b; | +----------------------- +现在,客户端
version_tokens_session
值与服务器令牌列表匹配,并且客户端可以再次成功执行语句:mysql>
SELECT 1; +--- + | 1 | +--- + | 1 | +--- +- 该
version_tokens_session_number
属性 值 命令行格式 --version-tokens-session-number=#
系统变量 version_tokens_session_number
范围 Global, Session 动态 没有 SET_VAR
提示适用没有 类型 Integer 默认值 0
此变量仅供内部使用。