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  }