Mysql主從複製

image.png | left | 682x296

1.主從複製簡介

複製是 MySQL 的一項功能,容許服務器將更改從一個實例複製到另外一個實例。mysql

1)主服務器將全部數據和結構更改記錄到二進制日誌中。
2)從屬服務器從主服務器請求該二進制日誌並在本地應用其內容。
3)IO:請求主庫,獲取上一次執行過的新的事件,並存放到relaylog
4)SQL:從relaylog中將sql語句翻譯給從庫執行sql

2.主從複製原理

1.__主從複製的前提__

1)兩臺或兩臺以上的數據庫實例
2)主庫要開啓二進制日誌
3)主庫要有複製用戶
4)主庫的server_id和從庫不一樣
5)從庫須要在開啓複製功能前,要獲取到主庫以前的數據(主庫備份,而且記錄binlog當時位置)
6)從庫在第一次開啓主從複製時,時必須獲知主庫:ip,port,user,password,logfile,pos
7)從庫要開啓相關線程:IO、SQL
8)從庫須要記錄複製相關用戶信息,還應該記錄到上次已經從主庫請求到哪一個二進制日誌
9)從庫請求過來的binlog,首先要存下來,而且執行binlog,執行過的信息保存下來數據庫

2.__從複製涉及到的文件和線程__

++主庫:++vim

1)主庫binlog:記錄主庫發生過的修改事件
2)dump thread:給從庫傳送(TP)二進制日誌線程緩存

++從庫:++服務器

1)relay-log(中繼日誌):存儲全部主庫TP過來的binlog事件
2)master.info:存儲複製用戶信息,上次請求到的主庫binlog位置點
3)IO thread:接收主庫發來的binlog日誌,也是從庫請求主庫的線程
4)SQL thread:執行主庫TP過來的日誌網絡

++原理++ide

1)經過change master to語句告訴從庫主庫的ip,port,user,password,file,pos
2)從庫經過start slave命令開啓複製必要的IO線程和SQL線程
3)從庫經過IO線程拿着change master to用戶密碼相關信息,鏈接主庫,驗證合法性
4)從庫鏈接成功後,會根據binlog的pos問主庫,有沒有比這個更新的
5)主庫接收到從庫請求後,比較一下binlog信息,若是有就將最新數據經過dump線程給從庫IO線程
6)從庫經過IO線程接收到主庫發來的binlog事件,存儲到TCP/IP緩存中,並返回ACK更新master.info
7)將TCP/IP緩存中的內容存到relay-log中
8)SQL線程讀取relay-log.info,讀取到上次已經執行過的relay-log位置點,繼續執行後續的relay-log日誌,執行完成後,更新relay-log.infospa

3.__主從複製搭建實戰__

主庫操做

修改主庫的配置文件命令行

vim /etc/my.cnf
#在[mysqld]標籤下開啓binlog和server_id
log_bin=mysql-bin
server_id =1

重啓數據庫(兩種方式)後進入

[root@db01 ~]# /etc/init.d/mysqld restart      
[root@db01 ~]# systemctl restart mysqld

查看日誌狀態

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)

建立一個複製用戶

mysql> grant replication slave on *.* to rep@'10.0.0.%' identified  by '123';
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;      #binlog pos 變成了324
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      324 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

從庫操做

修改從庫的配置文件

vim /etc/my.cnf
#在[mysqld]標籤下開啓server_id  從庫server_id不可與主庫相同,從庫之間能夠一致
server_id =2

重啓數據庫後進入執行change master to 語句

mysql> change master to
master_host='10.0.0.51',     #主庫ip
master_user='rep',              #主從複製用戶
master_password='123',        #主從複製用戶密碼
master_log_file='mysql-bin.000003',     #binlog
master_log_pos=324,            #binlog 起始點
master_port=3306;            #數據庫端口

開啓slave

mysql> start slave;

查看slave狀態(yes開啓成功)

mysql> show slave status\G

image.png | left | 826x461

4.驗證主從複製

查看主庫上的庫

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

建立一個新庫zeq

mysql> create database zeq;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| zeq                |
+--------------------+
5 rows in set (0.00 sec)

查看從庫

mysql> show databases;        #從庫上已經複製過來了
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| zeq                |
+--------------------+
5 rows in set (0.01 sec)

5.主從複製基本故障處理

IO線程

++鏈接主庫++

1)user password ip port
2)網絡:不通,延時高,防火牆

++請求binlog++

1)binlog不存在或者損壞

++更新relay-log和master.info++

SQL線程
1)relay-log出現問題
2)從庫作寫入了

  • 操做對象已存在(create)
  • 操做對象不存在(insert update delete drop truncate alter)
  • 約束問題、數據類型、列屬性

處理方法一:

#臨時中止同步
mysql> stop slave;
#將同步指針向下移動一個(可重複操做)
mysql> set global sql_slave_skip_counter=1;
#開啓同步
mysql> start slave;

處理方法二:

#編輯配置文件
vim /etc/my.cnf
#在[mysqld]標籤下添加如下參數
slave-skip-errors=1032,1062,1007

可是以上操做都是有風險存在的

處理方法三:

1)從新備份數據庫,恢復到從庫
2)給從庫設置爲只讀

#在命令行臨時設置
mysql> set global read_only=1;
#在配置文件中永久生效/etc/my.cnf
read_only=1

6.延時從庫

企業中通常會延時3-6小時

延時從庫配置方法
從庫操做

#中止主從
mysql>stop slave;
#設置延時爲180秒
mysql>change master to master_delay = 180;
#開啓主從
mysql>start slave;
#查看狀態
mysql> show slave status \G
SQL_Delay: 60
3.延時從庫中止方法
#中止主從
mysql> stop slave;
#設置延時爲0
mysql> CHANGE MASTER TO MASTER_DELAY = 0;
#開啓主從
mysql> start slave;

image.png | left | 826x420

關閉半同步:

主庫執行
SET GLOBAL rpl_semi_sync_master_enabled = 0;
SET GLOBAL rpl_semi_sync_master_wait_no_slave = 0;

從庫執行:
SET GLOBAL rpl_semi_sync_slave_enabled = 0;
相關文章
相關標籤/搜索