MySQL主從及主主環境部署

主從同步

主機環境

mysql的安裝能夠參考:http://www.javashuo.com/article/p-zsycgvbg-cq.html
Centos7版本
master:192.168.192.128
slave: 192.168.192.129

注意下面幾點:
1)要保證同步服務期間之間的網絡聯通。即能相互ping通,能使用對方受權信息鏈接到對方數據庫(防火牆開放3306端口)。
2)關閉selinux。
3)同步前,雙方數據庫中須要同步的數據要保持一致。這樣,同步環境實現後,再次更新的數據就會如期同步了.html

實現過程

爲了測試效果,先在master機器上建立數據庫並插入一些數據
建立數據庫
mysql> create database brian character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

切到新建立的數據中建立表結構
mysql> use brian;
Database changed
mysql> create table if not exists haha (id int(10) primary key auto_increment,name varchar(50) not null);
Query OK, 0 rows affected (0.01 sec)

連續插入兩條數據
mysql> insert into brian.haha values(1,"zhujingzhi"),(2,"xiaozhi");
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

查看錶中的數據
mysql> select * from brian.haha;
+----+------------+
| id | name       |
+----+------------+
|  1 | zhujingzhi |
|  2 | xiaozhi    |
+----+------------+
2 rows in set (0.00 sec)

------------------------------------------------------------------------------------------------------
舒適提示:
修改庫或表的字符集
mysql> alter database brian default character set utf8;                      # 修改brian庫的字符集
mysql> alter table brian.haha default character set utf8;                    # 修改brian.haha表的字符集
    
添加主鍵
mysql> Alter table brian.haha add primary key(id);                           # brian.haha表的id添加主鍵
mysql> Alter table brian.haha change id id int(10) not null auto_increment;  # 自增加屬性
    
刪除主鍵時要先刪除自增加,再刪除主鍵
mysql> Alter table brian.haha change id id int(10);                          # 刪除自增加
mysql> Alter table brian.haha drop primary key;                              # 刪除主建
------------------------------------------------------------------------------------------------------

下面是master數據庫上的操做:
1)設置master數據庫的my.cnf文件(在[mysqld]配置區域添加下面內容)
[root@master1 ~]# vim /etc/my.cnf
.........
server-id=1                     #數據庫惟一ID,主從的標識號絕對不能重複。
log-bin=mysql-bin               #開啓bin-log,並指定文件目錄和文件名前綴
binlog-do-db=brian              #須要同步的數據庫。若是是多個同步庫,就以此格式另寫幾行便可。若是不指明對某個具體庫同步,就去掉此行,表示同步全部庫(除了ignore忽略的庫)。
binlog-ignore-db=mysql          #不一樣步mysql系統數據庫。若是是多個不一樣步庫,就以此格式另寫幾行;也能夠在一行,中間逗號隔開。
sync_binlog = 1                 #確保binlog日誌寫入後與硬盤同步
binlog_checksum = crc32         #跳過現有的採用checksum的事件,mysql5.6.5之後的版本中binlog_checksum=crc32,而低版本都是binlog_checksum=none
binlog_format = mixed           #bin-log日誌文件格式,設置爲MIXED能夠防止主鍵重複。
validate_password_policy=0      #指定密碼策略
validate_password = off         #禁用密碼策略

----------------------------------------------------------------------------------------------------------------------------------------------------------------
舒適提示:在主服務器上最重要的二進制日誌設置是sync_binlog,這使得mysql在每次提交事務的時候把二進制日誌的內容同步到磁盤上,即便服務器崩潰也會把事件寫入日誌中。
sync_binlog這個參數是對於MySQL系統來講是相當重要的,他不只影響到Binlog對MySQL所帶來的性能損耗,並且還影響到MySQL中數據的完整性。對於"sync_binlog"參數的各類設置的說明以下:
sync_binlog=0,當事務提交以後,MySQL不作fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定何時來作同步,或者cache滿了以後才同步到磁盤。
sync_binlog=n,當每進行n次事務提交以後,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
     
在MySQL中系統默認的設置是sync_binlog=0,也就是不作任何強制性的磁盤刷新指令,這時候的性能是最好的,可是風險也是最大的。由於一旦系統Crash,在binlog_cache中的全部binlog信息都會被丟失。
而當設置爲「1」的時候,是最安全可是性能損耗最大的設置。由於當設置爲1的時候,即便系統Crash,也最多丟失binlog_cache中未完成的一個事務,對實際數據沒有任何實質性影響。
     
從以往經驗和相關測試來看,對於高併發事務的系統來講,「sync_binlog」設置爲0和設置爲1的系統寫入性能差距可能高達5倍甚至更多。
----------------------------------------------------------------------------------------------------------------------------------------------------------------

