github.com/polarismesh/polaris@v1.17.8/store/mysql/default.go (about) 1 /** 2 * Tencent is pleased to support the open source community by making Polaris available. 3 * 4 * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. 5 * 6 * Licensed under the BSD 3-Clause License (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * https://opensource.org/licenses/BSD-3-Clause 11 * 12 * Unless required by applicable law or agreed to in writing, software distributed 13 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 14 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 15 * specific language governing permissions and limitations under the License. 16 */ 17 18 package sqldb 19 20 import ( 21 "errors" 22 "fmt" 23 24 _ "github.com/go-sql-driver/mysql" 25 26 "github.com/polarismesh/polaris/plugin" 27 "github.com/polarismesh/polaris/store" 28 ) 29 30 const ( 31 // SystemNamespace system namespace 32 SystemNamespace = "Polaris" 33 // STORENAME database storage name 34 STORENAME = "defaultStore" 35 // DefaultConnMaxLifetime default maximum connection lifetime 36 DefaultConnMaxLifetime = 60 * 30 // 默认是30分钟 37 // emptyEnableTime 规则禁用时启用时间的默认值 38 emptyEnableTime = "STR_TO_DATE('1980-01-01 00:00:01', '%Y-%m-%d %H:%i:%s')" 39 ) 40 41 // init 自动引入包初始化函数 42 func init() { 43 s := &stableStore{} 44 _ = store.RegisterStore(s) 45 } 46 47 // stableStore 实现了Store接口 48 type stableStore struct { 49 *namespaceStore 50 *serviceStore 51 *instanceStore 52 *routingConfigStore 53 *l5Store 54 *rateLimitStore 55 *circuitBreakerStore 56 *toolStore 57 *userStore 58 *groupStore 59 *strategyStore 60 *faultDetectRuleStore 61 62 // 配置中心stores 63 *configFileGroupStore 64 *configFileStore 65 *configFileReleaseStore 66 *configFileReleaseHistoryStore 67 *configFileTemplateStore 68 69 // client info stores 70 *clientStore 71 72 // v2 存储 73 *routingConfigStoreV2 74 75 // maintain store 76 *adminStore 77 78 // 主数据库,可以进行读写 79 master *BaseDB 80 // 对主数据库的事务操作,可读写 81 masterTx *BaseDB 82 // 备数据库,提供只读 83 slave *BaseDB 84 start bool 85 } 86 87 // Name 实现Name函数 88 func (s *stableStore) Name() string { 89 return STORENAME 90 } 91 92 // Initialize 初始化函数 93 func (s *stableStore) Initialize(conf *store.Config) error { 94 if s.start { 95 return nil 96 } 97 98 masterConfig, slaveConfig, err := parseDatabaseConf(conf.Option) 99 if err != nil { 100 return err 101 } 102 master, err := NewBaseDB(masterConfig, plugin.GetParsePassword()) 103 if err != nil { 104 return err 105 } 106 s.master = master 107 108 masterTx, err := NewBaseDB(masterConfig, plugin.GetParsePassword()) 109 if err != nil { 110 return err 111 } 112 s.masterTx = masterTx 113 114 if slaveConfig != nil { 115 log.Infof("[Store][database] use slave database config: %+v", slaveConfig) 116 slave, err := NewBaseDB(slaveConfig, plugin.GetParsePassword()) 117 if err != nil { 118 return err 119 } 120 s.slave = slave 121 } 122 // 如果slave为空,意味着slaveConfig为空,用master数据库替代 123 if s.slave == nil { 124 s.slave = s.master 125 } 126 127 log.Infof("[Store][database] connect the database successfully") 128 129 s.start = true 130 s.newStore() 131 return nil 132 } 133 134 // parseDatabaseConf return slave, master, error 135 func parseDatabaseConf(opt map[string]interface{}) (*dbConfig, *dbConfig, error) { 136 // 必填 137 masterEnter, ok := opt["master"] 138 if !ok || masterEnter == nil { 139 return nil, nil, errors.New("database master db config is missing") 140 } 141 masterConfig, err := parseStoreConfig(masterEnter) 142 if err != nil { 143 return nil, nil, err 144 } 145 146 // 只读数据库可选 147 slaveEntry, ok := opt["slave"] 148 if !ok || slaveEntry == nil { 149 return masterConfig, nil, nil 150 } 151 slaveConfig, err := parseStoreConfig(slaveEntry) 152 if err != nil { 153 return nil, nil, err 154 } 155 156 return masterConfig, slaveConfig, nil 157 } 158 159 // parseStoreConfig 解析store的配置 160 func parseStoreConfig(opts interface{}) (*dbConfig, error) { 161 obj, _ := opts.(map[interface{}]interface{}) 162 163 needCheckFields := map[string]string{"dbType": "", "dbUser": "", "dbPwd": "", "dbAddr": "", "dbName": ""} 164 165 for key := range needCheckFields { 166 val, ok := obj[key] 167 if !ok { 168 return nil, fmt.Errorf("config Plugin %s:%s type must be string", STORENAME, key) 169 } 170 171 needCheckFields[key] = fmt.Sprintf("%v", val) 172 } 173 174 c := &dbConfig{ 175 dbType: needCheckFields["dbType"], 176 dbUser: needCheckFields["dbUser"], 177 dbPwd: needCheckFields["dbPwd"], 178 dbAddr: needCheckFields["dbAddr"], 179 dbName: needCheckFields["dbName"], 180 } 181 if maxOpenConns, _ := obj["maxOpenConns"].(int); maxOpenConns > 0 { 182 c.maxOpenConns = maxOpenConns 183 } 184 if maxIdleConns, _ := obj["maxIdleConns"].(int); maxIdleConns > 0 { 185 c.maxIdleConns = maxIdleConns 186 } 187 c.connMaxLifetime = DefaultConnMaxLifetime 188 if connMaxLifetime, _ := obj["connMaxLifetime"].(int); connMaxLifetime > 0 { 189 c.connMaxLifetime = connMaxLifetime 190 } 191 192 if isolationLevel, _ := obj["txIsolationLevel"].(int); isolationLevel > 0 { 193 c.txIsolationLevel = isolationLevel 194 } 195 return c, nil 196 } 197 198 // Destroy 退出函数 199 func (s *stableStore) Destroy() error { 200 s.start = false 201 if s.master != nil { 202 _ = s.master.Close() 203 } 204 if s.masterTx != nil { 205 _ = s.masterTx.Close() 206 } 207 if s.slave != nil { 208 _ = s.slave.Close() 209 } 210 211 if s.adminStore != nil { 212 s.adminStore.StopLeaderElections() 213 } 214 215 s.master = nil 216 s.masterTx = nil 217 s.slave = nil 218 219 return nil 220 } 221 222 // CreateTransaction 创建一个事务 223 func (s *stableStore) CreateTransaction() (store.Transaction, error) { 224 // 每次创建事务前,还是需要ping一下 225 _ = s.masterTx.Ping() 226 227 nt := &transaction{} 228 tx, err := s.masterTx.Begin() 229 if err != nil { 230 log.Errorf("[Store][database] database begin err: %s", err.Error()) 231 return nil, err 232 } 233 234 nt.tx = tx 235 return nt, nil 236 } 237 238 func (s *stableStore) StartTx() (store.Tx, error) { 239 tx, err := s.masterTx.Begin() 240 if err != nil { 241 return nil, err 242 } 243 return NewSqlDBTx(tx), nil 244 } 245 246 func (s *stableStore) StartReadTx() (store.Tx, error) { 247 tx, err := s.slave.Begin() 248 if err != nil { 249 return nil, err 250 } 251 return NewSqlDBTx(tx), nil 252 } 253 254 // newStore 初始化子类 255 func (s *stableStore) newStore() { 256 s.namespaceStore = &namespaceStore{master: s.master, slave: s.slave} 257 258 s.serviceStore = &serviceStore{master: s.master, slave: s.slave} 259 260 s.instanceStore = &instanceStore{master: s.master, slave: s.slave} 261 262 s.routingConfigStore = &routingConfigStore{master: s.master, slave: s.slave} 263 264 s.l5Store = &l5Store{master: s.master, slave: s.slave} 265 266 s.rateLimitStore = &rateLimitStore{master: s.master, slave: s.slave} 267 268 s.circuitBreakerStore = &circuitBreakerStore{master: s.master, slave: s.slave} 269 270 s.toolStore = &toolStore{db: s.master} 271 272 s.userStore = &userStore{master: s.master, slave: s.slave} 273 274 s.groupStore = &groupStore{master: s.master, slave: s.slave} 275 276 s.strategyStore = &strategyStore{master: s.master, slave: s.slave} 277 278 s.faultDetectRuleStore = &faultDetectRuleStore{master: s.master, slave: s.slave} 279 280 s.configFileGroupStore = &configFileGroupStore{master: s.master, slave: s.slave} 281 282 s.configFileStore = &configFileStore{master: s.master, slave: s.slave} 283 284 s.configFileReleaseStore = &configFileReleaseStore{master: s.master, slave: s.slave} 285 286 s.configFileReleaseHistoryStore = &configFileReleaseHistoryStore{master: s.master, slave: s.slave} 287 288 s.configFileTemplateStore = &configFileTemplateStore{master: s.master, slave: s.slave} 289 290 s.clientStore = &clientStore{master: s.master, slave: s.slave} 291 292 s.routingConfigStoreV2 = &routingConfigStoreV2{master: s.master, slave: s.slave} 293 294 s.adminStore = newAdminStore(s.master) 295 } 296 297 func buildEtimeStr(enable bool) string { 298 etimeStr := "sysdate()" 299 if !enable { 300 etimeStr = emptyEnableTime 301 } 302 return etimeStr 303 }