MySQL性能優化(十)-- 主從複製

1、概念  

Mysql複製(replication)是一個異步的複製,從一個Mysql 實例(Master)複製到另外一個Mysql 實例(Slave)。實現整個主從複製,須要由Master服務器上的IO進程,和Slave服務器上的Sql進程和IO進程共從完成。要實現主從複製,首先必須打開Master端的binary log(bin-log)功能,由於整個 MySQL 複製過程實際上就是Slave從Master端獲取相應的二進制日誌,而後再在本身slave端徹底順序的執行日誌中所記錄的各類操做。 (二進制日誌幾乎記錄了除select之外的全部針對數據庫的sql操做語句)mysql

2、複製解決的問題

(1) 數據分佈 (Data distribution )sql

(2) 負載平衡(load balancing)數據庫

(3) 備份(Backups)緩存

(4) 高可用性和容錯行 High availability and failover安全

3、複製的原理

(1) master將改變記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件,binary log events);服務器

(2) slave將master的binary log events拷貝到它的中繼日誌(relay log);ssh

(3) slave重作中繼日誌中的事件,將更改應用到本身的數據上。異步

下圖描述了複製的過程:ide

img

該過程的第一部分就是master記錄二進制日誌。在每一個事務更新數據完成以前,master在二日誌記錄這些改變。MySQL將事務串行的寫入二進制日誌,即便事務中的語句都是交叉執行的。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務。工具

下一步就是slave將master的binary log拷貝到它本身的中繼日誌。首先,slave開始一個工做線程——I/O線程。I/O線程在master上打開一個普通的鏈接,而後開始binlog dump process。Binlog dump process從master的二進制日誌中讀取事件,若是已經跟上master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日誌。

SQL slave thread(SQL從線程)處理該過程的最後一步。SQL線程從中繼日誌讀取事件,並重放其中的事件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日誌一般會位於OS的緩存中,因此中繼日誌的開銷很小。

此外,在master中也有一個工做線程:和其它MySQL的鏈接同樣,slave在master中打開一個鏈接也會使得master開始一個線程。複製過程有一個很重要的限制——複製在slave上是串行化的,也就是說master上的並行更新操做不能在slave上並行操做。

4、配置

  1. 建立一個數據庫 : create database testXbq;
  2. 建立表:create table student(id int primary key auto_increment,name varchar(20));
  3. 先將master上的數據複製到slave上(基於二進制日誌備份(默認是關閉的))

(1)先開啓二進制日誌:

編輯配置文件:vi /etc/my.cnf,在裏面增長

log-bin=mysql-bin            // 二進制存放的目錄和名字
binlog_format=mixed          // 
server-id=1                  // 標誌 master的惟一標識
複製代碼

img

(2)重啓mysql: service mysql restart

(3)查看master的狀態:show master status;

img

(4)查看目錄下的二進制文件: ll /var/lib/mysql

img

其中,mysql-bin.index存的是:

img

(5)基於 位置 備份

mysqldump -uroot -p --single-transaction --master-data=2  --triggers --routines --all-databases > xbq.sql
複製代碼

// 基於獨立的事務 // =2 註釋掉 =1 不註釋 // 備份到當前目錄下xbq.sql

img

查看 xbq.sql,會發現以下(或者 直接重啓master後 登陸mysql,執行 show master status也能夠看到 從 mysql-bin.000001的579位置開始複製):

img

後續的複製工做會從 mysql-bin.000001的579位置開始複製。

(6)master須要受權 一個用戶給 slave,即創建一個複製帳號,在master上執行(能夠經過 ? grand 查看 grand的語法):

grant replication slave on . to 'reppc'@'%' identified by 'xbq123'; // 通常不用root賬號,% 表示全部客戶端均可能連,只要賬號,密碼正確,此處可用具體客戶端IP代替,如192.168.1.112,增強安全。

須要刷新權限 才能夠生效: flush privileges;(此時,在salve上鍊接 master的數據庫)

(7)重啓master

(8)在slave上應用 xbq.sql,有兩種方式:(master中執行下面命令,ip換成slave的ip)

方法一:遠程拷貝到 slaver, scp root@192.168.242.129:/usr/xbq.sql /usr/xbq.sql ,機器上需安裝openssh-client,yum install -y openssh-client

方法二:遠程鏈接 執行sql, mysql -h192.168.242.129 -uroot -p < /usr/xbq.sql,前提,須要在slave上給master遠程鏈接的權限,以下:

grant all privileges on *.* to 'root'@'master的IP' identified by 'master的mysql密碼' with grant option;
FLUSH PRIVILEGES;
複製代碼

4.slave 應用sql(前提:slave中已經有了master導出的sql文件,如下命令在slave中執行。若是使用 (8)中的方法二的話,忽略此步驟)

方法一: source /usr/xbq.sql

方法二: mysql -uroot -p < /usr/xbq.sql

通過上面的操做 master上的數據 就到了 slave中

5.複製的過程:

(1)slave開始二進制日誌,和 master同樣的配置 ,可是 server-id 須要 =2。而後重啓salve上的mysql。

驗證在slave上是否能夠登陸master,mysql -u root -h master的IP -p ,輸入密碼後,能夠登陸 則證實能夠登陸。不然,須要在 master上給slave受權,以下:

grant all privileges on *.* to 'root'@'slave的IP' identified by 'slave的mysql密碼' with grant option;
FLUSH PRIVILEGES;
複製代碼

(2)讓slave鏈接master,並開始重作master二進制日誌中的事件(能夠經過 ? change master to 查看語法):

change master to master_host='192.168.242.129', master_user='reppc',master_password='xbq123', master_port=3306,master_log_file='mysql-bin.000001',master_log_pos=579;
複製代碼

img

從 服務器的哪個日誌的哪個位置 複製。

其中,master_host是master的IP,master_user是在master中賦予複製權限的用戶,master_log_file是master中二進制文件,master_log_pos是開始複製的位置。

(3)查看IOThread和SQLThread是否成功,只有 這兩個狀態 都是 YES才能夠複製。

img

(4)查看maste上的用戶表 select * from mysql.user \G,看到多了一個 咱們剛剛指定的用戶,看到 此記錄 的 reppc:Y ,即說明該用戶 具備複製的權限

此時,master已經配置ok了,查看狀態:show master status;

img

(5)先重啓slave:

img

(6) 查看salve的狀態 show slave status :

img

出現 Slave-IO-Running:YES,Slave-SQL-Running :YES ,則主從配置成功!

五.測試

(1)在matser中的 student 表中新增長一條記錄:

insert into student(name) values('徐邦啓');

(2)在slave中查看student表:

img

OK!

6、經常使用命令

1.查看二進制日誌:

方法一:mysql> show binlog events in ‘日誌文件’ from 位置;

方法二:使用mysql工具查看日誌文件(二進制日誌中包含中各類DML和DDL)

#mysqlbinlog --no-defaults mysql-bin.000001 查看指定文件binlog

#mysqlbinlog --start-position=位置 日誌路徑,例如: mysqlbinlog -start-position=120 /var/lib/mysql/mysql-bin.000001

# 查看某個時間段的二進制日誌,而且輸出到指定的文件
mysqlbinlog --no-defaults --start-datetime="2018-12-12 13:00:00" --stop-datetime="2018-12-12 14:40:00" mysql-bin.000085 -vv --base64-output=decode-rows | more  >> target.txt

# 查看某個二進制日誌中的指定命令,而且輸出到指定的文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v -v mysql-bin.000085  | sed -n '/### DELETE FROM `數據庫名`.`表名`/,/COMMIT/p' > target.txt

# 將@一、@2等一系列看不懂的符號轉換爲SQL語句
cat target.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;' | sed -r 's/(@4.*),/\1;/g' | sed 's/@[0-9]*\=//g' > test.sql

# 查看某個二進制日誌的某個時間段內 DELETE 語句出現的次數
mysqlbinlog --no-defaults --start-datetime="2018-12-12 13:00:00" --stop-datetime="2018-12-12 14:40:00" mysql-bin.000085 -d 數據庫名 mysql-bin.000085 -v|grep UPDATE | wc -l
複製代碼

2.查看中繼日誌(和查看二進制日誌是同一個命令):

mysql> show relaylog events in ‘日誌文件’ from 位置;

3.查看mysql線程列表:

mysql> processlist;

4.查看mysql的配置文件(my.cnf)目錄:whereis my.cnf

5.查看mysql的配置文件(my.cnf)目錄:mysql --verbose --help | grep -C 1 'Default opt'

6.清空master:reset master;

7、說明

本文是一主一從,固然,一主多從也是同樣的道理,在增長一臺slave,而後在my.cnf修改,而後 change master to,在master上 修改 change master to master_host= '192.168.242.%'。


歡迎關注個人公衆號,第一時間接收最新文章~ 搜索公衆號: 碼咖 或者 掃描下方二維碼:

img
相關文章
相關標籤/搜索