2)導出master數據庫多餘slave數據庫中的數據,而後導入到slave數據庫中。保證雙方在同步環境實現前的數據一致。
導出數據庫以前先鎖定數據庫
mysql> flush tables with read lock; # 數據庫只讀鎖定命令,防止導出數據庫的時候有數據寫入。unlock tables命令解除鎖定
Query OK, 0 rows affected (0.00 sec)    

導出master數據庫中多餘的brian庫(master數據庫的root用戶登錄密碼:12345)
[root@master1 ~]# mysqldump -uroot brian -p12345 > /opt/brian.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
上面給出了一個警告,意思是在命令行使用密碼是不安全的(引發的緣由是咱們在-p後面直接寫上了密碼)
舒適提示:在生產環境中固然是不建議直接在命令行寫密碼的

將導出的sql文件上傳到slave機器上
[root@master1 ~]# scp /opt/brian.sql root@192.168.192.129:/opt/
[root@master1 ~]# rsync -e "ssh -p22" -avpgolr /opt/brian.sql 192.168.192.129:/opt/    # rsync的方式須要服務器上安裝rsync包(yum -y install rsync)

3)設置數據同步用戶並賦予權限
mysql> grant replication slave,replication client,select on *.* to slave@'192.168.192.%' identified by 'Slave@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

--------------------------------------------------------------------------------
舒適提示:
權限查看方式
mysql> show grants;
mysql> show grants for slave@'192.168.192.%';
--------------------------------------------------------------------------------

4)查看主服務器master狀態(注意File與Position項,從服務器須要這兩項參數)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      630 | brian        | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


下面是slave數據庫上的操做:
1)設置slave數據庫的my.cnf配置文件
[root@node1 ~]# vim /etc/my.cnf
........
server-id=2                     #數據庫惟一ID,主從的標識號絕對不能重複
log-bin=mysql-bin               #啓動MySQ二進制日誌系統
replicate-do-db=brian           #須要同步的數據庫名。若是不指明同步哪些庫,就去掉這行,表示全部庫的同步(除了ignore忽略的庫)。
replicate-ignore-db=mysql       #不一樣步mysql系統數據庫
slave-skip-errors = all         #跳過全部的錯誤錯誤,繼續執行復制操做
validate_password_policy=0      #指定密碼策略
validate_password = off         #禁用密碼策略

-----------------------------------------------------------------------------------------------
舒適提示:
當只針對某些庫的某張表進行同步時,以下,只同步brian庫的haha表和zjz庫的heihei表:
replicate-do-db = brian
replicate-wild-do-table = brian.haha       //當只同步幾個或少數表時,能夠這樣設置。注意這要跟上面的庫指定配合使用;
replicate-do-db = zjz
replicate-wild-do-table = brian.heihei      //若是同步的庫的表比較多時,就不能這樣一一指定了,就把這個選項配置去掉,直接根據指定的庫進行同步。
-----------------------------------------------------------------------------------------------


2)在slave數據庫中導入從master傳過來的數據
先建立一個brian空庫,不然下面導入數據時會報錯說此庫不存在
mysql> create database brian character set utf8 collate utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

切到新建立的數據中
mysql> use brian;
Database changed
導入sql文件(下面會出現不少OK的輸出)
mysql> source /opt/brian.sql;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
...........

3)配置主從同步指令
設置以前先把從庫停掉
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

配置主從
mysql> change master to master_host='192.168.192.128',master_port=3306,master_user='slave',master_password='Slave@123',master_log_file='mysql-bin.000001',master_log_pos=630; 
Query OK, 0 rows affected, 2 warnings (0.01 sec)

啓動主從
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

查看同步狀態(Slave_IO_Running和Slave_SQL_Running爲YES表示主從配置成功)
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.192.128
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 630
               Relay_Log_File: node1-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: brian
          Replicate_Ignore_DB: mysql

查看slave數據庫中的數據狀況
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| brian              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> select * from brian.haha;
+----+------------+
| id | name       |
+----+------------+
|  1 | zhujingzhi |
|  2 | xiaozhi    |
+----+------------+
2 rows in set (0.00 sec)

下面測試下Mysql主從同步的效果
如今主數據庫上寫入新數據
mysql> insert into brian.haha values(200,"zjz");           
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
上面錯誤的緣由是由於剛剛在導出的時候加鎖了還未解鎖

解鎖
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

插入數據
mysql> insert into brian.haha values(200,"zjz");
Query OK, 1 row affected (0.00 sec)

