From a9011d34e1d397500678ee2c93bcdda154235d22 Mon Sep 17 00:00:00 2001 From: xjxia Date: Fri, 15 Nov 2024 10:36:24 +0800 Subject: [PATCH] feat(dbm-services): only one address under domain should skip release close #7954 --- .../dbha/ha-module/client/name_service.go | 26 +++++++++++++++++++ .../dbmodule/dbmysql/MySQLProxy_switch.go | 16 ++++++++++-- .../dbmodule/dbmysql/MySQL_common_switch.go | 4 +-- .../dbmysql/SpiderProxyLayer_switch.go | 16 +++++++++--- .../common/dbha/ha-module/dbutil/db_switch.go | 24 +++++++++++++++++ 5 files changed, 79 insertions(+), 7 deletions(-) diff --git a/dbm-services/common/dbha/ha-module/client/name_service.go b/dbm-services/common/dbha/ha-module/client/name_service.go index d3cc1ba42a..9b42743794 100644 --- a/dbm-services/common/dbha/ha-module/client/name_service.go +++ b/dbm-services/common/dbha/ha-module/client/name_service.go @@ -68,6 +68,32 @@ func (c *NameServiceClient) GetDomainInfoByIp(ip string) ([]DomainInfo, error) { return res.Detail, nil } +// GetAddressNumberByDomain get address number under this domain name +func (c *NameServiceClient) GetAddressNumberByDomain(domainName string) (int, error) { + var res DomainRes + req := map[string]interface{}{ + "db_cloud_token": c.Conf.BKConf.BkToken, + "bk_cloud_id": c.CloudId, + "domain_name": []string{domainName}, + } + + response, err := c.DoNew(http.MethodPost, + c.SpliceUrlByPrefix(c.Conf.UrlPre, constvar.GetDomainInfoUrl, ""), req, nil) + if err != nil { + return 0, err + } + if response.Code != 0 { + return 0, fmt.Errorf("%s failed, return code:%d, msg:%s", util.AtWhere(), response.Code, response.Msg) + } + + err = json.Unmarshal(response.Data, &res) + if err != nil { + return 0, err + } + + return res.RowsNum, nil +} + // GetDomainInfoByDomain get address info from dns by domain func (c *NameServiceClient) GetDomainInfoByDomain(domainName string) ([]DomainInfo, error) { var res DomainRes diff --git a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQLProxy_switch.go b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQLProxy_switch.go index 570c7d302c..324c82cd83 100644 --- a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQLProxy_switch.go +++ b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQLProxy_switch.go @@ -22,8 +22,20 @@ func (ins *MySQLProxySwitch) CheckSwitch() (bool, error) { // DoSwitch mysql-proxy do switch // delete ip under the entry func (ins *MySQLProxySwitch) DoSwitch() error { - ins.ReportLogs(constvar.InfoResult, fmt.Sprintf("try to release ip[%s] from all cluster entery", ins.Ip)) - return ins.DeleteNameService(ins.Entry) + //1. delete name service + isSingle, err := ins.SingleAddressUnderDomain(ins.Entry) + if err != nil { + ins.ReportLogs(constvar.FailResult, fmt.Sprintf("check whether single address under domain failed:%s", + err.Error())) + return err + } + if isSingle { + return fmt.Errorf("only single address under this domain, skip release domain") + } else { + ins.ReportLogs(constvar.InfoResult, fmt.Sprintf("try to release ip[%s#%d] from all cluster entry", + ins.Ip, ins.Port)) + return ins.DeleteNameService(ins.Entry) + } } // ShowSwitchInstanceInfo display switch proxy info diff --git a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQL_common_switch.go b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQL_common_switch.go index cc77dba67b..972d42f098 100644 --- a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQL_common_switch.go +++ b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/MySQL_common_switch.go @@ -826,8 +826,8 @@ func (ins *SpiderCommonSwitch) RemoveNodeFromRoute(primaryConn *sql.DB, host str // GetPrimary found primary node from any connected tdbctl node's route table // If no primary found, return error. // Any blow condition could get primary success -// 1. There is only one node: PrimaryRole, StatusOnline -// 2. No primary role found, and all alive SecondaryRole node's ReplicationMaster are the same, +// 1) There is only one node: PrimaryRole, StatusOnline +// 2) No primary role found, and all alive SecondaryRole node's ReplicationMaster are the same, // then thought the ReplicationMaster must be the Primary node's ServerName func (ins *SpiderCommonSwitch) GetPrimary() error { replicaServer := "" diff --git a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/SpiderProxyLayer_switch.go b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/SpiderProxyLayer_switch.go index 69fb81488e..8c902b2340 100644 --- a/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/SpiderProxyLayer_switch.go +++ b/dbm-services/common/dbha/ha-module/dbmodule/dbmysql/SpiderProxyLayer_switch.go @@ -211,11 +211,21 @@ func (ins *SpiderProxyLayerSwitch) DoSwitch() error { ) //1. delete name service - ins.ReportLogs(constvar.InfoResult, fmt.Sprintf("try to release ip[%s#%d] from all domain entry", - ins.Ip, ins.Port)) - if err := ins.DeleteNameService(ins.Entry); err != nil { + isSingle, err := ins.SingleAddressUnderDomain(ins.Entry) + if err != nil { + ins.ReportLogs(constvar.FailResult, fmt.Sprintf("check whether single address under domain failed:%s", + err.Error())) return err } + if isSingle { + return fmt.Errorf("only single address under this domain, skip release domain") + } else { + ins.ReportLogs(constvar.InfoResult, fmt.Sprintf("try to release ip[%s#%d] from all domain entry", + ins.Ip, ins.Port)) + if err := ins.DeleteNameService(ins.Entry); err != nil { + return err + } + } //2. set all spider nodes if err := ins.SetSpiderNodes(); err != nil { diff --git a/dbm-services/common/dbha/ha-module/dbutil/db_switch.go b/dbm-services/common/dbha/ha-module/dbutil/db_switch.go index d067aba9b3..d28e63457d 100644 --- a/dbm-services/common/dbha/ha-module/dbutil/db_switch.go +++ b/dbm-services/common/dbha/ha-module/dbutil/db_switch.go @@ -184,6 +184,30 @@ func (ins *BaseSwitch) GetInfo(infoKey string) (bool, interface{}) { } } +// SingleAddressUnderDomain check whether only one address under domain +// if only one address under dns entry, return true +// if no dns entry found, return false +func (ins *BaseSwitch) SingleAddressUnderDomain(entry BindEntry) (bool, error) { + if entry.Dns == nil { + return false, nil + } + conf := ins.Config + dnsClient := client.NewNameServiceClient(&conf.NameServices.DnsConf, conf.GetCloudId()) + for _, dns := range entry.Dns { + number, err := dnsClient.GetAddressNumberByDomain(dns.DomainName) + if err != nil { + return false, err + } + ins.ReportLogs(constvar.InfoResult, fmt.Sprintf("found %d address under domain %s", + number, dns.DomainName)) + if number == 1 { + return true, nil + } + } + + return false, nil +} + // DeleteNameService delete broken-down ip from entry func (ins *BaseSwitch) DeleteNameService(entry BindEntry) error { //flag refer to whether release name-service success