Mysql
檢測伺服器是否是儲存過程中的主伺服器的最佳方法是什麼?
我想創建一個儲存過程/事件來執行一些維護任務。我的設置是為故障轉移場景配置的主/從(意味著從不用於報告,只是在主主故障的情況下可能會升級)。
我想讓這個儲存過程在兩者的事件調度程序中執行。在正常的操作過程中,我希望它做它的事情,讓這些操作通過正常的複制鏈流動。在故障轉移的情況下,我希望它只是檢測到它不是主人並繼續處理以前的奴隸。(在這樣的事件中,不必擔心就位的事情)。
我正在考慮將初始呼叫包裝在一個看起來像的虛擬碼塊中
如果 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