mysql主從複製原理

一、mysql複製解決的問題

  1. 實現在不同服務器上的數據分佈
  2. 實現數據讀取的負載均衡
  3. 增強數據安全性,利用備庫的備份來減少主庫的負載,方便進行數據庫高可用的架構部署

      避免MySQL單點失敗

     4、實現數據庫的在線升級

二、MySQL二進制日誌

二進制日誌記錄了所有對MySQL數據庫的修改事件,包括增刪改查事件與對錶結構的修改事件

二進制日誌的記錄格式:

1.基於段的格式binlog_format=STATEMENT

優點:日誌記錄量相對較小,節約磁盤及網絡I/O,只對一條記錄修改或者插入

row 格式所產生的日誌量小於段產生的日誌量

缺點:必須要記錄上下文信息,保證語句在從服務器上執行結果與住服務器上相同

特定的函數如UUID(),user() 這樣非確定性函數還是無法複製,可能造成MySQL複製的主

備服務器的數據不一致

查看binlog日誌格式

登錄數據庫

[root@localhost ~]# mysql -uroot -p

Enter password:

mysql> show variables like 'binlog_format';

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

| Variable_name | Value |

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

| binlog_format | MIXED |

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

1 row in set (0.00 sec)

臨時更改日誌格式

set session binlog_format=statement;

在 /etc/my.cnf文件中也可以修改,修改之後需要重啓mysql服務

刷新binlog

mysql> show binary logs;

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

| Log_name | File_size |

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

| mysql-bin.000001 | 177 |

| mysql-bin.000002 | 177 |

| mysql-bin.000003 | 437 |

| mysql-bin.000004 | 1403 |

| mysql-bin.000005 | 177 |

| mysql-bin.000006 | 201 |

| mysql-bin.000007 | 201 |

| mysql-bin.000008 | 177 |

| mysql-bin.000009 | 154 |

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

9 rows in set (0.00 sec)

 

mysql>

mysql> flush logs;

Query OK, 0 rows affected (0.02 sec)

mysql> show binary logs;

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

| Log_name | File_size |

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

| mysql-bin.000001 | 177 |

| mysql-bin.000002 | 177 |

| mysql-bin.000003 | 437 |

| mysql-bin.000004 | 1403 |

| mysql-bin.000005 | 177 |

| mysql-bin.000006 | 201 |

| mysql-bin.000007 | 201 |

| mysql-bin.000008 | 177 |

| mysql-bin.000009 | 201 |

| mysql-bin.000010 | 154 |

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

10 rows in set (0.00 sec)

插入測試數據

mysql> create table t(id int,c1 varchar(10));

Query OK, 0 rows affected (0.03 sec)

mysql> insert into t values(1,'22'),(2,'rrr');

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

用mysqlbin查看日誌文件

/usr/local/mysql/bin/mysqlbinlog mysql-bin.000010

可以看到執行的sql語句

2、基於行的日誌格式,binlog_format=ROW

可以避免MySQL主從複製中主從不一致的問題,同一個sql語句修改1000條數據的情況下,基於段的日誌格式只會記錄這個sql語句,基於行的日誌會有1000條記錄分別記錄每一行數據的修改

優點:

1、mysql主從複製更加安全

2、對每一行數據修改比基於段的高效

基於行的日誌格式可以對數據進行恢復

缺點:1、日誌記錄量非常大

 

日誌量控制參數

binlog_row_image=[FULL|MINIMAL|NOBLOB]

FULL記錄每一行的變更,minimal只記錄影響後的行

修改binlog日誌格式

mysql> set session binlog_format=ROW;

刷新日誌

mysql> flush logs;

查看參數binlog_row_image

mysql> show variables like 'binlog_row_image';

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

| Variable_name | Value |

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

| binlog_row_image | FULL |

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

1 row in set (0.00 sec)

增加一列

mysql> alter table t add c2 text;

mysql> insert into t values(3,'ee','ttt');

mysql> delete from t where id=1;

update t set c2='ttwwwtt' where id=2;

 

/usr/local/mysql/bin/mysqlbinlog -vv mysql-bin.000011

查看日誌

更新記錄了每列的變化前後的值

可以看到日誌記錄的刪除的詳細信息

設置

mysql> set session binlog_row_image=minimal;

mysql> update t set c2='tttt' where id=2;

/usr/local/mysql/bin/mysqlbinlog -vv mysql-bin.000011

可以看到修改前後的值

但是沒有記錄其他列的變化值

修改參數

set session binlog_row_image=noblob;

該參數更新text列不被記錄

mysql> update set c1='tttsss' where id=3;

查看日誌沒有記錄text列的更新前後的值

3.混合日誌格式binlog_format=MIXED

特點:根據SQL語句由系統決定是在基於段與基於行的日誌格式中進行決策,數據量的大小由執行的sql語句決定

 

基於行的日誌對複製的影響

優點:可以應用於任何sql的複製包括非確定性函數,存儲過程

可以減少數據庫鎖的使用

缺點:要求主要從數據庫的表結構相同,否則可能會中斷複製