而後在slave數據庫上查看,發現master上新寫入的數據已經同步過來了
mysql> select * from brian.haha;
+-----+------------+
| id  | name       |
+-----+------------+
|   1 | zhujingzhi |
|   2 | xiaozhi    |
| 200 | zjz        |
+-----+------------+
3 rows in set (0.00 sec)

至此,主從同步環境已經實現!node

舒適提示:若是是新部署的環境,什麼數據都沒有的狀況下,也不須要執行導入導出,直接配置主從就行,沒有要指定的同步那個庫,也能夠在my.cnf中修改mysql

主主同步

主機環境

mysql的安裝能夠參考:http://www.javashuo.com/article/p-zsycgvbg-cq.html
Centos7版本
master:192.168.192.128 
slave: 192.168.192.129 

注意下面幾點:
1)要保證同步服務期間之間的網絡聯通。即能相互ping通,能使用對方受權信息鏈接到對方數據庫(防火牆開放3306端口)。
2)關閉selinux。
3)同步前,雙方數據庫中須要同步的數據要保持一致。這樣,同步環境實現後,再次更新的數據就會如期同步了.linux

主主複製的缺點和解決方法

根據上面的主從環境部署,master和slave已經實現同步,即在master上寫入新數據,自動同步到slave。而從庫只能讀不能寫,一旦從庫有寫入數據,就會形成主從數據不一致!
下面就說下Mysql主主複製環境,在slave上更新數據時,master也能自動同步過來。
---------------------------------------------------------------------------
舒適提示:
在作主主同步前,提醒下須要特別注意的一個問題:
主主複製和主從複製有一些區別,由於多主中均可以對服務器有寫權限,因此設計到自增加重複問題,例如:
出現的問題(多主自增加ID重複)
1)首先在A和B兩個庫上建立test表結構;
2)停掉A,在B上對數據表test(存在自增加屬性的ID字段)執行插入操做,返回插入ID爲1;
3)而後停掉B,在A上對數據表test(存在自增加屬性的ID字段)執行插入操做,返回的插入ID也是1;
4)而後 同時啓動A,B,就會出現主鍵ID重複

解決方法:
只要保證兩臺服務器上的數據庫裏插入的自增加數據不一樣就能夠了
如:A插入奇數ID,B插入偶數ID,固然若是服務器多的話,還能夠自定義算法,只要不一樣就能夠了
在下面例子中,在兩臺主主服務器上加入參數,以實現奇偶插入!
記住:在作主主同步時須要設置自增加的兩個相關配置,以下:
auto_increment_offset 表示自增加字段從那個數開始,取值範圍是1 .. 65535。這個就是序號。若是有n臺mysql機器,則從第一臺開始分爲設1,2...n
auto_increment_increment 表示自增加字段每次遞增的量,其默認值是1,取值範圍是1 .. 65535。若是有n臺mysql機器,這個值就設置爲n算法

在主主同步配置時,須要將兩臺服務器的:
auto_increment_increment 增加量都配置爲2
auto_increment_offset 分別配置爲1和2。這是序號,第一臺從1開始,第二臺就是2,以此類推.....
這樣才能夠避免兩臺服務器同時作更新時自增加字段的值之間發生衝突。(針對的是有自增加屬性的字段)
---------------------------------------------------------------------------sql

實現過程

1)在master上的my.cnf配置
[root@master1 ~]# vim /etc/my.cnf
.........
server-id=1                     #數據庫惟一ID,主從的標識號絕對不能重複。
log-bin=mysql-bin               #開啓bin-log,並指定文件目錄和文件名前綴
binlog-ignore-db=mysql          #不一樣步mysql系統數據庫。若是是多個不一樣步庫,就以此格式另寫幾行;也能夠在一行,中間逗號隔開。
sync_binlog = 1                 #確保binlog日誌寫入後與硬盤同步
binlog_checksum = crc32         #跳過現有的採用checksum的事件,mysql5.6.5之後的版本中binlog_checksum=crc32,而低版本都是binlog_checksum=none
binlog_format = mixed           #bin-log日誌文件格式,設置爲MIXED能夠防止主鍵重複。
auto-increment-increment = 2    #自增加字段每次遞增2
auto-increment-offset = 1       #自增加字段從1開始
slave-skip-errors = all         #跳過全部的錯誤錯誤,繼續執行復制操做
validate_password_policy=0      #指定密碼策略
validate_password = off         #禁用密碼策略

重啓MySQL
[root@master1 ~]# systemctl restart mysqld

數據同步受權(iptables防火牆開啓3306端口,要確保對方機器能使用下面權限鏈接到本機mysql)
mysql> grant replication slave,replication client,select on *.* to slave@'192.168.192.%' identified by 'Slave@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

