Mysql

檢測伺服器是否是儲存過程中的主伺服器的最佳方法是什麼?

  • June 4, 2014

我想創建一個儲存過程/事件來執行一些維護任務。我的設置是為故障轉移場景配置的主/從(意味著從不用於報告,只是在主主故障的情況下可能會升級)。

我想讓這個儲存過程在兩者的事件調度程序中執行。在正常的操作過程中,我希望它做它的事情,讓這些操作通過正常的複制鏈流動。在故障轉移的情況下,我希望它只是檢測到它不是主人並繼續處理以前的奴隸。(在這樣的事件中,不必擔心就位的事情)。

我正在考慮將初始呼叫包裝在一個看起來像的虛擬碼塊中

如果 I_AM_MASTER 那麼

呼叫 real_work_sp;

萬一;

測試 I_AM_MASTER 的最佳方法是什麼?我知道我可以從命令行顯示主狀態,但我不確定如何擷取該狀態以用於此測試。我該怎麼做,或者有更好的方法嗎?

PS 這些操作不僅僅是刪除,如果它們碰巧執行兩次,我可以讓“失敗”。

如果主伺服器連接了從伺服器,這將起作用

SELECT COUNT(1) FROM
(SELECT user FROM information_schema.processlist) A
INNER JOIN
(SELECT user FROM mysql.user B WHERE repl_slave_priv = 'Y')
USING (user);

如果答案是…

  • > 0,Replication 正在執行(這表明這是一個 Master)
  • = 0,複製未執行

您還可以檢查全域狀態變數“Slave_running”

SELECT COUNT(1) FROM information_schema.global_status
WHERE variable_name = 'Slave_running'
AND variable_value = 'ON';

如果答案是…

  • > 0,複製正在執行(這表明這是一個從站)
  • = 0,複製未執行

您還可以檢查“系統使用者”的程序列表

SELECT COUNT(1) FROM information_schema.processlist
WHERE user = 'system user';

如果答案是…

  • = 2,Replication 正在執行(這表明這是一個 Slave)
  • = 1,複製被破壞(這表明這是一個從站)
  • = 0,複製未執行

我希望這些查詢能給你一些方向。

警告

SHOW MASTER STATUS;只是告訴你目前的二進制日誌是什麼。如果您的從站禁用了二進制日誌,則不SHOW MASTER STATUS;返回任何內容。無法在 information_schema 數據庫中擷取此資訊。

唯一明顯的方法是

  • SHOW SLAVE STATUS\G
  • 在作業系統中查找 master.info 文件

更新 2011-12-30 12:50 EDT

這是從您的奴隸中辨識您的主人的簡單方法:創建一個表,其唯一目的是保存構成您的主人的伺服器名稱。在所有數據庫伺服器(主伺服器和從伺服器)上執行這些命令

CREATE TABLE mysql.MasterList
(
   hostname VARCHAR(64),
   PRIMARY KEY (hostname)
) ENGINE=MyISAM;
INSERT INTO mysql.MasterList VALUES ('dbserver1'),('dbserver2'),('dbserver3');

現在只需執行此查詢以確定它是否是 Master:

SELECT COUNT(1) INTO @IsThisMaster FROM 
(SELECT variable_value hostname FROM information_schema.global_variables
WHERE variable_name='hostname') A
INNER JOIN mysql.MasterList B USING (hostname);

這是使用 MySQL 5.5.12 在我的 PC 上執行的範例

mysql> show variables like 'hostname';
+---------------+--------------+
| Variable_name | Value        |
+---------------+--------------+
| hostname      | LW-REDWARDS2 |
+---------------+--------------+
1 row in set (0.00 sec)

mysql> CREATE TABLE mysql.MasterList
   -> (
   ->     hostname VARCHAR(64),
   ->     PRIMARY KEY (hostname)
   -> ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO mysql.MasterList VALUES ('dbserver1'),('dbserver2'),('dbserver3');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT COUNT(1) INTO @IsThisMaster FROM
   -> (SELECT variable_value hostname FROM information_schema.global_variables
   -> WHERE variable_name='hostname') A
   -> INNER JOIN mysql.MasterList B USING (hostname);
Query OK, 1 row affected (0.01 sec)

mysql> SELECT @IsThisMaster;
+---------------+
| @IsThisMaster |
+---------------+
|             0 |
+---------------+
1 row in set (0.00 sec)

mysql> INSERT INTO mysql.MasterList VALUES ('LW-REDWARDS2');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT COUNT(1) INTO @IsThisMaster FROM
   -> (SELECT variable_value hostname FROM information_schema.global_variables
   -> WHERE variable_name='hostname') A
   -> INNER JOIN mysql.MasterList B USING (hostname);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT @IsThisMaster;
+---------------+
| @IsThisMaster |
+---------------+
|             1 |
+---------------+
1 row in set (0.00 sec)

mysql>

試一試 !!!

更新 2011-12-30 13:06 EDT

這是您需要的儲存函式:

DELIMITER $$

DROP FUNCTION IF EXISTS `mysql`.`Is_This_A_Master` $$
CREATE FUNCTION `mysql`.`Is_This_A_Master` () RETURNS INT
DETERMINISTIC
BEGIN

   SELECT COUNT(1) INTO @IsThisReplicationMaster FROM
   (SELECT variable_value hostname FROM information_schema.global_variables
   WHERE variable_name='hostname') A
   INNER JOIN mysql.MasterList B USING (hostname);

   RETURN @IsThisReplicationMaster;

END $$

DELIMITER ;

這是一個範例呼叫:

mysql> select mysql.Is_This_A_Master();
+--------------------------+
| mysql.Is_This_A_Master() |
+--------------------------+
|                        1 |
+--------------------------+

更新 2011-12-30 13:12 EDT

只要記住

  • 一旦伺服器成為從屬伺服器,從 mysql.MasterList 中刪除該主機名
  • 一旦伺服器成為主伺服器,將該主機名插入 mysql.MasterList

引用自:https://dba.stackexchange.com/questions/9938