必讀
歡迎關注白日夢的公眾號(風一樣的程式設計師)回覆:資料庫中介軟體 。
即可獲取寫有註釋的中介軟體原始碼包,開箱即用~
一、Centos7、Mac安裝MySQL
筆記地址:https://www.cnblogs.com/ZhuChangwu/p/12984153.html
視訊串講地址:https://www.bilibili.com/video/BV19g411N7NR?p=2
二、主從複製原理
2.1、基於binlog_filename + position
原理圖:
筆記地址:https://mp.weixin.qq.com/s/cSToNVQPK8QCpkjapxNoEw
視訊串講地址:https://www.bilibili.com/video/BV19g411N7NR?p=3
2.2、基於GTID
原理圖:
筆記地址:https://mp.weixin.qq.com/s/V5hU2ATeey871loWQIqHKg
視訊串講地址:https://www.bilibili.com/video/BV19g411N7NR?p=4
三、my.cnf
[mysqld]
# 埠
port = 3306
# 資料目錄
datadir=/var/lib/mysql
# 錯誤日誌
log-error=/var/log/mysqld.log
# 為每張表單獨建立一個表空間檔案
# 大家常說的表空間到底是什麼?究竟什麼又是資料表呢? https://mp.weixin.qq.com/s/CwxRjGI843UerF89G_WJ-Q
innodb_file_per_table=on
innodb_file_format = Barracuda
# binlog 相關配置
# 1、MySQL的 bin log有啥用?在哪裡?誰寫的?怎麼配置?
# https://mp.weixin.qq.com/s/DN1shuyxPJ6BkE_RLezAnA
# 2、瞭解bin log的寫入機制嗎?說說你們線上如何調整引數的!
# https://mp.weixin.qq.com/s/MtWzoiJtupso5M8z1KUaQQ
# 3、bin log有哪些格式?有啥區別?優缺點?線上用哪種格式?
# https://mp.weixin.qq.com/s/ar-wVbDi4CYjPI1t6fTjVw
log_bin=mysql-bin
log-bin-index = mysql-bin.index
max_binlog_size = 256M
sync-binlog = 1000
binlog-format = ROW
# relaylog相關配置
relay_log_recovery = 1
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay-log = relay-log
relay-log-index = relay-log.index
sync_relay_log = 1000
max_relay_log_size = 256M
# 設定server-id,叢集唯一
server-id=1
# pid、socket
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
四、測試SQL
create database test;
use test;
CREATE TABLE `runoob_tbl` (
`runoob_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`runoob_title` varchar(100) NOT NULL,
`runoob_author` varchar(40) NOT NULL,
`submission_date` date DEFAULT NULL,
PRIMARY KEY (`runoob_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
INSERT INTO runoob_tbl (runoob_title, runoob_author, submission_date)
VALUES("歡迎微信搜尋:", "風一樣的程式設計師", NOW());
CHANGE MASTER TO
MASTER_HOST='10.4.7.103',
MASTER_USER='MySQLsync',
MASTER_PASSWORD='MySQLsync123',
MASTER_PORT=3306,
MASTER_AUTO_POSITION = 1;
CHANGE MASTER TO
MASTER_HOST='10.4.7.103',
MASTER_USER='mysqlsync',
MASTER_PASSWORD='mysqlsync123',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=434;
CHANGE MASTER TO MASTER_AUTO_POSITION=0;
grant replication slave on *.* to MySQLsync@"%" identified by "MySQLsync123";
grant replication slave on *.* to mysqlsync@"127.0.0.1" identified by "mysqlsync123";
grant replication slave on *.* to mysqlsync@"%" identified by "mysqlsync123";
五、中介軟體使用、概念串講
腦圖:
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=5
搞明白這幾點:
- 跟大家講明白這樣一件事,你以為你是直連的MySQL?其實不是的,你直連的MySQL_Proxy
- Node、分片的概念
- Proxy配置檔案的解讀
- 演示Proxy的使用
六、總攬啟動流程
- 基於mysql協議,獲取主從庫的連線
- 將主從庫的連線維護進連線池
- 探活機制
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=6
Notice:跟大家講明白這樣一件事,你以為你是直連的MySQL?其實不是的,你直連的MySQL_Proxy!
七、許可權管理實現原理
重點關注的地方:
# server.go:381
// todo 使用者白名單校驗,只有指定的user、ip才能使用Proxy
if allowConnect := conn.IsAllowConnect(); allowConnect == false {
err := mysql.NewError(mysql.ER_ACCESS_DENIED_ERROR, "ip address access denied by kingshard.")
conn.writeError(err)
conn.Close()
return
}
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=7
八、MySQL協議-Handshake!和中介軟體握手機制原理
原理圖:
重點關注的地方:
server.go:388
// todo 基於MySQL協議和客戶端建立握手機制
if err := conn.Handshake(); err != nil {
golog.Error("server", "onConn", err.Error(), 0)
conn.writeError(err)
conn.Close()
return
}
backend_conn.go:101
// todo 這裡其實Proxy和MySQL Server之間建立連線的邏輯
// todo 大家看到這裡不明白也沒關係,因為想看懂這裡需要了解MySQL協議,後面的視訊中我會跟大家講明白這件事
// todo 大家只需要知道,執行過這裡的程式碼之後呢,proxy和MySQL-Service之間就會建立一個Conn,
// todo 並且Proxy會維護這個Conn,後續使用者的SQL打過來之後,Proxy會將使用者的SQL轉發給這裡獲取到的Conn,進爾讓MySQL的引擎去真正的執行這裡的SQL
// todo 讀MySQL發過來的握手報文
if err := c.readInitialHandshake(); err != nil {
c.conn.Close()
return err
}
// todo 寫自己的資訊(port、username、password、host)
if err := c.writeAuthHandshake(); err != nil {
c.conn.Close()
return err
}
// todo 讀取MySQL-Server發過來的ok報文
if _, err := c.readOK(); err != nil {
c.conn.Close()
return err
}
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=8
九、中介軟體不斷接受處理客戶端SQL原理
重點關注的地方:
conn.go:279
// todo 下面的程式碼在一個無限迴圈中, 不斷的接受客戶端傳送過來的sql語句
for {
// todo 根據MySQL協議解析資料包,獲取出資料包中sql語句
data, err := c.readPacket()
if err != nil {
return
}
if c.configVer != c.proxy.configVer {
err := c.reloadConfig()
if nil != err {
golog.Error("ClientConn", "Run",
err.Error(), c.connectionId,
)
c.writeError(err)
return
}
c.configVer = c.proxy.configVer
golog.Debug("ClientConn", "Run",
fmt.Sprintf("config reload ok, ver:%d", c.configVer), c.connectionId,
)
}
// 使用dispatch方法,繼續處理資料包
if err := c.dispatch(data); err != nil {
c.proxy.counter.IncrErrLogTotal()
golog.Error("ClientConn", "Run",
err.Error(), c.connectionId,
)
c.writeError(err)
if err == mysql.ErrBadConn {
c.Close()
}
}
if c.closed {
return
}
c.pkg.Sequence = 0
}
}
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=9
十、中介軟體是如何執行你的select語句的?
重點關注的地方:
conn.go:279
// 使用dispatch方法,繼續處理資料包
if err := c.dispatch(data); err != nil {
c.proxy.counter.IncrErrLogTotal()
golog.Error("ClientConn", "Run",
err.Error(), c.connectionId,
)
c.writeError(err)
if err == mysql.ErrBadConn {
c.Close()
}
}
conn.go:340
func (c *ClientConn) dispatch(data []byte) error {
c.proxy.counter.IncrClientQPS()
// todo MYSQL協議規定了,客戶端傳送過來的資料格式是:cmd+data
// todo 其中的cmd就是sql的型別,型別都列舉在下面了,打眼一看都能懂
cmd := data[0]
// todo data部分就是sql詳細內容
data = data[1:]
switch cmd {
case mysql.COM_QUIT:
c.handleRollback()
c.Close()
return nil
case mysql.COM_QUERY: // todo select 語句
return c.handleQuery(hack.String(data))
case mysql.COM_PING: // todo ping 語句
return c.writeOK(nil)
case mysql.COM_INIT_DB:
return c.handleUseDB(hack.String(data))
case mysql.COM_FIELD_LIST:
return c.handleFieldList(data)
case mysql.COM_STMT_PREPARE:
return c.handleStmtPrepare(hack.String(data))
case mysql.COM_STMT_EXECUTE:// todo insert、update 語句
return c.handleStmtExecute(data)
case mysql.COM_STMT_CLOSE:
return c.handleStmtClose(data)
case mysql.COM_STMT_SEND_LONG_DATA:
return c.handleStmtSendLongData(data)
case mysql.COM_STMT_RESET:
return c.handleStmtReset(data)
case mysql.COM_SET_OPTION:
return c.writeEOF(0)
default:
msg := fmt.Sprintf("command %d not supported now", cmd)
golog.Error("ClientConn", "dispatch", msg, 0)
return mysql.NewError(mysql.ER_UNKNOWN_ERROR, msg)
}
return nil
}
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=10
十一、讀寫分離實現原理
重點關注的地方:
conn_pershard.go:97
// todo 從選出DB中獲取一條可用的連線,如果是沒有開事物且是讀請求的話,executeDB.IsSlave一般為true
conn, err := c.getBackendConn(executeDB.ExecNode, executeDB.IsSlave)
defer c.closeConn(conn, false)
if err != nil {
return false, err
}
視訊地址:https://www.bilibili.com/video/BV19g411N7NR?p=11
十二、贈送Proxy原始碼
寫有註釋的專案已上傳置百度網盤,專案基於vendor管理依賴包,開箱即用~
關注白日夢的公眾號(風一樣的程式設計師),回覆:資料庫中介軟體 ,即可領取當前文件以及原始碼包。