WL#3665: Plug-in interface for master replication module

Affects: Server-Prototype Only   —   Status: On-Hold

In order to handle the master side of replication, it would be beneficial to
allow the master replication module to be dynamically loadable.

There are at least the following interfaces that master-side replication has to
consider:

1. Transaction and statement execution monitoring
2. Thread management
3. Error reporting
4. Memory allocation
In order to separate the replication from the main server, it is necessary to
provide the following items:

- Adding listeners on statement execution
- Adding listeners on row operations


Replication call sequence
-------------------------

The sequence of calls between the server, the handlerton, and the handler is
captured in the following sequence diagram:




Listening on statement execution
--------------------------------

Whenever a statement starts execute, the handlerton for the storage engine that
statement affects will be able to detect the start of a statement because of a
call to create() to create a handler and a subsequent call to external_lock().
The storage engine can then call trans_register_ha() to register for that
transaction and get notifications when the transaction commits or aborts.

However, the replication is implicit in each statement, and will not
automatically receive a call where it can register for the transaction. Support
for calling replication is currently hard-coded, but for a replication plug-in
it is necessary to provide interfaces for registering listeners.

In order to allow the binary log to register for a transaction, two separate
callback to the handlerton interface will be added:

  int (*query_start)(handlerton *hton, THD *thd);
  int (*query_finish)(handlerton *hton, THD *thd);

To register a handlerton to receive callbacks on the start and finish of each
query, the following functions will be added:

  int query_exec_register_ha(handlerton *ht_arg);
  int query_exec_unregister_ha(handlerton *ht_arg);


Listening on row operations
---------------------------

Whenever a row is written, deleted, or updated, the handler receives a call to
the write_row(), delete_row(), and update_row() callback for the handler.

Currently, it is hard-coded that replication will execute a row operation
similar to what the engine does after the row operation have successfully completed.

In order to support the binary log to listen in on replication of individual
rows, it is necessary to allow also the binary log handlerton to create a
handler, which will then receive row operations in parallel with the storage
engine handler.

However, depending on circumstances and implementation, the binary log might be
interested in receiving the row before the actual storage engine as well as
after the storage engine.
Module log
==========

binlog_init()
Register the binlog handlerton to get callbacks on statement start.

binlog_deinit()
Unregister the handlerton.


Module si_trans
===============

New module: files si_trans.h and si_trans.cc

query_exec_register_ha(handlerton *)
Will register a handlerton to receive callbacks when statements start and end.

query_exec_unregister_ha(handlerton *)
Unregister handlerton