Hi, Daniel, On Jun 29, Lenski, Daniel wrote:
Hi Sergei,
I'm afraid MDEV-15935 is a bit confusing. There are lots of discussions and ideas in the comments, like, using a specially modified OK packet, using the error message, etc.
Right! I got the sense from the Jira discussion (https://jira.mariadb.org/browse/MDEV-15935) that there's a large and varied "wish lish" of different capabilities for this feature — not all of which are practical or compatible.
It has also been open for over 5 years without an accepted implementation.
There was an original pull request from ~5 years ago, but then the contributor disappeared and I didn't want to do anything until they'd at least confirm that the new suggested approach works for them. We waited until we got new users requesting this very feature.
This is why I thought it would make a lot of sense to implement redirection in a very MINIMAL and SIMPLE form — but one that would already be useful in its initial form, and with a design that's amentable to future extensibility. (Many thanks to Otto for encouraging and guiding this implementation!)
But the final consensus was to use session tracking feature, it allows for most flexibility and user control over how redirect is happening. To quote here:
We'll add a new global/session variable, say, redirect_url. The value should be an empty string or a connection string in the conventional format (in the style of a connection url of C/J or C/NodeJS or C/C or FederatedX).
This variable is appended to the default value of session_track_system_variables variable.
When this variable is changed, the existing SESSION_TRACK_SYSTEM_VARIABLES implementation will send its new value to the client as a part of the OK packet. It's up to the client or to the connector to use this value or to ignore it.
I read through this proposal as well, but I didn't realize that it had been in any way chosen as the desired implementation. I am surprised, because there seems to be 2 key problems with it…
(1) Redirection targets in "URL" format will be extremely difficult to support in consistent and secure ways across client implementations.
MDEV-15935 itself (the server part) does not specify what the URL should look like, it's only about passing basically an arbitrary string to the client. Although the original PR used URLs, Federated uses URLs, Connector/J uses URLs - it's de facto very common already. It might be good to standardize the URL format and use it everywhere.
The Connector/C library currently has no ability to parse connection "URLs" in either the Connector/J (https://mariadb.com/kb/en/about-mariadb-connector-j) or the MySQL formats ( https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-jdbc-url-...), which are partially but fully compatible with each other, and to my knowledge there is no formal definition of either. As far as I know, Connector/C is the basis for most higher-level languages’ connector libraries (e.g. Connector/Python).
Not quite. Connector/C can parse both DSN format (key=value pairs, semicolon-separated) and URI format, See https://github.com/mariadb-corporation/mariadb-connector-c/blob/5af90f00ff/l... and https://github.com/mariadb-corporation/mariadb-connector-c/blob/5af90f00ff/l... although the latter cannot be used for normal connections yet, which is good, becayse without standard URI syntax it would've definitely been incompatible with everything.
If the redirection target can contain all the different kinds of connection information that MariaDB Connector/J URLs support (very long list of optional parameters! https://mariadb.com/kb/en/about-mariadb-connector-j/#optional-url-parameters), it will be very difficult to ensure that all languages’ Connector/X libraries handle all of these parameters in a consistent and secure way when redirecting.
Right, that's why I moved URI topic out of MDEV-15935, making the latter only about "how to pass <arbitrary string> to the client" There are two common approaches to a connection string - let's call them "JDBC way" (that's URI) and "ODBC way" (semicolon separated key=value pairs). mysqljs uses URI, Perl DBI uses DSN, PHP PDO uses DSN, Federated engine uses URI, etc. I'd really rather avoid introducing a new connection string format.
Precisely in order to avoid this level of complexity, my proposal includes a *much simpler* format for the redirection target: `host[:port]`. This should be simple enough for any and all Connector/X client libraries to implement in a uniform fashion. At the same time, it is designed to be extensible; if there are clear use cases for it, it could be extended in the future to include more complex formats for the redirection target, such as Connector/J-style and/or MySQL-style connection URLs.
MDEV-15935 says that we "might" optionally implement URI validation in the server. Without it one can literally send an arbitrary string. This might be error-prone. With the server side URI validation we can limit redirection URIs to "mysql://host[:port]" which basically is what you wanted and postpones all the URI complexity till we have some standard specs for it.
(2) Using OK packets and session-tracking, the server would have no way to enforce redirection. As you wrote, "It's up to the client or to the connector to use this value [of redirect_url] or to ignore it." In this form, redirection instructions sent by the server would be merely "advisory", and the server would have no way to ensure that clients stop connecting to it.
Correct. This was the point.
This "advisory" redirection would seem to be greatly limited in the kind of use cases it supports. If servers sending redirection information can't RELY ON clients disconnecting from them, then they can't use redirection as a prelude to shutting down the server.
Of course, they can. The idea is to tell clients to connect to another server and to disconnect them after that. If redirection is forced, then the server will send a "redirection error" and disconnect. If redirection is advisory, the server will send a redirection info and disconnect few seconds later when it shuts down. Anyway, in the original proposal (from ~5 years ago) it was advisory, apparently it's what the user needed. Currently the main user requesting it is Markus, and he's apparently fine with advisory too. When we'll get someone requesting forceful redirection *for his own use case* - then, I'm sure, we can extend this approach to redirect and disconnect. The problem is - I don't see a logical way of extending suggested in MDEV-15935 approach to be forceful. I'll add a comment there about your error message based implementation, just to have all implementation details in one place, in Jira. Regards, Sergei VP of MariaDB Server Engineering and security@mariadb.org