MYSQL 的主主同步配置及問題

剛剛抽空做了一下MYSQL 的主主同步。
把步驟寫下來,至於會出現的什麼問題,以後隨時更新。這裏我同步的數據庫是TEST
1、環境描述。
主機:192.168.0.231(A)
主機:192.168.0.232(B)
MYSQL 版本爲5.1.21
2、授權用戶。
A:
mysql> grant replication slave,file on *.* to 'repl1'@'192.168.0.232' identified
 by '123456';
Query OK, 0 rows affected (0.00 sec)


mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
B:
mysql> grant replication slave,file on *.* to 'repl2'@'192.168.0.231' identified
 by '123456';
Query OK, 0 rows affected (0.00 sec)


mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
然後都停止MYSQL 服務器。


3、配置文件。
在兩個機器上的my.cnf裏面都開啓二進制日誌 。
A:
user = mysql
log-bin=mysql-bin
server-id       = 1
binlog-do-db=test
binlog-ignore-db=mysql
replicate-do-db=test
replicate-ignore-db=mysql
log-slave-updates                             #如果一個MASTER 掛掉的話,另外一個馬上接管。
slave-skip-errors=all
sync_binlog=1
auto_increment_increment=2
auto_increment_offset=1


B:
user = mysql
log-bin=mysql-bin
server-id       = 2
binlog-do-db=test
binlog-ignore-db=mysql
replicate-do-db=test
replicate-ignore-db=mysql
log-slave-updates               
slave-skip-errors=all
sync_binlog=1 #服務器頻繁的刷新日誌。這個保證了在其中一臺掛掉的話,
auto_increment_increment=2 #日誌刷新到另外一臺。從而保證了數據的同步 。
auto_increment_offset=2 #


對上面參數作出部分解釋:
 
log-bin=mysql-bin                   #M/S 需開啓log-bin 日記文件
server-id=1                                #指定server-id 必須不一致,M/s 結構時 M > S
binlog-do-db=test                           #同步數據庫名稱
binlog-ignore-db=mysql                     #忽略數據名稱
replicate-do-db=test                       #用於控制slave來執行同步的行爲
replicate-ignore-db=mysql                  #用於控制slave來執行同步的行爲
log-slave-updates                          #把更新的記錄寫到二進制文件中
slave-skip-errors=all                      #跳過錯誤,繼續執行復制
auto_increment_increment=2                 #設置主鍵單次增量
auto_increment_offset=1                    #設置單次增量中主鍵的偏移量
#expire_logs_days = 20                     #設置log-bin 超過多少天刪除
max-binlog-size= 512M
 
# auto_increment_increment、auto_increment_offset 可以防止雙主主鍵衝突問題


4、重新啓動MYSQL服務器。
在A和B上執行相同的步驟
[root@localhost ~]# /usr/local/mysql/bin/mysqld_safe &
[1] 4264
[root@localhost ~]# 071213 14:53:20 mysqld_safe Logging to '/usr/local/mysql/data/localhost.localdomain.err'.
/usr/local/mysql/bin/mysqld_safe: line 366: [: -eq: unary operator expected
071213 14:53:20 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data


5、進入MYSQL的SHELL。
A:
mysql> flush tables with read lock\G
Query OK, 0 rows affected (0.00 sec)


mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000007
Position: 528
Binlog_Do_DB: test
Binlog_Ignore_DB: mysql
1 row in set (0.00 sec)


B:
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)


mysql> show master status\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 595
Binlog_Do_DB: test
Binlog_Ignore_DB: mysql
1 row in set (0.00 sec)
然後備份自己的數據,保持兩個機器的數據一致。
方法很多。完了後看下一步。
6、在各自機器上執行CHANGE MASTER TO命令。
A:
mysql> change master to
    -> master_host='192.168.0.232',
    -> master_user='repl2',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000004',
    -> master_log_pos=595;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)




B:
mysql> change master to
    -> master_host='192.168.0.231',
    -> master_user='repl1',
    -> master_password='123456',
    -> master_log_file='mysql-bin.000007',
    -> master_log_pos=528;
Query OK, 0 rows affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)


7、查看各自機器上的IO進程和 SLAVE進程是否都開啓。
A:


mysql> show processlist\G
*************************** 1. row ***************************
Id: 2
User: repl
Host: 192.168.0.232:54475
db: NULL
Command: Binlog Dump
Time: 1590
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
*************************** 2. row ***************************
Id: 3
User: system user
Host: 
db: NULL
Command: Connect
Time: 1350
State: Waiting for master to send event
Info: NULL
*************************** 3. row ***************************
Id: 4
User: system user
Host: 
db: NULL
Command: Connect
Time: 1149
State: Has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
*************************** 4. row ***************************
Id: 5
User: root
Host: localhost
db: test
Command: Query
Time: 0
State: NULL
Info: show processlist
4 rows in set (0.00 sec)


