1.簡(jiǎn)介
隨著互聯(lián)網(wǎng)急速增長(zhǎng),系統(tǒng)業(yè)務(wù)并發(fā)也越來(lái)越高,特別是在讀多寫少的場(chǎng)景下,我們不得不考慮將數(shù)據(jù)層面讀寫分離,所以mysql的主從結(jié)構(gòu)也應(yīng)運(yùn)而生
Replication 線程
master與slave之間實(shí)現(xiàn)整個(gè)復(fù)制過(guò)程主要由三個(gè)線程完成:兩個(gè)(SQL線程和IO線程)在slave端,一個(gè)(IO線程)在master端。
要實(shí)現(xiàn)MySQL的replication,必須打開master端的Binary Log(mysql-bin.xxx)功能。
整個(gè)復(fù)制過(guò)程實(shí)際上就是slave從master端獲取日志然后在自己身上順序執(zhí)行日志中記錄的各種操作
復(fù)制基本過(guò)程(異步的)
slave上的IO線程連接master,請(qǐng)求從指定日志文件的指定位置(或者從最開始)之后的日志內(nèi)容。
master收到請(qǐng)求,負(fù)責(zé)復(fù)制的IO根據(jù)請(qǐng)求信息讀取指定的日志,并返回(日志文件的地址也返回,方便下次直接根據(jù)地址請(qǐng)求)
slave的IO收到信息后,將日志內(nèi)容依次寫入到slave端的relay log文件的最末端,創(chuàng)建一個(gè)master.info的文件,該文件記錄了master ip 用戶名 密碼 master bin-log名稱,bin-log position。
slave的SQL線程檢測(cè)到Relay Log中新加內(nèi)容后,馬上解析該Log文件的內(nèi)容(Query語(yǔ)句),從而能保證兩端的數(shù)據(jù)是一樣的。
2.MySQL安裝
準(zhǔn)備兩臺(tái)機(jī)器,系統(tǒng)環(huán)境centos7,master:192.168.126.128,slave:192.168.126.129
2.1下載
訪問https://dev.mysql.com/downloads/mysql/

我是centos7 64位,我選擇對(duì)應(yīng)的tar.gz包下載,然后上傳到master上
2.2配置安裝
先檢查本機(jī)有沒有安裝過(guò)mysql或者mariadb:
rpm -qa|grep mysql
有的話先卸載:
rpm -e --nodeps xxx (xxx表示上面查詢到的包名)
將下載好的mysql tar.gz包解壓:
tar -zxvfmysql-5.7.29-linux-glibc2.12-x86_64.tar.gz -C /usr/local/
cd /usr/local/
mv mysql-5.7.29-linux-glibc2.12-x86_64 mysql(重命名)
創(chuàng)建mysql組和用戶:
groupadd mysql
useradd -r -g mysql mysql #useradd -r參數(shù)表示mysql用戶是系統(tǒng)用戶,不可用于登錄系統(tǒng)
修改配置:vim /etc/my.cnf
[mysqld]
#設(shè)置mysql的安裝目錄
basedir = /usr/local/mysql
#設(shè)置mysql數(shù)據(jù)庫(kù)的數(shù)據(jù)存放目錄
datadir = /usr/local/mysql/data
#設(shè)置端口
port = 3306
socket = /tmp/mysql.sock
#設(shè)置字符集
character-set-server=utf8
#日志存放目錄
log-error = /usr/local/mysql/data/mysqld.log
pid-file = /usr/local/mysql/data/mysqld.pid
#允許時(shí)間類型的數(shù)據(jù)為零(去掉NO_ZERO_IN_DATE,NO_ZERO_DATE)
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
#ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
創(chuàng)建data目錄:
mkdir /usr/local/mysql/data
#初始化
./bin/mysqld --initialize --user=mysql--basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
查看密碼
cat /usr/local/mysql/data/mysqld.log

把啟動(dòng)腳本放到開機(jī)初始化目錄
cp support-files/mysql.server/etc/init.d/mysql
#啟動(dòng)
service mysql start
#登錄
./bin/mysql -u root -p
#修改密碼
set password=password('123456');
#為遠(yuǎn)程root用戶授權(quán)
grant all privileges on *.* to root@'%'identified by '123456';
flush privileges;
#用工具遠(yuǎn)程登錄成功(注意防火墻問題,本地可以直接禁用防火墻,線上配置開發(fā)特定端口)
2.3主從配置
2.3.1 master上
#命令行登錄
./bin/mysql -u root -p
#創(chuàng)建同步binlog用戶
create user 'repl'@'%' identified by'123456';
GRANT REPLICATION SLAVE ON *.* TO'repl'@'%';
flush privileges;
添加如下配置:
vim /etc/my.cnf
#配置binlog日志名稱
log_bin=master-bin
log_bin_index = master-bin.index
#配置serverid全局唯一
server-id=1
#設(shè)置binlog日志有效期,避免日志過(guò)多占用磁盤容量
expire-logs-days=7
#不同步這些表
binlog_ignore_db=mysql
binlog_ignore_db=information_schema
binlog_ignore_db=performation_schema
binlog_ignore_db=sys
重啟服務(wù):
service mysql restart
命令行登錄:
./bin/mysql -u root -p
查看master狀態(tài):
show master status;

這樣master就配置好了,記住File和Position,后面slave上面會(huì)使用到
2.3.2 slave上
和master一樣,2.2配置安裝好mysql后
添加如下配置:
vim /etc/my.cnf
server-id = 2
relay-log = slave-relay-bin
relay-log-index = slave-relay-bin.index
保存重啟mysql服務(wù):
service mysql restart
命令行登錄:
./bin/mysql -u root -p
執(zhí)行命令:
change master tomaster_host='192.168.126.128', master_port=3306, master_user='repl',master_password='123456', master_log_file='master-bin.000001',master_log_pos=154;
start slave;
查看slave狀態(tài):
show slave status \G;

如果IO和SQL兩個(gè)線程是Yes狀態(tài)說(shuō)明主從配置成功
驗(yàn)證:
我使用navicat連接兩個(gè)數(shù)據(jù)庫(kù),128(master), 129(slave),我在128上面創(chuàng)建數(shù)據(jù)庫(kù)test_tm,然后創(chuàng)建表t1,在t1中插入一條數(shù)據(jù)

然后我們?cè)?29上面驗(yàn)證:

發(fā)現(xiàn)數(shù)據(jù)庫(kù)和表數(shù)據(jù)都同步過(guò)來(lái)了,完成
如有疑問歡迎來(lái)討論