github.com/xiyichan/dm8@v0.0.0-20211213021639-be727be3e136/zv.go (about) 1 /* 2 * Copyright (c) 2000-2018, 达梦数据库有限公司. 3 * All rights reserved. 4 */ 5 6 package dm 7 8 import ( 9 "math/rand" 10 "strconv" 11 "time" 12 ) 13 14 var rwMap = make(map[string]*rwCounter) 15 16 type rwCounter struct { 17 ntrx_primary int64 18 19 ntrx_total int64 20 21 primaryPercent float64 22 23 standbyPercent float64 24 25 standbyNTrxMap map[string]int64 26 27 standbyCount int 28 } 29 30 func newRWCounter(primaryPercent int, standbyCount int) *rwCounter { 31 rwc := new(rwCounter) 32 rwc.reset(primaryPercent, standbyCount) 33 return rwc 34 } 35 36 func (rwc *rwCounter) reset(primaryPercent int, standbyCount int) { 37 rwc.ntrx_primary = 0 38 rwc.ntrx_total = 0 39 rwc.standbyNTrxMap = make(map[string]int64) 40 rwc.standbyCount = standbyCount 41 if standbyCount > 0 { 42 rwc.primaryPercent = float64(primaryPercent) / 100.0 43 rwc.standbyPercent = float64(100-primaryPercent) / 100.0 / float64(standbyCount) 44 } else { 45 rwc.primaryPercent = 1 46 rwc.standbyPercent = 0 47 } 48 } 49 50 /** 51 * 连接创建成功后调用,需要服务器返回standbyCount 52 */ 53 func getRwCounterInstance(conn *DmConnection) *rwCounter { 54 key := conn.dmConnector.host + "_" + strconv.Itoa(conn.dmConnector.port) + "_" + strconv.Itoa(conn.dmConnector.rwPercent) 55 56 rwc, ok := rwMap[key] 57 if !ok { 58 rwc = newRWCounter(conn.dmConnector.rwPercent, int(conn.StandbyCount)) 59 rwMap[key] = rwc 60 } else if rwc.standbyCount != int(conn.StandbyCount) { 61 rwc.reset(conn.dmConnector.rwPercent, int(conn.StandbyCount)) 62 } 63 return rwc 64 } 65 66 /** 67 * @return 主机; 68 */ 69 func (rwc *rwCounter) countPrimary() RWSiteEnum { 70 rwc.adjustNtrx() 71 rwc.ntrx_primary++ 72 rwc.ntrx_total++ 73 return PRIMARY 74 } 75 76 /** 77 * @param dest 主机; 备机; any; 78 * @return 主机; 备机 79 */ 80 func (rwc *rwCounter) count(dest RWSiteEnum, standby *DmConnection) RWSiteEnum { 81 rwc.adjustNtrx() 82 switch dest { 83 case ANYOF: 84 { 85 if rwc.primaryPercent != 1 && (rwc.primaryPercent == 0 || float64(rwc.getStandbyNtrx(standby)) < float64(rwc.ntrx_total)*rwc.standbyPercent || float64(rwc.ntrx_primary) > float64(rwc.ntrx_total)*rwc.primaryPercent) { 86 rwc.incrementStandbyNtrx(standby) 87 dest = STANDBY 88 } else { 89 rwc.ntrx_primary++ 90 dest = PRIMARY 91 } 92 } 93 case STANDBY: 94 { 95 rwc.incrementStandbyNtrx(standby) 96 } 97 case PRIMARY: 98 { 99 rwc.ntrx_primary++ 100 } 101 } 102 103 rwc.ntrx_total++ 104 return dest 105 } 106 107 /** 108 * 防止ntrx超出有效范围,等比调整 109 */ 110 func (rwc *rwCounter) adjustNtrx() { 111 if rwc.ntrx_total < INT64_MAX { 112 return 113 } 114 115 var min int64 116 i := 0 117 for _, value := range rwc.standbyNTrxMap { 118 if i == 0 { 119 min = value 120 } else { 121 if value < min { 122 min = value 123 } 124 } 125 i++ 126 } 127 128 if min >= rwc.ntrx_primary { 129 min = rwc.ntrx_primary 130 } 131 132 rwc.ntrx_primary = rwc.ntrx_primary / min 133 rwc.ntrx_total = rwc.ntrx_total / min 134 135 for key, value := range rwc.standbyNTrxMap { 136 rwc.standbyNTrxMap[key] = value / min 137 } 138 139 } 140 141 func (rwc *rwCounter) getStandbyNtrx(standby *DmConnection) int64 { 142 key := standby.dmConnector.host + ":" + strconv.Itoa(standby.dmConnector.port) 143 ret, ok := rwc.standbyNTrxMap[key] 144 if !ok { 145 ret = 0 146 } 147 148 return ret 149 } 150 151 func (rwc *rwCounter) incrementStandbyNtrx(standby *DmConnection) { 152 key := standby.dmConnector.host + ":" + strconv.Itoa(standby.dmConnector.port) 153 ret, ok := rwc.standbyNTrxMap[key] 154 if ok { 155 ret += 1 156 } else { 157 ret = 1 158 } 159 rwc.standbyNTrxMap[key] = ret 160 } 161 162 func (rwc *rwCounter) random(rowCount int) int { 163 rand.Seed(time.Now().UnixNano()) 164 return int(rand.Int31n(int32(rowCount))) 165 } 166 167 func (rwc *rwCounter) String() string { 168 return "PERCENT(P/S) : " + strconv.FormatFloat(rwc.primaryPercent, 'f', -1, 64) + "/" + strconv.FormatFloat(rwc.standbyPercent, 'f', -1, 64) + "\nNTRX_PRIMARY : " + 169 strconv.FormatInt(rwc.ntrx_primary, 10) + "\nNTRX_TOTAL : " + strconv.FormatInt(rwc.ntrx_total, 10) + "\nNTRX_STANDBY : " 170 }