B:


mysql> show processlist\G
*************************** 1. row ***************************
Id: 1
User: system user
Host: 
db: NULL
Command: Connect
Time: 2130
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host: 
db: NULL
Command: Connect
Time: 1223
State: Has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
*************************** 3. row ***************************
Id: 4
User: root
Host: localhost
db: test
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 4. row ***************************
Id: 5
User: repl2
Host: 192.168.0.231:50718
db: NULL
Command: Binlog Dump
Time: 1398
State: Has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
4 rows in set (0.00 sec)


如果紅色部分沒有出現,檢查DATA目錄下的錯誤文件。


8、釋放掉各自的鎖,然後進行插數據測試。
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)


插入之前兩個機器表的對比:
A:


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t11_innodb     | 
| t22            | 
+----------------+
B:


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t11_innodb     | 
| t22            | 
+----------------+
從A機器上進行插入
A:
mysql> create table t11_replicas
    -> (id int not null auto_increment primary key,
    -> str varchar(255) not null) engine myisam;
Query OK, 0 rows affected (0.01 sec)


mysql> insert into t11_replicas(str) values
    -> ('This is a master to master test table');
Query OK, 1 row affected (0.01 sec)


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t11_innodb     | 
| t11_replicas   | 
| t22            | 
+----------------+
3 rows in set (0.00 sec)


mysql> select * from t11_replicas;
+----+---------------------------------------+
| id | str                                   |
+----+---------------------------------------+
|  1 | This is a master to master test table | 
+----+---------------------------------------+
1 row in set (0.00 sec)




現在來看B機器:


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t11_innodb     | 
| t11_replicas   | 
| t22            | 
+----------------+
3 rows in set (0.00 sec)


mysql> select * from t11_replicas;
+----+---------------------------------------+
| id | str                                   |
+----+---------------------------------------+
|  1 | This is a master to master test table | 
+----+---------------------------------------+
1 row in set (0.00 sec)


現在反過來從B機器上插入數據:
B:


mysql> insert into t11_replicas(str) values('This is a test 2');
Query OK, 1 row affected (0.00 sec)


mysql> select * from t11_replicas;
+----+---------------------------------------+
| id | str                                   |
+----+---------------------------------------+
|  1 | This is a master to master test table | 
|  2 | This is a test 2                      | 
+----+---------------------------------------+
2 rows in set (0.00 sec)
我們來看A
A:
mysql> select * from t11_replicas;
+----+---------------------------------------+
| id | str                                   |
+----+---------------------------------------+
|  1 | This is a master to master test table | 
|  2 | This is a test 2                      | 
+----+---------------------------------------+
2 rows in set (0.00 sec)


好了。現在兩個表互相爲MASTER。


對開啓權限、grant 這些基本的這裏就不在詳細說明,下面貼出自動建立同步的gant 腳本,項目在生產過程中總會遇到Mysql 數據庫服務器宕機等情況,可用以下腳本來重新構建Master -to-Master 環境。


#!/bin/bash 
# Setting Variables
 _REMOTEHOST=192.168.0.231  #遠程主機IP
 _LOCALHOST=192.168.0.232   #本地主機IP
 _USER=root                #用戶名
 _REMOTEPASD=123456        #遠程主機密碼
 _LOCALPASD=123456         #本地主機密碼
 _BASE=TSC
 
 _LF=`mysql -u root -h $_REMOTEHOST -p$_REMOTEPASD -e "show master status\G;" | awk '/File/ {print $2}'`
 _LLF=`mysql -u root -p$_LOCALPASD -e "show master status\G;" | awk '/File/ {print $2}'`
 _PS=`mysql -u root -h $_REMOTEHOST -p$_REMOTEPASD -e "show master status\G;" | awk '/Position/ {print $2}'`
 _LPS=`mysql -u root -p$_LOCALPASD -e "show master status\G;" | awk '/Position/ {print $2}'`
 
# Backup Mysql 
mysqldump -u root -h $_REMOTEHOST -p$_REMOTEPASD  $_BASE > $_BASE.sql
mysql -u root -p$_LOCALPASD $_BASE < $_BASE.sql
rm -rf $_BASE.sql
 
mysql -uroot -p$_LOCALPASD -e "stop slave;"
mysql -h $_REMOTEHOST -uroot -p$_LOCALPASD -e "stop slave;"
 
