WL#16520: InnoDB: Allow clone from one LTS version to the next

Affects: Server-9.x   —   Status: Complete

This worklog proposes to relax the server version restriction of Clone to allow support for cases which are supported by in-place Upgrade but not the cases supported by in-place downgrade. The proposal is to handle the below cases appropriately:

  1. Cloning within LTS releases (for example 9.7.x to 9.7.y) is supported
  2. Cloning from one LTS to next LTS (for example from 9.7.x to 10.7.y) is supported,
  3. Cloning from one LTS to later (not the immediate next) LTS (for example from 9.7.x to 11.7.y) is not supported
  4. Cloning from a higher LTS source to a lower LTS recipient (for example from 10.7.x to 9.7.y) is not supported
  5. These changes are only applicable for 9.7 and above

For example,

  1. Cloning from 9.7.x to 9.7.y is supported
  2. Cloning from 9.7.x to 10.7.y (assume LTS) and 10.7.y to 11.7.z (assume LTS) is supported
  3. Cloning from 10.7.x (assume LTS) to 9.7.y is not supported
  4. Cloning from 9.7.x to 11.7.y (assume LTS) and vice versa are not supported
  5. Cloning from 9.7.x to any lower version (like 8.4.y or 9.z, z < 7) is not supported
  6. Cloning from any lower version (like 8.x.y or 9.z, z < 7) to 9.7.x is not supported

Clone creates a dynamic physical snapshot of a running server instance (source) and recover (recipient) from the snapshot using regular recovery. It has dependency on the physical format of the data and logs. Hence, cloning was restricted to scenarios where both source and target are on the same server version.

Since any change in physical format is backward compatible with the previous LTS, Clone can relax the restriction to allow Cloning to the next LTS.

Functional Requirements

FR-1: Cloning from the source in one LTS to the replica in the next LTS must be permitted only when the source is in 9.7 LTS or above. For example, cloning must be permitted in the following cases: + From 9.7.x to 10.7.y + From 10.7.x to 11.7.y (assuming 11.7 is LTS series) And, cloning must not be permitted in the following cases: - From 8.4.x to 9.7.y - From 8.0.x to 8.4.y

FR-2: Cloning from the source in one LTS to the replica in any later LTS must not be permitted. For example, cloning must not be permitted in the following cases: - From 9.7.x to 11.7.y (assuming 11.7 is LTS series) - From 8.0.x to 9.7.y

FR-3: Cloning from the source in one LTS to the replica in any lower LTS must not be permitted. For example, cloning must not be permitted in the following cases: - From 9.7.x to 8.4.y - From 8.4.x to 8.0.y - From 10.7.x to 8.4.y - From 10.7.x to 9.7.y

FR-4: Cloning must not be permitted if source or replica is not LTS and their Major and/or Minor versions mismatch. For example, cloning must not be permitted in the following cases: - From 9.7.x to 10.0.y - From 10.4.x to 10.7.y

Background

During clone, the source sends the predetermined set of configurations to the replica. The replica then validates the configurations from the source against its own configurations to determine if clone can be permitted. These configurations are system variables read from the server using the sysvar service. The system variable version is used to determine the MySQL server version.

Prerequisites

Clone must know if a given version is Long Term Stability (LTS) or Innovation release (IR). This is required to reject Clone when Major/Minor do not match and either source or replica is not an LTS. This information can be accessed by Clone plugin using MYSQL_VERSION_MATURITY macro which is created during the build process. This information must be passed by the source to the replica.

Clone treats each configuration as independent from the other when the replica checks configurations against the source. This worklog requires a change in this mechanism as the version and maturity configurations must be considered together when deciding if clone is permitted.

Clone is currently in CLONE_PROTOCOL_VERSION = CLONE_PROTOCOL_VERSION_V3. To transfer the new information, the protocol version will need to bumped and the new protocol must be supported by both the source and replica. Further, the replica must continue to support older protocol version for backward compatibility with older source (like 9.6.0).

Proposed implementation

The source sends an additional configuration "maturity" with the value same as the macro MYSQL_VERSION_MATURITY ("LTS" or "INNOVATION"). The replica parses this value to determine if the source is in LTS or not.

To process version and maturity in parallel, both these configurations are packed into a JSON string:

  1. Source
    1. Creates a JSON document with configuration 'name' and 'value' stored as key-value pairs for both version and maturity
    2. Serializes the JSON into a string and sends the string to the replica
  2. Replica
    1. Creates a JSON document with same format
    2. Receives, de-serializes and parses the source's JSON string into a JSON document
    3. Populates its own JSON document using the sysvar reader service and MYSQL_VERSION_MATURITY
    4. Runs the check using the sources' and replicas' JSON documents.

Clone Protocol version is bumped to CLONE_PROTOCOL_VERSION_V4 and new response command COM_RES_CONFIG_V4 is introduced. The COM_RES_CONFIG_V4 is used to send, receive and process the JSON document. To ensure backward compatibility, existing mechanism is reused when processing any lower protocol version.

JSON Document

The JSON Document is implemented using the extra::rapidjson library.

Source

  1. The clone source (Server class) reads the required configurations using sysvar-reader service.
  2. The clone source adds the configuration "maturity" using MYSQL_VERSION_MATURITY.
  3. Each configuration is encoded as a JSON Object containing Key-Value pairs (key being config-name and Value being config-value).
  4. The source adds each Object to the JSON Document.
  5. It converts this document into a string and sends it to the replica.

Replica

  1. The replica creates a JSON Document during initialization.
  2. As it receives each configuration sent by previous protocol version, it creates respective Objects containing Key-Value pairs (key being config-name and Value being config-value).
  3. When processing COM_RES_CONFIG_V4, the JSON string received is directly converted into the source's JSON document. Each of the Object in the source's document is then added to the replica's JSON document.
  4. When validating the configurations, the replica creates another JSON document and populates it using it's own configuration values.
  5. Both the documents are compared with respect to the Functional Requirements.

Check if Clone is permitted

Checks done by in-place upgrade is duplicated and called only when the MAJOR and MINOR versions mismatch when comparing clone version. Thus, the function are_versions_clone_compatible must be modified to work with not only version, but also version maturity:

  backport_version = 9.7.0

  are_version_clone_compatible:
    if (replica == source)
      return true;

    else if (replica[MAJOR] == source[MAJOR] &&
             replica[MINOR] == source[MINOR])
      return true;

    else if (replica[MAJOR] != source[MAJOR]) {
      if (replica < source)
        // FR-3: Downgrade not supported
        return false;

      else if (replica < backport_version || source < backport_version)
        // FR-1: Supported only from 9.7 and above
        return false;

      else if (!is_replica_LTS || !is_source_LTS)
        // FR-4: Major mismatch and source/replica is not LTS
        return false;

      else if (replica[MAJOR] != source[MAJOR] + 1)
        // FR-2: Upgrade to later LTS is not supported
        return false;

      // FR-1: Supported from one LTS to next
      return true;
    }
    else if (replica[MINOR] != source[MINOR]) {
      // FR-5: Not supported against Innovation
      return false;
    }
    else
      return true;