文/A.Lang 於 2009/2/28 (alang<dot>hsu<at>gmail<dot>com) *轉載請註明原作者*
MySQL Replication - MySQL 資料庫抄寫。
為何要作Replication(抄寫)
- 報表(Reporting) - 對於需產出大量報表的資料庫而言,為不影響 Master DB 的效能,建議另外建置另一個專屬的報表資料庫。
- 資料安全 - 資料庫抄寫至 Slave DB,必要時可隨時關閉抄寫程序。對 Slave DB 作資料庫備份也可避免對 Master DB 的線上運作影響。
- 異地備份 - 對於分公司資料庫的複製或異地備份需求。
系統環境
Master DB)
Purpose: Production
IP address: 10.10.10.112
DB version: mysql-server-5.0.22-2.2.el5_1.1
Slave DB)
Purpose: Backup or Reporting
IP address: 10.10.10.134
DB version:
如何建置兩個資料庫的抄寫
新增一個資料庫用戶用以執行抄寫
這個用戶是在 Master DB,用來讓 Slave DB 連接用,其權限僅需要開啟 REPLICATION SLAVE,例如新增一個用戶為 repl,密碼為 replpass。
在 Master DB 執行下列 SQL statements:
reference to undefined name 'syntax' Exception of type 'MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException' was thrown. (click for details)Callstack:
at User:Alang/Linux_&_UNIX_工作筆記/MySQL_DBA_筆記/MySQL_Replication
MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException: reference to undefined name 'syntax' Exception of type 'MindTouch.Deki.Script.Runtime.DekiScriptUndefinedNameException' was thrown.
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptVar expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptVar.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Evaluate (MindTouch.Deki.Script.Expr.DekiScriptAccess expr, DekiScriptExpressionEvaluationState state, Boolean evaluateProperties) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptAccess expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptAccess.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptCall expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptCall.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptSequence expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Expr.DekiScriptSequence.VisitWith[DekiScriptExpressionEvaluationState,Range] (IDekiScriptExpressionVisitor`2 visitor, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
at MindTouch.Deki.Script.Compiler.DekiScriptExpressionEvaluation.Visit (MindTouch.Deki.Script.Expr.DekiScriptReturnScope expr, DekiScriptExpressionEvaluationState state) [0x00000] in <filename unknown>:0
你可以對每一個 Slave DB 設定不同連接帳號,也可以用同一個帳號。
Tip:
上述的新增帳戶方式是以 Slave DB 的 IP 來限制連接的來源,如果實際的操作環境有使用 domain 也可以改成 domain name 方式來作,詳細方法請參考官方的線上手冊。
要驗證帳號是否可以運作,可以在 Slave DB 嘗試使用該帳號連接,請在 Slave DB 執行下述指令
shell> mysql -u repl --password='replpass' -h 10.10.10.112
設定 Master DB
要作抄寫的 Master DB 必須開啟 binary logging,並且在每一個 DB 主機上,需設定不同的 server-id 值,這個值是用來辨識群組內的不同主機識別用,其值是介於 1 - 232 。
請關閉 MySQL 並修改 /etc/my.cnf 內容如下:
shell> service mysqld stop
shell> vi /etc/my.cnf
[mysqld]
# Replication on Master DB
log-bin=mysql-bin
server-id=1
shell> service mysqld start
設定 Slave DB
關閉 MySQL 並修改 /etc/my.cnf 內容如下:
shell> service mysqld stop
shell> vi /etc/my.cnf
[mysqld]
# Replication on Slave DB
server-id=2
shell> service mysqld start
Tips:
如果有多部 Slave DB,每一個 DB 必須設不同的 server-id 值,這就類似主機 IP 位址一樣,如果DB未指定 server-id 時,系統預設為 0。
在 Slave DB 不需要開啟 binary logging,不過,如果有開啟此參數時,可以作資料庫備份以及資料庫異常的回復作業,同時對其他不同的 Slave DB,可以切換為 Master DB。
取得 Master DB 抄寫點資訊
為了要使 Slave DB 作抄寫,必須先在 Master DB 上確定目前的資料點資訊,以使 Slave DB 可以從目前的資料點開始作資料抄寫,如此可確保兩端的資料是同步的。
要取得 Master DB 目前資料點,必須先鎖住要作作抄寫資料庫的所有 tables 的寫入操作。
執行下述 SQL statements:
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)
mysql> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 5752 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
注意:
對於 InnoDB tables,當執行 FLUSH TABLES WITH READ LOCK 時會鎖定所有 table 的 COMMIT 操作。
請記住這兩項資訊,後續設定 Slave DB 時會用到:
File - binary log 檔名
Position - 資料點位置