1. 程式人生 > >218.4.3-4.4 15周2,3次課

218.4.3-4.4 15周2,3次課

Linux學習

十五周二,三次課 mysql擴展知識

MySQL主從復制原理

MYSQL的主從復制是一個異步的復制過程,數據將從一個MySQL數據庫(Master)復制到另一個MySQL數據庫(Slave), 在Master與Slave 之間實現整個主從復制的過程是由三個線程參與完成的。其中有兩個線程 (SQL線程和I/O線程) 在Slave端 , 另外一個線程 ( I/O線程) 在 Master端.

要實現MySQL的主從復制,首先必須打開Master端的binlog記錄功能, 否則就無法實現。 因為整個復制過程實際上就是Slave從Master端獲取binlog日誌,然後再在 Slave上以相同順序執行獲取的binlog日誌中所記錄的各種SQL操作。

要打開MySQL的binlog記錄功能,可通過在MYSQL的配置文件my.cnf中的 mysqld模塊([mysqld]標識後的參數部分)增加"log-bin"參數選項來實現,具體信息如下。

[mysqld]

Log-bin=/data/mysql/mysql-bin

提示:有些讀者因把log-bin放在了配置文件結尾,而不是[mysqld]標識後,從而導致配置復制不成功。

下面簡單描述MySQL Replication的復制原理過程。

1) 在Slave服務器上執行start slave命令開啟主從復制開關,開始進行主從復

2) 此時,Slave服務器的I/O線程會通過在Master上已經授權的復制用戶權限請求連接Master服務器,並請求從指定binlog日誌文件的指定位置(日誌文件名和位置就是在配置主從復制服務時執行change master命令指定的)之後開始發送binlog日誌內

3) Master服務器接收到來自Slave服務器的I/O線程的請求後,其上負責復制的I/O線程會根據Slave服務器的I/O線程請求的信息分批讀取指定binlog日誌文件指定位置之後的binlog日誌信息,然後返回給Slave端的I/O線程。返回的信息中除了binlog日誌內容外,還有在Master服務器端記錄的新的binlog文件名稱,以及在新的binlog中的下一個指定更新位置

4) 當Slave服務器的I/O線程獲取到Master服務器上I/O線程發送的日誌內容、日誌文件及位置點後,會將binlog日誌內容依次寫到Slave端自身的Relay Log(即中繼日誌)文件(MySQL-relay-bin.xxxxxx)的最末端,並將新的binlog文件名和位置記錄到 master-info文件中,以便下一次讀取Master端新binlog日誌時能夠告訴Master服務器從新binlog日誌的指定文件及位置開始請求新的binlog日誌內容

5) Slave服務器端的SQL線程會實時檢測本地Relay Log中I/O線程新增加的日誌內容,然後及時地把Relay Log文件中的內容解析成SQL語句,並在自身Slave服務器上按解析SQL語句的位置順序執行應用這些SQL語句,並在relay-log.info中記錄當前應用中繼日誌的文件名及位置點.

經過了上面的過程,就可以確保在Master端和Slave端執行了同樣的SQL語句。當復制狀態正常時,Master端和Slave端的數據是完全一樣的。當然,MySQL的復制機制也有一些特殊情況 ,不過在大多數情況下,大家不用擔心。

針對MYSQL主從復制原理的重點進行小結:

  • 主從復制是異步的邏輯的SQL語句級的復制。

  • 復制時,主庫有一個I/O線程,從庫有兩個線程,即I/O 和SQL線程。

  • 實現主從復制的必要條件是主庫要開啟記錄binlog功能。

  • 作為復制的所有MYSQL節點的server-id都不能相同。

  • binlog文件只記錄對數據庫有更改的SQL語句(來自主數據庫內容的變更),不記錄任何查詢(如select、show)語句。

mysql主從數據庫不同步的2種解決方法

Mysql的主從數據庫沒有同步

先上Master庫:

mysql>show processlist; 查看下進程是否Sleep太多。發現很正常。

show master status; 也正常。

mysql> show master status;

+-------------------+----------+--------------+-------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+-------------------+----------+--------------+-------------------------------+

| mysqld-bin.000001 | 3260 | | mysql,test,information_schema |

+-------------------+----------+--------------+-------------------------------+

1 row in set (0.00 sec)

再到Slave上查看

mysql> show slave status\G

Slave_IO_Running: Yes

Slave_SQL_Running: No

可見是Slave不同步

下面介紹兩種解決方法:

方法一:忽略錯誤後,繼續同步

該方法適用於主從庫數據相差不大,或者要求數據可以不完全統一的情況,數據要求不嚴格的情況

解決:

stop slave;

#表示跳過一步錯誤,後面的數字可變

set global sql_slave_skip_counter =1;

start slave;

之後再用mysql> show slave status\G 查看:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

ok,現在主從同步狀態正常了。。。

方式二:重新做主從,完全同步

該方法適用於主從庫數據相差較大,或者要求數據完全統一的情況

解決步驟如下:

1.先進入主庫,進行鎖表,防止數據寫入

使用命令:

mysql> flush tables with read lock;

註意:該處是鎖定為只讀狀態,語句不區分大小寫

2.進行數據備份

#把數據備份到mysql.bak.sql文件

[root@server01 mysql]#mysqldump -uroot -p -hlocalhost > mysql.bak.sql

這裏註意一點:數據庫備份一定要定期進行,可以用shell腳本或者python腳本,都比較方便,確保數據萬無一失

3.查看master 狀態

mysql> show master status;

+-------------------+----------+--------------+-------------------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+-------------------+----------+--------------+-------------------------------+

| mysqld-bin.000001 | 3260 | | mysql,test,information_schema |

+-------------------+----------+--------------+-------------------------------+

