WL#17019: MRS Server Component - Add UDFs and Configuration Interfaces

Affects: MySQL-Router-26.x   —   Status: Complete

Background

The initial implementation of the MySQL REST Service (MRS) as a server component introduced an embedded runtime with hardcoded defaults (WL#17018). While suitable for early experimentation and standalone use cases, it lacks support for runtime configurability and operational introspection.

This WorkLog builds upon the foundational component by introducing UDFs (User Defined Functions), system variables, and status variables to enable dynamic control and monitoring of the MRS Component.

Motivation

Adding runtime configurability and observability enhances the usability and manageability of the MRS component:

  • Enable configuration: View and adjust runtime settings such as HTTP port, SSL, resource limits, and others.
  • Enable control: Start, stop, and restart the REST service without restarting the MySQL Server.
  • Enable observability: Monitor the REST service status using SHOW STATUS and component-specific metrics.

User Stories

  • As a DBA, I want to configure my REST service to match the environment (dev/test/prod), so that it runs with the correct database connections and settings.
  • As a DBA, I want to control the MRS backend without restarting the MySQL server.
  • As a DBA, I want to monitor and observe the MRS component status.
  • As a DBA, I want to manage the REST service lifecycle using SQL UDFs.

Summary

This WorkLog introduces:

  • A set of system variables to configure the service:

    • mysql_rest_service.http_port
    • mysql_rest_service.ssl_cert
    • mysql_rest_service.ssl_key
    • mysql_rest_service.ssl_cipher
    • mysql_rest_service.io_worker_threads
    • mysql_rest_service.http_max_connections
    • mysql_rest_service.http_max_request_body_size
    • mysql_rest_service.http_max_response_body_size
  • Status variables to monitor active runtime values and component state:

    • mysql_rest_service.current_http_port
    • mysql_rest_service.current_tls_cert
    • mysql_rest_service.current_tls_key
    • mysql_rest_service.current_tls_cipher
    • mysql_rest_service.current_io_worker_threads
    • mysql_rest_service.state
  • UDFs for controlling the service lifecycle:

    • mysql_rest_service_start()
    • mysql_rest_service_stop()
    • mysql_rest_service_restart()

Functional Requirements

  • FR1: Installation of the MySQL REST Service (MRS) component must register a new dynamic privilege named MYSQL_REST_SERVICE_ADMIN.

    • FR1.1: Execution of MRS lifecycle UDFs must require MYSQL_REST_SERVICE_ADMIN. Changes to MRS system variables must follow the normal MySQL Server privilege requirements for global and persisted system variables.
  • FR2: Installation of the MRS component must expose configuration parameters through system variables.

    • FR2.1: System variables must be dynamic, support persistence (SET PERSIST), and apply according to their documented runtime or component-start/restart application mode.

    • FR2.2: Invalid configuration values must be rejected when applied, with clear, descriptive error messages. Values written through SET PERSIST_ONLY follow native Server semantics and undergo component-specific validation when the persisted value is loaded.

    • FR2.3: The system variable interface must expose resource-governance controls for the embedded MRS runtime, including worker-thread count, HTTP connection limit, and request-body and response-body size limits.

    • FR2.4: The system variable interface must map resource-governance values to the underlying embedded Router and MRS subsystems without requiring manual editing of Router configuration files.

    • FR2.5: Changes to the three HTTP-limit system variables must be applied to a running HTTP server through the runtime override interface without restarting MRS.

    • FR2.6: The system-variable interface must expose the certificate chain, private key, and TLS 1.2 cipher list used by the MRS HTTP listener.

    • FR2.7: TLS configuration changes must apply only to a newly created MRS TLS context during component start or restart. They must not modify the MySQL main or administrative TLS contexts, and reloading either Server TLS context must not implicitly reload the MRS TLS context.

  • FR3: Installation of the MRS component must expose observability parameters through status variables.

    • FR3.1: Status variables must expose current runtime values and the operational state of the component.

    • FR3.2: The operational state must distinguish stopped, starting, waiting for required metadata, ready, stopping, and fatal backend failure.

    • FR3.3: Global status variables must expose the HTTP port bound by the active listener, the certificate and key paths and TLS 1.2 cipher-list policy loaded by the active TLS context, and the resolved active IO worker-thread count. Updating a corresponding configured system variable must not change the current status value; the newly configured value is applied only by a successful component start or restart. When no backend is active, the status variables must expose their documented inactive values.

    • FR3.4: The operational state must report the lifecycle of the embedded MRS backend. It must not expose internal startup stages or represent individual metadata-definition, metadata-reload, or HTTP-request failures.

  • FR4: Installation of the MRS component must register user-defined functions (UDFs) to control the component lifecycle.

    • FR4.1: UDFs must support asynchronous start/restart and synchronous stop, returning 0 on immediate success and raising a SQL error on failure.

    • FR4.2: Lifecycle operations must be serialized. Start and stop must be idempotent. Final completion of asynchronous start and restart must be reported through the component state and server log.

    • FR4.3: Once component uninstallation or MySQL Server shutdown begins, pending and new lifecycle UDF calls must fail without starting or restarting the MRS backend.

    • FR4.4: Before any lifecycle side effect, a lifecycle UDF must reject the invocation unless the current SQL command is SELECT and the caller THD is not executing a Server substatement, including a stored function or trigger.

  • FR5: Uninstallation of the MRS component must unregister all system variables, status variables, UDFs, and the dynamic privilege registered during installation.

Non-Functional Requirements

  • NFR1: The component must comply with the MySQL Server Component API conventions for registering privileges, sysvars, statusvars, and UDFs.

  • NFR2: Registration and deregistration must not affect overall server performance or stability.

  • NFR3: Startup failures, fatal runtime failures, metadata refresh or validation failures, privilege issues, and unexpected request-processing errors must produce clear, actionable MySQL Server log output. Diagnostic information must remain available when the MRS metadata schema cannot be written.

  • NFR4: Lifecycle operations, runtime configuration updates, and publication of current runtime values must be thread-safe and protected against concurrent access.

  • NFR5: The component must be compatible with all MySQL-supported platforms.

  • NFR6: The MRS HTTP listener must not negotiate a protocol version or cipher outside the TLS policy successfully applied during its most recent start or restart.

  • NFR7: MySQL sessions and associated THDs created by MRS for data-plane work, including REST request execution, must count toward and be subject to the Server-wide @@max_connections limit. WL#17019 does not introduce a separate MRS-specific MySQL session limit.

    • NFR7.1: Only a bounded set of metadata control-plane sessions required for component bootstrap, metadata readiness, and metadata schema monitoring or reload may use an administrative session path that is immune to @@max_connections. The exception must not extend to REST request execution, user-defined endpoint work, or supplementary logging and statistics.

    • NFR7.2: A connection-admission exemption must not grant additional SQL privileges. Each exempt session must continue to use the security context and privileges assigned to that operation by WL#17018.

  • NFR8: The design must allow future extension with additional configuration variables, status metrics, or lifecycle functions.

Dynamic Privilege

Upon installation, the component registers a new dynamic privilege:

  • Name: MYSQL_REST_SERVICE_ADMIN
  • Description: Grants permission to control the lifecycle of the MySQL REST Service component.

Privilege Enforcement

Lifecycle UDFs obtain the current thread's security context and verify MYSQL_REST_SERVICE_ADMIN through global_grants_check at execution entry, before any lifecycle side effect. Failure to obtain the security context or verify the grant fails closed with an access-denied error naming MYSQL_REST_SERVICE_ADMIN.

Changes to MRS system variables follow the normal MySQL Server privilege requirements for global and persisted system variables. Additional component-specific privilege enforcement for system-variable changes is deferred until the Server can enforce it consistently across all supported assignment, persistence, DEFAULT, and RESET PERSIST forms.

System Variables

(Implements FR2, NFR1)

All system variables are dynamic and GLOBAL in scope. They support SET PERSIST for persistent configuration.

+------------------------------------------------------------------------------------------------------------------------------------+
| Name                                  | Type     | Scope  | Dynamic | Default                                      | Apply         |
|---------------------------------------|----------|--------|---------|----------------------------------------------|---------------|
| http_port                             | LONG     | GLOBAL | YES     | 33443                                        | START/RESTART |
| ssl_cert                              | STRING   | GLOBAL | YES     | @@ssl_cert                                   | START/RESTART |
| ssl_key                               | STRING   | GLOBAL | YES     | @@ssl_key                                    | START/RESTART |
| ssl_cipher                            | STRING   | GLOBAL | YES     | @@ssl_cipher, or Router default if empty     | START/RESTART |
| io_worker_threads                     | LONG     | GLOBAL | YES     | 0                                            | START/RESTART |
| http_max_connections                  | LONG     | GLOBAL | YES     | 1024                                         | RUNTIME       |
| http_max_request_body_size            | LONGLONG | GLOBAL | YES     | 16777216                                     | RUNTIME       |
| http_max_response_body_size           | LONGLONG | GLOBAL | YES     | 16777216                                     | RUNTIME       |
+------------------------------------------------------------------------------------------------------------------------------------+

Validation and Constraints

  • General Rules

    • All variables are dynamic.
    • SET GLOBAL and SET PERSIST update the configured value and apply it according to the variable's documented apply mode.
    • Runtime-applied HTTP-limit variables are applied to a running HTTP server through the runtime override interface. If the backend is not running, their configured values are used at the next start.
    • Start/restart-applied variables do not change the running backend. They are captured by the next successful component start or restart.
    • SET PERSIST_ONLY and RESET PERSIST do not change the current configured value or the running backend. Their effect becomes visible when persisted configuration is reloaded during server restart or component re-registration.
    • System variables expose configured values. The current_* status variables expose values used by the active backend and remain unchanged when only configured start/restart values are updated.
    • Values applied through SET GLOBAL or SET PERSIST are validated at assignment time. Constraints requiring backend resources, such as the ability to bind the configured port, are validated during the next backend start attempt, whether initiated by component installation, loading during server startup, or a start/restart UDF.
    • Component-specific validation of SET PERSIST_ONLY values occurs when persisted configuration is loaded. An invalid value remains unapplied and is reported in the server log.
    • Changes to MRS system variables follow the corresponding normal MySQL Server privilege requirements; WL#17019 does not impose an additional component-specific privilege check.
    • Negative values are rejected for all resource-control sysvars.
  • http_port

Used to configure the MySQL REST Service HTTP Port.

  • Accepts integer values from 1–65535.
  • Defaults to 33443.
  • The ability to bind the configured port is validated during each backend start attempt.
  • Changes take effect when the component starts or restarts.

TLS Listener Configuration

The following system variables configure the TLS context owned by the MySQL REST Service HTTP listener. This context is separate from the MySQL main and administrative protocol-channel TLS contexts.

  • ssl_cert / ssl_key

Used to configure the MRS certificate-chain file and private-key file.

  • Default to @@ssl_cert and @@ssl_key.
  • Explicit assignments of empty certificate or key values are rejected.
  • If an inherited Server value is empty, component registration succeeds, but asynchronous backend startup fails as described by WL#17018.
  • Relative paths are interpreted relative to @@datadir, consistent with the MySQL Server TLS-file convention. Absolute paths are used unchanged.
  • current_tls_cert and current_tls_key report the path values applied to the active listener; they are not canonicalized.
  • ssl_cert may contain the server certificate followed by the intermediate certificate chain required by REST clients.
  • The files must be readable and contain certificate and key material that the embedded TLS stack can load successfully.
  • The private key must match the certificate.
  • Failure to load or validate the configured material causes the MRS backend start to fail; the component remains installed but inactive.
  • Configuring these variables does not guarantee that REST clients trust the issuing CA or accept the certificate for the REST endpoint identity.

    • ssl_cipher

Used to configure the OpenSSL-style colon-separated cipher list for TLS 1.2.

  • Defaults to @@ssl_cipher when that value is non-NULL and nonempty.
  • A NULL or empty value selects the embedded Router HTTP server default cipher list.
  • Ciphers prohibited by the embedded TLS stack remain disabled.
  • This variable does not configure TLS 1.3 ciphersuites.

All three TLS variables take effect only when the component starts or restarts. Changing their configured values does not modify an active TLS context. ALTER INSTANCE RELOAD TLS reloads the MySQL protocol-channel TLS contexts but does not reload the MRS TLS context.

A backend start fails if the configured certificate and key cannot be loaded or the TLS 1.2 cipher-list policy cannot be applied.

Fixed TLS Behavior and Scope

Mutual TLS (mTLS) authentication for REST clients is outside the scope of WL#17019. The MRS HTTP listener does not request or verify client certificates. Consequently, this WorkLog does not introduce ssl_ca, ssl_capath, ssl_crl, or ssl_crlpath system variables. The server certificate and its intermediate chain are supplied through ssl_cert; CA and CRL settings would be needed only for validating client certificates.

A future mTLS WorkLog must design client-certificate verification, trust and revocation configuration, and the mapping of certificate identities to MRS authentication and authorization identities as one coherent feature.

TLS is mandatory for the MRS HTTP listener; this WorkLog does not expose an ssl switch. The listener accepts TLS 1.2 and, when supported by the linked TLS library, TLS 1.3. This fixed protocol policy is provided by the embedded Router TLS server context and is not inherited from @@tls_version.

The embedded Router TLS defaults used by the listener must comply with the TLS policy applicable to the MySQL release; WL#17019 does not duplicate the cipher-suite or key-exchange-group lists.

TLS 1.3 ciphersuites use the linked TLS library's default policy. WL#17019 does not expose a tls_ciphersuites system variable and does not inherit @@tls_ciphersuites. The ssl_cipher system variable controls only the TLS 1.2 cipher list.

The listener uses automatically selected DH parameters and the embedded Router TLS stack's default key-exchange groups. Router-specific ssl_dh_param and ssl_curves options are not exposed through the component. Independent tls_kex, force_pqc, and use_pqc_sign controls are outside this WorkLog and are not inherited from the corresponding MySQL protocol-channel system variables.

TLS session caching and session tickets are disabled, and TLS compression is disabled. ssl_fips_mode remains a process-wide Server/OpenSSL setting and therefore affects the MRS TLS context indirectly. The MRS component validates that its configured certificate and key can be loaded regardless of @@tls_certificates_enforced_validation.

  • io_worker_threads

Used to configure the number of worker threads that drive asynchronous network I/O for the MRS HTTP listener. These threads process connection, TLS, and HTTP read/write events; they are not MySQL connection threads, and their count is not a THD limit.

  • Accepts integer values from 0 through 1024.
  • 0 selects component-specific automatic sizing: 25% of the available logical CPUs, rounded up, with a minimum of one worker thread.
  • A positive value configures the exact number of MRS HTTP listener I/O worker threads.
  • This setting does not limit HTTP client connections or MySQL sessions/THDs.
  • Changes take effect when the component starts or restarts.

    • http_max_connections

Used to configure the maximum number of simultaneously active HTTP client connections accepted by the embedded HTTP server.

  • Accepts integer values from 1 through 100000.
  • Defaults to 1024.
  • The value maps to the HTTP server connection-limit support.
  • Changes are applied to a running HTTP server without restart and take effect at the next connection-admission boundary. Existing active connections are not terminated.

Interaction with the MySQL Server Connection Limit

MRS does not introduce a separate system variable for limiting its internal MySQL sessions. Sessions used for REST request execution and other data-plane work, together with their associated THDs, consume slots from the shared Server connection budget governed by @@max_connections. Their creation must use the Server's normal connection-admission path.

@@max_connections is a shared Server-wide limit, not a quota reserved for MRS data-plane work. When the shared budget is exhausted, creation of a new data-plane session fails with ER_CON_COUNT_ERROR; existing sessions are not terminated. The affected operation follows the existing MRS error-handling path for a failed MySQL session acquisition.

A bounded set of metadata control-plane sessions needed for component bootstrap, metadata readiness, and metadata schema monitoring or reload may use an administrative session path so that MRS can continue to observe and recover its metadata state when ordinary connection capacity is exhausted. This admission exemption does not change the session's SQL security context or privileges and is not available to arbitrary background work.

http_max_connections is independent: it limits active HTTP client connections, not MySQL sessions. HTTP connections and MySQL sessions do not have a one-to-one relationship: an idle HTTP connection does not itself require a THD, while MRS may open or retain MySQL sessions for SQL execution and background work. Consequently, io_worker_threads and http_max_connections must not be interpreted as the maximum number of MySQL sessions or THDs.

  • http_max_request_body_size

Used to configure the maximum allowed size, in bytes, of an HTTP request body.

  • Accepts integer values from 0 through 2147483648 (2 GiB).
  • Defaults to 16777216 (16 MiB).
  • 0 disables non-empty request bodies; any request body larger than 0 is oversized.
  • Requests exceeding this limit are rejected before SQL execution.
  • The value maps to the HTTP server request-body limit support.
  • Changes are applied to a running HTTP server without restart and take effect when request-body enforcement starts for a subsequent request. An in-progress request retains its selected limit.

    • http_max_response_body_size

Used to configure the maximum allowed size, in bytes, of an HTTP response body.

  • Accepts integer values from 0 through 2147483648 (2 GiB).
  • Defaults to 16777216 (16 MiB).
  • 0 disables non-empty response bodies; any response body larger than 0 is oversized.
  • For an oversized response, the HTTP server does not send the original body and instead sends 500 Internal Server Error with no response body, then closes the connection.
  • The value maps to the HTTP server response-body limit support.
  • Changes are applied to a running HTTP server without restart and take effect when response-body enforcement starts for a subsequent response. An in-progress response retains its selected limit.

Authentication throttling remains configured through mysql_rest_service_metadata.config as defined by WL#17018. Runtime-applied component system variables and their observability interface are deferred to a follow-up WorkLog and will be introduced together.

The http_max_connections, http_max_request_body_size, and http_max_response_body_size system variables depend on the HTTP server capabilities and internal runtime override interface. The HTTP server remains responsible for enforcing the effective limits, producing the specified HTTP errors, and rate-limiting rejection logs.

Status Variables

(Implements FR3, NFR1)

Status variables provide observability into current runtime values and component state.

+------------------------------------------------------------------------------------------------------+
| Name                                  | Type    | Description                                        |
|---------------------------------------|---------|----------------------------------------------------|
| current_http_port                     | LONG    | Port bound by the active HTTP listener             |
| current_tls_cert                      | STRING  | Certificate path loaded by the active TLS context  |
| current_tls_key                       | STRING  | Key path loaded by the active TLS context          |
| current_tls_cipher                    | STRING  | Active TLS 1.2 cipher-list policy                   |
| current_io_worker_threads             | LONG    | Resolved active IO worker-thread count             |
| state                                 | STRING  | State of the MRS stack                             |
+------------------------------------------------------------------------------------------------------+

Current Runtime Values

The current_* status variables are global and expose the values used by the active backend. They are available through SHOW GLOBAL STATUS and performance_schema.global_status and are not reset by FLUSH STATUS.

The backend publishes all current values as one immutable snapshot immediately before reporting READY. While the component remains READY, changes to a start/restart-applied system variable do not change the corresponding current status value.

When no backend is active, the current values are cleared to their inactive values: current_http_port=0, current_tls_cert='', current_tls_key='', current_tls_cipher='', and current_io_worker_threads=0. A failed start or restart must not expose values from a previous or partially initialized backend. The values are cleared when the active listener and runtime have stopped.

current_tls_cipher reports the resolved ssl_cipher value applied when the active listener was created. When ssl_cipher is NULL or empty, it reports the resolved embedded Router HTTP server default rather than the empty configured value. It does not enumerate the ciphers ultimately enabled by the TLS library or report the cipher negotiated for an individual client connection.

current_io_worker_threads exposes the resolved number of active IO worker threads. When io_worker_threads=0 selects automatic sizing, the status value therefore reports the resolved count rather than 0. Because the status variable reports only the active count, equality or inequality between io_worker_threads and current_io_worker_threads does not indicate whether a restart is required.

  • mysql_rest_service.state

    • Can report the following values:

      State Description
      STOPPED The component is loaded and the MRS backend is not running.
      STARTING Backend startup is in progress.
      WAITING_FOR_METADATA Startup is waiting for required MRS metadata and will retry.
      READY The embedded MRS backend and HTTP listener are running.
      STOPPING Backend startup cancellation or runtime shutdown is in progress.
      ERROR Backend startup failed irrecoverably or a running backend terminated unexpectedly. See the MySQL Server error log.

The state is a coarse lifecycle indicator, not a record of startup stages or a diagnostic history. READY does not imply that every metadata-defined endpoint is valid or that every HTTP request will succeed.

Lifecycle State Transitions

Start and restart enter STARTING. If required MRS metadata is missing or not ready, startup enters WAITING_FOR_METADATA and continues retrying as defined by WL#17018. Startup reaches READY only after the embedded backend and HTTP listener are operational. An unrecoverable startup failure releases partially initialized resources, enters ERROR, and writes the detailed cause to the MySQL Server error log.

After reaching READY, a return or exception from the embedded loader that was not initiated by stop, component uninstallation, or server shutdown is an unexpected runtime failure. The component atomically enters ERROR and logs the cause. A rejected metadata definition, a metadata refresh failure, or an individual HTTP request failure does not change the component lifecycle state while the backend remains running.

While cleanup is in progress, the current_* status variables continue to describe any listener and runtime resources that remain active and are cleared when those resources stop. If no such resources remain active when ERROR is reported, the status variables expose their inactive values. The component completes runtime cleanup before accepting another lifecycle operation. Once STOPPING has been entered, loader termination is treated as expected shutdown and must not overwrite STOPPING or STOPPED with ERROR.

Stop, component uninstallation, and server shutdown enter STOPPING, cancel pending startup, and release runtime resources according to WL#17018. Stop ends in STOPPED; uninstallation unregisters the state variable after shutdown.

UDFs

(Implements FR4, NFR1)

The component registers the following UDFs for lifecycle management:

  • mysql_rest_service_start()

    • Starts the REST Service backend, asynchronously.
  • mysql_rest_service_stop()

    • Stops the REST Service backend, synchronously.
  • mysql_rest_service_restart()

    • Restarts the REST Service backend, asynchronously.

Behaviour:

  • Lifecycle UDFs may be invoked only from a SELECT statement executing outside a Server substatement, including a stored function or trigger. All other invocation contexts raise a SQL error before changing backend state.
  • Lifecycle UDF invocations are serialized and reevaluate the state after any preceding synchronous lifecycle work completes.
  • mysql_rest_service_start() initiates startup from STOPPED or, after cleanup, from ERROR. It is an idempotent no-op while starting or READY.
  • mysql_rest_service_stop() is an idempotent no-op in STOPPED; otherwise, it synchronously stops the backend and returns in STOPPED.
  • mysql_rest_service_restart() synchronously stops the existing lifecycle, if any, then initiates startup with the current system-variable values.
  • Each UDF returns integer 0 when the immediate operation succeeds, including an idempotent no-op. When asynchronous startup is initiated, 0 does not mean that the backend reached READY. Immediate failures raise a SQL error and are logged. Final start or restart completion is reported through mysql_rest_service.state and the server log.
  • All UDFs use the MySQL component logging framework for output and errors.
  • Execution of any MRS UDF requires MYSQL_REST_SERVICE_ADMIN.

Observing Asynchronous Start and Restart

mysql_rest_service_start() and mysql_rest_service_restart() initiate startup asynchronously. Returning 0 reports only immediate success: startup was initiated or, for mysql_rest_service_start(), the requested state was already satisfied as an idempotent no-op. It does not mean that the backend reached READY, and the UDF does not wait for that final state.

After either UDF returns 0, an administrator checks progress and completion with:

SHOW GLOBAL STATUS LIKE 'mysql_rest_service.state';

While startup is progressing, the status variable reports STARTING or WAITING_FOR_METADATA. The states relevant to startup completion or intervention are:

  • READY: startup completed successfully and the REST endpoint is operational.
  • WAITING_FOR_METADATA: the required metadata schema is missing or not ready. MRS remains inactive, logs the condition, and continues retrying until the metadata becomes ready or startup is stopped.
  • ERROR: an unrecoverable validation or runtime-bootstrap failure prevented startup, or an active backend terminated unexpectedly.
  • STOPPING: pending startup cancellation or runtime shutdown is in progress. An ordinary stop ends in STOPPED; component uninstallation unregisters the status variable after shutdown.

Failures detected before asynchronous startup is accepted are returned immediately as SQL errors. Once the UDF has returned 0, a failure discovered by the asynchronous startup path cannot be returned to the completed SQL statement: the component enters ERROR, and the detailed cause is written to the MySQL Server error log.

MRS Observability and Diagnostics

The status variables introduced by WL#17019 cover component lifecycle and active listener configuration. They do not replace the existing MRS observability facilities for metadata configuration and HTTP request processing.

Component and Backend Lifecycle

mysql_rest_service.state reports the coarse lifecycle of the embedded backend. Immediate lifecycle-UDF failures are returned as SQL errors. Failures discovered after an asynchronous start or restart has been accepted, and unexpected termination of a running backend, are written to the MySQL Server error log.

The state variable does not preserve the startup stage at which an error occurred. The MySQL Server error log is the authoritative source for the detailed cause.

Metadata Configuration and Reload

REST definitions and their change history remain owned by the existing mysql_rest_service_metadata schema and MRS metadata-monitoring machinery. The audit_log table records committed metadata changes used by MRS to detect configuration updates; it is not a diagnostic error log.

If MRS rejects a metadata definition or cannot complete a metadata refresh, normal MRS logging must identify the affected metadata entity when known, describe the cause, and report whether the definition was ignored, removed, or left at its previously applied value. This diagnostic requirement refines the clear, actionable logging requirement in WL#17018; WL#17019 does not otherwise change existing MRS metadata validation, rejection, retention, or retry semantics. Such a failure does not change mysql_rest_service.state to ERROR unless it causes the embedded backend itself to terminate.

HTTP Request Processing

Errors attributable to an individual HTTP request are reported to the client through the corresponding HTTP status and error response. Unexpected internal request-processing failures are also written through the normal MRS logging path, which the component routes to the MySQL Server error log.

Existing MRS runtime counters may be persisted in mysql_rest_service_metadata.router_status. These counters provide supplementary observability and do not replace the HTTP response or MySQL Server error log for diagnosing an individual request.

Metadata Write Failures

The MySQL Server error log is the authoritative diagnostic destination because it remains available when the MRS metadata schema cannot be written.

If required metadata is missing or not ready during startup, the state is WAITING_FOR_METADATA and startup continues retrying. If a required startup write is rejected, including because read_only or super_read_only is enabled, startup enters ERROR and must be retried after the cause is corrected, as defined by WL#17018.

If required metadata access becomes unavailable while MRS is running, existing MRS behavior controls endpoint availability and retry. The condition and its effect on REST serving must be written to the MySQL Server error log. The component may remain READY while the embedded backend continues running.

Failure to persist supplementary runtime statistics in router_status must not hide the original error and must not by itself change the component lifecycle state to ERROR.

Replication and Topology Scope

The system variables, status variables, and lifecycle UDFs defined by WL#17019 are instance-local. System-variable assignments configure only the component in the local mysqld, status variables report only local state, and lifecycle UDFs control only the local MRS backend. WL#17019 introduces no cross-member propagation or coordination mechanism.

An accepted lifecycle-UDF invocation is executed by a SELECT statement, which is not written to the binary log and does not itself create a GTID transaction. Rejecting non-SELECT and substatement invocation contexts prevents a lifecycle UDF from being replayed as part of a statement-based replication event.

In a replication deployment, each candidate member must be configured independently, and lifecycle UDFs must be invoked directly on the target member. The single-active deployment and promotion behavior defined by WL#17018 applies. Automatic role detection, coordinated configuration, failover, traffic switching, and active-active operation are outside WL#17019.

Uninstallation

(Implements FR5)

On UNINSTALL COMPONENT 'file://component_mysql_rest_service':

  • All system variables, status variables, and UDFs are unregistered.
  • The dynamic privilege MYSQL_REST_SERVICE_ADMIN is unregistered. Existing grants of the privilege are not revoked.
  • Values stored through SET PERSIST or SET PERSIST_ONLY are not removed. They remain in the persisted configuration until removed with RESET PERSIST. If MySQL Server is restarted while the component is not installed, retained MRS entries produce the native unknown-variable warnings for persisted component variables.

Component Service Interfaces

(Supports NFR1, NFR3)

Interface Direction Purpose
dynamic_privilege_register Required Register/unregister MYSQL_REST_SERVICE_ADMIN.
mysql_current_thread_reader, mysql_thd_security_context Required Obtain the caller's security context.
global_grants_check Required Verify MYSQL_REST_SERVICE_ADMIN.
component_sys_variable_register, component_sys_variable_unregister Required Manage system variables.
status_variable_registration Required Manage status variables.
udf_registration Required Register/unregister UDFs.

Internal architecture

MRSComponent
  ├─ ServerConfig
  ├─ SystemVars
  ├─ StatusVars
  ├─ UDFs
  ├─ Log
  ├─ SecurityContextHandler
  └─ Backend
       ├─ RouterConfig
       │   └─ MRSAccount
       └─ ComponentEmbeddedRuntimeServices

SystemVars

Manages the component's system variable interface:

  • Defines and registers all system variables.
  • Defines getters and setters.
  • Handles value validation.
  • Defines default values.

TLS Start/Restart Mapping

At backend start or restart:

  1. Backend captures ssl_cert, ssl_key, and ssl_cipher and passes them through the embedded HTTP server configuration.
  2. HttpServerFactory creates a TlsServerContext dedicated to the MRS HTTP listener.
  3. The HTTP server loads the certificate chain and private key and applies ssl_cipher through the existing TLS 1.2 cipher-list interface. A NULL or empty ssl_cipher selects the embedded Router HTTP server default.
  4. TlsServerContext retains the fixed protocol-version and TLS 1.3 ciphersuite behavior documented above.
  5. Startup fails before READY if the certificate, key, or TLS 1.2 cipher-list policy cannot be applied.
  6. After successful listener creation, the component publishes the active TLS values in the immutable current_* snapshot.
  7. After READY, the active TLS context and status snapshot remain unchanged until the backend is stopped and started again.

A successful start logs the effective TLS protocol and cipher policy. current_tls_cipher reports the active TLS 1.2 listener policy; the protocol version and cipher negotiated for an individual client connection remain properties of that connection.

HTTP-Limit Runtime Mapping

At backend start or restart:

  1. Backend reads and validates http_max_connections, http_max_request_body_size, and http_max_response_body_size.
  2. Before the component reports READY, Backend applies the three values to the embedded HTTP server through set_max_http_connections(), set_max_request_body_size(), and set_max_response_body_size().
  3. The HTTP server enforces the resulting effective limits.

While the backend is running, a successful SET GLOBAL or SET PERSIST for one of the three HTTP-limit variables calls the corresponding runtime setter. The new value applies at the next enforcement boundary. Existing active connections and in-progress request or response operations retain the limit already selected for them.

If no HTTP server is running, only the configured system-variable value is updated and the next backend start applies it. System-variable updates and HTTP-server startup/publication are synchronized so a committed update cannot be lost: the starting backend either captures the new value or receives it through the runtime setter before reporting READY.

The component validates the configuration policy ranges before calling the runtime setters. The internal setters accept a wider uint64_t domain and do not replace this validation.

Internal MySQL Session Admission

The command-service/Srv_session integration used by MRS must distinguish two admission classes:

  • Data-plane sessions use normal Server connection admission. They increment and release the same connection count used to enforce @@max_connections, and admission fails with ER_CON_COUNT_ERROR when no slot is available.
  • Metadata control-plane sessions may use mysql_admin_session only for component bootstrap, metadata readiness or version validation, and metadata schema monitoring or reload.

The administrative exception must be selected explicitly and must remain bounded independently of the number of HTTP clients, REST requests, endpoints, or IO worker threads. REST request execution, user-defined endpoint work, supplementary logging, statistics, and all other background work use normal admission. Every session continues to use the security context selected for the operation; administrative admission does not grant SQL privileges.

The existing command-service path obtains every new THD through mysql_admin_session. Implementing WL#17019 therefore includes extending the embedded MRS command-service integration so its callers select the admission class, with normal admission as the default. This internal change does not introduce a separate MRS session-limit system variable or reserve connection slots for MRS data-plane work.

StatusVars

Manages the component's status variable interface:

  • Defines and registers all status variables.
  • Initializes current runtime values to their inactive values.
  • Owns the immutable current-runtime snapshot.
  • Publishes a coherent snapshot immediately before a successful transition to READY.
  • Clears the snapshot when no active backend remains, after the listener and runtime stop.
  • Exposes current values through SHOW_FUNC callbacks so concurrent reads copy stable numeric and string values and FLUSH STATUS does not reset them.

UDFs

Manages the component's UDF interface:

  • Registers all UDFs.
  • Implements each UDF behavior.

Component Lifecycle

Startup

Component initialization proceeds in the following order:

1) Reads the MySQL Server configuration values required by WL#17018 and those needed to establish component system-variable defaults. Component system variables are not read at this point because they are not yet registered.