echo "mysql -uroot -p$_LOCALPASD -e +change master to master_REMOTEHOST=*${_REMOTEHOST}*,master_user=*${_USER}*,master_password=*${_REMOTEPASD}*,master_log_file=*${_LF}*,master_log_pos=${_PS};+" > tmp
echo "mysql -h $_REMOTEHOST -uroot -p$_LOCALPASD -e +change master to master_REMOTEHOST=*${_LOCALHOST}*,master_user=*${_USER}*,master_password=*${_LOCALPASD}*,master_log_file=*${_LLF}*,master_log_pos=${_LPS};+" > tmp2
 
 
  sed -ri 's/\+/"/g' tmp
  sed -ri 's/\+/"/g' tmp2
  sed -ri "s/\*/\'/g" tmp
  sed -ri "s/\*/\'/g" tmp2
  sh tmp
  sh tmp2
  rm -rf tmp
  rm -rf tmp2
 
mysql -uroot -p$_LOCALPASD -e "start slave;"
mysql -h $_REMOTEHOST -uroot -p$_LOCALPASD -e "start slave;"
 
mysql -uroot -p$_LOCALPASD -e "show slave status\G;" | awk '$0 ~/Host/ || $0 ~/State/'
mysql -h $_REMOTEHOST -uroot -p$_LOCALPASD -e "show slave status\G;" | awk '$0 ~/Host/ || $0 ~/State/'




這個過程可能會出現的問題:
一、出現ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.0.231'(111)錯誤。
1、可能網絡連接問,遠程ping 192.168.0.231 ,能ping通,排除此情況
 
[mysql@vvmvcs0 ~]$ ping 192.168.0.231 
PING 192.168.0.231 (192.168.0.231) 56(84) bytes of data.
64 bytes from 192.168.0.231: icmp_seq=1 ttl=63 time=0.230 ms
 
2,排查可能由於85上my.cnf裏配置了skip_networking或者bind_address,只允許本地socket連接
2.1 在[mysqld]下設置skip_networking,
知識說明: 這使用MySQL只能通過本機Socket連接(socket連接也是本地連接的默認方式),放棄對TCP/IP的監聽  www.2cto.com  
當然也不讓本地java程序連接MySQL(Connector/J只能通過TCP/IP來連接)。
2.2 可能使用了bind_address=127.0.0.1(當然也可以是其他ip)
 
[mysqld] 
bind_address=127.0.0.1
知識說明:這種情況可以TCP/IP連接
通過查看了my.cnf文件,以上兩個都是沒設置的,排除掉這兩種情況
 
3,排查DNS解析問題,檢查是否設置了: skip_name_resolve。 這個情況肯定不可能,因爲我用的是ip,不是主機名。
 
[mysqld]
skip_name_resolve
知識說明:這個參數加上後,不支持主機名的連接方式。
 
4, 排查用戶和密碼問題, 其實用戶和密碼的錯誤,不會出現111的,所以排除用戶密碼問題
ERROR 1045 (28000): Access denied for user 'root'@'192.168.0.231' (using password: YES)
 
5,排查--port問題,有可能85的MySQL port不是默認3306, 這樣我遠程連接時,沒有指定--port,用的是3306, 而85上沒有對3306進行監聽。
ps -ef | grep mysqld
果然是: 85上的MySQL使用的是3308 port.
最終連接方式:加上--port=3308


6、如果都不是,那麼可能是防火牆的問題,可以把iptables 服務關閉
service iptables stop


除此之外,可以從日誌文件中來獲取錯誤信息。我的linux裏面是放在/var/log/mysqld.log中
[mysql@vvmvcs0 ~]$ tail -n100 /var/log/mysqld.log
150430  9:41:06 [Note] /usr/libexec/mysqld: Normal shutdown


150430  9:41:06 [Note] Event Scheduler: Purging the queue. 0 events
150430  9:41:06 [Note] Error reading relay log event: slave SQL thread was killed
150430  9:41:06 [Note] Slave I/O thread killed while connecting to master
150430  9:41:06 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000002', position 1360
150430  9:41:06  InnoDB: Starting shutdown...
150430  9:41:09  InnoDB: Shutdown completed; log sequence number 0 44233
150430  9:41:09 [Note] /usr/libexec/mysqld: Shutdown complete
50430  9:43:09 [ERROR] Slave I/O: error connecting to master '[email protected]:3306' - retry-time: 60  retries: 86400, Error_code: 2013
150430  9:54:00 [Note] Error reading relay log event: slave SQL thread was killed
150430  9:54:00 [Note] Slave I/O thread killed while connecting to master
150430  9:54:00 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000002', position 1360


150430  9:55:42 [ERROR] Slave I/O: error connecting to master '[email protected]:3306' - retry-time: 60  retries: 86400, Error_code: 2013
150430  9:55:42 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.000003' at position 106, relay log './mysqld-relay-bin.000001' position: 4


二、Access denied; you need the SUPER privilege for...
運行腳步的時候可能會有這個錯誤,那麼需要賦權限:
ysql> grant super on *.* to [email protected] identified by 'engine';
Query OK, 0 rows affected (0.02 sec)


mysql> flush privilege;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'privilege' at line 1
mysql> flush privileges;
Query OK, 0 rows affected (0.02 sec)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章