vitess.io/vitess@v0.16.2/go/vt/vtorc/inst/resolve_dao.go (about) 1 /* 2 Copyright 2014 Outbrain Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package inst 18 19 import ( 20 "github.com/rcrowley/go-metrics" 21 22 "vitess.io/vitess/go/vt/external/golib/sqlutils" 23 24 "vitess.io/vitess/go/vt/log" 25 "vitess.io/vitess/go/vt/vtorc/config" 26 "vitess.io/vitess/go/vt/vtorc/db" 27 ) 28 29 var writeResolvedHostnameCounter = metrics.NewCounter() 30 var writeUnresolvedHostnameCounter = metrics.NewCounter() 31 var readResolvedHostnameCounter = metrics.NewCounter() 32 var readUnresolvedHostnameCounter = metrics.NewCounter() 33 var readAllResolvedHostnamesCounter = metrics.NewCounter() 34 35 func init() { 36 _ = metrics.Register("resolve.write_resolved", writeResolvedHostnameCounter) 37 _ = metrics.Register("resolve.write_unresolved", writeUnresolvedHostnameCounter) 38 _ = metrics.Register("resolve.read_resolved", readResolvedHostnameCounter) 39 _ = metrics.Register("resolve.read_unresolved", readUnresolvedHostnameCounter) 40 _ = metrics.Register("resolve.read_resolved_all", readAllResolvedHostnamesCounter) 41 } 42 43 // WriteResolvedHostname stores a hostname and the resolved hostname to backend database 44 func WriteResolvedHostname(hostname string, resolvedHostname string) error { 45 writeFunc := func() error { 46 _, err := db.ExecVTOrc(` 47 insert into 48 hostname_resolve (hostname, resolved_hostname, resolved_timestamp) 49 values 50 (?, ?, NOW()) 51 on duplicate key update 52 resolved_hostname = VALUES(resolved_hostname), 53 resolved_timestamp = VALUES(resolved_timestamp) 54 `, 55 hostname, 56 resolvedHostname) 57 if err != nil { 58 log.Error(err) 59 return err 60 } 61 if hostname != resolvedHostname { 62 // history is only interesting when there's actually something to resolve... 63 _, _ = db.ExecVTOrc(` 64 insert into 65 hostname_resolve_history (hostname, resolved_hostname, resolved_timestamp) 66 values 67 (?, ?, NOW()) 68 on duplicate key update 69 hostname=values(hostname), 70 resolved_timestamp=values(resolved_timestamp) 71 `, 72 hostname, 73 resolvedHostname) 74 } 75 writeResolvedHostnameCounter.Inc(1) 76 return nil 77 } 78 return ExecDBWriteFunc(writeFunc) 79 } 80 81 // ReadResolvedHostname returns the resolved hostname given a hostname, or empty if not exists 82 func ReadResolvedHostname(hostname string) (string, error) { 83 var resolvedHostname string 84 85 query := ` 86 select 87 resolved_hostname 88 from 89 hostname_resolve 90 where 91 hostname = ? 92 ` 93 94 err := db.QueryVTOrc(query, sqlutils.Args(hostname), func(m sqlutils.RowMap) error { 95 resolvedHostname = m.GetString("resolved_hostname") 96 return nil 97 }) 98 readResolvedHostnameCounter.Inc(1) 99 100 if err != nil { 101 log.Error(err) 102 } 103 return resolvedHostname, err 104 } 105 106 func ReadAllHostnameResolves() ([]HostnameResolve, error) { 107 res := []HostnameResolve{} 108 query := ` 109 select 110 hostname, 111 resolved_hostname 112 from 113 hostname_resolve 114 ` 115 err := db.QueryVTOrcRowsMap(query, func(m sqlutils.RowMap) error { 116 hostnameResolve := HostnameResolve{hostname: m.GetString("hostname"), resolvedHostname: m.GetString("resolved_hostname")} 117 118 res = append(res, hostnameResolve) 119 return nil 120 }) 121 readAllResolvedHostnamesCounter.Inc(1) 122 123 if err != nil { 124 log.Error(err) 125 } 126 return res, err 127 } 128 129 // ExpireHostnameUnresolve expires hostname_unresolve entries that haven't been updated recently. 130 func ExpireHostnameUnresolve() error { 131 writeFunc := func() error { 132 _, err := db.ExecVTOrc(` 133 delete from hostname_unresolve 134 where last_registered < NOW() - INTERVAL ? MINUTE 135 `, config.ExpiryHostnameResolvesMinutes, 136 ) 137 if err != nil { 138 log.Error(err) 139 } 140 return err 141 } 142 return ExecDBWriteFunc(writeFunc) 143 } 144 145 // ForgetExpiredHostnameResolves 146 func ForgetExpiredHostnameResolves() error { 147 _, err := db.ExecVTOrc(` 148 delete 149 from hostname_resolve 150 where 151 resolved_timestamp < NOW() - interval ? minute`, 152 2*config.ExpiryHostnameResolvesMinutes, 153 ) 154 return err 155 } 156 157 // DeleteInvalidHostnameResolves removes invalid resolves. At this time these are: 158 // - infinite loop resolves (A->B and B->A), remove earlier mapping 159 func DeleteInvalidHostnameResolves() error { 160 var invalidHostnames []string 161 162 query := ` 163 select 164 early.hostname 165 from 166 hostname_resolve as latest 167 join hostname_resolve early on (latest.resolved_hostname = early.hostname and latest.hostname = early.resolved_hostname) 168 where 169 latest.hostname != latest.resolved_hostname 170 and latest.resolved_timestamp > early.resolved_timestamp 171 ` 172 173 err := db.QueryVTOrcRowsMap(query, func(m sqlutils.RowMap) error { 174 invalidHostnames = append(invalidHostnames, m.GetString("hostname")) 175 return nil 176 }) 177 if err != nil { 178 return err 179 } 180 181 for _, invalidHostname := range invalidHostnames { 182 _, err = db.ExecVTOrc(` 183 delete 184 from hostname_resolve 185 where 186 hostname = ?`, 187 invalidHostname, 188 ) 189 if err != nil { 190 log.Error(err) 191 } 192 } 193 return err 194 } 195 196 // writeHostnameIPs stroes an ipv4 and ipv6 associated witha hostname, if available 197 func writeHostnameIPs(hostname string, ipv4String string, ipv6String string) error { 198 writeFunc := func() error { 199 _, err := db.ExecVTOrc(` 200 insert into 201 hostname_ips (hostname, ipv4, ipv6, last_updated) 202 values 203 (?, ?, ?, NOW()) 204 on duplicate key update 205 ipv4 = VALUES(ipv4), 206 ipv6 = VALUES(ipv6), 207 last_updated = VALUES(last_updated) 208 `, 209 hostname, 210 ipv4String, 211 ipv6String, 212 ) 213 if err != nil { 214 log.Error(err) 215 } 216 return err 217 } 218 return ExecDBWriteFunc(writeFunc) 219 }