文章目錄
前言:
主從複製(也稱 AB 複製)允許將來自一個MySQL數據庫服務器(主服務器)的數據複製到一個或多個MySQL數據庫服務器(從服務器)。
一、案例概述
1.1 背景
- 在企業網站中,後端的MySQL數據庫只有一臺時,會有以下問題
- ① 單點故障,服務不可用
- ② 無法處理大量的併發數據請求
- ③ 數據丟失
1.2 解決方法
- 改造辦法
- ① 增加MySQL數據庫服務器,對數據進行備份,形成主備
- ② 確保主備MySQL數據庫是一樣的
- ③ 主服務器宕機,備份服務器繼續工作,數據有保障
- MySQL主從複製與讀寫分離是密切相關的
選舉出主服務器,其他的都是從服務器,從服務器向主服務器看齊
1.3 更高級解決方法
-
通過主從複製的方式來同步數據,再通過讀寫分離來提升數據庫的併發負載能力
-
Amoeba:是一個以MySql爲底層數據存儲,並對應提供MySQL協議接口的proxy(代理),外號變形蟲
讀取請求發送給從服務器是,採用輪詢調度算法
-
amoeba使用的java語言編寫,配置文件爲xml
-
amoeba主要負責對外的一個代理IP
訪問這個IP時,發送的請求爲“寫”請求,則會轉給主服務器
當發送的請求爲“讀”時,會通過調度轉發給從服務器,使用輪詢算法,輪流分配給兩臺從服務器
amoeba可以視爲調度器,如果主服務器掛掉,則會有MHA解決中國問題
-
本篇博客實驗使用到的賬號權限爲以下幾個
- 主從同步賬號
- 節點服務器開放調度賬號
- Amoeba代理賬號
1.4 MySQL主從複製類型
-
基於語句的複製
再主服務器上執行的語句,從服務器執行相同的語句
-
基於行的複製
把改變的內容複製到從服務器
-
混合類型的複製
一旦發現基於語句無法精確複製時,就會採用基於行的複製
1.5 主從複製工作過程圖
二、主從複製實驗
2.1 環境部署
- ① 五臺centos7虛擬機
- ② 一臺做爲client(後續實驗讀寫分離使用)
- ③ 三臺做爲mysql服務器(其中一臺爲master服務器)
- ④ 一臺作爲amoeba服務器(後續實驗讀寫分離使用)
2.1.1 實驗拓撲
2.2 實驗過程
2.2.1 主從服務器時間同步
- master服務器配置
- ① 安裝ntp、修改配置文件
[root@master ~]# yum install ntp -y
[root@master ~]# vim /etc/ntp.conf
#在第25行插入以下內容
#前2個127代表的是(192.168)
server 127.127.226.0
#允許226段的主機與本機同步,時間環數爲8個
fudge 127.127.226.0 stratum 8
-------》wq
- ② 開啓NTP服務、關閉防火牆和增強性安全功能
[root@master ~]# systemctl start ntpd
[root@master ~]# systemctl stop firewalld.service
[root@master ~]# setenforce 0
- 兩臺SLAVE服務器配置
- ① 安裝ntp、ntpdate服務
[root@localhost ~]# yum install ntp ntpdate -y
- ② 開啓ntp服務,關閉防火牆、增強性安全功能
[root@localhost ~]# systemctl start ntpd
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# setenforce 0
- ③ 時間同步master服務器
[root@localhost ~]# /usr/sbin/ntpdate 192.168.226.132
29 Feb 14:48:00 ntpdate[83952]: the NTP socket is in use, exiting
- 兩臺slave服務器配置相同
2.2.2 MySQL手工編譯安裝
- ① 三臺MySQL服務器同時安裝
[root@master ~]# mount.cifs //192.168.226.1/LAMP-C7 /mnt
Password for root@//192.168.226.1/LAMP-C7:
[root@master ~]# cd /mnt
[root@master mnt]# ls
amoeba-mysql-binary-2.2.0.tar.gz LNMP-C7
apr-1.6.2.tar.gz LNMP-C7.rar
apr-util-1.6.0.tar.gz mha
awstats-7.6.tar.gz mha.rar
cat.jpg mw.jpg
CentOS-7-x86_64-DVD-1708.iso mysql-5.6.26.tar.gz
cronolog-1.6.2-14.el7.x86_64.rpm php-5.6.11.tar.bz2
Discuz_X2.5_SC_UTF8.zip shuita.jpg
dog.jpg yum
error.png yum.repos.d.zip
httpd-2.4.29.tar.bz2
[root@master mnt]# tar zxvf mysql-5.5.22.tar.gz -C /opt
.......省略部分內容
- ② 安裝環境依賴包
[root@master mnt]# yum -y install gcc gcc-c++ make pcre-devel expat-devel perl ncurses-devel autoconf cmake
- ③ 創建程序性用戶
[root@master opt]# useradd -s /sbin/nologin mysql
#-s 不讓此用戶從控制檯登錄
- ④ 編譯
[root@master opt]# cd mysql-5.6.26/
[root@master mysql-5.6.26]# ls
BUILD config.h.cmake extra libmysqld packaging sql-bench unittest
BUILD-CMAKE configure.cmake include libservices plugin sql-common VERSION
client COPYING INSTALL-SOURCE man README storage vio
cmake dbug INSTALL-WIN-SOURCE mysql-test regex strings win
CMakeLists.txt Docs libevent mysys scripts support-files zlib
cmd-line-utils Doxyfile-perfschema libmysql mysys_ssl sql tests
[root@master mysql-5.6.26]# cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DSYSCONFIDIR=/etc \
-DMYSQL_DATADIR=/home/mysql/ \
-DMYSQL_UNIX_ADDR=/home/mysql/mysql.sock
........省略部分內容
[root@master mysql-5.6.26]# make && make install
#把源碼包編譯成二進制可執行文件
........省略部分內容
- ⑤ 給MySQL程序用戶配置權限
[root@master mysql-5.6.26]# chown -R mysql.mysql /usr/local/mysql/
- ⑥ 優化MySQL自帶命令(支持其環境變量)
[root@master mysql-5.6.26]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@master mysql-5.6.26]# source /etc/profile
- ⑦ 將默認啓動腳本複製到/etc/init.d中,給與755權限,添加到service中,便於service管理
[root@master mysql-5.6.26]# cp support-files/mysql.server /etc/init.d/mysqld
[root@master mysql-5.6.26]# chmod 755 /etc/init.d/mysqld
[root@master mysql-5.6.26]# chkconfig --add /etc/init.d/mysqld
[root@master mysql-5.6.26]# chkconfig mysqld --level 35 on
- ⑧ 將解壓包中的默認配置文件複製到/etc下,覆蓋原配置文件
[root@master ~]# cd /opt/mysql-5.6.26/
[root@master mysql-5.6.26]# cp support-files/my-default.cnf /etc/my.cnf
cp: overwrite ‘/etc/my.cnf’? y
- ⑨ 初始化數據庫
[root@master mysql-5.6.26]# /usr/local/mysql/scripts/mysql_install_db \
--user=mysql \
--ldata=/var/lib/mysql \
--basedir=/usr/local/mysql \
--datadir=/home/mysql
........省略部分內容
- ⑩ 在啓動腳本添加工作目錄和數據目錄
[root@master mysql-5.6.26]# vim /etc/init.d/mysqld
basedir=/usr/local/mysql
datadir=/home/mysql
- 開啓MySQL服務、修改數據庫密碼
[root@master mysql-5.6.26]# service mysqld start
Starting MySQL. SUCCESS!
[root@master mysql-5.6.26]# mysqladmin -u root -p password "abc123"
- 三臺MySQL同時手工編譯安裝
2.2.3 配置主從同步
- ① master服務器修改配置文件
[root@master ~]# vi /etc/my.cnf
#在mysqld模塊下修改一下內容
#開啓二進制日誌文件(之後生成的日誌名爲master-bin)
log_bin=master-bin
#開啓從服務器日誌同步
log_slave=updates=true
#主服務器id爲11(不可重複)
server_id = 11
--------》wq
- 重啓服務
[root@master ~]# service mysqld restart
Shutting down MySQL.. SUCCESS!
Starting MySQL. SUCCESS!
- 配置規則
[root@master ~]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.226.%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)
#刷新數據庫
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
規則解析:GRANT REPLICATION SLAVE ON . TO ‘myslave’@‘192.168.226.%’ IDENTIFIED BY ‘123456’;
給從服務器提權,允許使用slave的身份複製master的所有數據庫的所有表,並指定密碼爲123456
- 查看master數據庫狀態
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 412 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
#以上可見產生了master-bin.000001日誌文件,定位爲412
#從服務器需要定位到此處進行復制
- ② 從服務器配置
[root@slave1 ~]# vi /etc/my.cnfvi /etc/my.cnf
#開啓二進制日誌文件
log-bin=mysql-bin
#設置server id爲22,slave2 爲23
server_id = 22
#從主服務器上同步日誌文件記錄到本地
relay-log=relay-log-bin
#定義relay-log的位置和名稱(index索引)
relay-log-index=slave-relay-bin.index
--------》wq
- 開啓從服務器功能
[root@slave1 ~]# mysql -uroot -p
...............
mysql> change master to master_host='192.168.226.132',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=412;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
- 查看從服務器狀態
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.226.132
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 412
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 284
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
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: 412
Relay_Log_Space: 455
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: 0
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: 11
Master_UUID: c59043ec-5ad8-11ea-b895-000c29fe085b
Master_Info_File: /home/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
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
1 row in set (0.00 sec)
- 同理、開啓另一臺從服務器同步
2.3 測試
- 在主服務器上創建一個數據庫
mysql> cerate database work;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cerate database work' at line 1
mysql> create database work;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| work |
+--------------------+
5 rows in set (0.00 sec)
- 在兩臺從服務器上直接查看數據庫列表
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
| work |
+--------------------+
5 rows in set (0.00 sec)
以上,主從同步複製配置完成
小結:
MySQL主從複製與讀寫分離是密切相關的,本篇博客介紹了MySQL的主從複製(同步),緊接着下一篇會介紹MySQL讀寫分離
這裏簡單介紹一下二進制日誌:
MySQL的二進制日誌是一個二進制文件,主要用於記錄修改數據或有可能引起數據變更的MySQL語句。
二進制日誌中記錄了對MySQL數據庫執行更改的所有操作,並且記錄了語句發生時間、執行時長、操作數據等其他額外信息,但是它不記錄SELECT 、SHOW等不修改數據的SQL語句。
二進制日誌主要用於數據庫恢復(⭐⭐)和主從複製及審計操作。
PS:如果同步失敗可使用以下方法嘗試解決
-
① slave數據庫中:SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
-
② slave數據庫中:CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000001’,MASTER_LOG_POS=0;