Ulf Wendel

2012/03/02
by admin
Comments Off on PECL/mysqlnd_qc: table pattern based query caching

PECL/mysqlnd_qc: table pattern based query caching

Cache all queries which match a schema pattern is one of the few visible feature additions to PECL/mysqlnd_qc 1.1, the client-side query cache plugin for the mysqlnd library. As usual, this client-side cache is mostly transparent, works with all PHP MySQL APIs (mysql, mysqli, PDO_MySQL) and, of course, supports various storage backends including Memcache, process memory, SQLite, user-defined and more. Please, find details in the quickstart.

Setting a cache condition

Caching only selected queries is something that could be done in 1.0 already, for example, using a callback. What’s new is that filtering is built-in to 1.1. The new feature is straigth forward to use.

mysqlnd_qc_set_cache_condition(
  MYSQLND_QC_CONDITION_META_SCHEMA_PATTERN,
  "test.old%",
  1);

/* cached, TTL = 1s */
$link->query("SELECT id, title FROM oldnews");

/* uncached */
$link->query("SELECT id, title FROM hotnews");

Internally, at the C level, we take an optimistic approach to caching. If cache conditions have been set, we start the internal cache logic for every query. Regardless if it contains a SQL hint to enable caching or not, regardless whether it is a SELECT statement or not. After the query has been processed by the MySQL server, the server send the result set to the client. The result set contains of the actual data and meta data. Then, we compare the database and table names from the meta data with the list of cache conditions set. If they match we cache the query. If they don’t match we drop the recorded wire protocol data and do not put it into the cache.

Other enhancements

The proposed API allows for potential future additions. For example, we may decide to support conditions which define a run time criteria. If a statement exceeds a certain run time, we cache it. Or, a size criteria. Let us know what you need.

However, this is not the main focus of the 1.1 release. The primary goal is to make PECL/mysqlnd_ms and PECL/mysqlnd_qc work together in a way that MySQL Replication slave reads can be transparently replaced with cache accesses, if the application allows for it (more on the idea). I got it working on my computer but that’s another story…

Happy hacking!

@Ulf_Wendel Follow me on Twitter

2012/01/31
by admin
Comments Off on PECL/mysqlnd_ms: faster slave reads

PECL/mysqlnd_ms: faster slave reads

Why read stale data from an asynchronous MySQL replica (slave)? Fetch it from a local cache instead! Good for the clusters overall load, good for your applications performance. And, possible with PECL/mysqlnd_ms 1.3, the replication and load balancing plugin for PHP MySQL users.

The idea is simple

Any application using asynchronous MySQL replication must be capable of handling stale results read from a slave (replica) that is lagging behind the master. The quality of service that the application needs from the database cluster is low. If an application explicitly states the minimum service quality it needs, the underlying systems can adopt to it. That’s a cool thing, because the underlying systems don’t need to do more work than necessary. In the case of a PHP MySQL user, the first underlying system is the database driver library, which is mysqlnd.

Tell mysqlnd that you can deal with data that is as old as five seconds. Then, mysqlnd can search a matching slave lagging no more than five seconds or even replace the slave access with a TTL-based cache access. Cache? Sure, PECL/mysqlnd_qc, various storage backends including main memory, user-defined, APC and Memcache … have a look at the quickstart.

It exists…

The first step is done. The development trees of PECL/mysqlnd_qc 1.1 and PECL/mysqlnd_ms 1.3 have been de-stabilized. A first, crude approach to make the query cache and replication plugin work transparently together exists.


./configure --enable-mysqlnd-ms --enable-mysqlnd-ms-cache-support

PECL/mysqlnd_ms 1.2 introduced the mysqlnd_ms_set_qos() function for setting the service level required from the cluster.

 mysqlnd_ms_set_qos($connection, 
  MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL, 
  MYSQLND_MS_OPTION_CACHE, 
  5);

If you set the service level as shown above, PECL/mysqlnd_ms does never read from a slave that reports itself to be lagging more than 5 seconds behind the master. If no matching slave is found, PECL/mysqlnd_ms picks the master. Additionally, PECL/mysqlnd_ms tries to cache all slave queries for up to 5 seconds. The cache logic is so, that you never get data older than 5 seconds.

The initial cache logic

First, PECL/mysqlnd_ms asks PECL/mysqlnd_qc if the query is already in the cache. If so, PECL/mysqlnd_ms stops searching slaves, continues working and tries to fetch the results from the cache in the following. If fetching from cache fails, which should happen rarely, it reads the result from a master.

