【原理:MySQL 同步機制基於 master 把全部對數據庫的更新、刪除 等)都記錄在二進制日誌裏。所以,想要啓用同步機制,在 master 就必須啓用二進制日誌。每一個 slave 接受來自master 上在二進制日誌中記錄的更新操做,所以在 slave 上執行了這個操做的一個拷貝。】mysql
slave 同步失敗主要問題:
二進制日誌只是從啓用二進制日誌開始的時刻才記錄更新操做的,全部的 slave 必須在
啓用二進制日誌時把 master 上已經存在的數據拷貝過來。若是運行同步時 slave 上的數據和 master 上啓用二進制日誌時的數據不一致的話,那麼 slave 同步就會失敗。
數據庫初始同步方式:
把 master 上的數據拷貝過來的方法之一實在 slave 上執行 LOAD DATA FROM MASTER 語句。不過要注意,LOAD DATA FROM MASTER 是從 MySQL4.0.0 以後纔開始能夠用的,並且只支持 master 上的 MyISAM 類型表
暫停主服務器,導入數據文件,在從服務器上導入。
【MySQL 同步細節】
MySQL 同步功能由 3 個線程(master 上 1 個,slave 上 2 個)來實現。執行 START SLAVE語句後,slave 就建立一個 I/O 線程。I/O 線程鏈接到 master 上,並請求 master 發送二進制日誌中的語句。master 建立一個線程來把日誌的內容發送到 slave 上。這個線程在 master
上執行 SHOW PROCESSLIST 語句後的結果中的 Binlog Dump 線程即是。slave 上的 I/O 線程讀取 master 的 Binlog Dump 線程發送的語句,而且把它們拷貝到其數據目錄下的中繼日誌(relay logs)中。第三個是 SQL 線程,salve 用它來讀取中繼日誌,而後執行它們來更新數
據。如上所述,每一個 mster/slave 上都有 3 個線程。每一個 master 上有多個線程,它爲每一個slave 鏈接都建立一個線程,每一個 slave 只有 I/O 和 SQL 線程。在 MySQL4.0.2 之前,同步只需 2 個線程(master 和 slave 各一個)。slave 上的 I/O 和 SQL 線程合併成一個了,它不使用中繼日誌。slave 上使用 2 個線程的優勢是,把讀日誌和執行分開成 2 個獨立的任務。執行任務若是慢的話,讀日誌任務不會跟着慢下來。例如,若是 slave 中止了一段時間,那麼
I/O 線程能夠在 slave 啓動後很快地從 master 上讀取所有日誌,儘管 SQL 線程可能落後 I/O線程好幾的小時。若是 slave 在 SQL 線程沒所有執行完就中止了,但 I/O 線程卻已經把全部的更新日誌都讀取而且保存在本地的中繼日誌中了,所以在 slave 再次啓動後就會繼續執行它們了。這就容許在 master 上清除二進制日誌,由於 slave 已經無需去 master 讀取更新日
志了。執行SHOW PROCESSLIST語句就會告訴咱們所關心的master和slave上發生的狀況。
地址參數設定
名稱
|
角色
|
IP 地址
|
Master-MySQL
(RHEL5.3)
|
Master-MySQL
A(nod1)
|
eth0:192.168.1.1/24
GW:192.168.1.1
|
Slave-MySQL
(RHEL5.3)
|
Slave-MySQL
B(nod2)
|
eth0:192.168.1.2/24
GW:192.168.1.1
|
在這裏我以root受權爲例
基礎安裝mysql
[root@localhost ~]# mount /dev/cdrom /media/
[root@localhost ~]# vim /etc/yum.repos.d/rhel-debuginfo.repo
baseurl=file:///media/Server
enabled=1
gpgcheck=0
[root@localhost ~]# yum -y install mysql-server
[root@localhost ~]# service mysqld start
[root@localhost ~]# mysqladmin -uroot password 123456
Node2上一樣方式安裝mysql,並作如上操做
在這裏我就用test數據庫來作測試,在test數據庫裏新建一個data表,並添加一些數據,具體操做以下:
[root@localhost ~]# mysql -u root -p123456
mysql> use test;
Database changed
mysql> create table data(name VARCHAR(20), address VARCHAR(50), phone VARCHAR(20));
Query OK, 0 rows affected (0.01 sec)
mysql> create table data(name VARCHAR(20), address VARCHAR(50), phone VARCHAR(20));
Query OK, 0 rows affected (0.01 sec)
mysql> select * from data;
+-----------+-----------+--------------+
| name | address | phone |
+-----------+-----------+--------------+
| wuxinglai | neimenggu | 135220449221 |
+-----------+-----------+--------------+
設置數據庫同步賬戶:
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SUPER ON *.* TO 'root'@'192.168.1.2' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> use mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select user,host from user;
+------+-----------------------+
| user | host |
+------+-----------------------+
| root | 127.0.0.1 |
| root | 192.168.1.2 |
| | localhost |
| root | localhost |
| | localhost.localdomain |
修改配置文件:
中止 mysql 服務
root@localhost ~]# service mysqld stop
在[mysqld]中加入如下內容
[root@localhost ~]# vim /etc/my.cnf
8 server-id=1
9 log-bin
10 binlog-do-db=test
11 max_binlog_size=104857600
12 replicate-same-server-id
13 master-host=192.168.1.2
14 master-user=root
15 master-password=123456
16 master-port=3306
17 master-connect-retry=60
18 replicate-do-db=test
19 binlog-ignore-db=mysql
如下是參數說明
server-id=1 #設置服務器的 ID 號
log-bin #設置同步 log
binlog-do-db=test #設置同步數據庫
max_binlog_size=104857600 #設置同步 log 最大 size:104857600 字節
replicate-same-server-id #在複製過程當中同步相同的 master id 號
#下面指定本身做爲客戶端同步時,與主機之間同步的設置信息
master-host=192.168.1.2 #主機IP
master-user=backup #登錄服務端的帳戶名
master-password=backup #登錄服務端的帳戶密碼
master-port=3306 #服務端打開的端口
master-connect-retry=60 #與服務端斷點重試間隔爲 60 秒
replicate-do-db=test #表示同步test數據庫
binlog-ignore-db=mysql #設置不一樣步的數據庫
[root@localhost ~]# service mysqld start
將test.sql複製到mysqlB的/tmp目錄下
[root@localhost ~]# mysqldump -h localhost -u root -p123456 test> test1.sql
[root@localhost ~]# scp test.sql root@192.168.1.2:/tmp
至此nod1 服務器上有關mysql的設置已完成,下一步開始配置nod2
設置nod2
設置數據庫同步賬戶:
[root@localhost ~]# mysql -u root -p123456
授與從 192.168.1.1 主機上登陸用戶root數據複製權限
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT,RELOAD,SUPER ON *.* to 'root'@'192.168.1.1' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
刷新權限
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
更改Mysql配置文件/etc/my.cnf
[root@localhost ~]# service mysqld stop
[root@localhost ~]# vi /etc/my.cnf
8 server-id=2
9 log-bin
10 binlog-do-db=test
11 max_binlog_size=104857600
12 replicate-same-server-id
13 master-host=192.168.1.1
14 master-user=root
15 master-password=123456
16 master-port=3306
17 master-connect-retry=60
18 replicate-do-db=test
19 binlog-ignore-db=mysql
還原從mysqlA備份過的test1.sql
[root@localhost tmp]# mysql -u root -p test < /tmp/test1.sql
重啓兩邊的 mysql 服務
在 primary (A)服務器上 MySQL 命令符下輸入
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000003 | 98 | test | mysql |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.2
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysqld-bin.000003
Read_Master_Log_Pos: 98
Relay_Log_File: mysqld-relay-bin.000007
Relay_Log_Pos: 236
Relay_Master_Log_File: mysqld-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: test
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 98
Relay_Log_Space: 236
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
mysql>stop slave;
mysql>start slave;
Show Slave status:此處 Slave_IO_Running ,Slave_SQL_Running 都應該是 yes,表示從庫的 I/O,Slave_SQL
線程都正確開啓.
在 Mysql 中可經過如下命令來查看主從狀態
show master status 查看 master 狀態
show slave status 查看 slave 狀態
show processlist G 查看當前進程
stop slave 暫時中止 slave 進程
start slave 開始 slave 進程
錯誤日誌
MySQL 安裝目錄\data\Hostname.err
4,CHANGE MASTER TO
若是 A 的 Slave 未啓動,Slave_IO_Running 爲 No.
可能會是 B 的 master 的信息有變化,
查看 B SHOW MASTER STATUS;
記錄下 File,Position 字段.假設爲'mysql_binary_log.000004',98 ;
在 A 下執行:
Stop Slave;
CHANGE MASTER TO
MASTER_LOG_FILE = 'mysql_binary_log.000004',
MASTER_LOG_POS = 98 ;
Start Slave;
5,SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
若是 A 的 Slave_SQL_Running 爲 No.
Err 文件中記錄:
Slave: Error 'Duplicate entry '1' for key 1' on query....
多是 master 未向 slave 同步成功,但 slave 中已經有了記錄。形成的衝突.
能夠在 A 上執行
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
跳過幾步。再
restart salve;
驗證
在A上test插入一條數據
mysql> use test;
mysql> insert into data(name,address,phone) values('yangchunlin','zhaqi','17590305988');
Query OK, 1 row affected (0.00 sec)
mysql> select * from data;
+-------------+-----------+--------------+
| name | address | phone |
+-------------+-----------+--------------+
| wuxinglai | neimenggu | 135220449221 |
| yangchunlin | zhaqi | 17590305988 |
+-------------+-----------+--------------+
2 rows in set (0.00 sec)
在B上查看
mysql> select * from data;
+-------------+-----------+--------------+
| name | address | phone |
+-------------+-----------+--------------+
| wuxinglai | neimenggu | 135220449221 |
| yangchunlin | zhaqi | 17590305988 |
+-------------+-----------+--------------+
2 rows in set (0.00 sec)