前言:html
首先,咱們得知道咱們爲何要作數據庫的主從與主主,然後,再討論他們的優劣與特色:爲何要作主從呢?由於Mysql數據庫沒有增量備份的機制,當數據量太大的時候備份是個難以解決的問題。可是mysql數據庫有主從備份的機制,說白了就是把主數據庫的全部的數據同時寫到備份的數據庫中。實現mysql數據庫的熱備份。 要想實現主從或主主,首先要知足主從數據庫服務器的版本的需求。要實現熱備,mysql的版本須要都高於5.5。還有一個基本的原則就是做爲從數據庫的數據版本能夠高於主服務器數據庫的版本,可是不能夠低於主服務器的數據庫版本。最好保持版本一致(其實要實現mysql雙機熱備,除了mysql自己自帶的REPLICATION功能能夠實現外,也能夠用Heartbeat這個開源軟件來實現。不過本文主要講如何用mysql自帶的REPLICATION來實現mysql主從或主主),而主主呢,就是兩個數據庫互爲主從,這樣的話,就能夠實現另外一個功能,這也是主主的優勢:實現mysql的讀寫分離與高可用。ok,下面咱們來着重瞭解其原理與配置實例:mysql
1、工做原理:算法
Mysql主從複製的實現原理圖大體以下(來源網絡):sql
MySQL之間數據複製的基礎是二進制日誌文件(binary log file)。一臺MySQL數據庫一旦啓用二進制日誌後,其做爲master,它的數據庫中全部操做都會以「事件」的方式記錄在二進制日誌中,其餘數據庫做爲slave經過一個I/O線程與主服務器保持通訊,並監控master的二進制日誌文件的變化,若是發現master二進制日誌文件發生變化,則會把變化複製到本身的中繼日誌中,而後slave的一個SQL線程會把相關的「事件」執行到本身的數據庫中,以此實現從數據庫和主數據庫的一致性,也就實現了主從複製。數據庫
2、主從複製實例:緩存
1.準備工做與環境介紹:安全
A服務器(主服務器Master):59.151.15.36服務器
B服務器(從服務器Slave):218.206.70.146網絡
Linux環境下將主服務器須要同步的數據庫內容進行備份一份,上傳到從服務器上,保證始初時兩服務器中數據庫內容一致。異步
不過這裏說明下,因爲我是利用Mysql在安裝後就有的數據庫test進行測試的,因此兩臺服務器裏面是沒有創建表的,只不分別在test裏面創建了一樣的一張空表tb_mobile;
Sql語句以下:
mysql> create table tb_mobile( mobile VARCHAR(20) comment'手機號碼', time timestamp DEFAULT now() comment'時間' );
2.Master服務器上建立同步用戶:
進入mysql操做界面,在主服務器上爲從服務器創建一個鏈接賬戶,該賬戶必須授予REPLICATION SLAVE權限。由於從mysql版本3.2之後就能夠經過REPLICATION對其進行雙機熱備的功能操做。
操做指令以下:
mysql> grant replication slave on *.* to 'replicate'@'218.206.70.146' identified by '123456'; mysql> flush privileges;
建立好同步鏈接賬戶後,咱們能夠經過在從服務器(Slave)上用replicat賬戶對主服務器(Master)數據庫進行訪問下,看下是否能鏈接成功。
在從服務器(Slave)上輸入以下指令:
[root@YD146 ~]# mysql -h59.151.15.36 -ureplicate -p123456
若是出現下面的結果,則表示登陸成功,說明對這兩臺服務器進行主從操做的前提具有。
3.修改mysql的配置文件:
首先找到mysql配置全部在目錄,通常在安裝好mysql服務後,都會將配置文件複製一一份出來放到/ect目錄下面,而且配置文件命名爲:my.cnf。即配置文件準確目錄爲/etc/my.cnf
(Linux下用rpm包安裝的MySQL是不會安裝/etc/my.cnf文件的,
至於爲何沒有這個文件而MySQL卻也能正常啓動和做用,這裏有兩種狀況,
第一種:my.cnf只是MySQL啓動時的一個參數文件,能夠沒有它,這時MySQL會用內置的默認參數啓動,
第二種:MySQL在啓動時自動使用/usr/share/mysql目錄下的my-medium.cnf文件,這種說法僅限於rpm包安裝的MySQL,
解決方法:只須要複製一個/usr/share/mysql目錄下的my-medium.cnf文件到/etc目錄,並更名爲my.cnf便可。
找到配置文件my.cnf打開後,在[mysqld]下修改便可: [mysqld] server-id = 1 log-bin=mysql-bin //其中這兩行是原本就有的,能夠不用動,添加下面兩行便可
binlog-do-db = test binlog-ignore-db = mysql
修改完配置文件,保存並重啓mysql服務。然後查看master服務的狀態:
輸入以下指令:
注意看裏面的參數,特別前面兩個File和Position,在從服務器(Slave)配置主從關係會有用到的。
注:這裏使用了鎖表,目的是爲了產生環境中不讓進新的數據,好讓從服務器定位同步位置,初次同步完成後,記得解鎖。
4.salve服務器的配置:
直接打開配置文件my.cnf進行修改便可,道理仍是同修改主服務器上的同樣,只不過須要修改的參數不同而已。以下:
[mysqld] server-id = 2 log-bin=mysql-bin replicate-do-db = test replicate-ignore-db = mysql,information_schema,performance_schema
修改完配置文件後,保存後,重啓一下mysql服務,若是成功則沒問題。
5.用change mster 語句指定同步位置:
這步是最關鍵的一步了,在進入mysql操做界面後,輸入以下指令:
mysql>stop slave; //先停步slave服務線程,這個是很重要的,若是不這樣作會形成如下操做不成功。
mysql>change master to >master_host='59.151.15.36',master_user='replicate',master_password='123456', > master_log_file=' mysql-bin.000016 ',master_log_pos=107;
注:master_log_file, master_log_pos由主服務器(Master)查出的狀態值中肯定。也就是剛剛叫注意的。master_log_file對應File, master_log_pos對應Position。Mysql 5.x以上版本已經不支持在配置文件中指定主服務器相關選項。
遇到的問題,若是按上面步驟以後還出現以下狀況:
則要從新設置slave。指令以下
mysql>stop slave; mysql>reset slave;
以後中止slave線程從新開始。成功後,則能夠開啓slave線程了。
mysql>start slave;
查看從服務器(Slave)狀態:
用以下指令進行查看
mysql> show slave status\G;
查看下面兩項值均爲Yes,即表示設置從服務器成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
6.測試:
以前開始已經說過了在數據庫test只有一個表tb_mobile沒有數據,咱們能夠先查看下兩服務器的數據庫是否有數據:
Master:59.151.15.36
Slave:218.206.70.146
好了,如今能夠在Master服務器中插入數據看下是否能同步。
Master:59.151.15.36
Slave:218.206.70.146
能夠從上面兩個截圖上看出,在Master服務器上進行插入的數據在Slave服務器能夠查到,這就表示主從配置成功了。
7.注意要點:
1)主從複製是異步的邏輯的SQL語句級的複製
2)複製時,主庫有一個I/O線程,從庫有兩個線程,I/O和SQL線程
3)實現主從複製的必要條件是主庫要開啓記錄binlog功能
4)做爲複製的全部Mysql節點的server-id都不能相同
5)binlog文件只記錄對數據庫有更改的SQL語句(來自主庫內容的變動),不記錄任何查詢(select,show)語句
...................................................................................................
完全解除主從複製關係
1)stop slave;
2)reset slave; 或直接刪除master.info和relay-log.info這兩個文件;
3)修改my.cnf刪除主從相關配置參數。
讓slave不隨MySQL自動啓動
修改my.cnf 在[mysqld]中增長 skip-slave-start 選項。
作了MySQL主從複製之後,使用mysqldump對數據備份時,必定要注意按照以下方式:
mysqldump --master-data --single-transaction --user=username --password=password dbname> dumpfilename
這樣就能夠保留 file 和 position 的信息,在新搭建一個slave的時候,還原完數據庫, file 和 position 的信息也隨之更新,接着再start slave 就能夠很迅速
的完成增量同步!
須要限定同步哪些數據庫,有3個思路:
1)在執行grant受權的時候就限定數據庫;
2)在主服務器上限定binlog_do_db = 數據庫名;
3)主服務器上不限定數據庫,在從服務器上限定replicate-do-db = 數據庫名;
[mysqld]
server-id=1 #數據庫惟一ID,主從的標識號絕對不能重複。
log-bin=mysql-bin #開啓bin-log,並指定文件目錄和文件名前綴
binlog-do-db=liting #須要同步liting數據庫。若是是多個同步庫,就以此格式另寫幾行便可。若是不指明對某個具體庫同步,就去掉此行,表示同步全部庫(除了ignore忽略的庫)。
binlog-ignore-db=mysql #不一樣步mysql系統數據庫。若是是多個不一樣步庫,就以此格式另寫幾行;也能夠在一行,中間逗號隔開。
sync_binlog = 1 #確保binlog日誌寫入後與硬盤同步
binlog_checksum = none #跳過現有的採用checksum的事件,mysql5.6.5之後的版本中binlog_checksum=crc32,而低版本都是binlog_checksum=none
binlog_format = mixed #bin-log日誌文件格式,設置爲MIXED能夠防止主鍵重複。
最後:在主服務器上最重要的二進制日誌設置是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中未完成的一個事務,對實際數據沒有任何實質性影響。
3、雙機熱備:
1.理論上:先說說它的原理,兩臺mysql均可讀寫,互爲主備,默認只使用一臺(masterA)負責數據的寫入,另外一臺(masterB)備用;masterA是masterB的主庫,masterB又是masterA的主庫,它們互爲主從;兩臺主庫之間作高可用,能夠採用keepalived等方案(使用VIP對外提供服務);全部提供服務的從服務器與masterB進行主從同步(雙主多從);
2.與主從相比,須要注意的地方:
主主複製和主從複製有一些區別,由於多主中均可以對服務器有寫權限,因此設計到自增加重複問題,例如:
出現的問題(多主自增加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,以此類推.....
這樣才能夠避免兩臺服務器同時作更新時自增加字段的值之間發生衝突。(針對的是有自增加屬性的字段)
3.修改並檢驗:
修改配置文件my.cnf
服務器A [mysqld] server-id = 1 log-bin=mysql-bin binlog-do-db = test binlog-ignore-db = mysql #主-主形式須要多添加的部分 log-slave-updates sync_binlog = 1 auto_increment_offset = 1 auto_increment_increment = 2 replicate-do-db = test replicate-ignore-db = mysql,information_schema 服務器B: [mysqld] server-id = 2 log-bin=mysql-bin master-slave need replicate-do-db = test replicate-ignore-db = mysql,information_schema,performance_schema #主-主形式須要多添加的部分 binlog-do-db = test binlog-ignore-db = mysql log-slave-updates sync_binlog = 1 auto_increment_offset = 2 auto_increment_increment = 2
分別重啓A服務器和B服務器上的mysql服務,重啓服務器方式和上面的同樣,這裏就不作講解了。分別查A服務器和B服務器做爲主服務器的狀態
服務器A:
服務器B:
分別在A服務器和B服務器上用change master to 指定同步位置:
服務器A: mysql>change master to >master_host='218.206.70.146',master_user='replicate',master_password='123456', > master_log_file=' mysql-bin.000011 ',master_log_pos=497; 服務器B: mysql>change master to >master_host='59.151.15.36',master_user='replicate',master_password='123456', > master_log_file=' mysql-bin.000016 ',master_log_pos=107;
分別在A和B服務器上重啓從服務線程
mysql>start slave;
分別在A和B服務器上查看從服務器狀態
mysql>show slave status\G;
查看下面兩項值均爲Yes,即表示設置從服務器成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
測試主-主同步例子
測試服務器A:
在服務器A上插入一條語句以下圖所示:
以後在服務器B上查看是否同步以下圖所示:
測試服務器B:
在服務器B上插入一條語句以下圖所示:
而後在從服務器A上查看是否有同步數據以下圖所示:
最後從結果能夠看出主-主形式的雙機熱備是能成功實現的。
4、配置參數的相關說明:
Server-id
ID值惟一的標識了複製羣集中的主從服務器,所以它們必須各不相同。Master_id必須爲1到232-1之間的一個正整數值,slave_id值必須爲2到232-1之間的一個正整數值。
Log-bin
表示打開binlog,打開該選項才能夠經過I/O寫到Slave的relay-log,也是能夠進行replication的前提。
Binlog-do-db
表示須要記錄二進制日誌的數據庫。若是有多個數據能夠用逗號分隔,或者使用多個binlog-do-dg選項。
Binglog-ingore-db
表示不須要記錄二進制日誌的數據庫,若是有多個數據庫可用逗號分隔,或者使用多binglog-ignore-db選項。
Replicate-do-db
表示須要同步的數據庫,若是有多個數據可用逗號分隔,或者使用多個replicate-do-db選項。
Replicate-ignore-db
表示不須要同步的數據庫,若是有多個數據庫可用逗號分隔,或者使用多個replicate-ignore-db選項。
Master-connect-retry
master-connect-retry=n表示從服務器與主服務器的鏈接沒有成功,則等待n秒(s)後再進行管理方式(默認設置是60s)。若是從服務器存在mater.info文件,它將忽略些選項。
Log-slave-updates
配置從庫上的更新操做是否寫入二進制文件,若是這臺從庫,還要作其餘從庫的主庫,那麼就須要打這個參數,以便從庫的從庫可以進行日誌同步。
Slave-skip-errors
在複製過程,因爲各類緣由致使binglo中的sql出錯,默認狀況下,從庫會中止複製,要用戶介入。能夠設置slave-skip-errors來定義錯誤號,若是複製過程當中遇到的錯誤是定義的錯誤號,即可以路過。若是從庫是用來作備份,設置這個參數會存在數據不一致,不要使用。若是是分擔主庫的查詢壓力,能夠考慮。
Sync_binlog=1 Or N
Sync_binlog的默認值是0,這種模式下,MySQL不會同步到磁盤中去。這樣的話,Mysql依賴操做系統來刷新二進制日誌binary log,就像操做系統刷新其餘文件的機制同樣。所以若是操做系統或機器(不只僅是Mysql服務器)崩潰,有可能binlog中最後的語句丟失了。要想防止這種狀況,可使用sync_binlog全局變量,使binlog在每N次binlog寫入後與硬盤同步。當sync_binlog變量設置爲1是最安全的,由於在crash崩潰的狀況下,你的二進制日誌binary log只有可能丟失最多一個語句或者一個事務。可是,這也是最慢的一種方式(除非磁盤有使用帶蓄電池後備電源的緩存cache,使得同步到磁盤的操做很是快)。
即便sync_binlog設置爲1,出現崩潰時,也有可能表內容和binlog內容之間存在不一致性。若是使用InnoDB表,Mysql服務器處理COMMIT語句,它將整個事務寫入binlog並將事務提交到InnoDB中。若是在兩次操做之間出現崩潰,重啓時,事務被InnoDB回滾,但仍然存在binlog中。能夠用-innodb-safe-binlog選項來增長InnoDB表內容和binlog之間的一致性。(註釋:在Mysql 5.1版本中不須要-innodb-safe-binlog;因爲引入了XA事務支持,該選項做廢了),該選項能夠提供更大程度的安全,使每一個事務的binlog(sync_binlog=1)和(默認狀況爲真)InnoDB日誌與硬盤同步,該選項的效果是崩潰後重啓時,在滾回事務後,Mysql服務器從binlog剪切回滾的InnoDB事務。這樣能夠確保binlog反饋InnoDB表的確切數據等,並使從服務器保持與主服務器保持同步(不接收回滾的語句)。
Auto_increment_offset和Auto_increment_increment
Auto_increment_increment和auto_increment_offset用於主-主服務器(master-to-master)複製,並能夠用來控制AUTO_INCREMENT列的操做。兩個變量都可以設置爲全局或局部變量,而且假定每一個值均可覺得1到65,535之間的整數值。將其中一個變量設置爲0會使該變量爲1。
這兩個變量影響AUTO_INCREMENT列的方式:auto_increment_increment控制列中的值的增量值,auto_increment_offset肯定AUTO_INCREMENT列值的起點。
若是auto_increment_offset的值大於auto_increment_increment的值,則auto_increment_offset的值被忽略。例如:表內已有一些數據,就會用如今已有的最大自增值作爲初始值。
最後,本篇博客來自我對網上博客的整理,在測試無誤的狀況下,對原博主的內容進行了相關的整理與補充,附上原文連接:
http://yunnick.iteye.com/blog/1845301
https://www.cnblogs.com/wade-lt/p/9008058.html