您好,登錄后才能下訂單哦!
MySQL 5.7.8或更高版本的發行版包括版本令牌,該特性支持創建和同步服務器令牌,應用程序可以使用這些令牌來防止訪問不正確或過時的數據。
版本令牌接口具有這些特征:
.版本令牌是由用作鍵或標識符的名稱和一個值組成的對
.版本令牌可以被鎖定。應用程序可以使用令牌鎖向其他協作應用程序表明正在使用令牌,不應該修改它們。
.每個服務器都建立版本令牌列表;例如,指定服務器分配或操作狀態。此外,與服務器通信的應用程序可以注冊自己的令牌列表,這些令牌表示它需要服務器處于的狀態。應用程序發送到不處于所需狀態的服務器的SQL語句將產生錯誤。這是給應用程序的一個信號,它應該尋找另一個處于所需狀態的服務器來接收SQL語句。
以下部分描述了版本令牌的組件,討論了如何安裝和使用它,并為其組件提供參考信息。
版本標識組件
名為version_token的服務器端插件持有與服務器關聯的版本令牌列表,并訂閱語句執行事件的通知。version_token插件使用審計插件API來監視來自客戶端的傳入語句,并將每個客戶端特定于會話的版本令牌列表與服務器版本令牌列表進行匹配。如果存在匹配,插件允許語句通過,服務器繼續處理它。否則,插件將向客戶端返回一個錯誤,語句將失敗。
一組用戶定義函數(udf)提供了一個sql級別的API,用于操作和檢查插件維護的服務器版本令牌列表。調用任何的令牌udf版本
系統變量允許客戶端指定注冊所需服務器狀態的版本令牌列表。如果客戶端發送語句時服務器處于不同的狀態,則客戶端接收到一個錯誤
安裝或卸載版本令牌
這里介紹如何安裝或卸載版本令牌,這些令牌是在包含插件和用戶定義函數的插件庫文件中實現的。有關安裝或卸載插件和udf的一般信息要使服務器可用,插件庫文件必須位于MySQL插件目錄中(由plugin_dir系統變量命名的目錄)。如果需要,在服務器啟動時設置plugin_dir的值,告訴服務器插件目錄的位置
插件庫的基本名是version_token。文件名后綴因平臺而異(例如,對于Unix和類Unix系統,.dll為Windows).
要安裝版本令牌插件和udf,請使用install plugin并創建函數語句(根據需要調整.so后綴):
mysql> INSTALL PLUGIN version_tokens SONAME 'version_token.so'; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 39 Current database: mysql Query OK, 0 rows affected (0.07 sec) mysql> CREATE FUNCTION version_tokens_set RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.02 sec) mysql> CREATE FUNCTION version_tokens_show RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.02 sec) mysql> CREATE FUNCTION version_tokens_edit RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.02 sec) mysql> CREATE FUNCTION version_tokens_delete RETURNS STRING SONAME 'version_token.so'; CREATE FUNCTION version_tokens_lock_shared RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.02 sec) mysql> CREATE FUNCTION version_tokens_lock_shared RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE FUNCTION version_tokens_lock_exclusive RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.00 sec) mysql> CREATE FUNCTION version_tokens_unlock RETURNS STRING SONAME 'version_token.so'; Query OK, 0 rows affected (0.03 sec)
您必須安裝udf來管理服務器的版本令牌列表,但是您還必須安裝插件,因為沒有它udf將無法正常工作。
如果在主復制服務器上使用插件和udf,也要將它們安裝在所有從服務器上,以避免復制問題
如前所述,一旦安裝完成,版本令牌插件和udf將一直保持安裝狀態,直到卸載為止。要刪除它們,使用UNINSTALL插件和DROP FUNCTION語句:
mysql> uninstall plugin version_tokens; Query OK, 0 rows affected, 1 warning (0.02 sec) mysql> drop function version_tokens_set; drop function version_tokens_show; Query OK, 0 rows affected (0.02 sec) mysql> drop function version_tokens_show; drop function version_tokens_edit; Query OK, 0 rows affected (0.00 sec) mysql> drop function version_tokens_edit; Query OK, 0 rows affected (0.00 sec) mysql> drop function version_tokens_delete; Query OK, 0 rows affected (0.01 sec) mysql> drop function version_tokens_lock_shared; Query OK, 0 rows affected (0.00 sec) mysql> drop function version_tokens_lock_exclusive; Query OK, 0 rows affected (0.00 sec) mysql> drop function version_tokens_unlock; Query OK, 0 rows affected (0.02 sec)
使用版本標記
版本令牌可能有用的一個場景是,系統訪問MySQL服務器集合,但是需要通過監視它們并根據負載變化調整服務器分配來管理它們,以實現負載平衡。這樣一個系統包括這些組件
.要管理的MySQL服務器集合
.與服務器通信并將它們組織成高可用性組的管理或管理應用程序。組有不同的用途,每個組中的服務器可能有不同的分配。某個組內的服務器的分配可以隨時更改
.訪問服務器以檢索和更新數據的客戶機應用程序,根據分配給它們的用途選擇服務器。例如,客戶端不應該向只讀服務器發送更新
版本令牌允許根據分配對服務器訪問進行管理,而不需要客戶端重復查詢服務器的分配
.管理應用程序執行服務器分配并在每個服務器上建立版本令牌以反映其分配。應用程序緩存此信息以提供對其的中央訪問點。如果在某個時候管理應用程序需要更改服務器分配(例如,將其從允許寫改為僅允許讀),則它將更改服務器的版本令牌列表并更新其緩存。
.為了提高性能,客戶端應用程序從管理應用程序獲取緩存信息,使它們不必為每個語句檢索關于服務器分配的信息。基于它將發出的語句類型(例如,讀與寫),客戶端選擇適當的服務器并連接到它
.此外,客戶端向服務器發送自己的客戶端特定版本的令牌來注冊它需要的服務器分配。對于客戶端發送到服務器的每個語句,服務器將自己的令牌列表與客戶端令牌列表進行比較。如果服務器令牌列表包含客戶端令牌列表中所有具有相同值的令牌,則存在匹配,服務器執行該語句
。
另一方面,可能管理應用程序更改了服務器分配及其版本令牌列表。在這種情況下,新的服務器分配現在可能與客戶端需求不兼容。服務器和客戶端令牌列表之間的令牌不匹配,服務器返回一個錯誤作為對語句的應答。這指示客戶機從管理應用程序緩存中刷新其版本令牌信息,并選擇要與之通信的新服務器。
檢測版本令牌錯誤和選擇新服務器的客戶端邏輯可以通過不同的方式實現:
.客戶端可以自己處理所有版本令牌注冊、不匹配檢測和連接切換
.這些操作的邏輯可以在管理客戶端和MySQL服務器之間連接的連接器中實現。這樣的連接器可以處理錯配錯誤檢測和語句重新發送本身,也可以將錯誤傳遞給應用程序,并將其留給應用程序重新發送語句。
下面的例子以更具體的形式說明了前面的討論。
當版本令牌在給定服務器上初始化時,服務器的版本令牌列表為空。通過調用用戶定義函數(udf)來執行令牌列表維護。調用任何版本令牌udf都需要超級特權,因此具有該特權的管理或管理應用程序需要修改令牌列表。
假設一個管理應用程序與一組服務器通信,客戶端查詢這些服務器以訪問雇員和產品數據庫(分別名為emp和prod)。所有服務器都被允許處理數據檢索語句,但只有一部分服務器被允許進行數據庫更新。為了在特定于數據庫的基礎上處理這個問題,管理應用程序在每個服務器上建立一個版本令牌列表。在給定服務器的令牌列表中,令牌名稱表示數據庫名稱,讀寫令牌值取決于數據庫是否必須以只讀方式使用,或者是否可以進行讀寫。
客戶端應用程序通過設置系統變量來注冊它們需要服務器匹配的版本令牌列表。變量設置是在客戶端特定的基礎上進行的,因此不同的客戶端可以注冊不同的需求。默認情況下,客戶端令牌列表是空的,它匹配任何服務器令牌列表。當客戶端將其令牌列表設置為非空值時,匹配可能成功也可能失敗,這取決于服務器版本令牌列表。
為了定義服務器的版本令牌列表,管理應用程序調用version_token_set() UDF。(稍后將介紹用于修改和顯示令牌列表的udf。)例如,應用程序可能將這些語句發送到三個服務器組成的組
服務器1:
mysql> SELECT version_tokens_set('emp=read;prod=read'); +------------------------------------------+ | version_tokens_set('emp=read;prod=read') | +------------------------------------------+ | 2 version tokens set. | +------------------------------------------+ 1 row in set (0.03 sec)
服務器2:
mysql> SELECT version_tokens_set('emp=write;prod=read'); +-------------------------------------------+ | version_tokens_set('emp=write;prod=read') | +-------------------------------------------+ | 2 version tokens set. | +-------------------------------------------+ 1 row in set (0.00 sec)
服務器3:
mysql> SELECT version_tokens_set('emp=read;prod=write'); +-------------------------------------------+ | version_tokens_set('emp=read;prod=write') | +-------------------------------------------+ | 2 version tokens set. | +-------------------------------------------+ 1 row in set (0.00 sec)
在每種情況下,令牌列表都被指定為以分號分隔的名稱=值對列表。產生的令牌列表值導致這些服務器連接:
.任何服務器都會接受對兩個數據庫中的任意一個進行讀取
.只有服務器2接受對emp數據庫的更新
.只有服務器3接受對prod數據庫的更新
除了為每個服務器分配一個版本令牌列表外,管理應用程序還維護一個反映服務器分配的緩存。
在與服務器通信之前,客戶機應用程序與管理應用程序進行聯系,并檢索關于服務器分配的信息。然后客戶端根據這些分配選擇服務器。假設客戶機希望同時執行對emp數據庫的讀寫操作。根據前面的分配,只有服務器2合格。客戶機連接到服務器2,并通過設置
version_tokens_session系統變量在服務器2上注冊服務器需求:
mysql> SET @@session.version_tokens_session = 'emp=write'; Query OK, 0 rows affected (0.00 sec)
對于客戶機發送到服務器2的后續語句,服務器將自己的版本令牌列表與客戶機列表進行比較,以檢查它們是否匹配。如果是,則語句正常執行:
mysql> UPDATE emp.employee SET salary = salary * 1.1 WHERE id = 4981; Query OK, 1 row affected (0.07 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> SELECT last_name, first_name FROM emp.employee WHERE 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. | +----------------------------------+ 1 row in set (0.00 sec)
服務器2:
mysql> SELECT version_tokens_edit('emp=read'); +---------------------------------+ | version_tokens_edit('emp=read') | +---------------------------------+ | 1 version tokens updated. | +---------------------------------+ 1 row in set (0.00 sec)
version_tokens_edit()修改服務器令牌列表中的指定令牌而其它的令牌不會改變。
當客戶機下一次向服務器2發送一條語句時,它自己的令牌列表將不再與服務器令牌列表匹配,并出現一個錯誤
mysql> UPDATE emp.employee SET salary = salary * 1.1 WHERE id = 4982; ERROR 3136 (42000): Version token mismatch for emp. Correct value read
在這種情況下,客戶端應該聯系管理應用程序以獲得關于服務器分配的更新信息,選擇一個新服務器,并將失敗的語句發送到新服務器
注意:每個客戶端必須與版本令牌進行協作,僅根據它在給定服務器上注冊的令牌列表發送語句。例如,如果客戶端注冊了一個'emp=read'的令牌列表,版本令牌中沒有任何內容可以阻止客戶端發送emp數據庫的更新。客戶本身必須避免這樣做
對于從客戶機接收到的每個語句,服務器隱式地使用鎖,如下所示:
.為客戶端令牌列表(即version_tokens_session值)中命名的每個令牌獲取一個共享鎖
.執行服務器和客戶端令牌列表之間的比較
.根據比較結果執行語句或產生錯誤
.釋放鎖
服務器使用共享鎖,以便可以在不阻塞的情況下對多個會話進行比較,同時防止對任何試圖在操作服務器令牌列表中具有相同名稱的令牌之前獲取獨占鎖的會話的令牌進行更改
前面的例子只使用了版本標記插件庫中包含的一些用戶定義,但是還有其他的。一組udf允許對服務器的版本令牌列表進行操作和檢查。另一組udf允許鎖定和解鎖版本標記
這些udf允許創建、更改、刪除和檢查服務器的版本標記列表:
.version_tokens_set()完全替換當前列表并分配一個新列表。參數是一個以分號分隔的名稱=值對列表。
.version_tokens_edit()支持對當前列表進行部分修改。它可以添加新的令牌或更改現有令牌的值。參數是一個以分號分隔的名稱=值對列表
.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. | +-------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT version_tokens_edit('tok3=c'); +-------------------------------+ | version_tokens_edit('tok3=c') | +-------------------------------+ | 1 version tokens updated. | +-------------------------------+ 1 row in set (0.00 sec) mysql> SELECT version_tokens_delete('tok2;tok1'); +------------------------------------+ | version_tokens_delete('tok2;tok1') | +------------------------------------+ | 2 version tokens deleted. | +------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT version_tokens_show(); +-----------------------+ | version_tokens_show() | +-----------------------+ | tok3=c; | +-----------------------+ 1 row in set (0.00 sec)
如果令牌列表格式不正確,就會出現警告:
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)
如前所述,版本標記是使用一個以分號分隔的名稱=值對列表來定義的。考慮一下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. | +---------------------------------------------------------------+ 1 row in set (0.00 sec)
版本標記對參數的解釋如下:
.名稱和值周圍的空白將被忽略。允許在名稱和值中使用空格。(對于version_tokens_delete(),它接受一個沒有值的名稱列表,名稱周圍的空白將被忽略。)
.沒有報價機制
.令牌的順序并不重要,除非令牌列表包含給定令牌名稱的多個實例,否則最后一個值優先于前面的值
根據這些規則,前面的version_tokens_set()調用會產生一個令牌列表,其中包含兩個令牌:tok1的值是1’2 3’4,tok2的值是a = b。
mysql> SELECT version_tokens_show(); +--------------------------+ | version_tokens_show() | +--------------------------+ | tok2=a = b;tok1=1'2 3"4; | +--------------------------+ 1 row in set (0.01 sec)
如果令牌列表包含兩個令牌,為什么version_tokens_set()返回設置的值3版本令牌?這是因為原來的令牌列表包含兩個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允許鎖定和解鎖版本標記。調用任何版本令牌UDF都需要超級特權。
下面的udf允許創建、更改、刪除和檢查服務器的版本令牌列表:
.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. | +------------------------------------+ 1 row in set (0.00 sec)
從MySQL 5.7.9開始,NULL參數被視為空字符串,這對令牌列表沒有影響。
version_tokens_delete()刪除其參數中指定的標記(如果它們存在的話)。(刪除不存在的令牌不是錯誤。)要在不知道列表中有哪些令牌的情況下完全清除令牌列表,請將NULL或不包含令牌的字符串傳遞給version_tokens_set():
mysql> SELECT version_tokens_set(NULL); +------------------------------+ | version_tokens_set(NULL) | +------------------------------+ | Version tokens list cleared. | +------------------------------+ 1 row in set (0.00 sec) mysql> SELECT version_tokens_set(''); +------------------------------+ | version_tokens_set('') | +------------------------------+ | Version tokens list cleared. | +------------------------------+ 1 row in set (0.00 sec)
.version_tokens_edit (token_list)
使用token_list參數修改服務器的版本令牌列表,并返回指示操作結果的二進制字符串。token_list是一個以分號分隔的名稱=值對列表,它指定要定義的每個令牌的名稱及其值。如果存在令牌,則使用給定的值更新其值。如果標記不存在,則使用給定的值創建它。如果參數為NULL或字符串不包含令牌,則令牌列表保持不變。
mysql> SELECT version_tokens_set('tok1=value1;tok2=value2'); +-----------------------------------------------+ | version_tokens_set('tok1=value1;tok2=value2') | +-----------------------------------------------+ | 2 version tokens set. | +-----------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT version_tokens_edit('tok2=new_value2;tok3=new_value3'); +--------------------------------------------------------+ | version_tokens_edit('tok2=new_value2;tok3=new_value3') | +--------------------------------------------------------+ | 2 version tokens updated. | +--------------------------------------------------------+ 1 row in set (0.00 sec)
.version_tokens_set (token_list)
用token_list參數中定義的令牌替換服務器的版本令牌列表,并返回指示操作結果的二進制字符串。token_list是一個用分號分隔的名稱=值對列表,指定要定義的每個令牌的名稱及其值。如果參數為空或字符串不包含令牌,則清除令牌列表。
mysql> SELECT version_tokens_set('tok1=value1;tok2=value2'); +-----------------------------------------------+ | version_tokens_set('tok1=value1;tok2=value2') | +-----------------------------------------------+ | 2 version tokens set. | +-----------------------------------------------+ 1 row in set (0.00 sec)
.version_tokens_show()
以二進制字符串的形式返回服務器的版本標記列表,其中包含一個以分號分隔的名稱=值對列表。
mysql> SELECT version_tokens_show(); +--------------------------+ | version_tokens_show() | +--------------------------+ | tok2=value2;tok1=value1; | +--------------------------+ 1 row in set (0.00 sec)
下面的udf允許鎖定和解鎖版本標記:
.version_tokens_lock_exclusive (token_name [token_name]…超時)
獲取一個或多個版本令牌(按名稱指定為字符串)上的獨占鎖,如果未在給定的超時值內獲取鎖,則超時并報錯
mysql> SELECT version_tokens_lock_exclusive('lock1', 'lock2', 10); +-----------------------------------------------------+ | version_tokens_lock_exclusive('lock1', 'lock2', 10) | +-----------------------------------------------------+ | 1 | +-----------------------------------------------------+
這個函數是在MySQL 5.7.8中添加的,名為vtoken_get_write_locks(),在5.7.9中重命名為version_tokens_lock_exclusive()
.version_tokens_lock_shared (token_name [token_name]…超時)
獲取一個或多個版本令牌(按名稱指定為字符串)上的共享鎖,如果未在給定的超時值內獲取鎖,則超時并報錯
mysql> SELECT version_tokens_lock_shared('lock1', 'lock2', 10); +--------------------------------------------------+ | version_tokens_lock_shared('lock1', 'lock2', 10) | +--------------------------------------------------+ | 1 | +--------------------------------------------------+
這個函數是在MySQL 5.7.8中添加的,名為vtoken_get_read_locks(),在5.7.9中重命名為version_tokens_lock_shared()
.version_tokens_unlock ()
使用version_tokens_lock_exclusive()和version_tokens_lock_shared()釋放在當前會話中獲取的所有鎖。
mysql> SELECT version_tokens_unlock(); +-------------------------+ | version_tokens_unlock() | +-------------------------+ | 1 | +-------------------------+
這個函數是在MySQL 5.7.8中添加的,名為vtoken_release_locks(),在5.7.9中重命名為version_tokens_unlock()。
鎖定功能共享這些特性:
.對于成功,返回值為非零。否則,將發生錯誤
.令牌名稱是字符串
.與操作服務器令牌列表的udf的參數處理不同,令牌名稱參數周圍的空白不會被忽略,并且=和;字符是允許的
.可以鎖定不存在的令牌名稱。這不會創建令牌
.超時值是非負整數,表示在出現錯誤超時之前等待獲取鎖所需的時間(以秒為單位)。如果超時為0,則不存在等待,如果不能立即獲取鎖,則該函數將產生一個錯誤
.版本令牌鎖定功能基于所描述的鎖定服務在Section 28.3.1 鎖服務中描述。
版本令牌系統變量
版本標記支持以下系統變量。這些變量不可用,除非安裝版本令牌插件
系統變量:
.version_tokens_session
命令行格式:--version-tokens-session=value
變量范圍:Global,Session
動態:Yes
允許的值:類型為字符串,默認值為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 a
第一個選擇成功是因為客戶端令牌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 | +---+
這個變量是在MySQL 5.7.8中添加的
.version_tokens_session_number
命令行格式:--version-tokens-session-number=N
變量范圍:Global,Session
動態:NO
允許的值:類型為整型,默認值為0
此變量供內部使用。
這個變量是在MySQL 5.7.8中添加的。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。