Friday, February 25, 2011

Drizzle's Slave Plugin and the Execute class

Well, you may have already read Andrew's and Patrick's blog posts on it, but if you haven't, we now have a Drizzle plugin that implements native replication between Drizzle servers.

So, the initial plan was to support work by the community to have Tungsten Replicator ready as a replication solution for our first GA release. However, this didn't look like it would get completed in time for GA, so the decision was made to make a strong push to get a native solution ready. So after a big group effort, and many, many late nights and long weekends, we are pleased to say that we have delivered the initial version of a native replication solution.

Now, does this version have all of the features that we want? No. It will certainly be added to, though, as we progress. Keep in mind that replication was totally ripped out of Drizzle, so it will take some time to build on its functionality.

But what makes this release so exciting if it doesn't have all the features you want? Well, thanks to the solid backbone of a well tested transaction log and a well designed and flexible replication architecture (big shout out to Jay), it took only 2 weeks (admittedly, 2 very hard weeks) and 1900 lines of C++ code to implement this plugin. With only 1900 LOC, it is extremely simple to understand and expand on and improve. A kid just out of college could understand this.  :)  So if you want to add a cool feature to the plugin, it shouldn't take too much effort to add your contribution. How easily could you do this in any other database?

Patrick has already blogged about how easy it is to begin using the replication slave plugin. It should hit our main trunk later today, so feel free to give it a try. In later posts, I'll attempt to cover some of the implementation details, but there is one REALLY cool feature in Drizzle that is used by the slave plugin that I want to quickly cover...

The slave plugin has to execute SQL statements on the local server to apply the changes from the master. In the MySQL code, executing SQL locally isn't easy to do. Logically, you would think that it should be easy for a database kernel to execute SQL on itself. Alas, this was not the case.

Thanks to some changes by Brian Aker to the Drizzle kernel, the slave plugin can very easily do this by using the drizzled::Execute class. This class has a run() method that takes a std::string with the SQL to execute. Here is a simple example from the slave plugin code:

Execute execute(*(_session.get()), true);
string sql("SELECT `trx_id` FROM `sys_replication`.`queue`"
               " WHERE `commit_order` IS NOT NULL ORDER BY `commit_order` ASC");
sql::ResultSet result_set(1);
execute.run(sql, result_set);

It's as simple as that. Execute wraps whatever SQL you give it (it can be multiple statements) in a transaction and executes it. The ResultSet object will contain your results and any exceptions that may have been thrown (we are trying to match the JDBC API here).  Some of this API is still a work-in-progress, but it has proven to be extremely useful and solid so far. If you are interested, you can look at the Execute class source in the drizzled/execute.h and drizzled/execute.cc files.