MySQL主從同步的幾種實(shí)現(xiàn)方式
一、MySQL主從同步
- MySQL內(nèi)建的復(fù)制功能是構(gòu)建大型,高性能應(yīng)用程序的基礎(chǔ)
- 通過(guò)將MySQL的某一臺(tái)主機(jī)(master)的數(shù)據(jù)復(fù)制到其他主機(jī)(slaves)上,并重新執(zhí)行一遍來(lái)執(zhí)行 復(fù)制過(guò)程中一臺(tái)服務(wù)器充當(dāng)主服務(wù)器,而其他一個(gè)或多個(gè)其他服務(wù)器充當(dāng)從服務(wù)器
1、MySQL支持的復(fù)制類型
- 基于語(yǔ)句(statement)的復(fù)制
- 在主服務(wù)器上執(zhí)行SQL語(yǔ)句,在從服務(wù)器上執(zhí)行同樣的語(yǔ)句。MySQL默認(rèn)采用基于語(yǔ)句的復(fù)制,效率比較高。
- 基于行(row)的復(fù)制
- 把改變的內(nèi)容復(fù)制過(guò)去,而不是把命令在從服務(wù)器上執(zhí)行一遍。從MySQL 5.0開(kāi)始支持。
- 混合型(mixed)的復(fù)制
- 默認(rèn)采用基于語(yǔ)句的復(fù)制,一旦發(fā)現(xiàn)基于語(yǔ)句的無(wú)法精確復(fù)制時(shí),就會(huì)采用基于行的復(fù)制。
2、為什么要做主從復(fù)制
- 災(zāi)備
- 數(shù)據(jù)分布
- 負(fù)載平衡
- 讀寫分離
- 提高并發(fā)能力
3、主從復(fù)制原理
主要基于MySQL二進(jìn)制日志 主要包括三個(gè)線程(2個(gè)I/O線程,1個(gè)SQL線程)
1、MySQL將數(shù)據(jù)變化記錄到二進(jìn)制日志中;
2、Slave將MySQL的二進(jìn)制日志拷貝到Slave的中繼日志中;
3、Slave將中繼日志中的事件在做一次,將數(shù)據(jù)變化,反應(yīng)到自身(Slave)的數(shù)據(jù)庫(kù)
詳細(xì)步驟:
1、從庫(kù)通過(guò)手工執(zhí)行change master to 語(yǔ)句連接主庫(kù),提供了連接的用戶一切條件(user 、password、port、ip),并且讓從庫(kù)知道,二進(jìn)制日志的起點(diǎn)位置(file名 position 號(hào)); start slave
2、從庫(kù)的IO線程和主庫(kù)的dump線程建立連接。
3、從庫(kù)根據(jù)change master to 語(yǔ)句提供的file名和position號(hào),IO線程向主庫(kù)發(fā)起binlog的請(qǐng)求。
4、主庫(kù)dump線程根據(jù)從庫(kù)的請(qǐng)求,將本地binlog以events的方式發(fā)給從庫(kù)IO線程。
5、從庫(kù)IO線程接收binlog events,并存放到本地relay-log中,傳送過(guò)來(lái)的信息,會(huì)記錄到master.info中
6、從庫(kù)SQL線程應(yīng)用relay-log,并且把應(yīng)用過(guò)的記錄到relay-log.info中,默認(rèn)情況下,已經(jīng)應(yīng)用過(guò)的relay 會(huì)自動(dòng)被清理purge
4、MySQL復(fù)制常用的拓?fù)浣Y(jié)構(gòu)
- 主從類型(Master-Slave)
- 主主類型(Master-Master)
- 級(jí)聯(lián)類型(Master-Slave-Slave)
1、基于binlog的主從同步
主庫(kù)配置
配置文件: [root@localhost ~]# tail -1 /etc/my.cnf server_id=1 [root@localhost ~]# systemctl restart mysqld 備份: [root@localhost ~]# mysqldump --opt -B db1 it school > db.sql 授權(quán)用戶: mysql> create user rep@'172.16.%.%' identified with mysql_native_password by '123456'; mysql> grant replication slave on *.* to rep@'172.16.%.%'; mysql> show master status; +---------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +---------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+ | binlog.000015 | 756 | | | 2db179b1-cf96-11ee-8b00-2e6ff2d90c84:1-14, d09e219c-cec9-11ee-baf1-2e6ff2d90c84:1-46 | +---------------+----------+--------------+------------------+--------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
從庫(kù)配置:
配置文件: [root@localhost ~]# tail -1 /etc/my.cnf server_id=2 [root@localhost ~]# systemctl restart mysqld [root@localhost ~]# tail -1 /etc/my.cnf server_id=3 [root@localhost ~]# systemctl restart mysqld 還原主庫(kù)備份: # scp db.sql 172.16.100.22:/root/ # scp db.sql 172.16.100.23:/root/ mysql -uroot -pMySQL@123 < db.sql
mysql> show slave status \G *************************** 1. row *************************** Slave_IO_State: Connecting to source Master_Host: 192.168.150.21 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.000003 Read_Master_Log_Pos: 157 Relay_Log_File: localhost-relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: binlog.000003 Slave_IO_Running: Connecting Slave_SQL_Running: Yes ... Last_IO_Error: error connecting to master 'rep@192.168.150.21:3306' - retry-time: 60 retries: 1 message: Can't connect to MySQL server on '192.168.150.21:3306' (111) [root@localhost ~]# mysqladmin -urep -p123456 -h192.168.150.21 ping mysqladmin: [Warning] Using a password on the command line interface can be insecure. mysqld is alive # 查詢?nèi)罩? [root@localhost ~]# tail /var/log/mysql/mysqld.log ... 2023-12-02T03:17:53.631813Z 5 [ERROR] [MY-010584] [Repl] Slave I/O for channel '': error connecting to master 'rep@192.168.150.21:3306' - retry-time: 60 retries: 3 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection. Error_code: MY-002061
解決方法:
方案一:修改master庫(kù)的密碼加密方式
mysql> alter user 'rep'@'192.168.150.%' identified with mysql_native_password by '123456'; Query OK, 0 rows affected (0.01 sec)
方案二:設(shè)置從庫(kù)的change master 時(shí)加get_master_public_key=1參數(shù)
mysql> stop slave; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> change master to -> master_host='172.16.100.21', -> master_user='rep', -> master_password='123456', -> master_log_file='binlog.000015', -> master_log_pos=756, -> get_master_public_key=1; Query OK, 0 rows affected, 9 warnings (0.00 sec) mysql> start slave; Query OK, 0 rows affected, 1 warning (0.01 sec)
可選配置
#[可選] 0(默認(rèn))表示讀寫(主機(jī)),1表示只讀(從機(jī)) read-only=0 #設(shè)置日志文件保留的時(shí)長(zhǎng),單位是秒 binlog_expire_logs_seconds=6000 #控制單個(gè)二進(jìn)制日志大小。此參數(shù)的最大和默認(rèn)值是1GB max_binlog_size=200M #[可選]設(shè)置不要復(fù)制的數(shù)據(jù)庫(kù) binlog-ignore-db=test #[可選]設(shè)置需要復(fù)制的數(shù)據(jù)庫(kù),默認(rèn)全部記錄。 binlog-do-db=需要復(fù)制的主數(shù)據(jù)庫(kù)名字 #[可選]設(shè)置binlog格式 binlog_format=STATEMENT
2、基于gtid的主從同步配置
開(kāi)啟gtid gtid_mode=ON enforce-gtid-consistency=ON mysql> CHANGE MASTER TO > MASTER_HOST = host, > MASTER_PORT = port, > MASTER_USER = user, > MASTER_PASSWORD = password, > MASTER_AUTO_POSITION = 1; Or from MySQL 8.0.23: mysql> CHANGE REPLICATION SOURCE TO > SOURCE_HOST = host, > SOURCE_PORT = port, > SOURCE_USER = user, > SOURCE_PASSWORD = password, > SOURCE_AUTO_POSITION = 1; mysql> START SLAVE; Or from MySQL 8.0.22: mysql> START REPLICA;
GTID 從庫(kù)誤寫入操作處理
查看監(jiān)控信息: Last_SQL_Error: Error 'Can't create database 'db4'; database exists' on query. Default database: 'db4'. Query: 'create database db4' Retrieved_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-3 Executed_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-2, 7ca4a2b7-4aae-11e9-859d-000c298720f6:1 注入空事務(wù)的方法: stop slave; set gtid_next='99279e1e-61b7-11e9-a9fc-000c2928f5dd:3'; begin;commit; set gtid_next='AUTOMATIC'; 這里的xxxxx:N 也就是你的slave sql thread報(bào)錯(cuò)的GTID,或者說(shuō)是你想要跳過(guò)的GTID。 最好的解決方案:重新構(gòu)建主從環(huán)境
二、MySQL 主從讀寫分離實(shí)現(xiàn)方案
(1).MySQL Router:MySQL官方提供的輕量級(jí)MySQL代理(路由),只提供讀寫分離功能,前身為SQL Proxy。
(2).ProxySQL:類似于MySQL Router,輕量級(jí)MySQL代理,提供讀寫分離功能,也支持一些sharding功能。有percona版和官方版兩個(gè)版本。
(3).MaxScale:MariaDB的中間件,和MySQL Router、ProxySQL類似。
這三者類似,都是輕量級(jí)數(shù)據(jù)庫(kù)中間件。
(4).Amoeba、Cobar、MyCAT:提供很多功能,最主要的功能包括讀寫分離、sharding。
這三者的淵源較深,都是開(kāi)源的。Amoeba后繼無(wú)人,于是Cobar出來(lái),Cobar后繼無(wú)人,加上2013年出現(xiàn)了一次較嚴(yán)重的問(wèn)題,于是MyCAT站在Cobar的肩膀上出來(lái)了。
( 1 )通過(guò)程序?qū)崿F(xiàn)讀寫分離(需要程序支持)
php和Java 程序都可以通過(guò)設(shè)置多個(gè)連接文件輕松地實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)讀寫分離,當(dāng)語(yǔ)句關(guān)鍵字為 select 時(shí),就去連接讀庫(kù)的連接文件,若為 update、 insert、 delete 時(shí),連接寫庫(kù)的連接文件
通過(guò)程序?qū)崿F(xiàn)讀寫分離的缺點(diǎn)就是需要開(kāi)發(fā)人員對(duì)程序進(jìn)行改造,程序本身無(wú)法直接支持讀寫分離
( 2)通過(guò)開(kāi)源的軟件實(shí)現(xiàn)讀寫分離
Maxscale 、Atlas 、Mycat 等代理軟件也可以實(shí)現(xiàn)讀寫分離的功能,并且無(wú)須對(duì)應(yīng)用程序做任何修改,而且它們還支持負(fù)載均衡等功能 ;缺點(diǎn)是又引入了單點(diǎn)服務(wù),并且穩(wěn)定性不如程序?qū)崿F(xiàn)好
( 3)大型門戶獨(dú)立開(kāi)發(fā) DAL 綜合軟件
百度、阿里等大型門戶都有開(kāi)發(fā)牛人,會(huì)花大力氣開(kāi)發(fā)適合自己業(yè)務(wù)的讀寫分離、負(fù)載均衡、監(jiān)控報(bào)警、自動(dòng)擴(kuò)容、自動(dòng)收縮等一系列功能的 DAL 層軟件
MySQL 寫分離的基本邏輯圖如圖
2.1 ProxySQL實(shí)現(xiàn)mysql8主從同步讀寫分離
1、ProxySQL基本介紹
1.1 前言
ProxySQL是 MySQL 的高性能、高可用性、協(xié)議感知代理。以下為結(jié)合主從復(fù)制對(duì)ProxySQL讀寫分離、黑白名單、路由規(guī)則等做些基本測(cè)試。
1.2 基本介紹
先簡(jiǎn)單介紹下ProxySQL及其功能和配置,主要包括:
- 最基本的讀/寫分離,且方式有多種;
- 可定制基于用戶、基于schema、基于語(yǔ)句的規(guī)則對(duì)SQL語(yǔ)句進(jìn)行路由,規(guī)則很靈活;
- 動(dòng)態(tài)加載配置,即絕大部分的配置可以在線修改,但有少部分參數(shù)還是需要重啟來(lái)生效;
- 可緩存查詢結(jié)果。雖然緩存策略比較簡(jiǎn)陋,但實(shí)現(xiàn)了基本的緩存功能;
- 過(guò)濾危險(xiǎn)的SQL,增加防火墻等功能;
- 提供連接池、日志記錄、審計(jì)日志等功能;
1.2.1 請(qǐng)求流程
流量從客戶端發(fā)出 → ProxySQL進(jìn)行處理轉(zhuǎn)發(fā) → 后端處理 → ProxySQL的前端連接 → 返回客戶端的基本流程
1.2.2 核心功能
- 讀寫分離:可查詢走從庫(kù),寫入走主庫(kù)
- 簡(jiǎn)單Sharding:ProxySQL的sharding是通過(guò)正則匹配來(lái)實(shí)現(xiàn)的,對(duì)于需要拆分SQL以及合并SQL執(zhí)行結(jié)果的不能支持,所以寫了簡(jiǎn)單sharding
- 連接池管理:常規(guī)功能,為了提高SQL執(zhí)行效率。
- 多路復(fù)用:主要優(yōu)化點(diǎn)在后端mysql連接的復(fù)用,對(duì)比smart client,中間層不僅對(duì)前端建連也會(huì)對(duì)后端建連,可自行控制后端連接的復(fù)用邏輯。
- 流量管控:kill連接和kill query;whitelist配置。
- 高可用:底層mysql,如果從庫(kù)掛了,自動(dòng)摘除流量;主庫(kù)掛了暫不處理。proxysql自身高可用提供cluster的功能,cluster內(nèi)部會(huì)自行同步元數(shù)據(jù)以及配置變更信息。
- 查詢緩存:對(duì)username+schema+query的key進(jìn)行緩存,設(shè)置ttl過(guò)期,不適合寫完就查的場(chǎng)景,因?yàn)樵跀?shù)據(jù)在未過(guò)期之前可能是臟數(shù)據(jù)。
- 動(dòng)態(tài)配置:大部分的配置可動(dòng)態(tài)變更,先load到runtime,在save到disk,通過(guò)cluster的功能同步到其他的節(jié)點(diǎn)。
- 流量鏡像:同一份流量可以多出寫入,但是并不保證mirror的流量一定成功。
- SQL改寫:在query rules中配置replace規(guī)則,可以對(duì)指定的SQL進(jìn)行改寫。
當(dāng)ProxySQL啟動(dòng)后,將監(jiān)聽(tīng)兩個(gè)端口:
(1).admin管理接口,默認(rèn)端口為6032。該端口用于查看、配置ProxySQL。
(2).接收SQL語(yǔ)句的接口,默認(rèn)端口為6033,這個(gè)接口類似于MySQL的3306端口。
ProxySQL的admin管理接口是一個(gè)使用MySQL協(xié)議的接口,所以,可以直接使用mysql客戶端、navicat等工具去連接這個(gè)管理接口
2、ProxySQL結(jié)構(gòu)
Qurey Processor 用于匹配查詢規(guī)則并根據(jù)規(guī)則決定是否緩存查詢或者將查詢加入黑名單或者重新路由、重寫查詢或者鏡像查詢到其他hostgroup。
User Auth 為底層后端數(shù)據(jù)庫(kù)認(rèn)證提供了用戶憑證。
Hostgroup manager – 負(fù)責(zé)管理發(fā)送SQL請(qǐng)求都后端數(shù)據(jù)庫(kù)并跟蹤SQL請(qǐng)求狀態(tài)。
Connection pool – 負(fù)責(zé)管理后端數(shù)據(jù)庫(kù)連接,連接池中建立的連接被所有的前端應(yīng)用程序共享。
Monitoring – 負(fù)責(zé)監(jiān)控后端數(shù)據(jù)庫(kù)健康狀態(tài)主從復(fù)制延時(shí)并臨時(shí)下線不正常的數(shù)據(jù)庫(kù)實(shí)例。
1.啟動(dòng)過(guò)程
RUNTIME層:代表的是ProxySQL當(dāng)前生效的配置,包括 global_variables, mysql_servers, mysql_users, mysql_query_rules。無(wú)法直接修改這里的配置,必須要從下一層load進(jìn)來(lái)
MEMORY層:是平時(shí)在mysql命令行修改的 main 里頭配置,可以認(rèn)為是SQLite數(shù)據(jù)庫(kù)在內(nèi)存的鏡像。該層級(jí)的配置在main庫(kù)中以mysql_開(kāi)頭的表以及global_variables表,這些表的數(shù)據(jù)可以直接修改;
DISK|CONFIG FILR層:持久存儲(chǔ)的那份配置,一般在
$(DATADIR)/proxysql.db
,在重啟的時(shí)候會(huì)從硬盤里加載。/etc/proxysql.cnf
文件只在第一次初始化的時(shí)候用到,完了后,如果要修改監(jiān)聽(tīng)端口,還是需要在管理命令行里修改,再 save 到硬盤。
注意:
- 如果找到數(shù)據(jù)庫(kù)文件(proxysql.db),ProxySQL 將從 proxysql.db 初始化其內(nèi)存中配置。因此,磁盤被加載到 MEMORY 中,然后加載到 RUNTIME 中。
- 如果找不到數(shù)據(jù)庫(kù)文件(proxysql.db)且存在配置文件(proxysql.cfg),則解析配置文件并將其內(nèi)容加載到內(nèi)存數(shù)據(jù)庫(kù)中,然后將其保存在 proxysql.db 中并在加載到 RUNTIME。 請(qǐng)務(wù)必注意,
- 如果找到 proxysql.db,則不會(huì)解析配置文件。也就是說(shuō),在正常啟動(dòng)期間,ProxySQL 僅從持久存儲(chǔ)的磁盤數(shù)據(jù)庫(kù)初始化其內(nèi)存配置。
2.數(shù)據(jù)庫(kù)結(jié)構(gòu)
ProxySQL自身共有5個(gè)庫(kù),分別為3個(gè)保存在內(nèi)存中的庫(kù),和2個(gè)保存在磁盤的SQLite庫(kù)。 通過(guò)6032管理端口登入后,默認(rèn)就是main庫(kù),所有的配置更改都必須在這個(gè)庫(kù)中進(jìn)行,disk存檔庫(kù)不會(huì)直接受到影響。
# mysql -uadmin -padmin -h127.0.0.1 -P6032 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.5.30 (ProxySQL Admin Module) mysql> show databases; +-----+---------------+-------------------------------------+ | seq | name | file | +-----+---------------+-------------------------------------+ | 0 | main | | | 2 | disk | /var/lib/proxysql/proxysql.db | | 3 | stats | | | 4 | monitor | | | 5 | stats_history | /var/lib/proxysql/proxysql_stats.db | +-----+---------------+-------------------------------------+ 5 rows in set (0.00 sec)
main:內(nèi)存配置數(shù)據(jù)庫(kù),表里存放后端db實(shí)例、用戶驗(yàn)證、路由規(guī)則等信息。表名以 runtime開(kāi)頭的表示proxysql當(dāng)前運(yùn)行的配置內(nèi)容,不能通過(guò)dml語(yǔ)句修改,只能修改對(duì)應(yīng)的不以 runtime 開(kāi)頭的(在內(nèi)存)里的表,然后 LOAD 使其生效, SAVE 使其存到硬盤以供下次重啟加載。
disk:是持久化到硬盤的配置,sqlite數(shù)據(jù)文件。SQLite3 數(shù)據(jù)庫(kù),默認(rèn)位置為 $(DATADIR)/proxysql.db,在重新啟動(dòng)時(shí),未保留的內(nèi)存中配置將丟失。因此,將配置保留在 DISK 中非常重要。(SQLite是一個(gè)進(jìn)程內(nèi)的庫(kù),實(shí)現(xiàn)了自給自足的、無(wú)服務(wù)器的、零配置的、事務(wù)性的 SQL 數(shù)據(jù)庫(kù)引擎)
stats:proxysql運(yùn)行抓取的統(tǒng)計(jì)信息,包括到后端各命令的執(zhí)行次數(shù)、流量、processlist、查詢種類匯總/執(zhí)行時(shí)間等等。
monitor:庫(kù)存儲(chǔ) monitor 模塊收集的信息,主要是對(duì)后端db的健康/延遲檢查。
stats_history:統(tǒng)計(jì)信息歷史庫(kù)
3.核心配置表
4.命令
5.小結(jié)
這些數(shù)據(jù)庫(kù)的功能實(shí)現(xiàn)了實(shí)用化內(nèi)容:
允許輕松動(dòng)態(tài)更新配置,便于運(yùn)維管理,與MySQL兼容的管理界面可用于此目的。
允許盡可能多的配置項(xiàng)目動(dòng)態(tài)修改,而不需要重新啟動(dòng)ProxySQL進(jìn)程
可以毫不費(fèi)力地回滾無(wú)效配置
通過(guò)多級(jí)配置系統(tǒng)實(shí)現(xiàn)的,其中設(shè)置從運(yùn)行時(shí)移到內(nèi)存,并根據(jù)需要持久保存到磁盤
3、實(shí)驗(yàn)環(huán)境
機(jī)器名稱 | IP配置 | 服務(wù)角色 | 備注 |
---|---|---|---|
proxy | 192.168.150.24 | proxysql控制器 | 用于監(jiān)控管理 |
master | 192.168.150.21 | 數(shù)據(jù)庫(kù)主服務(wù)器 | |
slave1 | 192.168.150.22 | 數(shù)據(jù)庫(kù)從服務(wù)器 | |
slave2 | 192.168.150.23 | 數(shù)據(jù)庫(kù)從服務(wù)器 |
4、實(shí)現(xiàn)數(shù)據(jù)庫(kù)主從復(fù)制
基于GTID實(shí)現(xiàn)mysql8.0主從同步,配置過(guò)程略。
5、安裝ProxySQL
# 配置yum源 cat > /etc/yum.repos.d/proxysql.repo << EOF [proxysql] name=ProxySQL YUM repository baseurl=https://repo.proxysql.com/ProxySQL/proxysql-2.5.x/centos/\$releasever gpgcheck=1 gpgkey=https://repo.proxysql.com/ProxySQL/proxysql-2.5.x/repo_pub_key EOF # 安裝proxysql yum install -y proxysql
啟動(dòng) ProxySQL
[root@proxy ~]# systemctl enable --now proxysql # 管理員登錄 [root@proxy ~]# mysql -uadmin -padmin -h 127.0.0.1 -P 6032 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.5.30 (ProxySQL Admin Module) Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> show databases; +-----+---------------+-------------------------------------+ | seq | name | file | +-----+---------------+-------------------------------------+ | 0 | main | | | 2 | disk | /var/lib/proxysql/proxysql.db | | 3 | stats | | | 4 | monitor | | | 5 | stats_history | /var/lib/proxysql/proxysql_stats.db | +-----+---------------+-------------------------------------+ 5 rows in set (0.00 sec) 可見(jiàn)有五個(gè)庫(kù): main、disk、stats 、monitor 和 stats_history main: 內(nèi)存配置數(shù)據(jù)庫(kù),即 MEMORY,表里存放后端 db 實(shí)例、用戶驗(yàn)證、路由規(guī)則等信息。main 庫(kù)中有如下信息: MySQL [(none)]> show tables from main; +----------------------------------------------------+ | tables | +----------------------------------------------------+ | coredump_filters | | global_variables | | mysql_aws_aurora_hostgroups | | mysql_collations | | mysql_firewall_whitelist_rules | | mysql_firewall_whitelist_sqli_fingerprints | | mysql_firewall_whitelist_users | | mysql_galera_hostgroups | | mysql_group_replication_hostgroups | | mysql_hostgroup_attributes | | mysql_query_rules | | mysql_query_rules_fast_routing | | mysql_replication_hostgroups | | mysql_servers | | mysql_users | | proxysql_servers | | restapi_routes | | runtime_checksums_values | | runtime_coredump_filters | | runtime_global_variables | | runtime_mysql_aws_aurora_hostgroups | | runtime_mysql_firewall_whitelist_rules | | runtime_mysql_firewall_whitelist_sqli_fingerprints | | runtime_mysql_firewall_whitelist_users | | runtime_mysql_galera_hostgroups | | runtime_mysql_group_replication_hostgroups | | runtime_mysql_hostgroup_attributes | | runtime_mysql_query_rules | | runtime_mysql_query_rules_fast_routing | | runtime_mysql_replication_hostgroups | | runtime_mysql_servers | | runtime_mysql_users | | runtime_proxysql_servers | | runtime_restapi_routes | | runtime_scheduler | | scheduler | +----------------------------------------------------+ 36 rows in set (0.00 sec) 庫(kù)下的主要表: mysql_servers: 后端可以連接 MySQL 服務(wù)器的列表 mysql_users: 配置后端數(shù)據(jù)庫(kù)的賬號(hào)和監(jiān)控的賬號(hào)。 mysql_query_rules: 指定 Query 路由到后端不同服務(wù)器的規(guī)則列表。 注: 表名以 runtime_開(kāi)頭的表示 ProxySQL 當(dāng)前運(yùn)行的配置內(nèi)容,不能通過(guò) DML 語(yǔ)句修改。 只能修改對(duì)應(yīng)的不以 runtime 開(kāi)頭的表,然后 “LOAD” 使其生效,“SAVE” 使其存到硬盤以供下次重啟加載。 disk :持久化的磁盤的配置 stats: 統(tǒng)計(jì)信息的匯總 monitor:一些監(jiān)控的收集信息,比如數(shù)據(jù)庫(kù)的健康狀態(tài)等 stats_history: 這個(gè)庫(kù)是 ProxySQL 收集的有關(guān)其內(nèi)部功能的歷史指標(biāo)
配置 ProxySQL 所需賬戶
在 Master (172.16.100.21) 的MySQL 上創(chuàng)建 ProxySQL 的監(jiān)控賬戶和對(duì)外訪問(wèn)賬戶
create user 'monitor'@'172.16.%.%' identified with mysql_native_password by 'Monitor@123.com'; grant all privileges on *.* to 'monitor'@'172.16.%.%' with grant option; #proxysql 的對(duì)外訪問(wèn)賬戶 create user 'proxysql'@'172.16.%.%' identified with mysql_native_password by '123456'; grant all privileges on *.* to 'proxysql'@'172.16.%.%' with grant option;
6、配置ProxySQL
使用proxysql,主要需要完成以下幾項(xiàng)內(nèi)容的配置:
- 配置監(jiān)控賬號(hào)。監(jiān)控賬號(hào)用于檢測(cè)后端mysql實(shí)例是否健康(是否能連接、復(fù)制是否正常、復(fù)制是否有延遲等)。
- 到后端mysql實(shí)例創(chuàng)建監(jiān)控賬號(hào)。
- 配置后端mysql實(shí)例連接信息。實(shí)例連接信息存儲(chǔ)在mysql_servers表。
- 配置連接proxysql和后端實(shí)例的賬號(hào)。賬號(hào)信息存儲(chǔ)在mysql_users表。
- 配置查詢路由信息。路由信息存儲(chǔ)在mysql_query_rules表。
- 配置后端mysql集群信息。根據(jù)后端mysql集群架構(gòu),配置分別存儲(chǔ)在mysql_replication_hostgroups、mysql_group_replication_hostgroups、runtime_mysql_galera_hostgroups、runtime_mysql_aws_aurora_hostgroups等表中。
- 根據(jù)具體需要,調(diào)優(yōu)相關(guān)參數(shù)。參數(shù)存儲(chǔ)在global_variables表。
一、配置ProxySQL主從分組信息
1.用到這個(gè)表:mysql_replication_hostgroup,表結(jié)構(gòu)如下:
MySQL [(none)]> show create table mysql_replication_hostgroups \G *************************** 1. row *************************** table: mysql_replication_hostgroups Create Table: CREATE TABLE mysql_replication_hostgroups ( writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY, reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND reader_hostgroup>=0), check_type VARCHAR CHECK (LOWER(check_type) IN ('read_only','innodb_read_only','super_read_only','read_only|innodb_read_only','read_only&innodb_read_only')) NOT NULL DEFAULT 'read_only', comment VARCHAR NOT NULL DEFAULT '', UNIQUE (reader_hostgroup)) 1 row in set (0.00 sec) 注:writer_hostgroup 和reader_hostgroup 寫組和讀組都要大于等于0且不能相同
2.創(chuàng)建組:(定義寫為1,讀為0)
MySQL [(none)]> insert into mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup,comment) values (1,0,'proxy'); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> load mysql servers to runtime; Query OK, 0 rows affected (0.01 sec) MySQL [(none)]> save mysql servers to disk; Query OK, 0 rows affected (0.02 sec) 注意:ProxySQL會(huì)根據(jù)server的read_only的取值將服務(wù)器進(jìn)行分組。read_only=0的server,master被分到編號(hào)為1的寫組,read_only=1的server,slave則分到編號(hào)為0的讀組 MySQL [(none)]> select * from mysql_replication_hostgroups; +------------------+------------------+------------+---------+ | writer_hostgroup | reader_hostgroup | check_type | comment | +------------------+------------------+------------+---------+ | 1 | 0 | read_only | proxy | +------------------+------------------+------------+---------+ 1 row in set (0.00 sec)
3.添加主從服務(wù)器節(jié)點(diǎn):
MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values (1,'172.16.100.21',3306); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values (0,'172.16.100.22',3306); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> insert into mysql_servers(hostgroup_id,hostname,port) values (0,'172.16.100.23',3306); Query OK, 1 row affected (0.00 sec) MySQL [(none)]> load mysql servers to runtime; Query OK, 0 rows affected (0.01 sec) MySQL [(none)]> save mysql servers to disk; Query OK, 0 rows affected (0.00 sec) MySQL [(none)]> select * from mysql_servers; +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 1 | 192.168.150.21 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 0 | 192.168.150.22 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | | 0 | 192.168.150.23 | 3306 | 0 | ONLINE | 1 | 0 | 1000 | 0 | 0 | 0 | | +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ 3 rows in set (0.00 sec)
4.為ProxySQL監(jiān)控MySQL后端節(jié)點(diǎn)
MySQL [(none)]> use monitor 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 [monitor]> set mysql-monitor_username='monitor'; Query OK, 1 row affected (0.00 sec) MySQL [monitor]> set mysql-monitor_password='Monitor@123.com'; Query OK, 1 row affected (0.00 sec) 上面這兩句是修改變量的方式還可以在main庫(kù)下面用sql語(yǔ)句方式修改 在main下修改: MySQL [monitor]> use main 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 [main]> UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username'; Query OK, 1 row affected (0.00 sec) MySQL [main]> UPDATE global_variables SET variable_value='Monitor@123.com' WHERE variable_name='mysql-monitor_password'; Query OK, 1 row affected (0.00 sec) 修改后,保存到runtime和disk MySQL [monitor]> load mysql variables to runtime; MySQL [monitor]> save mysql variables to disk; 查看監(jiān)控賬號(hào)【ProxySQL】 SELECT * FROM global_variables WHERE variable_name LIKE 'mysql-monitor_%'; //也可以這樣快速定位 MySQL [(none)]> select @@mysql-monitor_username; +--------------------------+ | @@mysql-monitor_username | +--------------------------+ | monitor | +--------------------------+ 1 row in set (0.00 sec) MySQL [(none)]> select @@mysql-monitor_password; +--------------------------+ | @@mysql-monitor_password | +--------------------------+ | Monitor@123.com | +--------------------------+ 1 row in set (0.00 sec) MySQL [(none)]> select * from monitor.mysql_server_connect_log; +----------------+------+------------------+-------------------------+---------------+ | hostname | port | time_start_us | connect_success_time_us | connect_error | +----------------+------+------------------+-------------------------+---------------+ | 192.168.150.21 | 3306 | 1701659547601785 | 2126 | NULL | | 192.168.150.23 | 3306 | 1701659548266990 | 1883 | NULL | | 192.168.150.22 | 3306 | 1701659548932828 | 1626 | NULL | | 192.168.150.21 | 3306 | 1701659607601353 | 1672 | NULL | | 192.168.150.22 | 3306 | 1701659608066386 | 1649 | NULL | | 192.168.150.23 | 3306 | 1701659608531392 | 1962 | NULL | | 192.168.150.21 | 3306 | 1701659667601720 | 1283 | NULL | | 192.168.150.23 | 3306 | 1701659668394216 | 2033 | NULL | | 192.168.150.22 | 3306 | 1701659669186458 | 1350 | NULL | +----------------+------+------------------+-------------------------+---------------+ 9 rows in set (0.00 sec) 驗(yàn)證監(jiān)控信息,ProxySQL 監(jiān)控模塊的指標(biāo)都保存在monitor庫(kù)的log表中 以下是連接是否正常的監(jiān)控,對(duì)connect指標(biāo)的監(jiān)控 ,在前面可能會(huì)有很多connect_error,這是因?yàn)闆](méi)有配置監(jiān)控信息時(shí)的錯(cuò)誤,配置后如果connect_error的結(jié)果為NULL則表示正常
5.對(duì)心跳信息的監(jiān)控:
MySQL [(none)]> select * from mysql_server_ping_log limit 10; +----------------+------+------------------+----------------------+------------+ | hostname | port | time_start_us | ping_success_time_us | ping_error | +----------------+------+------------------+----------------------+------------+ | 192.168.150.21 | 3306 | 1701659547602344 | 460 | NULL | | 192.168.150.23 | 3306 | 1701659547604095 | 245 | NULL | | 192.168.150.22 | 3306 | 1701659547604690 | 258 | NULL | | 192.168.150.23 | 3306 | 1701659557601548 | 471 | NULL | | 192.168.150.21 | 3306 | 1701659557601738 | 313 | NULL | | 192.168.150.22 | 3306 | 1701659557601713 | 349 | NULL | | 192.168.150.22 | 3306 | 1701659567602161 | 572 | NULL | | 192.168.150.23 | 3306 | 1701659567602361 | 405 | NULL | | 192.168.150.21 | 3306 | 1701659567602318 | 460 | NULL | | 192.168.150.22 | 3306 | 1701659577602909 | 434 | NULL | +----------------+------+------------------+----------------------+------------+ 10 rows in set (0.00 sec)
6.查看read_only日志監(jiān)控:
MySQL [(none)]> select * from mysql_server_read_only_log limit 5; +----------------+------+------------------+-----------------+-----------+-------+ | hostname | port | time_start_us | success_time_us | read_only | error | +----------------+------+------------------+-----------------+-----------+-------+ | 192.168.150.23 | 3306 | 1701659547606174 | 373 | 1 | NULL | | 192.168.150.22 | 3306 | 1701659547606768 | 634 | 1 | NULL | | 192.168.150.21 | 3306 | 1701659547606639 | 858 | 0 | NULL | | 192.168.150.21 | 3306 | 1701659549101574 | 657 | 0 | NULL | | 192.168.150.22 | 3306 | 1701659549101863 | 422 | 1 | NULL | +----------------+------+------------------+-----------------+-----------+-------+ 5 rows in set (0.00 sec) Monitor 模塊就會(huì)開(kāi)始監(jiān)控后端的read_only值,當(dāng)監(jiān)控到read_only值,就會(huì)按照read_only的值將某些節(jié)點(diǎn)自動(dòng)移到讀寫組 一些監(jiān)控的狀態(tài)斗志在log相關(guān),都在monitor庫(kù)下面的 global_variables 變量。
7.ProxySQL配置對(duì)外訪問(wèn)賬號(hào):(要在MySQL節(jié)點(diǎn)上創(chuàng)建)
前面已經(jīng)配置:配置ProxySQL 賬戶,我創(chuàng)建的對(duì)外訪問(wèn)賬戶是:用戶:proxysql,密碼:123456
mysql_users表結(jié)構(gòu)如下:
MySQL [(none)]> show create table mysql_users\G *************************** 1. row *************************** table: mysql_users Create Table: CREATE TABLE mysql_users ( username VARCHAR NOT NULL, password VARCHAR, active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1, use_ssl INT CHECK (use_ssl IN (0,1)) NOT NULL DEFAULT 0, default_hostgroup INT NOT NULL DEFAULT 0, default_schema VARCHAR, schema_locked INT CHECK (schema_locked IN (0,1)) NOT NULL DEFAULT 0, transaction_persistent INT CHECK (transaction_persistent IN (0,1)) NOT NULL DEFAULT 1, fast_forward INT CHECK (fast_forward IN (0,1)) NOT NULL DEFAULT 0, backend INT CHECK (backend IN (0,1)) NOT NULL DEFAULT 1, frontend INT CHECK (frontend IN (0,1)) NOT NULL DEFAULT 1, max_connections INT CHECK (max_connections >=0) NOT NULL DEFAULT 10000, attributes VARCHAR CHECK (JSON_VALID(attributes) OR attributes = '') NOT NULL DEFAULT '', comment VARCHAR NOT NULL DEFAULT '', PRIMARY KEY (username, backend), UNIQUE (username, frontend)) 1 row in set (0.00 sec)
將對(duì)外訪問(wèn)賬號(hào)添加到mysql_users表中:
insert into mysql_users (username,password,default_hostgroup,transaction_persistent) values ('proxysql','123456',1,1); load mysql users to runtime; save mysql users to disk; MySQL [(none)]> select * from mysql_users\G *************************** 1. row *************************** username: proxysql password: 123456 active: 1 use_ssl: 0 default_hostgroup: 1 default_schema: NULL schema_locked: 0 transaction_persistent: 1 fast_forward: 0 backend: 1 frontend: 1 max_connections: 10000 attributes: comment: 1 row in set (0.00 sec) 注:transaction_persistent 如果為1,則一個(gè)完整的SQL只可能路由到一個(gè)節(jié)點(diǎn);這點(diǎn)非常重要,主要解決這種情況:一個(gè)事務(wù)有混合的讀操作和寫操作組成,事務(wù)未提交前,如果事務(wù)中的讀操作和寫操作路由到不同節(jié)點(diǎn),那么讀取到的結(jié)果必然是臟數(shù)據(jù)。所以一般情況下,該值應(yīng)該設(shè)置為1,尤其是業(yè)務(wù)中使用到事務(wù)機(jī)制的情況(默認(rèn)為0) mysql_users 表有不少字段,最主要的三個(gè)字段username,password,default_hostgroup A.username: 前端鏈接ProxySQL ,以及ProxySQL 將SQL 語(yǔ)句路由給MySQL所使用的的用戶名 B.password:用戶名對(duì)應(yīng)的密碼,??梢允敲魑拿艽a,也可以是hash密碼。如果想使用hash密碼,可以先在某個(gè)MySQL節(jié)點(diǎn)上執(zhí)行select password(PASSWORD),然后將加密結(jié)果復(fù)制到該字段。 C.default_hostgroup:該用戶名默認(rèn)的路由目標(biāo)。例如,指定root用戶的該字段值為1時(shí),則使用 proxysql 用戶發(fā)送的SQL語(yǔ)句默認(rèn)情況下將路由到hostgroup_id=1 組中的某個(gè)
在從庫(kù)端172.16.100.22上通過(guò)對(duì)方訪問(wèn)賬號(hào)proxy連接,測(cè)試是否路由能默認(rèn)到hostgroup_id=1,它是一個(gè)寫組
[root@slave1 ~]# mysql -h172.16.100.24 -uproxysql -p'123456' -P 6033 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.5.30 (ProxySQL) Copyright (c) 2000, 2022, Oracle and/or its affiliates. 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; +--------------------+ | Database | +--------------------+ | db1 | | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 5 rows in set (0.01 sec) mysql> select @@server_id; +-------------+ | @@server_id | +-------------+ | 21 | +-------------+ 1 row in set (0.00 sec) #通過(guò)proxysql用戶,創(chuàng)建一個(gè)keme庫(kù) mysql> create database keme; Query OK, 1 row affected (0.00 sec)
在slave2:172.16.100.23 上去驗(yàn)證一下,是否同步過(guò)去keme這個(gè)庫(kù)
mysql> select @@server_id; +-------------+ | @@server_id | +-------------+ | 23 | +-------------+ 1 row in set (0.00 sec) mysql> show databases; +--------------------+ | Database | +--------------------+ | db1 | | information_schema | | keme | | mysql | | performance_schema | | sys | +--------------------+ 6 rows in set (0.01 sec)
8.添加讀寫分離規(guī)則(mysql_query_rules)
proxysql支持正則,這里添加兩條匹配規(guī)則
1) 表示像select * from xxx for update這種語(yǔ)句都會(huì)分到到寫組
2)表示像select這種語(yǔ)句都會(huì)被分配到讀組。
insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(1,1,'^select .* for update$',1,1); insert into mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) values(2,1,'^select',0,1); load mysql query rules to runtime; save mysql query rules to disk;
9.測(cè)試讀寫分離
[root@slave1 ~]# mysql -uproxysql -p123456 -h 172.16.100.24 -P 6033 -e "select @@server_id" mysql: [Warning] Using a password on the command line interface can be insecure. +-------------+ | @@server_id | +-------------+ | 3 | +-------------+ [root@slave1 ~]# mysql -uproxysql -p123456 -h 172.16.100.24 -P 6033 -e "select @@server_id" mysql: [Warning] Using a password on the command line interface can be insecure. +-------------+ | @@server_id | +-------------+ | 2 | +-------------+ [root@slave1 ~]# mysql -uproxysql -p123456 -h 172.16.100.24 -P 6033 -e "begin;select @@server_id commit;" mysql: [Warning] Using a password on the command line interface can be insecure. +--------+ | commit | +--------+ | 1 | +--------+
到此這篇關(guān)于MySQL主從同步的幾種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)MySQL主從同步內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL存儲(chǔ)結(jié)構(gòu)用法案例分析
這篇文章主要介紹了MySQL存儲(chǔ)結(jié)構(gòu)用法,結(jié)合具體案例形式分析了mysql存儲(chǔ)結(jié)構(gòu)相關(guān)使用方法與操作注意事項(xiàng),需要的朋友可以參考下2018-07-07MySQL定時(shí)備份數(shù)據(jù)庫(kù)操作示例
這篇文章主要介紹了MySQL定時(shí)備份數(shù)據(jù)庫(kù)操作,結(jié)合實(shí)例形式分析了MySQL定時(shí)備份數(shù)據(jù)庫(kù)相關(guān)命令、原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03解決mysql報(bào)錯(cuò):Data?source?rejected?establishment?of?connect
這篇文章主要給大家介紹了關(guān)于如何解決mysql報(bào)錯(cuò):Data?source?rejected?establishment?of?connection,?message?from?server:?\"Too?many?connectio的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02mysql8.0.11數(shù)據(jù)目錄遷移的實(shí)現(xiàn)
這篇文章主要介紹了mysql8.0.11數(shù)據(jù)目錄遷移的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02MySQL 數(shù)據(jù)庫(kù)雙向鏡像、循環(huán)鏡像(復(fù)制)
在MySQL數(shù)據(jù)庫(kù)鏡像的貼子中,主數(shù)據(jù)庫(kù)A 的數(shù)據(jù)鏡像到從數(shù)據(jù)庫(kù)B,是單向的,Zen Cart網(wǎng)店的數(shù)據(jù)讀寫都必須在數(shù)據(jù)庫(kù)A進(jìn)行,結(jié)果會(huì)自動(dòng)鏡像到數(shù)據(jù)庫(kù)B中。但是對(duì)數(shù)據(jù)庫(kù)B的直接操作,不會(huì)影響數(shù)據(jù)庫(kù)A。2011-05-05一文帶你了解如何用MySQL通配符實(shí)現(xiàn)過(guò)濾功能
本文章將介紹什么是通配符、如何使用通配符以及怎樣使用LIKE操作符進(jìn)行通配搜索,以便對(duì)數(shù)據(jù)進(jìn)行復(fù)雜過(guò)濾,感興趣的小伙伴跟著小編一起來(lái)學(xué)習(xí)吧2023-07-07