一,mysql主從複製的原理mysql
mysql支持單向、異步複製,複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。mysql複製基於主服務器在二進制日誌中跟蹤全部對數據庫的更改(更新、刪除等等)。所以,要進行復制,必須在主服務器上啓用二進制日誌。每一個從服務器從主服務器接收主服務器已經記錄到其二進制日誌的保存的更新。當一個從服務器鏈接主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發生的任何更新,並在本機上執行相同的更新。而後封鎖並等待主服務器通知新的更新。從服務器執行備份不會干擾主服務器,在備份過程當中主服務器能夠繼續處理更新。 可是若是在從服務器對數據進行增刪的話,主服務器數據不一樣步。sql
如下是經過該圖的詳解。數據庫
經過show slave status\G和show master status能夠查看複製線程狀態。常見的線程狀態有:
(1)主服務器Binlog Dump線程
Has sent all binlog to slave; waiting for binlog to be updated
線程已經從二進制日誌讀取全部主要的更新並已經發送到了從服務器。線程如今正空閒,等待由主服務器上新的更新致使的出如今二進制日誌中的新事件。
(2)從服務器I/O線程狀態
Waiting for master to send event
線程已經鏈接上主服務器,正等待二進制日誌事件到達。若是主服務器正空閒,會持續較長的時間。若是等待持續slave_read_timeout秒,則發生超時。此時,線程認爲鏈接被中斷並企圖從新鏈接。
(3)從服務器SQL線程狀態
Reading event from the relay log
線程已經從中繼日誌讀取一個事件,能夠對事件進行處理了。
Has read all relay log; waiting for the slave I/O thread to update it
線程已經處理了中繼日誌文件中的全部事件,如今正等待I/O線程將新事件寫入中繼日誌。
2.複製過程當中使用的傳遞和狀態文件
默認狀況,中繼日誌使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是從服務器主機名,nnnnnn是序列號。中繼日誌與二進制日誌的格式相同,而且能夠用mysqlbinlog讀取。
從服務器在data目錄中另外建立兩個小文件。這些狀態文件默認名爲主master.info和relay-log.info。狀態文件保存在硬盤上,從服務器關閉時不會丟失。下次從服務器啓動時,讀取這些文件以肯定它已經從主服務器讀取了多少二進制日誌,以及處理本身的中繼日誌的程度。安全
二,mysql主從複製配置的條件:bash
1,確保主從版本兼容,從服務器至少與主服務器版本相同或更高。服務器
2,初始化表,並子後臺啓動mysql
異步
3,修改root密碼
ide
三,修改主服務器master:測試
vi /etc/my.cnf [mysqld] log-bin=mysql-bin //[必須]啓用二進制日誌 server-id=1 //[必須]服務器惟一ID,默認是1,通常取IP最後一段
備註:og-bin,server-id是配置文件中必須添加的內容。此時主服務器默認對全部數據庫進行備份。若是須要特殊指明只對某個數據庫進行備份或不備份,則能夠加入binlog-do-db和binlog-ignore-db選項spa
四,修改從服務器slave:
#vi /etc/my.cnf [mysqld] #log-bin=mysql-bin //[不是必須]啓用二進制日誌 server-id=245 //[必須]服務器惟一ID,默認是1,通常取IP最後一段
五,分別重啓兩臺服務器的mysql
# /etc/init.d/mysqld restart
六,在主服務器上創建帳戶並受權slave:
[root@localhost ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.25-log Source distribution Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> GRANT REPLICATION SLAVE ON *.* to 'lqb'@'%' identified by 'abc123456'; Query OK, 0 rows affected (0.00 sec) mysql>
備註:在主服務器上,必須爲從服務器建立一個用來鏈接主服務器的用戶,並設置replication slave權限。所用具體命令以下:通常不用root,只要帳戶和密碼正確可用具體的客戶端ip代替以增強安全。
grant replication slave
on *.*
to '賬號' @ '從服務器IP或%' identified by '密碼';
七,登陸主服務器的mysql,查詢master的狀態
mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 1192 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
八,配置從服務器slave:
mysql> change master to master_host='192.168.1.247',master_user='mysync',master_password='abc123456',master_log_file='mysql-bin.000001',master_log_pos=1192 \\注意不要斷開,1192不須要引號。 mysql> start slave; \\啓動從服務器複製功能 Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> show slave status\G \\查看從服務器複製功能的狀態 *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.247 Master_User: mysync //受權帳戶名,儘可能避免使用root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 1192 Relay_Log_File: zabbix-relay-bin.000002 Relay_Log_Pos: 1155 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes //此狀態必須爲yes Slave_SQL_Running: Yes //此狀態必須爲yes,有一個不爲yes都是錯誤狀態 Replicate_Do_DB: 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: 1192 Relay_Log_Space: 1329 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 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: e9139a38-289e-11e6-9bbd-005056892313 Master_Info_File: /data/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.00 sec)
九,處從服務器測試:
在主服務器的mysql,建立數據庫和表,並向表中插入一條數據:
mysql> create database hello; Query OK, 1 row affected (0.00 sec) mysql> use lqb; Database changed mysql> create table test(id int(4),name char(20)); Query OK, 0 rows affected (0.01 sec) mysql> insert into test values(1,'abc'); Query OK, 1 row affected (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | hi_lqb | | lqb | | mysql | | performance_schema | | test | +--------------------+ 6 rows in set (0.00 sec)
在從服務器上mysql查詢:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | hello | //剛剛建立的 | | mysql | | | performance_schema | | test | | | zabbix | +--------------------+ 9 rows in set (0.00 sec) mysql> use hello; Database changed mysql> show tables; +-----------------+ | Tables_in_hello | +-----------------+ | test | +-----------------+ 1 row in set (0.01 sec) mysql> select * from test; \\查看服務器上新增的具體數據 +------+------+ | id | name | +------+------+ | 1 | abc | +------+------+ 1 row in set (0.00 sec)
至此,mysql主從複製完成。
注意:關於log_bin日誌
my.conf 文件中的[mysqld]標籤下的log_bin指定日誌文件,若是不提供文件名,mysql將本身產生缺省文件名。mysql會在文件名後面自動添加數字引,每次啓動服務時,都會從新生成一個新的二進制文件。此外,使用log-bin-index能夠指定索引文件;使用binlog-do-db能夠指定記錄的數據庫;使用binlog-ignore-db能夠指定不記錄的數據庫。注意的是:binlog-do-db和binlog-ignore-db一次只指定一個數據庫,指定多個數據庫須要多個語句。並且,MySQL會將全部的數據庫名稱改爲小寫,在指定數據庫時必須所有使用小寫名字,不然不會起做用。之後對數據庫每作的一次操做,都會在binlog中有所記錄。
備註:如下腳本是用來檢測mysql主從複製是否正常,若是兩個都不爲yes說明有問題了,可經過zabbix來進行監控。
#!/bin/bash port=`netstat -anl|grep 3306 |sed -n '1p' |awk '{print $4}'|awk -F: '{ print $2}'` array=($(mysql -uroot -p123 -e "show slave status\G"|grep "Running" |awk '{print $2}')) if ["$port" == "3306"] then if [ "${array[0]}" == "Yes" ] || [ "${array[1]}" == "Yes" ] then echo "slave is OK" else echo "slave is error" fi fi