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-chb...@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


Reply via email to