Last Summer I implemented a non-blocking client API in MariaDB, and it was included in the MariaDB 5.5 release. But somehow I never got around to announcing it.

However, that did not prevent Brian White from noticing it, and using it to implement a new mysql binding for node.js called mariasql.

Now, node.js is a single-threaded, event-driven framework for web application sever development. In such frameworks, all I/O is done non-blocking or asynchronously, as are all other actions that may need to wait for external events. There is a single event loop which uses a poll() or similar system call to wait for any pending I/O or other event to complete, and then dispatches the appropriate event handler(s). Such frameworks are often used instead of a multi-threaded model, eg. if threads are not available or to avoid complex inter-thread synchronisations and expensive context switch overhead.

Such frameworks are exactly where the non-blocking client library in MariaDB is useful. The Knowledgebase has all the details, but here is the basic idea:

To run a query, the application does a call like this:

mysql_real_query_start(&status, mysql, “SELECT * FROM t1”);

This will send data on the socket, and the server will start executing the query. But instead of waiting for the results, like in the normalĀ  API, the call then returns immediately. The application can then check the status of the running query; in this case it finds that the query is waiting for data to arrive on such-and-such socket descriptor. The application will then register a callback and include the socket descriptor in the poll() call in its main loop. When data arrives, the callback fires and invokes:

mysql_real_query_cont(&status, mysql, <data_is_ready>)

Then the query processing continues, possibly returning multiple times while waiting for more data to arrive, and finally completing the operation.

The API is carefully designed to be just what is needed for event-driven frameworks like node.js to use it conveniently and efficiently. So I was really pleased to discover the mariasql project apply this theory to practise. I was of course especially pleased to see the benchmarks, where the non-blocking library is significantly faster than other MySQL bindings for node.js when queries (and thus waiting on the network) is involved. Without a proper non-blocking API, frameworks must resort to spawning background threads and defering blocking operations to such background threads; presumably the speedup comes from avoiding the inter-thread synchronisation and context switches. Of course avoiding the maintenance of background threading also simplifies the implementation.

Note by the way that the MariaDB non-blocking client library is fully compatible with all versions of the server, including all MySQL versions. So while mariasql must be linked against the MariaDB client library, it can be used with any MySQL server (the mariasql source tree seems to include the MariaDB client library to make this even easier for users).

Yesterday I set up a new machine for our MariaDB Buildbot. This is quite an important build host for us, it runs more than 20 different builds for each push into our most important trees, and is the host that builds most of our release packages. So quite a workhorse! It is a pretty fast machine, with 5 SSD disks, 48GB of RAM and 2 x quad-core Intel Xeon E5420.

This is a replacement for the previous machine serving the same builds. The previous machine was also nice, at least on paper, with no less than 24 cores. Unfortunately we were never able to run that machine stably, it would crash/hang every few days requiring manual power cycling, which was unacceptable, of course.

The new host has been running for a day or so and seems to work well, hopefully it will prove to be more stable. I wanted to do a quick comparison of the speed of builds on the new host compared to the old:

Overall, the new builder looks about the same speed as the old one, maybe a bit faster even. Which is quite nice, given that the old one has three times the number of cores. The windows build is though significantly faster. This is probably because it turns out this is quite I/O heavy for some reason, and the new host, having SSD for storage, has significantly better I/O performance.