Mysql數據庫的主從與主主


前言:

  首先,我們得知道我們為什么要做數據庫的主從與主主,而后,再討論他們的優劣與特點:為什么要做主從呢?因為Mysql數據庫沒有增量備份的機制,當數據量太大的時候備份是個難以解決的問題。所幸mysql數據庫有主從備份的機制(說白了就是把主數據庫的所有的數據同時寫到備份的數據庫中),以實現mysql數據庫的熱備份。其次,在實現了備份需求的同時,我們也可以在其基礎上進一步實現更多的功能。如讀寫分離等等。

  但要想實現主從或主主,首先要滿足主從數據庫服務器的版本的需求。要實現熱備,mysql的版本需要都高於5.5。還有一個基本的原則就是作為從數據庫的數據版本可以高於主服務器數據庫的版本,但是不可以低於主服務器的數據庫版本。最好保持版本一致(其實要實現mysql雙機熱備,除了mysql本身自帶的REPLICATION功能可以實現外,也可以用Heartbeat這個開源軟件來實現。不過本文主要講如何用mysql自帶的REPLICATION來實現mysql主從或主主),而主主呢,就是兩個數據庫互為主從,這樣的話,就可以實現另一個功能,這也是主主的優點:實現mysql的讀寫分離與高可用。ok,下面我們來着重了解其原理與配置實例:

一、工作原理:

Mysql主從復制的實現原理圖大致如下(來源網絡):

  MySQL之間數據復制的基礎是二進制日志文件(binary log file)。一台MySQL數據庫一旦啟用二進制日志后,其作為master,它的數據庫中所有操作都會以“事件”的方式記錄在二進制日志中,其他數據庫作為slave通過一個I/O線程與主服務器保持通信,並監控master的二進制日志文件的變化,如果發現master二進制日志文件發生變化,則會把變化復制到自己的中繼日志中,然后slave的一個SQL線程會把相關的“事件”執行到自己的數據庫中,以此實現從數據庫和主數據庫的一致性,也就實現了主從復制。

二、主從復制實例:

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中未完成的一個事務,對實際數據沒有任何實質性影響。

 

三、雙機熱備:

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上查看是否有同步數據如下圖所示:


 

 最后從結果可以看出主-主形式的雙機熱備是能成功實現的。

四、配置參數的相關說明:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM