官網下載下傳 mysql
https://www.mysql.com/
現在企業中用的最多的也是5.6 5.7,我們下載下傳5.7版本的就可。
實驗環境:
server1 172.25.254.1 前三種複制方式中充當master結點
server2 172.25.254.2 前三中複制方式中充當slave結點
server3 172.25.254.3 再做全同步複制時開啟
在做實驗的時候每台主機之間必須有解析,因為後面的實驗會用到解析。
安裝mysql
下載下傳的 rpm-bundle 包裡面有:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSP9ElWtx2RiZGeXlFdKhlWvJ1MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4YDN3ADN0EjM5ATNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
将他們用rpm的方式進行安裝。
它的配置檔案為 /etc/my.cnf
并且會自動生成 /var/log/mysqld.log 的日志檔案,并且會生成一個初始密碼:
[[email protected] ~]# cat /var/log/mysqld.log | grep password
2020-05-09T13:56:35.301030Z 1 [Note] A temporary password is generated for [email protected]: Khq*fpetp1S<
初次登陸它會警告我們更改密碼:
進行安全初始化:
mysql_secure_installation
這裡的密碼設定要求較高,需要設定的複雜一點 ,我的密碼為Cc990718-+
進行相關的設定就可以了。
登陸資料庫:
就可以登陸了。
mysql中的鎖
對資料的操作其實隻有兩種,也就是讀和寫,而資料庫在實作鎖時,也會對這兩種操作使用不同的鎖,
- 共享鎖(讀鎖),允許多個事務讀一行資料。Share Lock
- 排他鎖(寫鎖),允許一個事務删除或更新一行資料,其他事物不可以在上鎖(讀或寫)。Exclusive Lock
mysql中的事務
事務: event ,具有四個個特性,原子性,隔離性,一緻性,持久性
是無就是一組原子性的SQL查詢,或者說一個獨立的工作單元。
如果資料庫引擎能夠成功地對資料庫進行該組查詢的全部語句,那麼就執行改組查詢,如果其中有任何一條語句因為崩潰或者其它原因而無法執行,那麼所有的語句都不會執行,也就是說,事務内的語句,要莫全部執行成功,要麼全部執行失敗。
mysql的主從複制(基于二進制日志)
主節點 server1 :172.25.254.1
從結點 server2 :172.25.254.2
原理:複制操作,不是複制資料,更穩定。
主節點先進行寫操作,然後會把操作記錄進二進制的日志檔案中,此時主節點的dump的線程會通知從結點的IO線程複制資料,IO線程就和master結點進行通信,然後把擷取到的二進制日志資料寫入到終繼日志(relay log)中,此時SQL線程會讀取中繼日志中的内容,在本機重新執行一次(replay)
master 主節點中配置檔案:
vim /etc/my.cnf
然後打開資料庫,執行指令,為複制建立一個使用者:
# 建立repl使用者,%代表整個網段,Cc9為密碼
mysql> CREATE USER 'repl'@'172.25.254.%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)
#授權所有庫的所有表的複制權限給剛建立的使用者
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.25.254.%';
Query OK, 0 rows affected (0.00 sec)
SHOW MASTER STATUS; 擷取,目前二進制日志的檔案名稱和位置
然後層測試使用repl使用者登入;
slave 從結點進行配置
配置檔案:vim /etc/my.cnf
登陸mysql執行指令:
mysql> CHANGE MASTER TO
-> MASTER_HOST='172.25.254.1', 主機名
-> MASTER_USER='repl', 使用者
-> MASTER_PASSWORD='Cc990718-+', 密碼
-> MASTER_LOG_FILE='mysql-bin.000001', 主節點擷取到的檔案名
-> MASTER_LOG_POS=154; 主節點擷取到的檔案位置
#CHANGE MASTER TO MASTER_HOST='172.25.254.1',MASTER_USER='repl',MASTER_PASSWORD='Cc990718-+',MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=154;
start slave; 開啟複制
show slave status\G 檢視slave結點狀态,可以看見SQL線程和IO線程都是yes ,則正常開啟複制
IO 線程負責和master結點進行通信,SQL程序負責把通信得來的資料寫入到本機的資料庫。
檢視複制:
在主節點建立的資料庫就可以在從結點看到了。
我們再在主節點建立一張表:
在從結點檢視:
這就說明主從複制是ok的,這就是基于二進制日志的主從複制.
這裡面是mysql的一些日志資訊,我們可以用 mysqlbinlog 讀取這些日志
基于全局事務辨別的複制GTID
避免了即與二進制檔案日志的複制的缺點:中途出現錯誤時事務就不能完整進行了,就成為了廢資料。
GTID的優點就就是把一個事物看成一個單元,要麼整體成功,要麼整體失敗。
在兩台主機上的配置檔案都加上GTID:
然後再slave結點去配置基于gtid的自動位置識别:
先停掉上面的基于二進制檔案的slave:
再修改複制的方式,開啟複制;
IO和SQL線程開啟。
跟蹤gtid 和執行gtid。
我們再次插入資料進行嘗試:
插入user2,
這時slave結點也能看到了,
并且此時檢視狀态 ,
gtid捕捉到了一個事務:
半同步複制 Semi-synchronous replication
傳統的複制原理:
master的新事務 t1 -> binlog buffer(緩沖區) -> dumper -> slave
binlog buffer(check) -> slave(IO) -> relay log -> SQL -> mysql
- 傳統的幾種複制方式存在一個普遍的問題,就是如果master主節點執行一個比較大的任務時,slave主機的複制會消耗系統資源,會有一些延遲,這個時候如果slave還沒有複制完成時master結點就挂掉了,這時還沒有完成複制的slave就被迫成為新的master主機,這樣的方式就會丢失資料。
- 這樣是有很大的缺陷的,是以mysql在5.5本本後就退出了這個半同步複制,相比于異步複制(GTID,二進制日志)提高了資料的完整性。
- 也就是說master的dumper線程在通知slave之後會接收slave的ack的确認消息,ack 就是是否成功收到 t1 的标志,slave結點再把所有的 binlog 的資料記錄到relay log 中後才會傳回ack給dumper線程。
- 如果沒有收到ack信号就進入到等待,直到接至少接收到一個ack信号為止(slave結點可能由有多個),如果等待逾時,就降級為普通的異步複制,接收到了ack就說明slave結點接收到了完整的 t1 ,就繼續進行新的事務。
在主節點安裝插件:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.16 sec)
在每個子結點安裝插件:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.03 sec)
插件安裝完成。
激活插件:
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
Query OK, 0 rows affected (0.00 sec)
slave 結點重新開機IO線程:
mysql> stop slave IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> start slave IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
在master結點檢視狀态:
功能打開,且又一個用戶端在半同步複制。
功能打開,逾時時間為10s。
slave結點檢視:
現在在主節點插入資料測試:
複制正常,但我們怎樣測試接收的ack信号哪?,我們關閉slave結點的IO線程。
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.04 sec)
然後再次在追結點插入資料。
可見此時等待了10s才結束的,這時就已經切換到了異步複制了。
再次插入:
就又非常快了,因為已經到了異步複制了。
但這時我們在slave主機看不到剛才插入的兩條資料:
我們再開啟slave結點上的IO線程:
可見資料就又回來了。
全同步複制,組複制
group replication。銀行機構一般會使用全同步。
組複制不同與半同步複制的地方在于,master結點會接收到所有的slave結點的ack信号時才會開始下一步。而半同步隻要求接收到 >= 一個的信号就可以了。由于每台結點的内容都一樣,是以每台結點主機都可以作為master結點。
我們開啟第三台虛拟機: server3 172.25.254.3 作為第二個slave結點。
在三個結點中進行配置:
關閉資料庫,并清空之前的資料。
systemctl stop mysqld
rm -fr /var/lib/mysql/*
配置檔案:
删除前面的配置,并添加下面的配置:
vim /etc/my.cnf
server1 :
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.1:33061"
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061" # 主機組
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF 關閉單主機模式,
server2:
server_id=2 這裡的id不能和上面相同
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="1d630e12-92a0-11ea-943f-525400685c65"
loose-group_replication_start_on_boot=off
loose-group_replication_local_address= "172.25.254.2:33061" 本地ip
loose-group_replication_group_seeds= "172.25.254.1:33061,172.25.254.2:33061,172.25.254.3:33061"
loose-group_replication_bootstrap_group=off
loose-group_replication_ip_whitelist='127.0.0.1,172.25.254.0/24'
loose-group_replication_enforce_update_everywhere_check=ON
loose-group_replication_single_primary_mode=OFF
做完後我們啟動mysqld ,并重新進行初始化,因為我們剛才删除了全部的檔案,是以會重新生成初始密碼,我們進行更改(三台主機都做):
mysql> alter user [email protected] identified by 'Cc990718-+';
Query OK, 0 rows affected (0.10 sec)
在mysql中進行配置:
server1:
#關閉二進制日志,防止中間三步産生的日志資料傳輸混亂
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
#建立使用者
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';
Query OK, 0 rows affected (0.00 sec)
#授權所有庫所有表
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)
#重新整理授權表
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
#再次開啟二進制日志
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
#更改master使用者,并指定組複制的插件。
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.25 sec)
#安裝組複制的插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
#發起組複制,生成組名,隻能再一個結點開啟, 這裡我們選擇server1
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)
#啟動組複制
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.56 sec)
#關閉這個是因為這個參數會再每次開啟組複制時生成一個組名,這樣就混亂了,是以我們開啟一次就關閉。
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)
#擷取組資訊,目前隻有一台
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | 26ff60fd-92a1-11ea-9713-525400e49b44 | server1 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
1 row in set (0.00 sec)
然後我們把server2 和server3 加進組去,和上面相同的操作:
server2和server3:
mysql> SET SQL_LOG_BIN=0;
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Cc990718-+';
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
mysql> FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Cc990718-+' FOR CHANNEL 'group_replication_recovery';
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
mysql> START GROUP_REPLICATION;
## 如果報錯,先關閉組複制,再執行這條指令,這是由于資料沖突産生的
set global group_replication_allow_local_disjoint_gtids_join=on;
這時我們再server1檢視組:
server2和server3就加進去了。
這時我們就可以輸入資料進行測試了:
再server1中插入資料:
再server3中插入資料:
在server2中檢視:
發現所有的組内的主機的資料都是一樣的。
這樣的方式是因為我們在哪一台主機上插入資料,那一台主機就是master主機。這就是組複制的原理。