2) Initializes the System variables handler and registers all component system variables. Registration resolves each effective value, applying valid install-time or persisted values before initialization continues.

3) Initializes the Status variables handler, registers all status variables, and publishes their inactive values with the lifecycle state STOPPED.

4) Registers the dynamic privilege MYSQL_REST_SERVICE_ADMIN.

5) Initializes the UDFs handler and registers all lifecycle UDFs.

6) Captures the resulting component system-variable values, opens lifecycle admission, enters STARTING, and initiates the automatic asynchronous backend startup defined by WL#17018.

Component initialization returns success once asynchronous startup has been accepted. Final readiness or failure is reported through mysql_rest_service.state and the MySQL Server error log as described above.

If any initialization step fails before asynchronous startup is accepted, the component closes lifecycle admission, releases any partially initialized backend resources, unregisters every SQL interface successfully registered, and returns failure to the component loader. Once asynchronous startup has been accepted, a later startup failure leaves the component installed, transitions the lifecycle state to ERROR, and is reported in the MySQL Server error log.

Lifecycle Synchronization

The lifecycle controller serializes UDFs, loader completion, uninstallation, and server shutdown, and updates the state thread-safely. It owns an internal lifecycle-admission flag protected by the same synchronization. Successful component initialization opens admission, and an ordinary lifecycle UDF stop does not close it.