In case the query is not cached yet, PECL/mysqlnd_ms searches for all slaves that lag no more than 5 seconds. The cache TTL is reduced by the highest lag found. If, for example, there are two slaves, lagging 2 and 3 seconds behind, the cache TTL is set to 5 - max(2, 3) = 5 - 3 = 2 seconds.

  MYSQLND_MS_OPTION_CACHE Slave lag TTL
Slave 1 5 2 3
Slave 2 5 3 2

Then, slave selection continues, for example, load balancing is done. At the end of the chain eventually one slave has been selected. The query is run on the slave and put into the cache for 2 seconds.

How the plugins work together

PECL/mysqlnd_ms does control the cache, PECL/mysqlnd_qc, through SQL hints. PECL/mysqlnd_ms sets exactly the same SQL hints that are also available to the user, as described in the PECL/mysqlnd_qc manual.

/*qc=on*//*qc_ttl=2*/SELECT id FROM test

… and tomorrow: a sneak preview of the new built-in pattern based caching for PECL/mysqlnd_qc 1.1.

Happy hacking!

@Ulf_Wendel Follow me on Twitter

2012/01/24
by admin
Comments Off on PECL/mysqlnd_qc: query cache statistics log

PECL/mysqlnd_qc: query cache statistics log

Is it worth the efforts to cache the results of a MySQL query at the client? In most cases the answer is: try it, measure it! Install the development version of the mysqlnd query cache plugin, which can be used with PDO_MySQL, mysqli and mysql. Set three PHP directives and find the answer in a log file.

While updating the query cache plugin to support PHP 5.4, the latest versions of APC and Memcached for cache storage, I virtually stumbled upon an undocumented feature I had long forgotten. The plugin can periodically dump statistics into a log file. The plugin collects tons of statistics and query traces to find cache candidates and for measuring cache efficiency. Details can be found in the quickstart.

Quick and dirty evaluation

A quick and dirty evaluation of the maximum performance gain client-side query caching can give you is obtained by caching all statements. The first PHP directive to set is mysqlnd_qc.cache_by_default = 1. Ignore the fact that the cache may serve stale data because its default invalidation strategy is Time-to-Live (TTL). Quick and dirty…

Continue Reading →

2012/01/13
by admin
Comments Off on PHP mysqlnd query cache plugin quickstart is online!

PHP mysqlnd query cache plugin quickstart is online!

New in the PHP manual: a quickstart for the mysqlnd query cache plugin. PECL/mysqlnd_qc, the mysqlnd query cache plugin, is transparent and ease to use. But, how? Some pointers have been given in assorted presentations, here on my blog and in some, few examples from the manual. Fixed. You can now browse a quickstart to gain a quick overview.

Should I consider it?

The PECL/mysqlnd_qc manual is well worth 15 minutes of your attention if you either have a remote MySQL server or, you cannot use the query cache built-in to the MySQL server but want to use query caching. If that’s not the case, you may still want to check its query traces to abuse them for performance monitoring. More on that below.

Caching for the web always follows the same pattern. First, you move caches as close to the client as possible. Then, you select an appropriate granularity for cache contents on all layers for which you plan to use caching. The MySQL server query cache is neat: it never serves stale data and, it comes with MySQL. But, it is not as close to the client as possible. This adds latency and makes scale-by-client a bit more difficult. Unfortunately, there is still no way to connect it to a client-side cache. Thus, PECL/mysqlnd_qc.

Monitoring
Simple monitor from the source distributions web/ directory.

The mysqlnd query cache plugin with its various storage handlers (process memory, APC, Memcache, SQLite, user-defined) has a slide edge over an application centric solution:

  • No or minimal application changes
    • no hassle when updating 3rd party solutions
    • can be used even if code change is not possible but auto_prepend can be set
    • compatible with all PHP MySQL APIs (mysqli, PDO_MySQL, mysql)
    • plugs into to the driver: no extra PHP library/software to install
  • Flexible storage
    • process scope: process memory
    • single machine scope: APC, Memcache, SQLite (memory)
    • multiple machines scope: Memcache
  • Solid monitoring

