|
|
|
@ -385,7 +385,7 @@
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="mysqlnd-ms.transaction">
|
|
|
|
|
<title>Transaction handling</title>
|
|
|
|
|
<title>Local transaction handling</title>
|
|
|
|
|
<para>
|
|
|
|
|
Transaction handling is fundamentally changed.
|
|
|
|
|
An SQL transaction is a unit of work that is run on one database server. The
|
|
|
|
@ -1433,7 +1433,8 @@ Transient error retries before error: 2
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
As of MySQL 5.6.5-m8 the MySQL server features built-in global transaction identifiers.
|
|
|
|
|
The MySQL built-in global transaction ID feature is supported by PECL/mysqlnd_ms 1.3.0-alpha or
|
|
|
|
|
The MySQL built-in global transaction ID feature is supported by
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> 1.3.0-alpha or
|
|
|
|
|
later. Neither are client-side transaction boundary monitoring nor any setup
|
|
|
|
|
activities required if using the server feature.
|
|
|
|
|
</para>
|
|
|
|
@ -1447,7 +1448,7 @@ Transient error retries before error: 2
|
|
|
|
|
<emphasis role="bold">Idea and client-side emulation</emphasis>
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
PECL/mysqlnd_ms can do client-side transparent global transaction ID injection.
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> can do client-side transparent global transaction ID injection.
|
|
|
|
|
In its most basic form, a global transaction identifier is a counter which is
|
|
|
|
|
incremented for every transaction executed on the master. The counter is held
|
|
|
|
|
in a table on the master. Slaves replicate the counter table.
|
|
|
|
@ -1491,7 +1492,8 @@ Transient error retries before error: 2
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Client-side global transaction ID injection has shortcomings. The potential
|
|
|
|
|
issues are not specific to PECL/mysqlnd_ms but are rather of general nature.
|
|
|
|
|
issues are not specific to <literal>PECL/mysqlnd_ms</literal>
|
|
|
|
|
but are rather of general nature.
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<simpara>
|
|
|
|
@ -1522,7 +1524,8 @@ Transient error retries before error: 2
|
|
|
|
|
<emphasis role="bold">Using server-side global transaction identifier</emphasis>
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Starting with PECL/mysqlnd_ms 1.3.0-alpha the MySQL 5.6.5-m8 or newer built-in global
|
|
|
|
|
Starting with <literal>PECL/mysqlnd_ms</literal> 1.3.0-alpha
|
|
|
|
|
the MySQL 5.6.5-m8 or newer built-in global
|
|
|
|
|
transaction identifier feature is supported. Use of the server feature lifts
|
|
|
|
|
all of the above listed limitations. Please, see the MySQL Reference Manual
|
|
|
|
|
for limitations and preconditions for using server built-in global transaction
|
|
|
|
@ -1589,7 +1592,7 @@ Transient error retries before error: 2
|
|
|
|
|
systems, such as a database cluster. Global transaction identifiers can
|
|
|
|
|
be used for, for example, system wide identification of transactions,
|
|
|
|
|
global ordering of transactions, heartbeat mechanism and
|
|
|
|
|
for checking the replication status of replicas. PECL/mysqlnd_ms, a clientside
|
|
|
|
|
for checking the replication status of replicas. <literal>PECL/mysqlnd_ms</literal>, a clientside
|
|
|
|
|
driver based software, does focus on using GTIDs for tasks that can be
|
|
|
|
|
handled at the client, such as checking the replication status of replicas
|
|
|
|
|
for asynchronous replication setups.
|
|
|
|
@ -1602,15 +1605,17 @@ Transient error retries before error: 2
|
|
|
|
|
<note>
|
|
|
|
|
<title>Version requirement</title>
|
|
|
|
|
<para>
|
|
|
|
|
The feature requires use of PECL/mysqlnd_ms 1.3.0-beta or later,
|
|
|
|
|
and PECL/mysqlnd_qc 1.1.0-alpha or newer. PECL/mysqlnd_ms must be
|
|
|
|
|
The feature requires use of <literal>PECL/mysqlnd_ms</literal> 1.3.0-beta or later,
|
|
|
|
|
and <literal>PECL/mysqlnd_qc</literal> 1.1.0-alpha or newer.
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> must be
|
|
|
|
|
compiled to support the feature. PHP 5.4.0 or newer is required.
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
<note>
|
|
|
|
|
<title>Setup: extension load order</title>
|
|
|
|
|
<para>
|
|
|
|
|
PECL/mysqlnd_ms must be loaded before PECL/mysqlnd_qc, when using shared
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> must be loaded before
|
|
|
|
|
<literal>PECL/mysqlnd_qc</literal>, when using shared
|
|
|
|
|
extensions.
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
@ -1631,7 +1636,8 @@ Transient error retries before error: 2
|
|
|
|
|
</note>
|
|
|
|
|
<para>
|
|
|
|
|
Support for MySQL replication clusters (asynchronous primary copy) is the
|
|
|
|
|
main focus of PECL/mysqlnd_ms. The slaves of a MySQL replication cluster
|
|
|
|
|
main focus of <literal>PECL/mysqlnd_ms</literal>.
|
|
|
|
|
The slaves of a MySQL replication cluster
|
|
|
|
|
may or may not reflect the latest updates from the master.
|
|
|
|
|
Slaves are asynchronous and can lag behind the master. A read from a slave
|
|
|
|
|
is eventual consistent from a cluster-wide perspective.
|
|
|
|
@ -1648,13 +1654,14 @@ Transient error retries before error: 2
|
|
|
|
|
replace a remote database access with a local cache access to gain better possibility.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
As of PECL/mysqlnd_ms 1.3.0-beta the plugin is capable of transparently controlling
|
|
|
|
|
PECL/mysqlnd_ms 1.1.0-alpha or newer to cache a read-only query if explicitly
|
|
|
|
|
allowed by setting an appropriate quality of service through
|
|
|
|
|
<function>mysqlnd_ms_set_qos</function>. Please, see the
|
|
|
|
|
As of <literal>PECL/mysqlnd_ms</literal> 1.3.0-beta the plugin is
|
|
|
|
|
capable of transparently controlling <literal>PECL/mysqlnd_ms</literal> 1.1.0-alpha
|
|
|
|
|
or newer to cache a read-only query if explicitly allowed by setting an
|
|
|
|
|
appropriate quality of service through <function>mysqlnd_ms_set_qos</function>. P
|
|
|
|
|
lease, see the
|
|
|
|
|
<link linkend="mysqlnd-ms.quickstart.cache">quickstart</link> for a code example.
|
|
|
|
|
Both plugins must be installed, PECL/mysqlnd_ms must be compiled to support the
|
|
|
|
|
cache feature and PHP 5.4.0 or newer has to be used.
|
|
|
|
|
Both plugins must be installed, <literal>PECL/mysqlnd_ms</literal>
|
|
|
|
|
must be compiled to support the cache feature and PHP 5.4.0 or newer has to be used.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Applications have full control of cache usage and can request fresh data
|
|
|
|
@ -1667,7 +1674,7 @@ Transient error retries before error: 2
|
|
|
|
|
relaxed to eventual consistency the cache can be used again.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
If caching is enabled for a read-only statement, PECL/mysqlnd_ms may inject
|
|
|
|
|
If caching is enabled for a read-only statement, <literal>PECL/mysqlnd_ms</literal> may inject
|
|
|
|
|
<link linkend="mysqlnd-qc.quickstart.caching">SQL hints to control caching</link>
|
|
|
|
|
by PECL/mysqlnd_qc. It may modify the SQL statement it got from the application.
|
|
|
|
|
Subsequent SQL processors are supposed to ignore the SQL hints. A SQL hint is a
|
|
|
|
@ -1735,7 +1742,7 @@ Transient error retries before error: 2
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<simpara>
|
|
|
|
|
Inject the appropriate SQL hints to enable caching by PECL/mysqlnd_qc.
|
|
|
|
|
Inject the appropriate SQL hints to enable caching by <literal>PECL/mysqlnd_qc</literal>.
|
|
|
|
|
</simpara>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
@ -1746,9 +1753,10 @@ Transient error retries before error: 2
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<simpara>
|
|
|
|
|
PECL/mysqlnd_qc is loaded after PECL/mysqlnd_ms by PHP. Thus, it will see
|
|
|
|
|
all query modifications of PECL/mysqlnd_ms and cache the query if instructed
|
|
|
|
|
to do so.
|
|
|
|
|
<literal>PECL/mysqlnd_qc</literal> is loaded after
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> by PHP. Thus, it will see
|
|
|
|
|
all query modifications of <literal>PECL/mysqlnd_ms</literal> and cache
|
|
|
|
|
the query if instructed to do so.
|
|
|
|
|
</simpara>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
@ -2124,6 +2132,201 @@ mysqlnd_ms.disable_rw_split=1
|
|
|
|
|
help to reduce collision rates and thus improve performance.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section xml:id="mysqlnd-ms.concept_xa_trx">
|
|
|
|
|
<title>XA/Distributed transactions</title>
|
|
|
|
|
<note>
|
|
|
|
|
<title>Version requirement</title>
|
|
|
|
|
<para>
|
|
|
|
|
XA related functions have been introduced in <literal>PECL/mysqlnd_ms</literal> version 1.6.0-alpha.
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
<note>
|
|
|
|
|
<title>Early adaptors wanted</title>
|
|
|
|
|
<para>
|
|
|
|
|
The feature is currently under development. There may be issues and/or
|
|
|
|
|
feature limitations. Do not use in production environments, although
|
|
|
|
|
early lab tests indicate reasonable quality.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Please, contact the development team if you are interested in this feature.
|
|
|
|
|
We are looking for real life feedback to complement the feature.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Below is a list of some feature restrictions.
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>The feature is not yet compatible with the MySQL Fabric support . This limitation is soon to be lifted.</para>
|
|
|
|
|
<para>XA transaction identifier are currently restricted to numbers. This limitation will be lifted upon request, it is a simplification used during the initial implementation.</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
<note>
|
|
|
|
|
<title>MySQL server restrictions</title>
|
|
|
|
|
<para>
|
|
|
|
|
The XA support by the MySQL server has some restrictions. Most noteably,
|
|
|
|
|
the servers binary log may lack changes made by XA transactions in case
|
|
|
|
|
of certain errors. Please, see the MySQL manual for details.
|
|
|
|
|
</para>
|
|
|
|
|
</note>
|
|
|
|
|
<para>
|
|
|
|
|
XA/Distributed transactions can spawn multiple MySQL servers.
|
|
|
|
|
Thus, they may seem like a perfect
|
|
|
|
|
tool for sharded MySQL clusters, for example, clusters managed with MySQL Fabric.
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> hides most of the SQL commands
|
|
|
|
|
to control XA transactions and performs automatic administrative tasks in cases
|
|
|
|
|
of errors, to provide the user with a comprehensive API. Users should
|
|
|
|
|
setup the plugin carefully and be well aware of server restrictions prior
|
|
|
|
|
to using the feature.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
<example>
|
|
|
|
|
<title>General pattern for XA transactions</title>
|
|
|
|
|
<programlisting role="php">
|
|
|
|
|
<![CDATA[
|
|
|
|
|
<?php
|
|
|
|
|
$mysqli = new mysqli("myapp", "username", "password", "database");
|
|
|
|
|
|
|
|
|
|
/* BEGIN */
|
|
|
|
|
mysqlnd_ms_xa_begin($mysqli, 1 /* xa id */);
|
|
|
|
|
|
|
|
|
|
/* run queries on various servers */
|
|
|
|
|
$mysqli->query("UPDATE some_table SET col_a = 1");
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
/* COMMIT */
|
|
|
|
|
mysqlnd_ms_xa_commit($link, 1);
|
|
|
|
|
?>
|
|
|
|
|
]]>
|
|
|
|
|
</programlisting>
|
|
|
|
|
</example>
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
XA transactions use the two-phase commit protocol. The two-phase commit
|
|
|
|
|
protocol is a blocking protocol. During the first phase participating servers
|
|
|
|
|
begin a transaction and the client carries out its work. This phase is followed
|
|
|
|
|
by a second voting phase. During voting, the servers first make a firm promise
|
|
|
|
|
that they are ready to commit the work even in case of their possible unexpected
|
|
|
|
|
failure. Should a server crash in this phase, it will still recall the aborted
|
|
|
|
|
transaction after recover and wait for the client to decide on whether
|
|
|
|
|
it shall be committed or rolled back.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Should a client that has initiated a global transaction crash after all the
|
|
|
|
|
participating servers gave their promise to be ready to commit, then the servers
|
|
|
|
|
must wait for a decision. The servers are not allowed to uniliterally decide on the
|
|
|
|
|
transaction.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
A client crash or disconnect from a participant, a server crash or server error
|
|
|
|
|
during the fist phase of the protocol is uncritical. In most cases, the server
|
|
|
|
|
will forget about the XA transaction and its work is rolled back. Additionally,
|
|
|
|
|
the plugin tries to reach out to as many participants as it can to instruct
|
|
|
|
|
the server to roll back the work immediately. It is not possible to disable this implicit
|
|
|
|
|
rollback carried out by <literal>PECL/mysqlnd_ms</literal> in case of errors
|
|
|
|
|
during the first phase of the protocol. This design decision has been made to
|
|
|
|
|
keep the implementation simple.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
An error during the second phase of the commit protocol can develop into a
|
|
|
|
|
more severe situation. The servers will not forget about
|
|
|
|
|
prepared but unfinished transactions in all cases. The plugin will not
|
|
|
|
|
attempt to solve these cases immediately but waits for optional background
|
|
|
|
|
garbage collection to ensure progress of the commit protocol. It is assumed
|
|
|
|
|
that a solution will take significant time as it may include waiting
|
|
|
|
|
for a participating server to recover from a crash. This time span may
|
|
|
|
|
be longer than a developer and end user expects when trying to commit a
|
|
|
|
|
global transaction with <function>mysqlnd_ms_xa_commit</function>. Thus,
|
|
|
|
|
the function returns with the unfinished global transaction still
|
|
|
|
|
requiring attention. Please, be warned that at this point, it is not yet
|
|
|
|
|
clear whether the global transaction will be committed or rolled back later on.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Errors during the second phase can be ignored, handled by yourself or solved
|
|
|
|
|
by the build-int garbage collection logic. Ignoring them is not recommended
|
|
|
|
|
as you may experience unfinished global transactions on your servers that block
|
|
|
|
|
resources virtually indefinetly. Handling the errors requires knowing the
|
|
|
|
|
participants, checking their state and issueing appropriate SQL commands on them.
|
|
|
|
|
There are no user API calls to expose this very information. You will have to
|
|
|
|
|
configure a state store and make the plugin record its actions in it to receive
|
|
|
|
|
the desired facts.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Please, see the
|
|
|
|
|
<link linkend="mysqlnd-ms.quickstart.xa_transactions">quickstart</link> and
|
|
|
|
|
related <link linkend="ini.mysqlnd-ms-plugin-config-v2.xa.state-store">plugin
|
|
|
|
|
configuration file settings</link> for an example how to configure a state.
|
|
|
|
|
In addition to configuring a state store, you have to setup some SQL tables.
|
|
|
|
|
The table definitions are given in the description of the plugin configuration
|
|
|
|
|
settings.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Setting up and configuring a state store is also a precondition for using the
|
|
|
|
|
built-in garbage collection for XA transactions that fail during the
|
|
|
|
|
second commit phase. Recording information about ongoing XA transactions is
|
|
|
|
|
an unavoidable extra task. The extra task consists of updating the state
|
|
|
|
|
store after each and every operation that changes the state of the global transaction
|
|
|
|
|
itself (started, committed, rolled back, errors and aborts), the addition of
|
|
|
|
|
participants (host, optionally user and password required to connect) and any
|
|
|
|
|
changes to a participants state. Please note, depending on configuration and your
|
|
|
|
|
security policies, these recordings may be considered sensitive.
|
|
|
|
|
It is therefore recommended to restrict access to the state store. Unless the
|
|
|
|
|
state store itself becomes overloaded, writing the state information may contribute
|
|
|
|
|
noteworthy to the runtime but should overall be only a minor factor.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
It is possible that the effort it takes to implement your own routines for handling
|
|
|
|
|
XA transactions that failed during the second commit phase exceeds the benefits
|
|
|
|
|
of using the XA feature of <literal>PECL/mysqlnd_ms</literal> in the first place.
|
|
|
|
|
Thus, the manual focussed on using the built-on garbage collection only.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Garbage collection can be triggered manually or automatically in the background.
|
|
|
|
|
You may want to call <function>mysqlnd_ms_xa_gc</function> immediately after
|
|
|
|
|
a commit failure to attempt to solve any failed but still open global transactions
|
|
|
|
|
as soon as possible. You may also decide to disable the automatic background
|
|
|
|
|
garbage collection, implement your own rule set for invoking the built-in
|
|
|
|
|
garbage collection and trigger it when desired.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
By default the plugin will start the garbage collection with a certain probability
|
|
|
|
|
in the extensions internal <literal>RSHUTDOWN</literal> method. The request
|
|
|
|
|
shutdown is called after your script finished. Whether the garbage collection
|
|
|
|
|
will be triggered is determined by computing a random value between
|
|
|
|
|
<literal>1...1000</literal> and comparing it with the configuration setting
|
|
|
|
|
<link linkend="ini.mysqlnd-ms-plugin-config-v2.xa.gc"><literal>probability</literal></link>
|
|
|
|
|
(default: 5). If the setting is
|
|
|
|
|
greater or equal to the random value, the garbage collection will be triggered.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Once started, the garbage collection acts upon up to
|
|
|
|
|
<literal>max_transactions_per_run</literal> (default: 100) global transactions
|
|
|
|
|
recorded. Records include successfully finished but also unfinished XA
|
|
|
|
|
transactions. Records for successful transactions are removed and unfinished
|
|
|
|
|
transactions are attempted to be solved. There are no statistics that help
|
|
|
|
|
you finding the right balance between keeping garbage collection runs short
|
|
|
|
|
by limiting the number of transactions considered per run and preventing the garbage
|
|
|
|
|
collection to fall behind, resulting in many records.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
For each failed XA transaction the garbage collection makes
|
|
|
|
|
<literal>max_retries</literal> (default: 5) attempts to finish it. After that
|
|
|
|
|
<literal>PECL/mysqlnd_ms</literal> gives up and the XA transaction must be
|
|
|
|
|
cleaned up by a human operator. There are two possible reasons for this. Either
|
|
|
|
|
a participating server crashed and has not become accessible again within
|
|
|
|
|
<literal>max_retries</literal> invocations of the garbage collection, or there
|
|
|
|
|
is a situation that the built-in garbage collection cannot cope with. Likely, the
|
|
|
|
|
latter would be considered a bug.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
The function <link linkend="function.mysqlnd-ms-get-stats"><function>mysqlnd_ms_get_stats</function></link>
|
|
|
|
|
provides some statistics on how many XA transactions have been started,
|
|
|
|
|
committed, failed or rolled back.
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
</chapter>
|
|
|
|
|
|
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
|
|
|