使用MySQL內建復制技巧來最佳化可用性(二)
發表時間:2023-08-16 來源:明輝站整理相關軟件相關文章人氣:
[摘要]第三步:創建相互的主從關系 首先在B機上的my.cnf文件中,在[mysqld]部分中加入'log-bin',接著重新啟動mysqld,然后創建可在它的上面執行復制功能的用戶帳號...
第三步:創建相互的主從關系
首先在B機上的my.cnf文件中,在[mysqld]部分中加入'log-bin',接著重新啟動mysqld,然后創建可在它的上面執行復制功能的用戶帳號,使用:
GRANT FILE ON *.* TO
[email protected] IDENTIFIED BY 'password';
在B機上運行'FLUSH PRIVILEGES'命令,以便裝入在加入復制用戶后的新的授權表,接著回到A機上,在它的'my.cnf'中加入下面幾行:
master-host=10.1.1.2
master-user=replicate
master-password=password
在重啟A機的服務程序之后,現在我們一擁有了在A機與B機之間的相互主-從關系。不管在哪個服務器上更新一條記錄或插入一條記錄,都將被復制到另一臺服務器上。要注意的是:我不敢確定一個備機合并二進制日志變化的速度有多快,所以用這種方法來進行插入或更新語句的負載平衡可能不是一個好辦法。
第四步:修改你的數據庫連接程序
既然你已經在A機和B機之間建立了一個相互的關系,你需要修改數據庫連接程序,以便從這種方式中得到好處。下面的函數首先試圖與A機連接,如果不能建立連接則與B機連接。
/********************************************************
function db_connect()
returns a link identifier on success, or false on error
********************************************************/
function db_connect(){
$username = "replUser";
$password = "password";
$primary = "10.1.1.1";
$backup = "10.1.1.2";
# attempt connection to primary
if(!$link_id = @mysql_connect($primary, $username, $password))
# attempt connection to secondary
$link_id = @mysql_connect($secondary, $username, $password)
return $link_id;
}
?>
我在兩種情況下對使用了上面技術的數據庫連接建立過程進行了測試,一種是主MySQL服務程序關閉了,但是服務器還在運行,另一種情況是主服務器關閉了。如果只是mysqld關閉了,連接會馬上轉向備機;但是如果整個服務器關閉了,就出現了無限地等待(兩分鐘后我放棄了跟蹤 -- 很短的注意跨度),因為PHP在查找一個不存在的服務器。不幸地是,不象fsockopen函數,mysql_connect函數沒有一個超時參數,然而我們可以使用fsockopen來模擬一個超時處理。
第五步:一個改進的數據庫連接程序
/********************************************************
function db_connect_plus()
returns a link identifier on success, or false on error
********************************************************/
function db_connect_plus(){
$username = "username";
$password = "password";
$primary = "10.1.1.1";
$backup = "10.1.1.2";
$timeout = 15; // timeout in seconds
if($fp = fsockopen($primary, 3306, &$errno, &$errstr, $timeout)){
fclose($fp);
return $link = mysql_connect($primary, $username, $password);
}
if($fp = fsockopen($secondary, 3306, &$errno, &$errstr, $timeout)){
fclose($fp);
return $link = mysql_connect($secondary, $username, $password);
}
return 0;
}
?>
這個新改進的函數向我們提供了一個可調的超時特性,這正是mysql_connect函數所缺少的。如果連接立即失敗,這種情況如機器"活"著,但mysqld"當"掉了,函數立即移到第二個服務器。上面的函數相當健壯,在試圖進行連接之前先測試一下,查看服務程序是否在指定端口進行監聽,讓你的腳本在一段可接受的時間段后超時,允許你適當地對出錯情況進行處理。如果你修改了缺省端口3306,請保證對端口號進行修改。
結論和意見
首先,要確定得到了一個完整的數據快照。如果忘記拷貝一個表或數據庫將導致備機線程序停止。生成快照的時刻是很關健的。你應該確保在拷貝數據文件之前二進制日志功能是無效的。如果在得到快照之前就允許了二進制日志功能,備機的線程可能會停止,原因就是當線程試圖導入重要的記錄時,可能會由于主鍵重復而停止。最好就是接照第二部分所討論的處理辦法來做:關閉-拷貝-允許二進制日志功能重啟。
你可能想要按照最初的一種方式來配制復制處理,并且在合適的時間關注備機,確保備機與主機保持同步。
我沒有測試過一個使用了復制特性的系統的負載平衡處理性能,但是我會靈活地使用這樣系統來平衡插入和更新。例如,如果在兩臺服務器上兩條記錄都給出了同一個auto_increment值,這種情況備機線程會在哪一條記錄上停掉呢?象這樣的問題將會讓負載平衡作為只讀的處理,一臺服務器處理所有的插入和更新,同時一組備機(是的,你可以有多個與主機分離的備機)處理所有的選擇。
我非常高興,MySQL已經具備了復制系統的某些功能,并且配置很簡單。使用它,你就可以開始針對失控的事件提供額外的安全措施了。我僅僅涉及了復制特性,這個我已經測試并且使用了,但是在MySQL的在線文檔中的第11部分有中更詳細的說明。
--------------------------------------------------------------------------------
譯者的話:
由于我原來使用的是3.22版的MySQL,所以為了測試一下我只好下載了3.23.24版的最新程序。而且因為只有一臺機器,我只是增加了二進制日志的設置。不過,正如本文所說,的確有文件生成。如果大家對此感興趣只好請自行測試了。另外,在最新的MySQL的使用手冊中,我發現這個復制功能是在3.23.15版以后才有的,請大家檢查自已的MySQL的版本。同時,文中關于二進制日志的設置是說在my.cnf中設置的。在我使用的3.23.24版本中,手冊上說可以有三個文件進行參數設置,分別為windows目錄下的my.ini文件,c:my.cnf和c:mysqldatamy.cnf中可以設置。我在設置'log-bin'時(不需要先設log參數)是使用mysql自帶的
WinMySQLadmin軟件進行設置的,并且在my.ini中設定的,與文中不同,請大家自行測試。