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  }