Connection pooling and switching
Connection pooling and switching
Connection pooling and switching
The replication and load balancing plugin changes
the semantics of a PHP MySQL connection handle. The existing API of
the PHP MySQL extensions (mysqli, mysql,
and PDO_MYSQL) are
not changed in a way that functions are added or removed. But their
behavior changes when using the plugin. Existing applications do
not need to be adapted to a new API, but they may need to be
modified because of the behavior changes.
The plugin breaks the one-by-one relationship
between a mysqli,
mysql, and PDO_MYSQL connection handle
and a MySQL network connection. And a mysqli, mysql, and PDO_MYSQL connection handle represents a local pool of
connections to the configured MySQL replication master and MySQL
replication slave servers. The plugin redirects queries to the
master and slave servers. At some point in time one and the same
PHP connection handle may point to the MySQL master server. Later
on, it may point to one of the slave servers or still the master.
Manipulating and replacing the network connection referenced by a
PHP MySQL connection handle is not a transparent operation.
Every MySQL connection has a state. The state of
the connections in the connection pool of the plugin can differ.
Whenever the plugin switches from one wire connection to another,
the current state of the user connection may change. The
applications must be aware of this.
The following list shows what the connection state
consists of. The list may not be complete.
- Transaction
status - Temporary
tables - Table locks
- Session system variables
and session user variables - The current database set
using USE and other state chaining SQL
commands - Prepared
statements - HANDLER
variables - Locks acquired with
GET_LOCK()
Connection switches happen right before queries are
executed. The plugin does not switch the current connection until
the next statement is executed.
Note: Replication
issuesSee also the MySQL reference manual chapter about
» replication features and related
issues. Some restrictions may not be related to the PHP plugin, but
are properties of the MySQL replication system.
Broadcasted messages
The plugins philosophy is to align the state of
connections in the pool only if the state is under full control of
the plugin, or if it is necessary for security reasons. Just a few
actions that change the state of the connection fall into this
category.
The following is a list of connection client
library calls that change state, and are broadcasted to all open
connections in the connection pool.
If any of the listed calls below are to be
executed, the plugin loops over all open master and slave
connections. The loop continues until all servers have been
contacted, and the loop does not break if a server indicates a
failure. If possible, the failure will propagate to the called user
API function, which may be detected depending on which underlying
library function was triggered.
Library call | Notes | Version |
---|---|---|
change_user() | Called by the mysqli_change_user() user API call. Also triggered upon reuse of a persistent mysqli connection. |
Since 1.0.0. |
select_db | Called by the following user API calls: mysql_select_db(), mysql_list_tables(), mysql_db_query(), mysql_list_fields(), mysqli_select_db(). Note, that SQL USE is not monitored. |
Since 1.0.0. |
set_charset() | Called by the following user API calls: mysql_set_charset(). mysqli_set_charset(). Note, that SQL SET NAMES is not monitored. |
Since 1.0.0. |
set_server_option() | Called by the following user API calls: mysqli_multi_query(), mysqli_real_query(), mysqli_query(), mysql_query(). | Since 1.0.0. |
set_client_option() | Called by the following user API calls: mysqli_options(), mysqli_ssl_set(), mysqli_connect(), mysql_connect(), mysql_pconnect(). | Since 1.0.0. |
set_autocommit() | Called by the following user API calls: mysqli_autocommit(), PDO::setAttribute(PDO::ATTR_AUTOCOMMIT). |
Since 1.0.0. PHP >= 5.4.0. |
ssl_set() | Called by the following user API calls: mysqli_ssl_set(). | Since 1.1.0. |
Broadcasting and lazy connections
The plugin does not proxy or remember
all settings to apply them on connections
opened in the future. This is important to remember, if using
lazy connections. Lazy connections are connections
which are not opened before the client sends the first connection.
Use of lazy connections is the default plugin action.
The following connection library calls each changed
state, and their execution is recorded for later use when lazy
connections are opened. This helps ensure that the connection state
of all connections in the connection pool are comparable.
Library call | Notes | Version |
---|---|---|
change_user() | User, password and database recorded for future use. | Since 1.1.0. |
select_db | Database recorded for future use. | Since 1.1.0. |
set_charset() | Calls set_client_option(MYSQL_SET_CHARSET_NAME, charset) on lazy connection to ensure charset will be used upon opening the lazy connection. |
Since 1.1.0. |
set_autocommit() | Adds SET AUTOCOMMIT=0|1 to the list of init commands of a lazy connection using set_client_option(MYSQL_INIT_COMMAND, “SET AUTOCOMMIT=…%quot;). |
Since 1.1.0. PHP >= 5.4.0. |
Connection state
The connection state is not only changed by API
calls. Thus, even if PECL mysqlnd_ms monitors all API calls, the
application must still be aware. Ultimately, it is the applications
responsibility to maintain the connection state, if needed.
Charsets and string escaping
Due to the use of lazy connections, which are a
default, it can happen that an application tries to escape a string
for use within SQL statements before a connection has been
established. In this case string escaping is not possible. The
string escape function does not know what charset to use before a
connection has been established.
To overcome the problem a new configuration setting
server_charset has been introduced in
version 1.4.0.
Attention has to be paid on escaping strings with a
certain charset but using the result on a connection that uses a
different charset. Please note, that PECL/mysqlnd_ms manipulates
connections and one application level connection represents a pool
of multiple connections that all may have different default
charsets. It is recommended to configure the servers involved to
use the same default charsets. The configuration setting
server_charset does help with this situation as well. If
using server_charset, the plugin will set the given
charset on all newly opened connections.