最好將庫鎖住,僅僅容許讀,以保證數據一致性;待主主同步環境部署後再解鎖;鎖住後,就不能往表裏寫數據,可是重啓mysql服務後就會自動解鎖!
注意該參數設置後,若是本身同步對方數據,同步前必定要記得先解鎖!
mysql> flush tables with read lock;    
Query OK, 0 rows affected (0.00 sec)

查看服務器master狀態(注意File與Position項,從服務器須要這兩項參數)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      154 |              | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


2)在slave上的my.cnf配置
[root@node1 ~]# vim /etc/my.cnf
.........
server-id=2                     #數據庫惟一ID,主從的標識號絕對不能重複。
log-bin=mysql-bin               #開啓bin-log,並指定文件目錄和文件名前綴
binlog-ignore-db=mysql          #不一樣步mysql系統數據庫。若是是多個不一樣步庫,就以此格式另寫幾行;也能夠在一行,中間逗號隔開。
sync_binlog = 1                 #確保binlog日誌寫入後與硬盤同步
binlog_checksum = crc32         #跳過現有的採用checksum的事件,mysql5.6.5之後的版本中binlog_checksum=crc32,而低版本都是binlog_checksum=none
binlog_format = mixed           #bin-log日誌文件格式,設置爲MIXED能夠防止主鍵重複。
auto-increment-increment = 2    #自增加字段每次遞增2
auto-increment-offset = 2       #自增加字段從1開始
slave-skip-errors = all         #跳過全部的錯誤錯誤,繼續執行復制操做
validate_password_policy=0      #指定密碼策略
validate_password = off         #禁用密碼策略

重啓MySQL
[root@node1 ~]# systemctl restart mysqld

數據同步受權(iptables防火牆開啓3306端口,要確保對方機器能使用下面權限鏈接到本機mysql)
同理,slave也要受權給master機器遠程同步數據的權限
mysql> grant replication slave,replication client,select on *.* to slave@'192.168.192.%' identified by 'Slave@123';
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)

最好將庫鎖住,僅僅容許讀,以保證數據一致性;待主主同步環境部署後再解鎖;鎖住後,就不能往表裏寫數據,可是重啓mysql服務後就會自動解鎖!
注意該參數設置後,若是本身同步對方數據,同步前必定要記得先解鎖!
mysql> flush tables with read lock;    
Query OK, 0 rows affected (0.00 sec)

查看服務器slave狀態(注意File與Position項,從服務器須要這兩項參數)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      640 |              | mysql            |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3)執行主張同步操做
先在slave數據庫上作同步master的設置。(確保slave上要同步的數據,提早在master上存在。最好雙方數據保持一致)
mysql> unlock tables; 
Query OK, 0 rows affected (0.00 sec)

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to master_host='192.168.192.128',master_user='slave',master_password='Slave@123',master_log_file='master-bin.000003',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.192.128
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 154
               Relay_Log_File: node1-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

這樣就實現了slave->master的同步環境


再在master數據庫上作同步slave的設置。(確保slave上要同步的數據,提早在master上存在。最好雙方數據保持一致)
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> change master to master_host='192.168.192.129',master_user='slave',master_password='Slave@123',master_log_file='mysql-bin.000002',master_log_pos=640;  
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.192.129
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 640
               Relay_Log_File: master1-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

這樣就實現了master->slave的同步環境。至此,主主雙向同步環境已經實現!


4)最後測試下Mysql主主同步的效果
在master上寫入新數據
mysql> select * from brian.haha;
+-----+------------+
| id  | name       |
+-----+------------+
|   1 | zhujingzhi |
|   2 | xiaozhi    |
| 200 | zhujingzhi |
+-----+------------+
3 rows in set (0.01 sec)

mysql> insert into brian.haha values(211,"xiaotiantian");
Query OK, 1 row affected (0.01 sec)

在slave數據庫中查看,發現master新寫入的數據已經同步過來了
mysql> select * from brian.haha;
+-----+--------------+
| id  | name         |
+-----+--------------+
|   1 | zhujingzhi   |
|   2 | xiaozhi      |
| 200 | zhujingzhi   |
| 211 | xiaotiantian |
+-----+--------------+
4 rows in set (0.00 sec)


在slave上刪除數據
mysql> delete from brian.haha where id=200;
Query OK, 1 row affected (0.00 sec)

在master數據庫中查看
mysql> select * from brian.haha;
+-----+--------------+
| id  | name         |
+-----+--------------+
|   1 | zhujingzhi   |
|   2 | xiaozhi      |
| 211 | xiaotiantian |
+-----+--------------+
3 rows in set (0.00 sec)

至此,主主同步環境已經實現!  數據庫

相關文章
相關標籤/搜索