2011-04-18 15:04:51 +00:00
|
|
|
<?xml version="1.0" encoding="utf-8"?>
|
2011-09-27 14:22:12 +00:00
|
|
|
<!-- $Revision$ -->
|
2011-04-18 15:04:51 +00:00
|
|
|
|
|
|
|
<refentry xml:id="function.mysqlnd-ms-set-user-pick-server" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
|
|
<refnamediv>
|
|
|
|
<refname>mysqlnd_ms_set_user_pick_server</refname>
|
|
|
|
<refpurpose>Sets a callback for user-defined read/write splitting</refpurpose>
|
|
|
|
</refnamediv>
|
|
|
|
|
|
|
|
<refsect1 role="description">
|
|
|
|
&reftitle.description;
|
|
|
|
<methodsynopsis>
|
|
|
|
<type>bool</type>
|
|
|
|
<methodname>mysqlnd_ms_set_user_pick_server</methodname>
|
|
|
|
<methodparam><type>string</type><parameter>function</parameter></methodparam>
|
|
|
|
</methodsynopsis>
|
|
|
|
<para>
|
|
|
|
Sets a callback for user-defined read/write splitting. The plugin will
|
|
|
|
call the callback only if <literal>pick[]=user</literal> is the default
|
|
|
|
rule for server picking in the relevant section of the plugins configuration
|
|
|
|
file.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The plugins built-in read/write query split mechanism decisions can be
|
|
|
|
overwritten in two ways. The easiest way is to prepend the query string
|
|
|
|
with the SQL hints <constant>MYSQLND_MS_MASTER_SWITCH</constant>,
|
|
|
|
<constant>MYSQLND_MS_SLAVE_SWITCH</constant> or
|
|
|
|
<constant>MYSQLND_MS_LAST_USED_SWITCH</constant>. Using SQL hints one can
|
|
|
|
control, for example, whether a query shall be send to the MySQL replication
|
|
|
|
master server or one of the slave servers. By help of SQL hints it is
|
|
|
|
not possible to pick a certain slave server for query execution.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
Full control on server selection can be gained using a callback function.
|
|
|
|
Use of a callback is recommended to expert users only because the callback
|
|
|
|
has to cover all cases otherwise handled by the plugin.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
The plugin will invoke the callback function for selecting a server from the
|
|
|
|
lists of configured master and slave servers. The callback function
|
|
|
|
inspects the query to run and picks a server for query execution by returning
|
|
|
|
the hosts URI, as found in the master and slave list.
|
|
|
|
</para>
|
|
|
|
<para>
|
|
|
|
If the lazy connections are enabled and the callback choses a slave server for
|
|
|
|
which no connection has been established so far and establishing the connection
|
|
|
|
to the slave fails, the plugin will return an error upon the next action
|
|
|
|
on the failed connection, for example, when running a query. It is the
|
|
|
|
responsibility of the application developer to handle the error. For example,
|
|
|
|
the application can re-run the query to trigger a new server selection and
|
|
|
|
callback invocation. If so, the callback must make sure to select
|
|
|
|
a different slave, or check slave availability, before returning to
|
|
|
|
the plugin to prevent an endless loop.
|
|
|
|
</para>
|
|
|
|
</refsect1>
|
|
|
|
|
|
|
|
<refsect1 role="parameters">
|
|
|
|
&reftitle.parameters;
|
|
|
|
<variablelist>
|
|
|
|
<varlistentry>
|
|
|
|
<term><parameter>function</parameter></term>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
The function to be called. Class methods may also be invoked
|
|
|
|
statically using this function by passing
|
|
|
|
<literal>array($classname, $methodname)</literal> to this parameter.
|
|
|
|
Additionally class methods of an object instance may be called by passing
|
|
|
|
<literal>array($objectinstance, $methodname)</literal> to this parameter.
|
|
|
|
</para>
|
|
|
|
</listitem>
|
|
|
|
</varlistentry>
|
|
|
|
</variablelist>
|
|
|
|
</refsect1>
|
|
|
|
|
|
|
|
<refsect1 role="returnvalues">
|
|
|
|
&reftitle.returnvalues;
|
|
|
|
<para>
|
|
|
|
Host to run the query on. The host URI is to be taken from the
|
|
|
|
master and slave connection lists passed to the callback function.
|
|
|
|
If callback returns a value neither found in the master nor in the slave
|
|
|
|
connection lists the plugin will fallback to the second pick method configured
|
|
|
|
via the <literal>pick[]</literal> setting in the plugin configuration file.
|
|
|
|
If not second pick method is given, the plugin falls back to the build-in
|
|
|
|
default pick method for server selection.
|
|
|
|
</para>
|
|
|
|
</refsect1>
|
|
|
|
|
2011-09-22 16:45:37 +00:00
|
|
|
<refsect1>
|
|
|
|
&reftitle.notes;
|
|
|
|
<note>
|
|
|
|
<para>
|
|
|
|
<function>mysqlnd_ms_set_user_pick_server</function> is available
|
|
|
|
with PECL mysqlnd_ms < 1.1.0. It has been replaced by the
|
|
|
|
<literal>user</literal> filter. Please, check the
|
|
|
|
<link linkend="mysqlnd-ms.changes_one_one">Change History</link>
|
|
|
|
for upgrade notes.
|
|
|
|
</para>
|
|
|
|
</note>
|
|
|
|
</refsect1>
|
|
|
|
|
2011-04-18 15:04:51 +00:00
|
|
|
<refsect1 role="examples">
|
|
|
|
&reftitle.examples;
|
|
|
|
<para>
|
|
|
|
<example>
|
|
|
|
<title><function>mysqlnd_ms_set_user_pick_server</function> example</title>
|
|
|
|
<programlisting role="ini">
|
|
|
|
<![CDATA[
|
|
|
|
[myapp]
|
|
|
|
master[] = localhost
|
|
|
|
slave[] = 192.168.2.27:3306
|
|
|
|
slave[] = 192.168.78.136:3306
|
|
|
|
pick[] = user
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
<programlisting role="php">
|
|
|
|
<![CDATA[
|
|
|
|
<?php
|
|
|
|
|
|
|
|
function pick_server($connected, $query, $master, $slaves, $last_used)
|
|
|
|
{
|
|
|
|
static $slave_idx = 0;
|
|
|
|
static $num_slaves = NULL;
|
|
|
|
if (is_null($num_slaves))
|
|
|
|
$num_slaves = count($slaves);
|
|
|
|
|
|
|
|
/* default: fallback to the plugins build-in logic */
|
|
|
|
$ret = NULL;
|
|
|
|
|
|
|
|
printf("User has connected to '%s'...\n", $connected);
|
|
|
|
printf("... deciding where to run '%s'\n", $query);
|
|
|
|
|
|
|
|
$where = mysqlnd_ms_query_is_select($query);
|
|
|
|
switch ($where)
|
|
|
|
{
|
|
|
|
case MYSQLND_MS_QUERY_USE_MASTER:
|
|
|
|
printf("... using master\n");
|
|
|
|
$ret = $master[0];
|
|
|
|
break;
|
|
|
|
case MYSQLND_MS_QUERY_USE_SLAVE:
|
|
|
|
/* SELECT or SQL hint for using slave */
|
|
|
|
if (stristr($query, "FROM table_on_slave_a_only"))
|
|
|
|
{
|
|
|
|
/* a table which is only on the first configured slave */
|
|
|
|
printf("... access to table available only on slave A detected\n");
|
|
|
|
$ret = $slaves[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* round robin */
|
|
|
|
printf("... some read-only query for a slave\n");
|
|
|
|
$ret = $slaves[$slave_idx++ % $num_slaves];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MYSQLND_MS_QUERY_LAST_USED:
|
|
|
|
printf("... using last used server\n");
|
|
|
|
$ret = $last_used;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("... ret = '%s'\n", $ret);
|
|
|
|
return $ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
mysqlnd_ms_set_user_pick_server("pick_server");
|
|
|
|
|
|
|
|
$mysqli = new mysqli("myapp", "root", "root", "test");
|
|
|
|
|
|
|
|
if (!($res = $mysqli->query("SELECT 1 FROM DUAL")))
|
|
|
|
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
|
|
|
|
else
|
|
|
|
$res->close();
|
|
|
|
|
|
|
|
if (!($res = $mysqli->query("SELECT 2 FROM DUAL")))
|
|
|
|
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
|
|
|
|
else
|
|
|
|
$res->close();
|
|
|
|
|
|
|
|
|
|
|
|
if (!($res = $mysqli->query("SELECT * FROM table_on_slave_a_only")))
|
|
|
|
printf("[%d] %s\n", $mysqli->errno, $mysqli->error);
|
|
|
|
else
|
|
|
|
$res->close();
|
|
|
|
|
|
|
|
$mysqli->close();
|
|
|
|
?>
|
|
|
|
]]>
|
|
|
|
</programlisting>
|
|
|
|
&example.outputs;
|
|
|
|
<screen>
|
|
|
|
<![CDATA[
|
|
|
|
User has connected to 'myapp'...
|
|
|
|
... deciding where to run 'SELECT 1 FROM DUAL'
|
|
|
|
... some read-only query for a slave
|
|
|
|
... ret = 'tcp://192.168.2.27:3306'
|
|
|
|
User has connected to 'myapp'...
|
|
|
|
... deciding where to run 'SELECT 2 FROM DUAL'
|
|
|
|
... some read-only query for a slave
|
|
|
|
... ret = 'tcp://192.168.78.136:3306'
|
|
|
|
User has connected to 'myapp'...
|
|
|
|
... deciding where to run 'SELECT * FROM table_on_slave_a_only'
|
|
|
|
... access to table available only on slave A detected
|
|
|
|
... ret = 'tcp://192.168.2.27:3306'
|
|
|
|
]]>
|
|
|
|
</screen>
|
|
|
|
</example>
|
|
|
|
</para>
|
|
|
|
</refsect1>
|
2011-09-27 14:22:12 +00:00
|
|
|
|
2011-04-18 15:04:51 +00:00
|
|
|
<refsect1 role="seealso">
|
|
|
|
&reftitle.seealso;
|
|
|
|
<para>
|
|
|
|
<simplelist>
|
|
|
|
<member>
|
|
|
|
<function>mysqlnd_ms_query_is_select</function>
|
2011-09-27 14:22:12 +00:00
|
|
|
</member>
|
|
|
|
<member>
|
|
|
|
<link linkend="mysqlnd-ms.filter">Filter concept</link>
|
|
|
|
</member>
|
|
|
|
<member>
|
|
|
|
<link linkend="ini.mysqlnd-ms-plugin-config-v2.filter_user"><literal>user</literal></link> filter
|
|
|
|
</member>
|
2011-04-18 15:04:51 +00:00
|
|
|
</simplelist>
|
|
|
|
</para>
|
|
|
|
</refsect1>
|
2011-09-27 14:22:12 +00:00
|
|
|
|
2011-04-18 15:04:51 +00:00
|
|
|
</refentry>
|
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
Local variables:
|
|
|
|
mode: sgml
|
|
|
|
sgml-omittag:t
|
|
|
|
sgml-shorttag:t
|
|
|
|
sgml-minimize-attributes:nil
|
|
|
|
sgml-always-quote-attributes:t
|
|
|
|
sgml-indent-step:1
|
|
|
|
sgml-indent-data:t
|
|
|
|
indent-tabs-mode:nil
|
|
|
|
sgml-parent-document:nil
|
|
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
|
|
sgml-exposed-tags:nil
|
|
|
|
sgml-local-catalogs:nil
|
|
|
|
sgml-local-ecat-files:nil
|
|
|
|
End:
|
|
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
|
|
vim: et tw=78 syn=sgml
|
|
|
|
vi: ts=1 sw=1
|
|
|
|
-->
|