Component uninstallation and MySQL Server shutdown close admission atomically before entering STOPPING. Each lifecycle UDF checks admission after entering the serialized controller. Once admission is closed, pending and new calls fail without starting or restarting the backend. If a UDF is admitted first, teardown subsequently cancels and joins the lifecycle it initiated.

Stop enters STOPPING before signalling cancellation and joining background threads. Unexpected loader completion when STOPPING has not been entered atomically enters ERROR and completes cleanup; after STOPPING, no background lifecycle completion may enter READY or ERROR. Restart joins the previous lifecycle before starting a new one.

The lifecycle state/admission mutex is not held while signalling cancellation or joining background threads. Teardown records STOPPING and stop ownership while holding the mutex, releases it for cancellation and joins, then reacquires it to complete cleanup and publish STOPPED. Concurrent lifecycle callers do not perform a competing join; they wait for the active lifecycle operation to complete and then reevaluate the state.

If component deinitialization fails, lifecycle admission remains closed, the backend remains STOPPED, and failure is returned to the component loader. Recovery from partial SQL-interface unregistration is outside the scope of this worklog.

Shutdown / Failure

During component uninstallation or MySQL Server shutdown, lifecycle admission is closed before stopping the backend. After stopping the backend:

1) Unregisters all UDFs.

2) Unregisters the dynamic privilege MYSQL_REST_SERVICE_ADMIN.

3) Unregisters all system variables.

4) Unregisters all status variables.