Whether your cache solution shall have a granularity of individual SQL statements or, for example, should cache rendered HTML fragments is a different story… A nice aspect of PECL/mysqlnd_qc is that you can use it to evaluate the impact of database caching pretty quickly. Turn on caching of all statements, run a benchmark. Whatever database cache solution you end up with, results won’t be better than that. Based on the figures you can decide if its worth the efforts.

The story about monitoring

Even if the caching aspect is not for you, mysqlnd_qc_get_query_trace_log() may appeal to you. To help finding cache candidates the plugin can be instructed to collect a query trace log. The trace contains a statements string, the statements run time, its store time and a backtrace to its origin in the source. Each and every query inspected by the plugin is listed. Because PECL/mysqlnd_qc operated on the driver level, you see all queries from every PHP MySQL extension. The background is described in more detail here.

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_query_trace=1


/* connect to MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");

/* dummy queries to fill the query trace */
for ($i = 0; $i < 2; $i++) {
  $res = $mysqli->query("SELECT 1 AS _one FROM DUAL");
  $res->free();
}

/* dump trace */
var_dump(mysqlnd_qc_get_query_trace_log());


array(2) {
  [0]=>
  array(8) {
    ["query"]=>
    string(26) "SELECT 1 AS _one FROM DUAL"
    ["origin"]=>
    string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(25)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
  [1]=>
  array(8) {
    ["query"]=>
    string(26) "SELECT 1 AS _one FROM DUAL"
    ["origin"]=>
    string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...')
#1 {main}"
    ["run_time"]=>
    int(0)
    ["store_time"]=>
    int(8)
    ["eligible_for_caching"]=>
    bool(false)
    ["no_table"]=>
    bool(false)
    ["was_added"]=>
    bool(false)
    ["was_already_in_cache"]=>
    bool(false)
  }
}

Happy hacking!

Follow me on Twitter - @Ulf_Wendel

2012/01/12
by admin
Comments Off on PHP mysqli quickstart is online!

PHP mysqli quickstart is online!

New in the PHP manual: a mysqli quickstart. You are new to PHP but you know how to code, you know SQL, you know relational databases and MySQL? Then, I hope, this is for you. All you need is a quick overview on the concepts? The rest is in the reference section! Here you go.

The quickstart contains:

In case you prefer listening over reading there is a PHP MySQL web seminar series on PHP for you (hint: search "On Demand" for more). To please everybody, we are giving a webinar summary in german as well on 18.01.2012, register now.

Please, note that I am inpatient and linking to the PHP documentation teams server: http://docs.php.net/manual/en/mysqli.quickstart.php. The php.net mirrors will need a while to catch up.

Happy hacking!

@Ulf_Wendel

2012/01/11
by admin
Comments Off on PECL/mysqlnd_*: CCC – cloud, cluster, caching!

PECL/mysqlnd_*: CCC – cloud, cluster, caching!

We are giving PECL/mysqlnd_qc a second chance. PECL/mysqlnd_qc is a query cache plugin for mysqlnd. It can cache any query issued by any PHP MySQL extension using storage handler for process memory, APC, Memcache and SQLlite. Its default invalidation strategy is Time to Live (TTL). Using a more sophisticated invalidation strategy is possible. Of course, its transparent to use and inherits all the other advantages of a driver based approach.

Cloud and Cluster

Albeit quite powerful the plugin came late and is faced with stiff competition from application-based solutions. With everybody talking about cloud and database clusters, there is a new use case for client-side caching.

No all-in-one cluster solution for all purposes exsits. MySQL users, for example, can choose between MySQL Replication, MySQL Cluster and an emerging number of third party solutions, which proof MySQL to be alive and rocking. The CAP theorem makes me assume that MySQL users will continue to have multiple choices.

Whatever cluster solution will become the dominating force, applications should be enabled to see a cluster as a service. Accordingly, PECL/mysqlnd_ms 1.2 has introduced an API to set the required service level. In version 1.2 the service level option focusses on consistency:

  • Eventual consistency – stale data allows, e.g. when reading from a MySQL replication slave
  • Session consistency – read your writes
  • Strong consistency – every client sees all writes

Whatever type of cluster is used, PECL/mysqlnd_ms will try to deliver the requested consistency by selecting appropriate nodes.

Caching

If the application hints the database driver that eventual consistency is sufficient but data returned shall not be more than five seconds behind, the database driver can replace a slow, eventually remote database access with a fast, local cache access. That’s the second chance PECL/mysqlnd_qc will be given.

PHP application
Service level: eventual consistency, max 5 seconds old
Any PHP MySQL extension (mysqli, PDO_MySQL, mysql)
mysqlnd library
PECL/mysqlnd_ms –> PECL/mysqlnd_qc
    | or |
    Process memory, Memcache, …   |
        MySQL

Documentation updates

Before we begin with it, I have given the PECL/mysqlnd_qc a second chance as well. You can expect to find an improved Quickstart and Examples section at http://docs.php.net/manual/en/book.mysqlnd-qc.php soon. Have a look during the next days, its a cool plugin thing even without the cloud buzzword bingo…

Happy New Year and happy hacking!

@Ulf_Wendel

PHP 5.4 and APC notes

PECL/mysqlnd_qc 1.0.1 is not compatible with PHP 5.4. It has not been updated to the latest mysqlnd API as found in PHP 5.4. Andrey and I have prepared a patch and hope to push a 1.0.2 release soon. Unfortunately, the (private) C API of APC has also changed in the past year. Thus, the cache cannot use a recent APC version for storing cache entries. Of course, you can still use the latest version of APC to boost your PHP scripts even if the scripts use the query cache plugin.

2011/12/23
by admin
Comments Off on PHP MySQL documentation updates

PHP MySQL documentation updates

The MySQL part of the PHP reference manual is currently being restructured: new landing and overview page, mysqli quickstart prepared. Ten years ago, there was the mysql extension and that was it. Today, beginners are faced with three MySQL APIs/extensions, two libraries and more than three library plugins. MySQL support by PHP has never been better. But, where to start: web search for tutorials, a book? The results one gets tend to be flawed: outdated, incomplete, flawed… Thus, the update.

A landing and overview page

The MySQL documentation staging server already shows the new landing and overview page "MySQL Drivers and Plugins". Its introduction makes the PHP reference manuals "Vendor Specific Database Extensions" section less cluttered by grouping all MySQL information under this new overview page.

Under the address http://docs.php.net/manual/en/mysql.php (later on php.net/mysql may work) users find an overview of the MySQL PHP drivers:

After an overview on terminology the three PHP MySQL APIs/extensions mysql, mysqli and PDO_MySQL are compared. A comprehensive feature matrix helps to get started. Next, it is explained how the extensions connect to MySQL by help of a client library. Again, a comprehensive feature matrix compares the two choices, the MySQL Client Library (AKA libmysql) and mysqlnd.

The landing page continues with links to the mysql, mysqli APIs/extensions, followed by mysqlnd and its various plugins.

Hands-on mysqli quickstart prepared

Many years ago when Zak Greant and Georg Richter developed the mysqli extension they made sure to have examples for each and every function. That’s fantastic but meanwhile there is a logical and good trend to include hands-on quickstarts and background concepts information to PHP manual. We all know, a software is worth nothing without adequate easy to use documentation.The documentation must cover the needs of beginners, intermediate users and experts who need little more than reference materials. A bit like with the ~70 pages of PECL/mysqlnd_ms documentation, which begins with a quickstart and a concepts section before the reference section.

Therefore, I’ve written a mysqli quickstart. You have seen some excerpts of it already in my blog:

I hope Philip will be able to review and add the quickstart to the mysqli extension documentation soon. That’s it? Come on, its not yet christmas eve and, do we really need chrismas for making presents…

If you would like to comment on the new contents, please do so on the php.net documentation mailing lists. That’s the appropriate forum for discussions on the PHP reference manual. I’m sure there are still some edges in the new materials that need to be cut off.

.oO( If Andrey and I continued our current pace, where would we be next christmas… )

Happy hacking, happy holidays!

@Ulf_Wendel

2011/12/23
by admin
Comments Off on Load balancing for PHP and MySQL

Load balancing for PHP and MySQL

A single MySQL server is a single point of failure. A single MySQL server can only be scaled vertically by increasing hardware size, which has its limits. That’s two good reasons to migrate from a single MySQL server to a cluster of MySQL servers. However, in cloudy white christmas times, few appreciate the extra work that using a cluster causes. For example, MySQL connections must be load balanced. Please, find a comparison of different load balancing architectures in the short presentation. Choose the one that’s best for you – maybe it is PECL mysqlnd_ms 1.2, the mysqlnd replication and load balancing plugin…

Seasons greetings!

@Ulf_Wendel

2011/12/14
by admin
Comments Off on Welcome PECL/mysqlnd_ms 1.2.0-alpha with global transaction ID support

Welcome PECL/mysqlnd_ms 1.2.0-alpha with global transaction ID support

Christmas time, time for presents! Version 1.2.0-alpha of the free and open source PHP mysqlnd replication and load balancing plugin has been made available on PECL. PECL/mysqlnd_ms makes using any kind of MySQL database cluster easier featuring:

  • Read-write splitting: automatic, SQL hints, can be disabled
  • Load balancing: random, round robin, user defined
  • Fail over
  • Global transaction ID support: client-side emulation
  • Service levels: eventual consistency, session consistency, strong consistency

The last two features are new. The motto/theme of the 1.2 series is: Global Transaction ID injection and quality-of-service concept.

For many years MySQL has adviced PHP developers to implement all kinds of logic needed to use MySQL Replication or MySQL Cluster in the application. PECL/mysqlnd_ms is changing this. Take any PHP MySQL application using any PHP MySQL extension (mysql, mysqli, PDO_MySQL), compile PHP to use the mysqlnd library, install the PECL module, drop it in and, be ready to migrate the application from a single database to a database cluster. At any time, it shall be possible to overrule all automatic decisions of the plugin, whenever needed.

Service levels

One of the biggest challenges when switching from a single database to an asynchronous database cluster, such as a MySQL Replication cluster, is the change in data consistency. A single server delivers strong consistency: all clients see each others changes. A MySQL replication cluster defaults to eventual consistency for a slave access: a client may or may not see its own changes, which is a significantly lower service level. However, in many cases its OK, why else would have an asynchronous approach have gained such popularity.

Version 1.2.0-alpha of mysqlnd_ms introduces a quality of service filter. The application says what service level it needs from the cluster and the plugin delivers:

  • Eventual consistency
    • optional parameter: maximum age, don’t read from slaves that lag too far behind
  • Session consistency (read your writes)
    • optional parameter: global transaction ID for reading from "up-to-date" slaves
  • Strong consistency

A simple function call – mysqlnd_ms_set_qos() – sets the service level.

Further readings:

Global Transaction ID support

In its most basic form a global transaction ID can be described as a transaction counter maintained on the master. If the master fails, the most current slave for master promotion can easily be found by searching the slave with highest transaction ID. The MySQL 5.6 Development Release contains this feature, however, it is neither production ready nor fully functional yet. And, so far, master fail over remains a manual task of the database administrator. Whenever the server solution is ready, mysqlnd_ms users are prepared to make the most out of it.

Beginning with version 1.2.0-alpha, PECL/mysqlnd_ms can to a client-side emulation of the feature and transparently maintain a global transaction ID table on the master. Client-side emulation is a second best solution but one of the few options one has in heterogenous environments with servers that do not have the functionality built-in.

A global transaction ID can also be used for improving session consistency (read your writes) load balancing for MySQL replication. Without a global transaction ID a client cannot say for sure in advance if a slave has already replicated a change. To read the own writes, the client must query the master. By help of a global transaction ID one can find if a certain write has been replicated already by a slave. Read your writes becomes possible on slaves. Read load is taken away from the master.

Further reading:

There is more to say about the release. Please, stay tuned. We started updating the manual. It will take a couple of days to complete the work and until the latest changes have made their way from the PHP manual staging area to the PHP manual mirrors. More blogs are coming as well.

Happy hacking!

@Ulf_Wendel

PS: Pierre, it should build fine on Windows.

2011/12/05
by admin
Comments Off on PECL/mysqlnd_ms: quality of service filter

PECL/mysqlnd_ms: quality of service filter

What if your PHP application could tell the mysqlnd library what service quality you need when using a MySQL replication cluster? If you wanted read-your-writes, the driver would select replication nodes for you which can offer it. If you can allow replication lag but no more than three seconds, the driver would select… One function call and you get the service you need. That’s what version 1.2 of PECL/mysqlnd_ms is about.

The quality of service filter

In the world of PECL/mysqlnd_ms, the free and Open Source replication and load balancing plugin for mysqlnd, a so-called filter is responsible for choosing nodes for statement execution. A filter looks at the SQL statement to be executed and picks a capable server. The current production ready 1.1 release has three filters. Two load balancing filter (random, round-robin) and a user hook filter (user).

For example, if you run a SELECT statement, the filters of PECL/mysqlnd_ms ensure it ends up on a slave.

query(SELECT id FROM test)
|
mysqli PDO_MySQL mysql
mysqlnd library
PECL/mysqlnd_ms magic
|
  Master  
Slave 1 Slave 2 Slave 3

PECL/mysqlnd_ms 1.2 brings a new quality-of-service filter. The quality of service filter can be configured in the plugins configuration file but also at runtime. The latter is new and unique to this filter.

Reading from slaves no more than n seconds behind

Certain elements on a web site qualify for simple TTL based caching. Others don’t. One could say, that the quality of service demands for cacheable contents are lower than for non-cacheable. The same goes for SQL statements. Stale data may be OK, but it may not be older than n seconds, you may want to set a time-to-live, so to say.

MySQL Replication is asynchronous. It takes some time until a write operation on the master has been replicated to all slaves. Slaves may not always serve current data. The MySQL administrative statement SHOW SLAVE STATUS give a hint how many seconds a slave is behind the master (Seconds_Behind_Master). It is a rather rough estimation that MySQL makes but its the best built-in logic I am aware of. Please, check the MySQL reference manual for details.

  Master  
Slave 1 Slave 2 Slave 3
Seconds_Behind_Master = 0 Seconds_Behind_Master = 3 Seconds_Behind_Master = 5

Say your application is fine with reading from slaves that lag no more than three seconds behind the master. With PECL/mysqlnd_ms 1.2 it will be one line to set the required service quality.


mysqlnd_ms_set_qos($link, 
  MYSQLND_MS_QOS_CONSISTENCY_EVENTUAL,
  MYSQLND_MS_QOS_OPTION_AGE,
  3);       

After the function call, PECL/mysqlnd_ms checks for every statement nodes quality for executing the statement. If the statement is a write, the quality-of-service (qos) filter, returns a list of all masters. If the statement is a read, the qos filter returns all masters and all slaves for which Seconds_Behind_Master <= 3 is true. In the example, a SELECT statement would be run on the master, slave 1 or slave 2, depending on the choice of the load balancing filter. Slave 3 is not used because its replication lag is too high.

To be very clear here: the qos filter may execute SHOW SLAVE STATUS on all slaves. This is an expensive and slow operation. But it is the only option availablewith todays MySQL replication server features. One may try to cache the SHOW SLAVE STATUS results but there’s no fundamental change until the MySQL replication cluster can tell clients which nodes to use.

Don’t drop and forget the idea after this warning. The cool thing is, that if you tell PECL/mysqlnd_ms it may replace the slave access with a local TTL cache access… allow disabling the slow status query, focus on the caching idea, and … But that’s for sure not for 1.2.

Reading from slaves which have replicated a global transaction ID

Setting the maximum age using the qos filter gives you eventual consistency. Using global transaction ids, the qos filter can also offer session consistency or read-your-wrtites. PECL/mysqlnd_ms 1.2 can do global transaction id injection and the MySQL replication team has published a global transaction id feature preview release in October. Because the server preview is not fully functional, 1.2 focusses on its client-side emulation and injection.

$link->query("INSERT INTO test(id) VALUES (123)");
$gtid = mysqlnd_ms_get_last_gtid($link);

|
  Master  
  GTID = 27263  
Slave 1 Slave 2 Slave 3
GTID = 27263 GTID = 27251 GTID = 27263

Whoever does maintain the global transaction ids, some SQL exists to check if a node has replicated a certain id or not. The qos filter knows the SQL and checks if a node has replicated the transaction in question. If so, the node can be used to achieve read-your-writes.

mysqlnd_ms_set_qos(
  $link,
  MYSQLND_MS_QOS_CONSISTENCY_SESSION,
  MYSQLND_MS_QOS_OPTION_GTID,
  27263);
$link->query("SELECT * FROM test ");

|
  Master  
  GTID = 27263  
Slave 1 Slave 2 Slave 3
GTID = 27263 GTID = 27251 GTID = 27263

Is it worth it?

The price of the qos filter is high. Checking nodes for every statement is slow. However, if you hit scalability limits of your master because of too many read-your-write requests, there is no choice . PECL/mysqlnd_ms, a driver-based solution, does not do worse than an application-based solution. But, it takes work from you, the application developer.

If that’s not convincing, OK, but what about the caching idea…

Happy hacking!

@Ulf_Wendel

PS: Do you speak portuguese? If so, you may want to check out this PHP Conference Brasil presentation from Airton Lastori.