1.主從複製:
mysql數據庫提供了一種主從備份的機制,其實就是把主數據庫的所有的數據同時寫到備份的數據庫中。實現mysql數據庫的熱備份。
要想實現雙機的熱備,首先要了解主從數據庫服務器的版本的需求。要實現熱備mysql的版本都高於3.2。還有一個基本的原則就是作爲從數據庫的數據版本可以高於主服務器數據庫的版本,但是不可以低於主服務器的數據庫版本。
當然要實現mysql雙機熱備,除了mysql本身自帶的REPLICATION功能可以實現外,也可以用Heartbeat這個開源軟件來實現 主從複製的根本操作就是把從主服務器上所執行過的sql在從機上再執行一遍,只要兩個機器的數據庫初態(數據庫結構,數據,配置)是一樣的,那麼我們開啓主從複製之後就能保證他們一直都是一樣的狀態。這些都是mysql自己實現的,我們就配置一下就可以了。
從圖中我們可以看出來了,主服務器需要做的事情非常簡單的,就只是把執行的sql語句存儲到二進制文件binary-log中,而從服務器需要做的事情比較多,而且還得使用兩個線程進行整個事件的監聽和處理。
mysql複製的優點:
- 如果主庫出現問題,可以快速切換到從庫提供服務
- 可以在從庫執行查詢操作,降低主庫的訪問壓力。
- 可以在從庫進行備份,以免備份期間影響主庫的服務。
mysql主從複製的原理
(1)首先,mysql主庫在事務提交時會把數據庫變更作爲事件Events記錄在二進制文件binlog中;mysql主庫上的sys_binlog控制binlog日誌刷新到磁盤。
(2)主庫推送二進制文件binlog中的事件到從庫的中繼日誌relay log,之後從庫根據中繼日誌重做數據庫變更操作。通過邏輯複製,以此來達到數據一致。
Mysql通過3個線程來完成主從庫之間的數據複製:其中BinLog Dump線程跑在主庫上,I/O線程和SQL線程跑在從庫上。當從庫啓動複製(start slave)時,首先創建I/O線程連接主庫,主庫隨後創建Binlog Dump線程讀取數據庫事件併發給I/O線程,I/O線程獲取到數據庫事件更新到從庫的中繼日誌Realy log中去,之後從庫上的SQl線程讀取中繼日誌relay log 中更新的數據庫事件並應用。
由於主從複製的一些特性,爲了保證數據一一致,所以這裏有些原則需要遵守
- 每個slave只有一個master
- 每個slave只能有一個唯一的服務器ID
- 每個master可以有多個salve
環境準備
主服務器(Master服務器Linux中Ubuntu版本):192.168.222.128
從服務器(Slave服務器Linux中Ubuntu版本):192.168.222.129
Mysql數據庫:5.6
防火牆3306端口要開放
兩臺服務器數據庫的數據表結構,配置都必須是一樣的。
Master服務器配置:
1.開放防火牆3306端口
首先,檢查防火牆端口是否打開,輸入命令如下:
netstat -an|grep 3306
然後,打開mysql配置文件,將bind-address = 127.0.0.1註銷,
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
重啓服務器,再次查看,如圖所示即爲端口打開。
2.創建slave用戶,並授權於slave用戶,輸入命令如下:
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT ALL PRIVILEGES ON *.* TO slave@"%" IDENTIFIED BY "123456";
3.修改數據庫配置文件my.cnf(my.cnf在路徑/etc/mysql/)下
log-bin:開啓二進制日誌,該日誌是在事務提交時寫日誌文件的。默認大小是1G,後面加001,002這樣的後綴順加。
server-id,唯一標識主機,mysql主從每個mysql實例配置都不一樣就行。這個值默認是0,如果是0,主服務器拒絕任何從服務器的連接。
skip-grant-tables:開啓免密登錄
3.重啓數據庫服務,輸入命令:
systemctl restart mysql
Slave服務器配置:
1.配置my.cnf文件
server-id=2
replicate-do-db=test
skip-slave-start=true
2.重啓數據庫服務
systemctl restart mysql
配置從服務器認主服務器
獲取binlog的信息
我們先到主(master)服務器上獲取binlog的信息,在mysql的命令界面輸入:
show master status;
這裏展示的就是我們當前主服務器使用的binlog的文件名,其中position是文件中偏移量,我們之後配置slave需要用到這些信息,這個文件在每次服務器狀態變化後都不同
進入從服務器輸入以下指令:
stop slave; //先停止slave服務線程
change master to
master_host='192.168.222.128',
master_user='slave',
master_password='123456',
master_log_file='mysql-bin.000009',
master_log_pos=154;
這裏user和password就是我們第一步在主服務器上創建的用戶名和密碼,然後MASTER_LOG_FILE 就是我們上一步查看到的master在使用的binlog文件(這個文件在每次主服務器狀態變化後都不同),MASTER_LOG_POS 就是binlog的偏移量,用於同步掃描使用。master_log_file對應File, master_log_pos對應Position。Mysql 5.x以上版本已經不支持在配置文件中指定主服務器相關選項。
開啓slave線程
start slave;
查看slave狀態:
show slave status\G;
圖中Slave _IO_Running:Yes和Slave_SQL_Running:Yes,就表示我們的從服務器已經在完全運行了。
現在我們可以在主服務器的數據庫上做一個修改數據看看是否同步到從服務器的數據庫上來證明可用性。
主從驗證
因爲之前數據庫的數據都是一樣的,現在就都新建個test 庫,並且在test 庫新建表 user_test.
這裏需要注意兩個數據庫都要執行
#創建新庫
CREATE DATABASE test;
#指定編碼
CREATE DATABASE IF NOT EXISTS my_db default charset utf8 COLLATE utf8_general_ci;
#創建新表
create table user_test( id int comment'ID',name VARCHAR(20) comment'名稱', create_time timestamp DEFAULT now() comment'創建時間' );
準備條件完成,進入測試
在主服務器上進行主庫查詢
在從服務器上進行從庫查詢
主服務器上手動插入條數據
use test;
insert INTO user_test value(1,"test",NOW());
在從服務器上直接查詢從庫看有沒有數據同步
數據同步成功
雙機熱備
實現雙機熱備,原理其實就是做兩個機器的互相主從,我們把上述步驟主從對調,然後做一遍就能實現了雙機熱備了
同時在主從服務器建立一個連接帳戶,該帳戶必須授予REPLIATION SLAVE權限。這裏因爲服務器A和服務器B互爲主從,所以都要分別建立一個同步用戶。
master服務器:
mysql> grant replication slave on *.* to 'slave'@'192.168.222.129' identified by '123456';
mysql> flush privileges;
slave服務器:
mysql> grant replication slave on *.* to 'slave'@'192.168.222.128' identified by '123456';
mysql> flush privileges;
修改my.cnf文件,master服務器配置:
log-bin=mysql-bin
server-id=1
# 雙機熱備需要添加
log-slave-updates
sync_binlog = 1
auto_increment_offset = 1
auto_increment_increment = 2
slave服務器配置:
log-bin=mysql-bin
server-id=2
# 雙機熱備需要添加
log-slave-updates
sync_binlog = 1
auto_increment_offset = 1
auto_increment_increment = 2
-
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:配置從庫上的更新操作是否寫入二進制文件,如果這臺從庫,還要做其他從庫的主庫,那麼就需要打這個參數,以便從庫的從庫能夠進行日誌同步。
-
skip-slave-start 從機服務器重啓後slave 不會自動開始,要手動執行,防止出錯
- 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的值被忽略。例如:表內已有一些數據,就會用現在已有的最大自增值做爲初始值。
分別在主,從服務器重啓mysql服務,輸入命令:
systemctl restart mysql
分別在主、從服務器上查看作爲主服務器的狀態,輸入命令如下:
show master status\G;
master服務器下查看的狀態如圖所示:
slave服務器 下查看的狀態如果所示:
分別在Master服務器和Slave服務器,使用change master to指定位置:
Master服務器,輸入命令如下所示:
mysql> change master to
-> master_host='192.168.222.129',
-> master_user='slave',
-> master_password='123456',
-> master_log_file='mysql-bin.000002',
-> master_log_pos=154;
Slave服務器,輸入命令如下:
mysql> change master to
-> master_host='192.168.222.128',
-> master_user='slave',
-> master_password='123456',
-> master_log_file='mysql-bin.000011',
-> master_log_pos=154;
分別在Master和Slave服務器上重啓Slave線程
mysql>start slave;
分別在Master和Slave服務器上查看從服務器狀態,輸入命令如下:
mysql>show slave status\G;
查看下面兩項值均爲Yes,即表示設置從服務器成功。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master服務器上的狀態,如下圖所示:
Slave服務器上的狀態,如下圖所示:
測試主主同步,從Master中插入一條數據,看Slave中是否存在,如下圖所示:
從Slave服務器中查看數據是否存在,如下圖所示:
在Slave服務器中刪除數據,看Master服務器中數據是否存在,如下圖所示:
在Master服務器查看是否存在此條數據,如下圖所示:
由此,測試即爲成功。