一.主從複製原理
從庫生成兩個線程,一個I/O線程,一個SQL線程;
i/o線程去請求主庫的binlog,並且得到的binlog日誌寫到relay log(中繼日誌)文件中;
主庫會生成一個log dump線程,用來給從庫的I/O線程傳binlog;
SQL線程,會讀取中繼日誌文件,並解析成具體的操作執行,來實現主從的操作一致,而最終數據一致;
二.實驗環境
實驗主機:rhel6.5
server1:172.25.254.1
server2:172.25.254.2
三.實驗具體步驟
1.下載安裝包:mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar,解壓
[root@server1 ~]# tar xf mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar
[root@server1 ~]# ls
mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar
mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-devel-5.7.17-1.el6.x86_64.rpm
mysql-community-embedded-5.7.17-1.el6.x86_64.rpm
mysql-community-embedded-devel-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm
mysql-community-test-5.7.17-1.el6.x86_64.rpm
[root@server1 ~]# rpm -qa | grep mysql #查到linux本身有mysql5.1要卸載,但容易卸載一些其他的依賴包,因此這裏直接安裝mysql5.7會覆蓋源軟件
mysql-libs-5.1.71-1.el6.x86_64
[root@server1 ~]# yum install mysql-community-client-5.7.17-1.el6.x86_64.rpm mysql-community-common-5.7.17-1.el6.x86_64.rpm mysql-community-libs-5.7.17-1.el6.x86_64.rpm mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm mysql-community-server-5.7.17-1.el6.x86_64.rpm -y #安裝軟件包
[root@server1 ~]# scp mysql-community-client-5.7.17-1.el6.x86_64.rpm mysql-community-common-5.7.17-1.el6.x86_64.rpm mysql-community-libs-5.7.17-1.el6.x86_64.rpm mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm mysql-community-server-5.7.17-1.el6.x86_64.rpm server2:
The authenticity of host 'server2 (172.25.254.2)' can't be established.
RSA key fingerprint is 2d:ee:0e:75:83:5d:48:50:16:0b:3b:39:b2:e8:57:11.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'server2,172.25.254.2' (RSA) to the list of known hosts.
root@server2's password:
mysql-community-client-5.7.17-1.el6.x86_64.rp 100% 23MB 22.7MB/s 00:00
mysql-community-common-5.7.17-1.el6.x86_64.rp 100% 328KB 327.6KB/s 00:00
mysql-community-libs-5.7.17-1.el6.x86_64.rpm 100% 2125KB 2.1MB/s 00:00
mysql-community-libs-compat-5.7.17-1.el6.x86_ 100% 1683KB 1.6MB/s 00:00
mysql-community-server-5.7.17-1.el6.x86_64.rp 100% 151MB 75.8MB/s 00:02
[root@server1 ~]# scp mysql-community-client-5.7.17-1.el6.x86_64.rpm mysql-community-common-5.7.17-1.el6.x86_64.rpm mysql-community-libs-5.7.17-1.el6.x86_64.rpm mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm mysql-community-server-5.7.17-1.el6.x86_64.rpm server3:
2.server2和server3上安裝軟件
3.編輯server1的/etc/my.cf
[root@server1 ~]# vim /etc/my.cnf
server-id=1
log-bin=mysql-bin
4.開啓數據庫,安全初始化數據庫密碼,密碼爲字符加數字加符號大於8位
[root@server1 ~]# /etc/init.d/mysqld start #開啓數據庫,並且初始化
Initializing MySQL database:
[ OK ]
Installing validate password plugin: [ OK ]
Starting mysqld: [ OK ]
[root@server1 ~]# grep password /var/log/mysqld.log #過濾初始化的密碼
2018-10-20T14:08:25.670692Z 1 [Note] A temporary password is generated for root@localhost: in+ZYgutO5:k
[root@server1 ~]# mysql -p
Enter password: #用鼠標選擇填入上面初始化的密碼
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.17-log
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases; #查看數據庫失敗
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. #你必須重置密碼
mysql> ^DBye
[root@server1 ~]# mysql_secure_installation #安全初始化
Securing the MySQL server deployment.
Enter password for user root: #輸入初始化密碼
The existing password for the user account root has expired. Please set a new password.
New password: #重置新密碼必須有大小寫,數字,特殊字符
Re-enter new password:
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.
Estimated strength of the password: 100
Change the password for root ? ((Press y|Y for Yes, any other key for No) : #是否修改root密碼
... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.
Remove anonymous users? (Press y|Y for Yes, any other key for No) : y #移除匿名用戶
Success.
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y#禁止root用戶登錄
Success.
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y #移除測試數據庫
- Dropping test database...
Success.
- Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.
All done!
[root@server1 ~]# mysql -p
Enter password:
--省--
測試數據庫密碼,查看master狀態
mysql> show databases; #密碼改成功可以查看數據庫
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> show master status; #查看主的狀態
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 710 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在master上進行授權
[root@server1 mysql]# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.17-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> grant replication slave on *.* to repl@'%' identified by 'XueMiao@0325'; #授權用戶
Query OK, 0 rows affected, 1 warning (0.63 sec)
5.在server2上用repl用戶訪問
[root@server2 ~]# mysql -h 172.25.254.1 -u repl
ERROR 1045 (28000): Access denied for user 'repl'@'server2' (using password: NO)
[root@server2 ~]# mysql -h 172.25.254.1 -u repl -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.17-log MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
6.在server2上安裝mysql,編輯配置文件,重啓mysql,安全初始化
[root@server2 ~]# vim /etc/my.cnf
server-id=2
[root@server2 ~]# /etc/init.d/mysqld start
Initializing MySQL database:
[ OK ]
Installing validate password plugin: [ OK ]
Starting mysqld: [ OK ]
[root@server2 ~]# grep password /var/log/mysqld.log
2018-10-20T14:52:03.497723Z 1 [Note] A temporary password is generated for root@localhost: p_.lptuG>6V/
-省-
[root@server2 ~]# mysql_secure_installation
-省-
7..server1授權用戶
[root@server1 mysql]# mysql -p
--省--
mysql> grant replication slave on *.* to repl@'%' identified by 'XueMiao@0325';
Query OK, 0 rows affected, 1 warning (0.63 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 993 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
8.在server2中顯示slave狀態,改變master
[root@server2 ~]# mysql -p
--------
mysql> show slave status\G; 顯示slave狀態
Empty set (0.00 sec)
ERROR:
No query specified
mysql> change master to master_host='172.25.254.1',master_user='repl',master_password='XueMiao@0325',master_log_file='mysql-bin.000003',master_log_pos=993; #根據show slave status\G; #master_log_file 和master_log_pos需要在主的服務器上查看必須和master保持一致
Query OK, 0 rows affected, 2 warnings (0.95 sec)
mysql> start slave;
Query OK, 0 rows affected (0.10 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.254.1
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 993
Relay_Log_File: server2-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000003
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: 993
Relay_Log_Space: 529
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: 1
Master_UUID: 9c5aafdf-d471-11e8-bf5a-5254002ebd88
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
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
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
9.server1中創建westos數據庫,stu表,server2中查看是否可以查詢
mysql> use westos
Database changed
mysql> create table stu (
-> stuid varchar(10) not null,
-> password varchar(20)not null);
Query OK, 0 rows affected (1.00 sec)
mysql> insert into stu values('stu1','111');
Query OK, 1 row affected (0.09 sec)
在server1上寫入數據server2上可以同步
基於GTID的主從複製
一.實驗原理
MySQL-5.6.2開始支持,MySQL-5.6.10後完善,GTID 分成兩部分,一部分是服務的UUid,UUID保存在mysql數據目錄的auto.cnf文件中,
這是一個非常重要的文件,不能刪除,這一部分是不會變的。另外一部分就是事務ID了,隨着事務的增加,值依次遞增。工作原理:
1.master更新數據時,會在事務前產生GTID,一同記錄到binlog日誌中。
2.slave端的i/o 線程將變更的binlog,寫入到本地的relay log中。
3.sql線程從relay log中獲取GTID,然後對比slave端的binlog是否有記錄。
4.如果有記錄,說明該GTID的事務已經執行,slave會忽略。
5.如果沒有記錄,slave就會從relay log中執行該GTID的事務,並記錄到binlog。
6.在解析過程中會判斷是否有主鍵,如果沒有就用二級索引,如果沒有就用全部掃描。GTID的優點:
1.一個事務對應一個唯一ID,一個GTID在一個服務器上只會執行一次
2.GTID是用來代替傳統複製的方法,GTID複製與普通複製模式的最大不同就是不需要指定二進制文件名和位置
3.減少手工干預和降低服務故障時間,當主機掛了之後通過軟件從衆多的備機中提升一臺備機爲主機
二.實驗步驟:
gtid的配置只要在master的/etc/my.cnf中添加這兩行
gtid_mode=ON
enforce_gtid_consistency=ON
slave中添加
enforce_gtid_consistency=ON
其他的初始化密碼,master上進行用戶授權,slave改變msater的ip,用戶,只有一個不同,不用指定日誌文件
change master to master_host='172.25.254.1',master_user='repl',master_password='XueMiao@0325',MASTER_AUTO_POSITION=1;
基於GTID的並行複製
一.基本原理
由於master是多線程的,而slave是單線程的,所以在複製的時候,會出現讀取和執行速度不一致。此時我們通過設置sql線程的個數來實現,進行線程的優化,當master中把數據庫的更新寫到二進制文件中,並通知slave進行讀取;然後slave的io進程把讀取到的數據存儲在中繼日誌中;最後slave的多個線程對中繼日誌進行回放執行命令,從而達到並行複製。
二.實驗步驟
在gtid的基礎上對slave的配置文件進行修改
vim /etc/my.cnf
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16
master_info_repository=TABLE
relay_log_recovery=ON
--enforce-gtid-consistency
服務器通過允許執行只能使用GTID安全地記錄的語句來強制執行GTID一致性
--gtid-mode
在MySQL 5.7.6及更高版本中,該 gtid_mode變量是動態的,並允許基於GTID的複製在線配置
slave-parallel-type
DATABASE:默認值,基於庫的並行複製方式
LOGICAL_CLOCK:基於組提交的並行複製方式
slave-parallel-workers=0則是單線程設置沒有意義
master_info_repository=TABLE master的信息存放在系統表中,而不是文件中
relay_log_info_repository=TABLE io從主獲取的信息