Request for submitting a PECL extension which uses mysqlnd plugin API and enables redirection functionality for MySQL servers
| From: | Qianqian Bu via pecl-dev | Date: | Wed, 07 Aug 2019 08:03:53 +0000 |
| Subject: | Request for submitting a PECL extension which uses mysqlnd plugin API and enables redirection functionality for MySQL servers | ||
| Groups: | php.pecl.dev | ||
| Request: | Send a blank email to pecl-dev+get-16138@lists.php.net to get a copy of this message | ||
Dear Madam/Sir,
My name is Qianqian Bu, I'm from Microsoft company and recently work on a project which enables
redirection functionality for MySQL servers using PHP mysqlnd driver. The functionality has been
implemented as a PHP extension using mysqlnd plugin API, and I'd like to request submitting it
to PECL website.
There is a document https://jira.mariadb.org/browse/MDEV-15935
for MariaDB Connector J for the same purpose which you may use as a reference. The document gives
the purpose and initial approach. The final implementation takes use of the message field of OK
packet, server fills the message field with redirection information, then driver side needs extract
the information and use it to establish a new connection. There is a ongoing pull request https://github.com/MariaDB/mariadb-connector-j/pull/134
for MariaDB Connector J for this, which you may also use as a reference. Following is the detailed
description of the scenario and extension solution for PHP mysqlnd.
Scenario (same as described in MDEV-15935):
Currently when multiple servers share one proxy, proxy forwards all the packets between servers and
clients. Thus, the proxy adds latency, take many computing resources and impacts the overall
performance. Especially for short connections scenarios like WordPress, the latency can be a
critical issue..
Supporting redirection mechanism is helpful for proxy-based scenario. It is more like HTTP redirects
or Oracle redirected connections. Clients get the servers' address from proxies and connect to
servers transparently without latency and computing resource wasted.
Extension solution:
We implement the solution as a PECL style extension using mysqlnd plugin API, and the basic idea is
modifying the MYSQLND_METHOD(mysqlnd_data, connect) method, make it possible to establish a new
connection based on the redirection information provided by the response OK packet in the last
message field, and use the new connection if connection succeed. And then cache the redirection
information, so next time, it only need one establishment phase to connect to MySQL server.
There are three MYSQLND_METHOD methods replaced as follows:
conn_m->connect = MYSQLND_METHOD(mysqlnd_rd, connect);
conn_d_m->connect = MYSQLND_METHOD(mysqlnd_rd_data, connect);
conn_d_m->dtor = MYSQLND_METHOD_PRIVATE(mysqlnd_rd_data, dtor);
And I've modified the interface of MYSQLND_METHOD(mysqlnd_rd_data, connect) a little, make the
first parameter as MYSQLND_CONN_DATA ** instead of MYSQLND_CONN_DATA *, so I can modify the content
of the connection object the pointer points to.
After the first connection established and before send the init_command which may update last
message field:
{
const MYSQLND_CSTRING scheme = { transport.s, transport.l };
if (FAIL == conn->m->connect_handshake(conn, &scheme, &username,
&password, &database, mysql_flags)) {
goto err;
}
}
Try to establish a new connection:
enum_func_status redirectState =
redirect_conn->m->connect_handshake(redirect_conn, &redirect_scheme,
&redirect_username, &password, &database, mysql_flags);
If succeeds, close the original connection, and update the connection information:
conn->m->send_close(conn);
conn->m->dtor(conn);
...
conn = redirect_conn;
...
*pconn = redirect_conn; //use new conn outside for caller
...
hostname = redirect_hostname;
username = redirect_username;
port = ui_redirect_port;
I've presented the code to @Christoph Becker (HAYS Professional Solutions GM)<mailto:a-chbeck@microsoft.com> before. Since currently
the code is hold on a private repository, and there is a limit foe email size so I cannot add it in
the attachment, may I ask how should I present the code to you?
The code does not have a package.xml yet, from https://pear.php.net/manual/en/pyrus.commands.pickle.php
it says that I can use picke with pyrus.phar to generate the package file, but it seems pyrus.phar
cannot work with PHP7. I cannot find pyrus.phar from pear2.php.net as described on https://pear.php.net/manual/en/installationpyrus.introduction.php,
and the download version from https://github.com/pyrus/Pyrus does not work, and the repo
has not been updated for many years. May I ask can you give me some help about how to generate the
package.xml file?
Thanks & Best Regards,
Qianqian Bu