無法在從上單獨執行觸發器

 

 

三、MySQL主從複製工作方式

 

 

1、主將變更寫入二進制日誌

2、從讀取主的二進制日誌變更到relay_log中

3、在從上重放relay_log中的日誌

基於sql段的日誌是在從庫上重新執行記錄的sql

基於行的日誌則是在從庫上直接應用對數據庫行的修改

二、配置MySQL複製

1、基於日誌點的複製配置步驟

在主DB服務器上建立複製賬號

create user 'repl' @ 'IP段', identified by 'PassWord';建立賬戶

grant replication slave on *.* to 'repl' @ 'IP段' 賬戶授權

配置主數據庫服務器:

bin_log=mysql-bin

server_id=1 //server_id 在集羣中唯一

配置從服務器

bin_log=mysql-bin

server_id=2

relay_log=mysql-relay-bin

log_slave_update=on (可選,設置中繼服務器必須設置on)

read_only=on(可選)

初始化從服務器數據

mysqldump --master-data=2 --single-transaction

xtrabackup --slave -info (可用於熱備份)

啓動複製鏈路

change master to matser_host = 'master_host_ip',

master_user='repl',

master_password = 'PassWord',

master_log_file = 'mysql_log_file_name',//主上的二進制文件

matser_log_pos=4//複製偏移量

配置機器,主數據庫ip192.168.31.101,從數據庫192.168.31.102

在主數據庫上創建賬戶並授權

mysql> create user repl@'192.168.31.%' identified by '123456';

grant replication slave on *.* to repl@'192.168.31.%';

flush privileges;

更改主從數據庫配置

server-id = 1(從數據庫設置爲2)

log-bin=mysql-bin

binlog_format=row

對主數據庫進行備份

[root@localhost ~]# /usr/local/mysql/bin/mysqldump --single-transaction --master-data --triggers --routines --all-databases -uroot -p >>all.sql

將備份sql拷貝到從數據庫

在從庫上導入sql

mysql -uroot -p <all.sql

在從庫上設置複製鏈路

mysql> change master to master_host='192.168.31.101',

-> master_user='repl',

-> master_password='123456',

-> MASTER_LOG_FILE='mysql-bin.000014', MASTER_LOG_POS=154;

Query OK, 0 rows affected, 2 warnings (0.01 sec)

在備份的sql文件中可以看到二進制文件與偏移量

複製鏈路配置完查看信息

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State:

Master_Host: 192.168.31.101

Master_User: repl

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000014

Read_Master_Log_Pos: 154

Relay_Log_File: localhost-relay-bin.000001

Relay_Log_Pos: 4

Relay_Master_Log_File: mysql-bin.000014

Slave_IO_Running: No

Slave_SQL_Running: No

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: 154

Relay_Log_Space: 154

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: NULL

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: 0

Master_UUID:

Master_Info_File: /usr/local/mysql/var/master.info

SQL_Delay: 0

SQL_Remaining_Delay: NULL

Slave_SQL_Running_State:

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

Replicate_Rewrite_DB:

Channel_Name:

Master_TLS_Version:

在從數據庫上執行start slave;開始主從複製

基於日誌點的優點:

1、 mysql最早支持的複製技術,Bug相對較少對

2、對sql執行沒有任何限制

3、故障處理容易

基於日誌點的缺點:

1、故障轉移時重新獲取新的日誌點信息比較困難

 

2、基於GTID的複製

GITD(Global Transaction Identifiers)即全局事務ID,其保證爲每一個在主上提交的事務在複製集羣中可以生成一個唯一的ID

在主DB上建立複製賬戶

create user 'repl' @ 'ip段' identified by 'PassWord';

grant replication slave on *.* to 'repl' @ 'ip段';

配置主數據庫

log-bin=mysql-bin

server_id=1

gtid_mode=on

enforce_gtid_consistency 強制GTIP一致性

log-slave-updates=on(5.7中不用設置)

從數據庫配置

relay_log=/usr/local/mysql/log/relay_log

gtid_mode=on

enforce_gtid_consistency

read_only=on 建議保證從庫數據不被修改

master_info_repository=table 建議

relaiy_log_info_repository = table 建議

 

初始化從服務器與基於點的主從複製一樣

啓動基於GTID的複製

change master to master_host = 'matser_host_ip',

matser_user = 'repl',

matser_password='PassWord',

matser_auto_position=1

 

在主服務器與從服務器配置文件中加入上述配置項

備份數據

mysqldump --single-transaction --master-data=2 --triggers --routines --all-databases -uroot -p >>all2.sql

在備份文件中可以看到gtid事務初始位置

在從數據庫上進行數據恢復,配置複製鏈路

mysql -uroot -p <all2.sql

change master to master_host='192.168.31.101',master_user='repl',master_password='123456',master_auto_position=1;

start slave;

GTID優點

1、可以方便的進行故障轉移

2、從庫上不會丟失主庫上的任何修改

缺點:

1、故障處理比較複雜

2、對執行的sql有一定限制(不能用create table select 建表)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章