1 row in set (0.00 sec)

4.把mysql備份文件傳到從庫機器,進行數據恢復

#使用scp命令

[root@server01 mysql]# scp mysql.bak.sql [email protected]:/tmp/

5.停止從庫的狀態

mysql> stop slave;

6.然後到從庫執行mysql命令,導入數據備份

mysql> source /tmp/mysql.bak.sql

7.設置從庫同步,註意該處的同步點,就是主庫show master status信息裏的| File| Position兩項

change master to master_host = '192.168.128.100', master_user = 'rsync', master_port=3306, master_password='', master_log_file = 'mysqld-bin.000001', master_log_pos=3260;

8.重新開啟從同步

mysql> stop slave;

9.查看同步狀態

mysql> show slave status\G 查看:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

好了,同步完成啦。

mysql一主多從同步配置

一主多從,其實和一主一從是一樣的原理

一、環境

Master:192.168.1.100

slave1:192.168.1.110

slave2:192.168.1.111

master和 slave上的相關配置

master 上編輯my.cnf文件

在[mysqld]下添加如下字段:

server-id = 100

log-bin=mysql-bin

binlog-do-db=YYY //需要同步的數據庫

binlog-ignore-db=mysql //被忽略的數據庫

binlog-ignore-db=information-schema //被忽略的數據庫

在master上為slave添加一個同步賬號

grant replication slave on *.* to 'repl'@192.168.1.110 identified by '123456'; //在slave1上登陸成功

grant replication slave on *.* to 'repl'@192.168.37.111 identified by 'password'; //在slave2上登陸成功

保存後,重啟master的mysql服務:

service mysql restart;

用show master status命令查看日誌情況

修改slave1上的配置文件my.cnf

在[mysqld]下添加如下字段:

server-id = 110

保存後,重啟slave1的mysql服務

先關閉主從同步:stop slave;

實現主從同步:

change master to master_host='192.168.1.100', master_user='repl', master_password='123456', master_log_file=' mysql-bin.000001', master_log_pos=320;

打開同步:start slave;

判斷主從是否配置成功:show slave status\G(最後可以不用分號,\G本身就是結束符)

確認以下兩項參數都為Yes

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

修改slave2上的配置文件my.cnf

在[mysqld]下添加如下字段:

server-id = 111

其他操作和slave1上相同

MySQL雙主(主主)架構方案

MySQL雙主(主主)架構方案思路是:

1.兩臺mysql都可讀寫,互為主備,默認只使用一臺(masterA)負責數據的寫入,另一臺(masterB)備用;

2.masterA是masterB的主庫,masterB又是masterA的主庫,它們互為主從;

3.兩臺主庫之間做高可用,可以采用keepalived等方案(使用VIP對外提供服務);

4.所有提供服務的從服務器與masterB進行主從同步(雙主多從);

5.建議采用高可用策略的時候,masterA或masterB均不因宕機恢復後而搶占VIP(非搶占模式);

這樣做可以在一定程度上保證主庫的高可用,在一臺主庫down掉之後,可以在極短的時間內切換到另一臺主庫上(盡可能減少主庫宕機對業務造成的影響),減少了主從同步給線上主庫帶來的壓力;

但是也有幾個不足的地方:

1.masterB可能會一直處於空閑狀態(可以用它當從庫,負責部分查詢);

2.主庫後面提供服務的從庫要等masterB先同步完了數據後才能去masterB上去同步數據,這樣可能會造成一定程度的同步延時;

架構的簡易圖如下:

技術分享圖片

主主環境:

1. 2臺:masterA(192.168.1.100,masterB(192.168.1.101)CentOS 7.4

2.Mysql5.6版本

添加masterA配置文件/etc/my.cnf

[mysqld]

server-id = 100

log-slave-updates = true #將復制事件寫入binlog,一臺服務器既做主庫又做從庫此選項必須要開啟

#masterA自增長ID

auto_increment_offset = 1

auto_increment_increment = 2 #奇數ID

添加masterB配置文件/etc/my.cnf

[mysqld]

server-id = 101

log-slave-updates = true #將復制事件寫入binlog,一臺服務器既做主庫又做從庫此選項必須要開啟

#masterB自增加ID

auto_increment_offset = 2

auto_increment_increment = 2 #偶數ID

添加主從同步賬戶

masterA上:

mysql> grant replication slave on *.* to 'repl'@'192.168.1.101' identified by '123456';

mysql> flush privileges;

masterB上:

mysql> grant replication slave on *.* to 'repl'@'192.168.1.100' identified by '123456';

mysql> flush privileges;

查看主庫的狀態

masterA上:

mysql> show master status;

File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000003 | 120 | | | |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

masterB上

mysql> show master status;

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000003 | 437 | | | |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

配置同步信息:

masterA上:

mysql>change master to

master_host='192.168.10.12',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=437;

mysql> start slave;

mysql> show slave status\G;

顯示有如下狀態則正常:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

masterB上:

#本人是測試環境,可以保證沒數據寫入,否則需要的步驟是:先masterA鎖表-->masterA備份數據-->masterA解鎖表 -->masterB導入數據-->masterB設置主從-->查看主從

mysql> change master to

master_host='192.168.1.100',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;

mysql>start slave;

mysql> show slave status\G;

顯示有如下狀態則正常:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

開啟MySQL5.6的GTID功能

masterA和masterB分別執行如下命令:

mysql> stop slave;

Query OK, 0 rows affected (0.00 sec)

mysql> change master to MASTER_AUTO_POSITION=1;

Query OK, 0 rows affected (0.01 sec)

mysql> start slave;

Query OK, 0 rows affected (0.00 sec)


218.4.3-4.4 15周2,3次課