github.com/polarismesh/polaris@v1.17.8/store/mysql/l5.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 "database/sql" 22 "fmt" 23 "time" 24 25 "github.com/polarismesh/polaris/common/model" 26 ) 27 28 // l5Store 实现了L5Store 29 type l5Store struct { 30 master *BaseDB // 大部分操作都用主数据库 31 slave *BaseDB // 缓存相关的读取,请求到slave 32 } 33 34 // GetL5Extend 获取L5扩展数据 35 func (l5 *l5Store) GetL5Extend(serviceID string) (map[string]interface{}, error) { 36 return nil, nil 37 } 38 39 // SetL5Extend 保存L5扩展数据 40 func (l5 *l5Store) SetL5Extend(serviceID string, meta map[string]interface{}) (map[string]interface{}, error) { 41 return nil, nil 42 } 43 44 // GenNextL5Sid 获取下一个sid 45 func (l5 *l5Store) GenNextL5Sid(layoutID uint32) (string, error) { 46 var sid string 47 var err error 48 49 err = RetryTransaction("genNextL5Sid", func() error { 50 sid, err = l5.genNextL5Sid(layoutID) 51 return nil 52 }) 53 54 return sid, err 55 } 56 57 // genNextL5Sid 58 func (l5 *l5Store) genNextL5Sid(layoutID uint32) (string, error) { 59 tx, err := l5.master.Begin() 60 if err != nil { 61 log.Errorf("[Store][database] get next l5 sid tx begin err: %s", err.Error()) 62 return "", err 63 } 64 defer func() { _ = tx.Rollback() }() 65 66 getStr := "select module_id, interface_id, range_num from cl5_module limit 0, 1 for update" 67 var mid, iid, rnum uint32 68 if err := tx.QueryRow(getStr).Scan(&mid, &iid, &rnum); err != nil { 69 log.Errorf("[Store][database] get next l5 sid err: %s", err.Error()) 70 return "", err 71 } 72 73 rnum++ 74 if rnum >= 65536 { 75 rnum = 0 76 iid++ 77 } 78 if iid >= 4096 { 79 iid = 1 80 mid++ 81 } 82 83 updateStr := "update cl5_module set module_id = ?, interface_id = ?, range_num = ?" 84 if _, err := tx.Exec(updateStr, mid, iid, rnum); err != nil { 85 log.Errorf("[Store][database] get next l5 sid, update module err: %s", err.Error()) 86 return "", err 87 } 88 // 更新完数据库之后,可以直接提交tx 89 if err := tx.Commit(); err != nil { 90 log.Errorf("[Store][database] get next l5 sid tx commit err: %s", err.Error()) 91 return "", err 92 } 93 94 // 数据表已经更改,生成sid的元素说明是唯一的,可以组合sid了 95 modID := mid<<6 + layoutID 96 cmdID := iid<<16 + rnum 97 return fmt.Sprintf("%d:%d", modID, cmdID), nil 98 } 99 100 // GetMoreL5Extend 获取更多的增量数据 101 func (l5 *l5Store) GetMoreL5Extend(mtime time.Time) (map[string]map[string]interface{}, error) { 102 return nil, nil 103 } 104 105 // GetMoreL5Routes 获取更多的L5 Route信息 106 func (l5 *l5Store) GetMoreL5Routes(flow uint32) ([]*model.Route, error) { 107 str := getL5RouteSelectSQL() + " where Fflow > ?" 108 rows, err := l5.slave.Query(str, flow) 109 if err != nil { 110 log.Errorf("[Store][database] get more l5 route query err: %s", err.Error()) 111 return nil, err 112 } 113 114 return l5RouteFetchRows(rows) 115 } 116 117 // GetMoreL5Policies 获取更多的L5 Policy信息 118 func (l5 *l5Store) GetMoreL5Policies(flow uint32) ([]*model.Policy, error) { 119 str := getL5PolicySelectSQL() + " where Fflow > ?" 120 rows, err := l5.slave.Query(str, flow) 121 if err != nil { 122 log.Errorf("[Store][database] get more l5 policy query err: %s", err.Error()) 123 return nil, err 124 } 125 126 return l5PolicyFetchRows(rows) 127 } 128 129 // GetMoreL5Sections 获取更多的L5 Section信息 130 func (l5 *l5Store) GetMoreL5Sections(flow uint32) ([]*model.Section, error) { 131 str := getL5SectionSelectSQL() + " where Fflow > ?" 132 rows, err := l5.slave.Query(str, flow) 133 if err != nil { 134 log.Errorf("[Store][database] get more l5 section query err: %s", err.Error()) 135 return nil, err 136 } 137 138 return l5SectionFetchRows(rows) 139 } 140 141 // GetMoreL5IPConfigs 获取更多的L5 IPConfig信息 142 func (l5 *l5Store) GetMoreL5IPConfigs(flow uint32) ([]*model.IPConfig, error) { 143 str := getL5IPConfigSelectSQL() + " where Fflow > ?" 144 rows, err := l5.slave.Query(str, flow) 145 if err != nil { 146 log.Errorf("[Store][database] get more l5 ip config query err: %s", err.Error()) 147 return nil, err 148 } 149 150 return l5IPConfigFetchRows(rows) 151 } 152 153 // getL5RouteSelectSQL 生成L5 Route的select sql语句 154 func getL5RouteSelectSQL() string { 155 str := `select Fip, FmodId, FcmdId, FsetId, IFNULL(Fflag, 0), Fflow from t_route` 156 return str 157 } 158 159 // getL5PolicySelectSQL 生成L5 Policy的select sql语句 160 func getL5PolicySelectSQL() string { 161 str := `select FmodId, Fdiv, Fmod, IFNULL(Fflag, 0), Fflow from t_policy` 162 return str 163 } 164 165 // getL5SectionSelectSQL 生成L5 Section的select sql语句 166 func getL5SectionSelectSQL() string { 167 str := `select FmodId, Ffrom, Fto, Fxid, IFNULL(Fflag, 0), Fflow from t_section` 168 return str 169 } 170 171 // getL5IPConfigSelectSQL 生成L5 IPConfig的select sql语句 172 func getL5IPConfigSelectSQL() string { 173 str := `select Fip, FareaId, FcityId, FidcId, IFNULL(Fflag, 0), Fflow from t_ip_config` 174 return str 175 } 176 177 // l5RouteFetchRows 从route中取出rows的数据 178 func l5RouteFetchRows(rows *sql.Rows) ([]*model.Route, error) { 179 if rows == nil { 180 return nil, nil 181 } 182 defer rows.Close() 183 184 var out []*model.Route 185 var flag int 186 187 progress := 0 188 for rows.Next() { 189 progress++ 190 if progress%100000 == 0 { 191 log.Infof("[Store][database] load cl5 route progress: %d", progress) 192 } 193 space := &model.Route{} 194 err := rows.Scan( 195 &space.IP, 196 &space.ModID, 197 &space.CmdID, 198 &space.SetID, 199 &flag, 200 &space.Flow) 201 if err != nil { 202 log.Errorf("[Store][database] fetch l5 route rows scan err: %s", err.Error()) 203 return nil, err 204 } 205 206 space.Valid = true 207 if flag == 1 { 208 space.Valid = false 209 } 210 211 out = append(out, space) 212 } 213 214 if err := rows.Err(); err != nil { 215 log.Errorf("[Store][database] fetch l5 route rows next err: %s", err.Error()) 216 return nil, err 217 } 218 return out, nil 219 } 220 221 // l5PolicyFetchRows 从policy中取出rows的数据 222 func l5PolicyFetchRows(rows *sql.Rows) ([]*model.Policy, error) { 223 if rows == nil { 224 return nil, nil 225 } 226 defer rows.Close() 227 228 var out []*model.Policy 229 var flag int 230 231 for rows.Next() { 232 space := &model.Policy{} 233 err := rows.Scan( 234 &space.ModID, 235 &space.Div, 236 &space.Mod, 237 &flag, 238 &space.Flow) 239 if err != nil { 240 log.Errorf("[Store][database] fetch l5 policy rows scan err: %s", err.Error()) 241 return nil, err 242 } 243 244 space.Valid = true 245 if flag == 1 { 246 space.Valid = false 247 } 248 249 out = append(out, space) 250 } 251 if err := rows.Err(); err != nil { 252 log.Errorf("[Store][database] fetch l5 policy rows next err: %s", err.Error()) 253 return nil, err 254 } 255 return out, nil 256 } 257 258 // l5SectionFetchRows 从section中取出rows的数据 259 func l5SectionFetchRows(rows *sql.Rows) ([]*model.Section, error) { 260 if rows == nil { 261 return nil, nil 262 } 263 defer rows.Close() 264 265 var out []*model.Section 266 var flag int 267 268 for rows.Next() { 269 space := &model.Section{} 270 err := rows.Scan( 271 &space.ModID, 272 &space.From, 273 &space.To, 274 &space.Xid, 275 &flag, 276 &space.Flow) 277 if err != nil { 278 log.Errorf("[Store][database] fetch section rows scan err: %s", err.Error()) 279 return nil, err 280 } 281 282 space.Valid = true 283 if flag == 1 { 284 space.Valid = false 285 } 286 287 out = append(out, space) 288 } 289 if err := rows.Err(); err != nil { 290 log.Errorf("[Store][database] fetch section rows next err: %s", err.Error()) 291 return nil, err 292 } 293 294 return out, nil 295 } 296 297 // l5IPConfigFetchRows 从ip config中取出rows的数据 298 func l5IPConfigFetchRows(rows *sql.Rows) ([]*model.IPConfig, error) { 299 if rows == nil { 300 return nil, nil 301 } 302 defer rows.Close() 303 304 var out []*model.IPConfig 305 var flag int 306 for rows.Next() { 307 space := &model.IPConfig{} 308 err := rows.Scan( 309 &space.IP, 310 &space.AreaID, 311 &space.CityID, 312 &space.IdcID, 313 &flag, 314 &space.Flow) 315 if err != nil { 316 log.Errorf("[Store][database] fetch ip config rows scan err: %s", err.Error()) 317 return nil, err 318 } 319 320 space.Valid = true 321 if flag == 1 { 322 space.Valid = false 323 } 324 325 out = append(out, space) 326 } 327 if err := rows.Err(); err != nil { 328 log.Errorf("[Store][database] fetch ip config rows next err: %s", err.Error()) 329 return nil, err 330 } 331 332 return out, nil 333 }