mysql主從
一. 主從簡介
在現代企業中,數據顯得尤爲重要,而存儲數據的數據庫選擇又五花八門,但無論是何種數據庫,均存在着一種隱患。
想幾個問題:
- 用一臺數據庫存放數據,若此數據庫服務器宕機了導致數據丟失怎麼辦?
- 業務量大了,數據多了,訪問的人多了,一臺數據庫無法保證服務質量了怎麼辦?
1.1 主從作用
- 實時災備,用於故障切換
- 讀寫分離,提供查詢服務
- 備份,避免影響業務
1.2 主從形式
- 一主一從
- 主主複製
- 一主多從—擴展系統讀取的性能,因爲讀是在從庫讀取的
- 多主一從—5.7開始支持
- 聯級複製
二.主從複製原理
主從複製步驟:
- 主庫將所有的寫操作記錄到binlog日誌中並生成一個log dump線程,將binlog日誌傳給從庫的I/O線程
- 從庫生成兩個線程,一個I/O線程,一個SQL線程
- I/O線程去請求主庫的binlog,並將得到的binlog日誌寫到relay log(中繼日誌) 文件中
- QL線程,會讀取relay log文件中的日誌,並解析成具體操作,來實現主從的操作一致,達到最終數據一致的目的
三. 主從複製配置
主從複製配置步驟:
- 確保從數據庫與主數據庫裏的數據一樣
- 在主數據庫裏創建一個同步賬號授權給從數據庫使用
- 配置主數據庫(修改配置文件)
- 配置從數據庫(修改配置文件)
需求:
搭建兩臺MySQL服務器,一臺作爲主服務器,一臺作爲從服務器,主服務器進行寫操作,從服務器進行讀操作
環境說明:
數據庫角色 | IP | 應用與系統版本 | 有無數據 |
---|---|---|---|
主數據庫 | 172.16.12.128 | centos7/redhat7mysql-5.7 | 有數據 |
從數據庫 | 172.16.12.129 | centos7/redhat7mysql-5.7 | 無數據 |
3.1 mysql安裝
分別在主從兩臺服務器上安裝mysql-5.7版本,此處略過安裝步驟
3.2 mysql主從配置
3.2.1 確保從數據庫與主數據庫裏的數據一樣
爲確保從數據庫與主數據庫裏的數據一樣,先全備主數據庫並還原到從數據庫中
//先查看主庫有哪些庫
[root@localhost ~]# mysql -uroot -pwangqing123! -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| student |
| sys |
| teacher |
+--------------------+
//再查看從庫有哪些庫
[root@localhost ~]# mysql -uroot -pwangqing123! -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
//全備主庫
//全備主庫時需要另開一個終端,給數據庫加上讀鎖,避免在備份期間有其他人在寫入導致數據不一致
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
//此鎖表的終端必須在備份完成以後才能退出
//備份主庫並將備份文件傳送到從庫
[root@localhost ~]# mysqldump -uroot -pwangqing123! --all-databases > /opt/all-201808191200.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# ls /opt/
all-201808191200.sql
[root@localhost ~]# scp /opt/all-201808191200.sql root@172.16.12.129:/opt/
root@172.16.12.129's password:
all-201808191200.sql 100% 786KB 10.6MB/s 00:00
//解除主庫的鎖表狀態,直接退出交互式界面即可
mysql> quit
Bye
//在從庫上恢復主庫的備份並查看從庫有哪些庫,確保與主庫一致
[root@localhost ~]# mysql -uroot -pwangqing123! < /opt/all-201808191200.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# mysql -uroot -pwangqing123! -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| student |
| sys |
| teacher |
+--------------------+
3.2.2 在主數據庫裏創建一個同步賬號授權給從數據庫使用
mysql> CREATE USER 'repl'@'172.16.12.129' IDENTIFIED BY 'repl123';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.16.12.129';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
3.2.3 配置主數據庫
[root@localhost ~]# vim /etc/my.cnf
//在[mysqld]這段的後面加上如下內容
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=mysql-bin //啓用binlog日誌
server-id=1 //數據庫服務器唯一標識符,主庫的server-id值必須比從庫的大
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
//重啓mysql服務
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 80 :::3306 :::*
//查看主庫的狀態
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
3.2.4 配置從數據庫
[root@localhost ~]# vim /etc/my.cnf
//添加如下內容
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server-id=2 //設置從庫的唯一標識符,從庫的server-id值必須小於主庫的該值
relay-log=mysql-relay-bin //啓用中繼日誌relay-log
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
//重啓從庫的mysql服務
[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:22 *:*
LISTEN 0 100 127.0.0.1:25 *:*
LISTEN 0 128 :::22 :::*
LISTEN 0 100 ::1:25 :::*
LISTEN 0 80 :::3306 :::*
//配置並啓動主從複製
mysql> CHANGE MASTER TO
-> MASTER_HOST='172.16.12.128',
-> MASTER_USER='repl',
-> MASTER_PASSWORD='repl123',
-> MASTER_LOG_FILE='mysql-bin.000001',
-> MASTER_LOG_POS=154;
Query OK, 0 rows affected, 2 warnings (0.33 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: 172.16.12.128
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes //此處必須爲Yes
Slave_SQL_Running: Yes //此處必須爲Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
3.2.5 測試驗證
在主服務器的student庫的bj2表中插入數據:
mysql> select * from bj2;
Empty set (0.00 sec)
mysql> insert into bj2 values (1,'sean',20),(2,'tom',23),(3,'jerry',30);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from bj2;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | sean | 20 |
| 2 | tom | 23 |
| 3 | jerry | 30 |
+----+-------+------+
3 rows in set (0.00 sec)
在從數據庫中查看數據是否同步:
mysql> use student;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from bj2;
+----+-------+------+
| id | name | age |
+----+-------+------+
| 1 | sean | 20 |
| 2 | tom | 23 |
| 3 | jerry | 30 |
+----+-------+------+
3 rows in set (0.00 sec)