WL#13327: Accept connections only if destinations are available

Affects: Server-8.0   —   Status: Complete

Motivation

Currently MySQL Router binds to the incoming socket at startup and keeps it open unconditionally.

That makes Load-Balancers believe that Router is able to handle traffic and forward MySQL connections to Router which will fail as if no destinations are available.

Goal

  • Only bind to the sockets if destinations are available.
  • Close incoming socket if no destinations are available (e.g. quorum is lost)

The destination of a route is considered invalid when Router either cannot determine a destination or cannot contact it. A routing strategy provides a set of valid destinations based on list of potential destinations and their availablity; this set is evaluated for each route separately. In case of static routing, the list of potential destinations is defined in configuration file and availability is determined by Routing Plugin as it tries to establish client connections. In case of InnoDB Cluster routing, the list of potential destinations is provided by cluster's metadata and availability is determined by MD Cache Plugin using various rules (i.e. quorum, whether a node is in ONLINE state, whether a node is hidden, etc); note that MD Refresh failure results in an empty list of potential destinations.

FR1
if a route has a non-empty set of valid destinations and its listening port is closed, its listening port MUST be opened.
FR2
if a route has an empty set of valid destinations and its listening port is open, its listening port MUST be closed.
FR3
if router fails to open a listening socket at startup, it MUST shutdown.
FR4
if router fails to open a listening socket after startup was finished, it MUST retry to open the listening socket.
FR5
retry on a listening socket open operation MUST be done until it succeeds, with an implementation defined retry interval.
NR1
a connection to a valid destination MAY fail.
NR2
when a valid destinations changes is implementation dependent.

Connection handling

Currently Router opens its listening sockets when it starts and they are kept open until Router shuts down. That could be misleading for external applications that may assume that they can forward traffic even though Router may not have any destinations on its part. To avoid that listening socket MUST be shut down if there are no valid destinations. New connections MUST NOT be accepted if there are no valid destinations. If any destination starts to be valid again then listening socket MUST be opened and new connections MUST be accepted. If socket cannot be reopened then a proper error message MUST be logged and the socket SHOULD be reopened on a next possible occasion.

Dynamic routing

Routing destination is not valid when when the destination node information is missing from the metadata. If a socket cannot be opened then it should be reopened on a next MetaData refresh.

Metadata unavailable

Client connections MUST be closed when the group is overloaded and when the disconnect_on_metadata_unavailable option is set to true. If the group is overloaded and disconnect_on_metadata_unavailable is set to false then any of the existing connections MUST NOT be closed.

disconnect_on_metadata_unavailable is not a new feature introduced in this worklog.

Static routing

Depending on the routing policy listening sockets are handled in the following way:

  1. first-available - listening socket CANNOT be closed in this case.
  2. next-available - if there are no destinations that could be connected by the Router then listening socket MUST be closed. If listening socket is closed then it is not possible to reopen it.
  3. round-robin - if there are no destinations that could be connected by the Router then listening socket MUST be closed. If any of the destinations could be connected again then listening socket MUST be opened. If the socket cannot be reopened then it SHOULD be reopened when any of the destinations become connectible again.

Note: in case of static routing destination information is obtained on accepting new connections.

Hidden instances

Routing destination is not valid when the instance is hidden. Router can be instructed to disconnect existing connections to instances that are marked to be hidden by using the disconnect_existing_sessions_when_hidden option. In case when there are no valid destinations left and some nodes are marked as hidden then there are two cases:

  1. disconnect_existing_sessions_when_hidden=true - existing connections MUST be disconnected.

  2. disconnect_existing_sessions_when_hidden=false - existing connections MUST NOT be disconnected.

disconnect_existing_sessions_when_hidden is not a new feature introduced in this worklog.

Routing policies

If there are no valid destinations for the read-only routing then:

  • if the routing policy allows to do the fallback to the primary node and there are existing destinations for the primary then listening read-only socket MUST NOT be closed.
  • if the routing policy allows to do the fallback to the primary node but there are no existing destinations for the primary then listening read-only socket MUST be closed.
  • if the routing policy do not allow to do the fallback to the primary node then listening read-only socket MUST be closed.

If there are no valid destinations for the read-write routing then the corresponding Router listening read-write socket MUST be closed.

Valid destinations update summary based on destination-class

Policy Valid destinations update: Retry:
metadata-cache metadata cache update metadata refresh (ttl)
round-robin failed connect 3s timeout
first-available never N/A
next-available failed connect never