Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge dev #203

Merged
merged 19 commits into from
Mar 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
cb5f100
bug: dead lock in etcd v2 api
panhongrainbow Jan 17, 2022
b76c0ae
Merge pull request #194 from panhongrainbow/feature_etcd_v3_api
xiyangxixian Jan 18, 2022
02bbbf0
fix: arrange code
panhongrainbow Jan 27, 2022
04b1747
Merge branch 'feature_etcd_v3_api_pr' into feature_etcd_v3_api
panhongrainbow Jan 27, 2022
3744c13
fix: correct commit
panhongrainbow Jan 27, 2022
e029ee1
修复 unregisterProxy 和 prepareConfig 未支持 etcdv3
xiyangxixian Feb 9, 2022
0755128
gaea cc etcdv3 支持
xiyangxixian Feb 9, 2022
25f666a
Merge pull request #1 from xiyangxixian/feature_etcd_v3_api
panhongrainbow Feb 9, 2022
fbac80a
Merge pull request #195 from panhongrainbow/feature_etcd_v3_api
xiyangxixian Feb 9, 2022
d301ccc
test: combine all commits to one
panhongrainbow Feb 22, 2022
869a35d
test: correct README.md
panhongrainbow Feb 23, 2022
b31a816
Merge pull request #196 from panhongrainbow/feature_dc_test_pr
xiyangxixian Feb 28, 2022
65e9a96
Gaea-cc二阶段提交重试
Mar 1, 2022
5b3b01d
Merge pull request #197 from chenchen10/feature/dev
xiyangxixian Mar 1, 2022
c4bb752
修复后端 mysql 5.x,使用 mysql8 客户端客户连接时 charset 错误
xiyangxixian Mar 1, 2022
c58faee
Merge pull request #198 from XiaoMi/fix-mysql8-charset
xiyangxixian Mar 1, 2022
fab29c0
Merge pull request #200 from XiaoMi/dev
xiyangxixian Mar 2, 2022
cac5bd6
#201 [优化]groupby orderby having limit语句单节点下不再走merge流程
funnyAnt Mar 10, 2022
99f6f91
Merge pull request #202 from funnyAnt/master
xiyangxixian Mar 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/direct_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ func (dc *DirectConnection) SetAutoCommit(v uint8) error {
func (dc *DirectConnection) SetCharset(charset string, collation mysql.CollationID) ( /*changed*/ bool, error) {
charset = strings.Trim(charset, "\"'`")

if collation == 0 {
if collation == 0 || collation > 247 {
collation = mysql.CollationNames[mysql.Charsets[charset]]
}

Expand Down
118 changes: 118 additions & 0 deletions backend/direct_connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ package backend

import (
"bytes"
"github.com/XiaoMi/Gaea/mysql"
"github.com/XiaoMi/Gaea/util/mocks/pipeTest"
"github.com/stretchr/testify/require"
"testing"
)

Expand All @@ -37,3 +40,118 @@ func TestAppendSetVariable2(t *testing.T) {
appendSetVariableToDefault(&buf, "sql_mode")
t.Log(buf.String())
}

var (
// 准备数据库的回应资料
mysqlInitHandShakeResponse = []uint8{
// 资料长度
93, 0, 0,
// 自增序列号码
0,
// 以下 93 笔数据
// 数据库的版本号 version
10, 53, 46, 53, 46,
53, 45, 49, 48, 46,
53, 46, 49, 50, 45,
77, 97, 114, 105, 97,
68, 66, 45, 108, 111,
103,
// 数据库的版本结尾
0,
// 连线编号 connection id
16, 0, 0, 0,
// Salt
81, 64, 43, 85, 76, 90, 97, 91,
// filter
0,
// 取得功能标志 capability
254, 247,
// 數據庫編碼 charset
33, // 可以用 SHOW CHARACTER SET LIKE 'utf8'; 查询
// 服务器状态,在 Gaea/mysql/constants.go 的 Server information
2, 0,
// 延伸的功能标志 capability
255, 129,
// Auth 资料和保留值
21, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0,
// 延伸的 Salt
34, 53, 36, 85,
93, 86, 117, 105, 49,
87, 65, 125,
// 其他未用到的资料
0, 109, 121, 115, 113, 108, 95, 110, 97, 116,
105, 118, 101, 95, 112, 97, 115, 115, 119, 111,
114, 100, 0,
}
)

// TestDirectConnWithoutDB 为测试数据库的后端连线流程,以下测试不使用 MariaDB 的服务器,只是单纯的单元测试
func TestDirectConnWithoutDB(t *testing.T) {
// 开始正式测试
t.Run("测试数据库后端连线的初始交握", func(t *testing.T) {
// 开始模拟
mockGaea, mockMariaDB := pipeTest.NewDcServerClient(t, pipeTest.TestReplyFunc) // 产生 Gaea 和 mockServer 模拟物件
mockGaea.SendOrReceive(mysqlInitHandShakeResponse) // 模拟数据库开始交握

// 產生 Mysql dc 直連物件 (用以下内容取代 reply() 函数 !)
var dc DirectConnection
var mysqlConn = mysql.NewConn(mockMariaDB.GetConnRead())
dc.conn = mysqlConn
err := dc.readInitialHandshake()
require.Equal(t, err, nil)

// 等待和确认资料已经写入 pipe 并单方向重置模拟物件
err = mockGaea.WaitAndReset(mockMariaDB)
require.Equal(t, err, nil)

// 开始计算

/* 功能标志 capability 的计算
先把所有的功能标志 capability 的数据收集起来,包含延伸部份
数值分别为 254, 247, 255, 129
并反向排列
数值分别为 129, 255, 247, 254
全部 十进制 转成 二进制
254 的二进制为 1111 1110
247 的二进制为 1111 0111
255 的二进制为 1111 1111
129 的二进制为 1000 0001
把全部二进制的数值合并
二进制数值分别为 1000 0001 1111 1111 1111 0111 1111 1110 (转成十进制数值为 2181036030)
再用文档 https://mariadb.com/kb/en/connection/ 进行对照
比如,功能标志 capability 的第一个值为 0,意思为 CLIENT_MYSQL 值为 0,代表是由服务器发出的讯息 */

/* 连线编号 connection id 的计算
先把所有的连线编号 connection id 的数据收集起来,包含延伸部份
数值分别为 16, 0, 0, 0
并反向排列
数值分别为 0, 0, 0, 16
全部 十进制 转成 二进制
0 的二进制为 0000 0000
16 的二进制为 0001 0000
把全部二进制的数值合并
二进制数值分别为 0000 0000 0001 0000 (转成十进制数值为 16) */

// 先把所有 Salt 的数据收集起来,包含延伸部份
// 数值分别为 81,64,43,85,76,90,97,91,34,53,36,85,93,86,117,105,49,87,65,125

/* 服务器状态 status 的计算
先把所有的服务器状态 的数据收集起来,包含延伸部份
数值分别为 2, 0
并反向排列
数值分别为 0, 2
全部 十进制 转成 二进制
2 的二进制为 0000 0010
0 的二进制为 0000 0000
把全部二进制的数值合并
二进制数值分别为 0000 0000 0000 0010 (转成十进制数值为 2)
再用代码 Gaea/mysql/constants.go 里的 Server information 进行对照
功能标志 capability 的第一个值为 0,意思为 CLIENT_MYSQL 值为 0,代表是由服务器发出的讯息 */

// 计算后的检查
require.Equal(t, dc.capability, uint32(2181036030)) // 检查功能标志 capability
require.Equal(t, dc.conn.ConnectionID, uint32(16)) // 检查连线编号 connection id
require.Equal(t, dc.salt, []uint8{81, 64, 43, 85, 76, 90, 97, 91, 34, 53, 36, 85, 93, 86, 117, 105, 49, 87, 65, 125}) // 检查 Salt
require.Equal(t, dc.status, mysql.ServerStatusAutocommit) // 检查服务器状态
})
}
53 changes: 39 additions & 14 deletions cc/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import (
"github.com/XiaoMi/Gaea/models"
)

const (
PREPARE_RETRY_TIMES = 3
COMMIT_RETRY_TIMES = 1
)

func getCoordinatorRoot(cluster string) string {
if cluster != "" {
return "/" + cluster
Expand All @@ -32,15 +37,15 @@ func getCoordinatorRoot(cluster string) string {

// ListNamespace return names of all namespace
func ListNamespace(cfg *models.CCConfig, cluster string) ([]string, error) {
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
mConn := models.NewStore(client)
defer mConn.Close()
return mConn.ListNamespace()
}

// QueryNamespace return information of namespace specified by names
func QueryNamespace(names []string, cfg *models.CCConfig, cluster string) (data []*models.Namespace, err error) {
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
mConn := models.NewStore(client)
defer mConn.Close()
for _, v := range names {
Expand Down Expand Up @@ -71,7 +76,7 @@ func ModifyNamespace(namespace *models.Namespace, cfg *models.CCConfig, cluster
}

// sink namespace
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
storeConn := models.NewStore(client)
defer storeConn.Close()

Expand All @@ -87,28 +92,48 @@ func ModifyNamespace(namespace *models.Namespace, cfg *models.CCConfig, cluster
return err
}

wg := sync.WaitGroup{}
// prepare phase
for _, v := range proxies {
err := proxy.PrepareConfig(v.IP+":"+v.AdminPort, namespace.Name, cfg)
if err != nil {
return err
}
wg.Add(1)
go func(v *models.ProxyMonitorMetric) {
for i := 0; i < PREPARE_RETRY_TIMES; i++ {
if err = proxy.PrepareConfig(v.IP+":"+v.AdminPort, namespace.Name, cfg); err == nil {
break
}
log.Warn("namespace %s, proxy prepare retry %d", namespace.Name, i)
}
if err != nil {
return
}
wg.Done()
}(v)
}
wg.Wait()

// commit phase
for _, v := range proxies {
err := proxy.CommitConfig(v.IP+":"+v.AdminPort, namespace.Name, cfg)
if err != nil {
return err
}
wg.Add(1)
go func(v *models.ProxyMonitorMetric) {
for i := 0; i < COMMIT_RETRY_TIMES; i++ {
if err := proxy.CommitConfig(v.IP+":"+v.AdminPort, namespace.Name, cfg); err == nil {
break
}
log.Warn("namespace %s, proxy prepare retry %d", namespace.Name, i)
}
if err != nil {
return
}
wg.Done()
}(v)
}

return nil
}

// DelNamespace delete namespace
func DelNamespace(name string, cfg *models.CCConfig, cluster string) error {
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
mConn := models.NewStore(client)
defer mConn.Close()

Expand Down Expand Up @@ -139,7 +164,7 @@ func SQLFingerprint(name string, cfg *models.CCConfig, cluster string) (slowSQLs
slowSQLs = make(map[string]string, 16)
errSQLs = make(map[string]string, 16)
// list proxy
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
mConn := models.NewStore(client)
defer mConn.Close()
proxies, err := mConn.ListProxyMonitorMetrics()
Expand Down Expand Up @@ -183,7 +208,7 @@ func SQLFingerprint(name string, cfg *models.CCConfig, cluster string) (slowSQLs
// ProxyConfigFingerprint return fingerprints of all proxy
func ProxyConfigFingerprint(cfg *models.CCConfig, cluster string) (r map[string]string, err error) {
// list proxy
client := models.NewClient(models.ConfigEtcd, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
client := models.NewClient(cfg.CoordinatorType, cfg.CoordinatorAddr, cfg.UserName, cfg.Password, getCoordinatorRoot(cluster))
mConn := models.NewStore(client)
defer mConn.Close()
proxies, err := mConn.ListProxyMonitorMetrics()
Expand Down
3 changes: 2 additions & 1 deletion etc/gaea.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; config type, etcd/file, you can test gaea with file type, you shoud use etcd in production
; config type, etcd/file/etcdv3, you can test gaea with file type, you shoud use etcd/etcdv3 in production
; 请指定设定方式为 file 或 etcd 或 etcdv3
config_type=etcd
;file config path, 具体配置放到file_config_path的namespace目录下,该下级目录为固定目录
file_config_path=./etc/file
Expand Down
3 changes: 2 additions & 1 deletion etc/gaea_cc.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ log_path =./logs
log_filename=gaea_cc
log_output=file

;coordinator目前支持etcd,coodinator config
;coordinator 目前支持 etcd 和 etcdv3,coodinator config
coordinator_type=etcd
coordinator_addr=http://127.0.0.1:2379
username=root
password=root
Expand Down
17 changes: 17 additions & 0 deletions models/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 中间件 Gaea Model 目录内容



## 1 功能列表

Model 目录包含以下功能

- 处理设定值的读写逻辑



## 2 相关文档

以下为相关文档

- [指定设定值的读写方式 (file etcd etcdv3)](./connection.md)
Binary file added models/assets/image-20220124113553383.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124142003588.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124143836664.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124145641452.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124154131750.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124182118946.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124182833234.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124182944970.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124183045456.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124183141813.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124183228814.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220124183310893.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220126175410955.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220127114256168.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added models/assets/image-20220127142531692.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions models/cc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type CCConfig struct {
ProxyUserName string `ini:"proxy_username"`
ProxyPassword string `ini:"proxy_password"`
// etcd 相关配置
CoordinatorType string `ini:"coordinator_type"`
CoordinatorAddr string `ini:"coordinator_addr"`
CoordinatorRoot string `ini:"coordinator_root"`
UserName string `ini:"username"`
Expand Down Expand Up @@ -56,6 +57,9 @@ func ParseCCConfig(cfgFile string) (*CCConfig, error) {
if ccConfig.DefaultCluster == "" && ccConfig.CoordinatorRoot != "" {
ccConfig.DefaultCluster = strings.TrimPrefix(ccConfig.CoordinatorRoot, "/")
}
if ccConfig.CoordinatorType == "" {
ccConfig.CoordinatorType = ConfigEtcd
}
return ccConfig, err
}

Expand Down
Loading