-
MySQL 5.6 Replication Webinar
Posted on March 26th, 2013 No commentsUpdate – the recording of this webinar is now available here.
This Wednesday (27th March) Mat Keep and I will be presenting a free, live webinar on MySQL 5.6 Replication. You need to register here ahead of the webinar – worth doing even if you can’t attend as you’ll then be sent a link to the replay when it’s available. We’ll also have some of the key MySQL replication developers on-line to answer your questions and so it’s also a great chance to get some free consultancy
Details….
Join this session to learn how the new replication features in MySQL 5.6 enable developers and DBAs to build and scale next generation services using the world’s most popular open source database. MySQL 5.6 delivers new replication capabilities which we will discuss and demonstrate in the webinar:
- High performance with Binary Log Group Commit, Multi-Threaded Slaves and Optimized Row Based Replication
- High availability with Global Transaction Identifiers, Failover Utilities and Crash Safe Slaves & Binlog
- Data integrity with Replication Event Checksums
Dev/Ops agility with new Replication Utilities, Time Delayed Replication and more
The session will wrap up with resources to get started with MySQL 5.6.
WHEN:
Wed, Mar 27: 07:00 Pacific time (America)
Wed, Mar 27: 08:00 Mountain time (America)
Wed, Mar 27: 09:00 Central time (America)
Wed, Mar 27: 10:00 Eastern time (America)
Wed, Mar 27: 14:00 UTC
Wed, Mar 27: 14:00 Western European time
Wed, Mar 27: 15:00 Central European time
Wed, Mar 27: 16:00 Eastern European time
Wed, Mar 27: 19:30 India, Sri Lanka
Wed, Mar 27: 22:00 Singapore/Malaysia/Philippines time
Wed, Mar 27: 22:00 China time
Wed, Mar 27: 23:00 日本
Thu, Mar 28: 01:00 NSW, ACT, Victoria, Tasmania (Australia)The presentation will be approximately 60 minutes long.
-
MySQL 5.6 GA – Replication Enhancements
Posted on February 5th, 2013 1 commentMySQL 5.6 has now been declared Generally Available (i.e. suitable for production use). This is a very exciting release from a MySQL replication perspective with some big new features. These include:- Global Transaction Identifiers (GTIDs) – a unique identifier that is used accross your replication topology to identify a transaction. Makes setting up and managing your cluster (including the promotion of a new master) far simpler and more reliable.
- Multi-threaded slaves (MTS) – Increases the performance of replication on the slave; different threads will handle applying events to different databases.
- Binary Log Group Commit – Improves replication performance on the master.
- Optimized Row Based Replication – reduces the amount of data that needs to be replicated; reducing network usage and potentially speeding up replication.
- Crash-Safe Replication – makes replication transactional. The data and replication positioning information are both updated as part of the same transaction.
- Replication Event Checksums – checks to ensure that the data being replicated hasn’t become corrupted, avoids writing corrupted data to the slave.
- Time-Delayed Replication – configure one or more of your slaves to only apply replicated events after a configured time. This can be useful to protect against DBA mistakes.
- Informational Logs – includes the original statement in the binary log when using row-based-replication to aid in debugging.
To coincide with the GA announcement, a new white paper has been released – MySQL 5.6 Replication An Introduction – that provides a lot more details on these new features. We’ve also released a second white paper – MySQL 5.6 Replication, Enhancing Scalability and Availability – A Tutorial that steps you through using MySQL Replication, with a particular focus on the new features.
If you’re already familiar with using MySQL Replication, here are a few pointers on what to do differently for the new MySQL 5.6 features but you should refer to the full tutorial to see these changes in context.
First of all, here are some extra configuration parameters to include…
[mysqld] gtid-mode=on # GTID enforce-gtid-consistency=true # GTID master-info-repository=TABLE # Chrash-safe replication relay-log-info-repository=TABLE # Chrash-safe replication slave-parallel-workers=2 # MTS binlog-checksum=CRC32 # Checksums master-verify-checksum=1 # Checksums slave-sql-verify-checksum=1 # Checksums binlog-rows-query-log_events=1 # Informational logs
When initiating (or restarting) replication on the slave, it is no longer necessary to include the binary log positioning information as the master and slave will automatically negotiate what outstanding events need to be replicated based on any GTIDs previously received by the slave…
slave> CHANGE MASTER TO MASTER_HOST='black', MASTER_USER='repl_user', MASTER_PASSWORD='billy', MASTER_AUTO_POSITION=1;Please try out these new features and let us know what you think.
-
Upcoming conferences to learn more about MySQL Cluster & Replication
Posted on May 18th, 2012 No commentsThere are a couple of conferences coming up where you can expect to learn about the latest developments in MySQL Cluster and MySQL Replication (as well as what else is happening in MySQL 5.6).
The first is the Oracle MySQL Innovation Day which is being held in Oracle HQ at Redwood Shores. This is an all-day event on 5th June – unfortunately I won’t be able to attend this one but there will be lots of great Cluster and replication sessions. If you can’t make it out to California then there will be a live Webcast. You can register here to attend in person or join the webcast.
The second is MySQL Connect – this runs the weekend before Oracle OpenWorld in San Francisco; it’s not until 29th September but it’s worth registering now to get the early bird pricing and save $500 (end 13th July). There are lots of great sessions lined up both from the MySQL experts within Oracle and users and community members.
-
Upcoming webinar: MySQL 5.6 Replication – For Next Generation of Web and Cloud Services
Posted on May 10th, 2012 No commentsOn Wednesday (16th May 2012), Mat Keep and I will be presenting the new replication features that are previewed as part of the latest MySQL 5.6 Development Release. If you’d like to attend then register here.
MySQL 5.6 delivers new replication capabilities which we will discuss in the webinar:
- High performance with Multi-Threaded Slaves and Optimized Row Based Replication
- High availability with Global Transaction Identifiers, Failover Utilities and Crash Safe Slaves & Binlog
- Data integrity with Replication Event Checksums
- Dev/Ops agility with new Replication Utilities, Time Delayed Replication and more
The session will wrap up with resources to get started with MySQL 5.6 and an opportunity to ask questions.
The webinar will last 45-60 minutes and will start on Wednesday, May 16, 2012 at 09:00 Pacific time (America); start times in other time zones:
- Wed, May 16: 06:00 Hawaii time
- Wed, May 16: 10:00 Mountain time (America)
- Wed, May 16: 11:00 Central time (America)
- Wed, May 16: 12:00 Eastern time (America)
- Wed, May 16: 16:00 UTC
- Wed, May 16: 17:00 Western European time
- Wed, May 16: 18:00 Central European time
- Wed, May 16: 19:00 Eastern European time
As always, it’s worth registering even if you can’t make the live webcast as you’ll be emailed a link to the replay as soon as it’s available.
-
MySQL 5.6 Replication Enhancements – webinar replay
Posted on January 6th, 2012 1 commentThe replay has now been released for the MySQL 5.6 replication enhancements replay where you can get the latest information on all of the great new content that has been included in the MySQL 5.6 Development Releases as well as some features that are still being developed. You can view the replay here.
Some of the topics discussed are:
- Enhanced data integrity: Global Transactions Identifiers, Crash-Safe Slaves and Replication Event Checksums;
- High performance: Multi-Threaded Slaves, Binlog Group Commit and Optimized Row-Based Replication;
- Improved flexibility: Time Delayed Replication, Multi-Source Replication, Binlog API and Informational Log Events
-
Delayed Replication in MySQL 5.6 Development Release
Posted on April 13th, 2011 4 commentsThe new Development Release for MySQL 5.6 contains a great feature that our users have been asking for for a while (work log 344 first raised in 2010!) – delayed replication.
The concept (and as you’ll see the execution) is extremely simple. If a user makes a mistake on the master – such as dropping some critical tables – then we want to give them the opportunity to recover the situation by using the data held on one of the slaves. The problem is that the slave is busily trying to keep up with the master and in all likelihood will have dropped these tables before the user has time to pull the plug on the replication stream. What this feature does is give the DBA the option to introduce a configurable delay into the replication process so that they have time to cut it off before the mistake is propagated.
This blog explains how this works, how to set that up and then how to bring the slave up to date (to the point in time just before the mistake was made on the master).
To understand how this is implemented, it helps to have a little bit of background on how MySQL replication is implemented. When a change is made on the master, it is applied to the master’s local disk copy and then written to the binary log. The change is then asynchronously (but normally immediately) copied from the master’s binary log to the relay log on the slave; from there an SQL thread on the slave will read the change from the relay log and apply it to the slave’s copy of the data.
This feature works by allowing the user to configure a delay between when the change is applied on the master and when that change is taken from the relay log and applied to the slave. Note that if the master fails during this delay period then the change is not lost as it is has already been safely recorded in the slave’s relay log.
As the delay is implemented on the slave, you are free to use ‘real-time’ replication to one slave (to allow the fastest possible failover if the master fails) and delayed replication to a second slave to guard against user error. This is the setup that this post steps through.
For simplicity, all three MySQL Servers will be run on a single host but each uses a different port number as shown in the diagram. “slave” will apply changes as quickly as it can while “slave2″ will introduce a delay when applying changes from its relay log.
Setting up the first slave is very standard:
master> CREATE USER repl_user@localhost; master> GRANT REPLICATION SLAVE ON *.* TO repl_user@localhost IDENTIFIED BY 'pw';
slave> CHANGE MASTER TO -> MASTER_HOST = 'localhost', -> MASTER_PORT = 3306, -> MASTER_USER = 'repl_user', -> MASTER_PASSWORD = 'pw';
slave> start slave;When setting up the delayed slave, one extra parameter is included in the CHANGE MASTER command:slave2> CHANGE MASTER TO -> MASTER_HOST = 'localhost', -> MASTER_PORT = 3306, -> MASTER_USER = 'repl_user', -> MASTER_PASSWORD = 'pw', -> MASTER_DELAY = 20;
slave2> START SLAVE;The MASTER_DELAY parameter indicates the delay in seconds (here I’ve used 20 seconds – in a production environment you’d probably want to give your self much longer.Prior to this, a simple table had already been created:master> CREATE DATABASE clusterdb;USE clusterdb; master> CREATE TABLE towns (Town VARCHAR(20));
Next we check that changes are immediately applied on slave while delayed on slave2:master> INSERT INTO towns VALUES ("Maidenhead"),("Bray");slave> SELECT * FROM towns; +------------+ | Town | +------------+ | Maidenhead | | Bray | +------------+slave2> SELECT * FROM towns; Empty set (0.00 sec) slave2> SELECT * FROM towns; +------------+ | Town | +------------+ | Maidenhead | | Bray | +------------+
The next step is to simulate a user error; I add some more data to the table and then drop the table. Following on from that I stop the replication on slave2 before the mistake is applied:master> INSERT INTO towns VALUES ("Cookham"),("Marlow"); master> DROP TABLE towns;slave> SELECT * FROM tables; ERROR 1146 (42S02): Table 'clusterdb.tables' doesn't existslave2> STOP SLAVE; slave2> SELECT * FROM towns; +------------+ | Town | +------------+ | Maidenhead | | Bray | +------------+
This is a good start, while slave has dropped the table, it still exists on slave2. Unfortunately, slave2 is missing the additions to the table that were made just before the mistake was made. The next step is to bring slave 2 almost up to date – stopping just before the table was dropped. To do this we need to find the position within the master’s binary log just before the table was dropped – this can be done using the SHOW BINLOG EVENTS command on the master. Once we have that position (file-name + position) we can tell slave 2 to catch up just to that point using START SLAVE UNTIL
. Once that has been done, I check that the extra 2 inserts have been applied to slave2: master> SHOW BINLOG EVENTS\G....*************************** 10. row *************************** Log_name: ws2-bin.000001 Pos: 842 Event_type: Query Server_id: 1 End_log_pos: 957 Info: use `clusterdb`; INSERT INTO towns VALUES ("Cookham"),("Marlow") *************************** 11. row *************************** Log_name: ws2-bin.000001 Pos: 957 Event_type: Xid Server_id: 1 End_log_pos: 984 Info: COMMIT /* xid=32 */ *************************** 12. row *************************** Log_name: ws2-bin.000001 Pos: 984 Event_type: Query Server_id: 1 End_log_pos: 1096 Info: use `clusterdb`; DROP TABLE `towns` /* generated by server */
slave2> START SLAVE UNTIL -> MASTER_LOG_FILE='ws2-bin.000001', -> MASTER_LOG_POS=984;
slave2> SELECT * FROM towns; +------------+ | Town | +------------+ | Maidenhead | | Bray | | Cookham | | Marlow | +------------+
Success! Now slave2 contains exactly the data we need. After this it’s up to you what to do next; typically this could involve promoting slave2 to be the new master.
If you want to try this out for yourselves then you can download the MySQL 5.6 Milestone Development Release from dev.mysql.com (select the Development Maintenance Release sub-tab to get MySQL 5.6).
-
Feature Preview – Multi-Threaded Replication Slaves
Posted on April 12th, 2011 No comments
This week, MySQL released a feature-preview – the ability to have multiple threads on the slave so that it is better able to keep pace with the updates being applied on the master. To simplify potential sequencing issues, all updates for a particular database will be handled by the same thread – in other words you need to make sure that your application uses multiple databases in order to see the benefits.
Luís Soares (from the development team) has written a great Blog going into the details. -
New white paper – MySQL Replication – Enhancing Scalability and Availability with MySQL 5.5
Posted on October 13th, 2010 1 commentA new white paper has been published that covers MySQL Replication – background information, how it works, how to use it and what’s new in MySQL 5.5. Simply register for the white paper at mysql.com and you’ll be sent your free copy.
The paper starts by covering the fundamental concepts behind replication such as the difference between synchronous and asynchronous replication and the idea behind semisynchronous replication.
It goes on to describe the common use-cases for replication – scaling out, high availability, geographic redundancy and offloading backups or analytics.
Various replication topologies are discussed from simple master-slave to multi-master rings.
As the title of the paper suggests, the paper covers the significant replication changes introduced in MySQL 5.5:
- Semisynchronous replication: Improved resilience by having master wait for slave to persist events.
- Slave fsync tuning & Automatic relay log recovery: Option to dictate when relay logs are written to disk rather than relying on default operating system behavior; set sync_relay_log=1 to ensure that no more than 1 statement or transaction is missing from the relay log after a crash. The slave can now recover from corrupted relay logs by requesting corrupt entries to be resent from the master. Three new options are introduced (sync-master-info, sync-relay-log and sync-relay-log-info)
- Replication Heartbeat: Automatically checks the status of the connection between the master and the slave(s), allowing a more precise failure detection mechanism. Can detect loss of connection within milliseconds (configurable). Avoid unnecessary relay log rotation when the master is idle.
- Per server replication filtering: When a server is removed from a replication ring, a surviving server can be selected to remove its outstanding replication messages once they’ve been applied by all servers.
- Precise Slave Type Conversions: Allows different types to be used on the master and slave, with automatic type promotion and demotion when using row-based replication (already possible with statement-based replication)
- Individual Log Flushing: Selectively flush server logs when using ‘FLUSH LOGS’ for greater control
- Safe logging of mixed transactions: Replicate transactions containing both InnoDB and MyISAM changes
To be better able to use replication, it helps to understand the basics about how MySQL Replication has been implemented – for example the roles of the binary and relay logs and so this is covered.
Perhaps the most useful sections are those that actually walk through using MySQL Replication – specifically these activities:
- Configuring, running and testing replication
- Migrating from traditional asynchronous replication to semisynchronous replication
- Administering & monitoring replication (including MySQL Enterprise Monitor)
- Failover and recovery
Replication is a little different when using MySQL Cluster; most significantly because you can have multiple MySQL Servers and other application nodes modifying the same database but also because the domains where MySQL Cluster has been used have required extreme High Availability and so there are Cluster-unique features such as active-active replication with conflict detection and resolution. This paper isn’t focussed on MySQL Cluster but a summary of these differences is included.
-
Software preview MySQL Scriptable Replication
Posted on November 24th, 2009 7 commentsA MySQL Software preview is available which allows you to write Lua scripts to control replication on a statement-by-statement basis. Note that this is prototype functionality and is not supported but feedback on its usefulness would be gratefully received.The final version would allow much greater functionality but this preview allows you to implement filters on either the master or slave to examine the statements being replicated and decide whether to continue processing each one or not.
After reading this article, you may be interested in trying this out for yourself and want to create your own script(s). You can get more information on the functionality and download the special version of MySQL from http://forge.mysql.com/wiki/ReplicationFeatures/ScriptableReplication
To understand how this feature works, you first need to understand the very basics about how MySQL replication works. Changes that are made to the ‘Master’ MySQL Server are written to a binary log. Any slave MySQL Servers that subscribe to this master are sent the data from the master’s binary log; the slave(s) then copy this data to their own relay log(s). The slave(s) will then work through all of the updates in their relay logs and apply them to their local database(s). The implementation is a little more complex when using MySQL Cluster as the master’s updates may come through multiple MySQL Servers or directly from an application through the NDB API but all of the changes will still make it into the binary log.
MySQL Replication supports both statement and row based replication (as well as mixed) but this software preview is restricted to statement based replication. As MySQL Cluster must use row based replication this preview cannot be used with Cluster but the final implementation should work with all storage engines.
As show in Fig. 1 there are 4 points where you can choose to filter statements being replicated:
- Before the update is written to the binary log
- After the update has been read from the binary log
- Before the update is written to the relay log
- After the update has been read from the relay log
The final 2 interest me most as it allows us to have multiple slaves which apply different filters – this article includes a worked example of how that could be exploited.
The filters are written as Lua scripts. The names of the script file, module name and function names vary depending on which of these filtering points is to be used. Fig. 2 shows these differences. In all cases, the scripts are stored in the following folder: “<mysql-base-directory>/ext/replication”.
This article creates 2 different scripts – one for each of 2 slave servers. In both cases the filter script is executed after an update is read from the relay log. One slave will discard any statement of the form “INSERT INTO <table-name> SET sub_id = 401, …” by searching for the sub string “sub_id = X” where X is even while the second slave will discard any where X is odd. Any statement that doesn’t include this pattern will be allowed through.
If a script returns TRUE then the statement is discarded, if it returns FALSE then the replication process continues. Fig. 3 shows the architecture and pseudo code for the odd/even replication sharding.
The actual code for the two slaves is included here:
slave-odd: <mysql-base-directory>/ext/replication/relay_log.lua
function after_read(event) local m = event.query if m then id = string.match(m, "sub_id = (%d+)") if id then if id %2 == 0 then return true else return false end else id = string.match(m, "sub_id=(%d+)") if id then if id %2 == 0 then return true else return false end else return false end end else return false end endslave-even: <mysql-base-directory>/ext/replication/relay_log.lua
function after_read(event) local m = event.query if m then id = string.match(m, "sub_id = (%d+)") if id then if id %2 == 1 then return true else return false end else id = string.match(m, "sub_id=(%d+)") if id then if id %2 == 1 then return true else return false end else return false end end else return false end endReplication can then be set-up as normal as described in Setting up MySQL Asynchronous Replication for High Availability with the exception that we use 2 slaves rather than 1.
Once replication has been started on both of the slaves, the database and tables should be created; note that for some reason, the creation of the tables isn’t replicated to the slaves when using this preview load and so the tables actually need to be created 3 times:
mysql-master> CREATE DATABASE clusterdb; mysql-master> USE clusterdb; mysql-master> CREATE TABLE sys1 (code INT NOT NULL PRIMARY KEY, country VARCHAR (30)) engine=innodb; mysql-master> CREATE TABLE subs1 (sub_id INT NOT NULL PRIMARY KEY, code INT) engine=innodb;
mysql-slave-odd> USE clusterdb; mysql-slave-odd> CREATE TABLE sys1 (code INT NOT NULL PRIMARY KEY, country VARCHAR (30)) engine=innodb; mysql-slave-odd> create table subs1 (sub_id INT NOT NULL PRIMARY KEY, code INT) engine=innodb;
mysql-slave-even> USE clusterdb; mysql-slave-even> CREATE TABLE sys1 (code INT NOT NULL PRIMARY KEY, country VARCHAR (30)) engine=innodb; mysql-slave-even> CREATE TABLE subs1 (sub_id INT NOT NULL PRIMARY KEY, code INT) engine=innodb;
The data can then be added to the master and then the 2 slaves can be checked to validate that it behaved as expected:
mysql-master> INSERT INTO sys1 SET area_code=33, country="France"; mysql-master> INSERT INTO sys1 SET area_code=44, country="UK"; mysql-master> INSERT INTO subs1 SET sub_id=401, code=44; mysql-master> INSERT INTO subs1 SET sub_id=402, code=33; mysql-master> INSERT INTO subs1 SET sub_id=976, code=33; mysql-master> INSERT INTO subs1 SET sub_id=981, code=44;
mysql-slave-odd> SELECT * FROM sys1; +------+---------+ | code | country | +------+---------+ | 33 | France | | 44 | UK | +------+---------+ mysql-slave-odd> SELECT * FROM subs1; +--------+------+ | sub_id | code | +--------+------+ | 401 | 44 | | 981 | 44 | +--------+------+
mysql-slave-even> SELECT * FROM sys1; +------+---------+ | code | country | +------+---------+ | 33 | France | | 44 | UK | +------+---------+ mysql-slave-even> SELECT * FROM subs1; +--------+------+ | sub_id | code | +--------+------+ | 402 | 33 | | 976 | 33 | +--------+------+
Fig. 4 illustrates this splitting of data between the 2 slaves – all rows from the system table are stored in both databases (as well as in the master) while the data in the subscriber table (and it would work for multiple subscriber tables too) are partitioned between the 2 databases – odd values in one, even in the other. Obviously, this could be extended to more slaves by changing the checks in the scripts.
As an illustration of how this example could be useful, all administrative data could be provisioned into and maintained by the master – both system and subscriber data. Each slave could then serve a subset of the subscribers, providing read-access to the administrative data andread/write access for the more volatile subscriber data (which is mastered on the ‘slave’). In this way, there can be a central point to manage the administrative data while being able to scale out to multiple, databases to provide maximum capacity and performance to the applications. For example, in a telco environment, you may filter rows by comparing a subscriber’s phone number to a set of area codes so that the local subscribers are accessed from the local database – minimising latency.
From a data integrity perspective, this approach is safe if (and only if) the partitioning rules ensures that all related rows are on the same slave (in our example, all rows from all tables for a particular subscriber will be on the same slave – so as long as we don’t need transactional consistency between different subscribers then this should be safe).
As mentioned previously this software preview doesn’t work with MySQL Cluster but looking forward to when it does, the example could be extended by having each of the slave servers be part of the same Cluster. In this case, the partitioned data will be consolidated back into a single database (for this scenario, you would likely configure just one server to act as the slave for the system data). On the face of it, this would be a futile exercise but in cases where the performance bottlenecks on the throughput of a single slave server, this might be a way to horizontally scale the replication performance for applications which make massive numbers of database writes.
-
MySQL Cluster: Geographic Replication Deep-Dive webinar
Posted on November 17th, 2009 No commentsI will be presenting a free Webinar on Geographic Replication for MySQL Cluster at 9:00 am (UK time) on Tuesday 24 November.MySQL Cluster has been deployed into some of the most demanding web, telecoms and enterprise /
government workloads, supporting 99.999% availability with real time performance and linear write scalability.You can register on-line here.
Tune into this webinar where you can hear from the MySQL Cluster product management team provide a detailed “deep dive” into one of MySQL Cluster’s key capabilities – Geographic Replication.
In this session, you will learn how using Geographic Replication enables your applications to:
- Achieve higher levels of availability within a data center or across a WAN
- Locate data closer to users, providing lower latency access
- Replicate to other MySQL storage engines for complex data analysis and reporting of real time data
- Gow to get started with Geographic Replication
Tuesday, November 24, 2009: 10:00 Central European time
- Tue, Nov 24: 09:00 Western European time
- Tue, Nov 24: 11:00 Eastern European time
The presentation will be approximately 1 hour long, including on-line Q&A.
-
Free MySQL webinar today – High Availability Architectures for Online Applications
Posted on September 29th, 2009 No commentsUpdate: You can now download a recording of the webinar and the slides from http://www.mysql.com/news-and-events/on-demand-webinars/display-od-403.html
I’ll be presenting the fourth (and final) session of the MySQL for Online Applications webinar series today (29 September). Today’s High Availability Architectures for Online Applications webinar covers:
- MySQL Replication
- MySQL Cluster
- Distributed Replicated Block Device (DRBD)
- Other high-availability technologies
This session starts at 10:00 am Pacific Time but will be rerun tomorrow at 10:00 am CET (9:00 am UK) with Ivan Zoratti presenting (I’ll be handling questions).
More details for today’s webinar:
Tuesday, September 29, 2009
Join us for the last of our 4 part webinar series exploring the different aspects of using MySQL as the backend database for online applications. With real life experience gained working with MySQL Customers such as Facebook, Alcatel Lucent and Google, this webinar series will give you the information you need to run scalable, highly available online applications.
In this last installment we look at MySQL high availability technologies and architectures. We will explore the uses cases for implementing:
- MySQL Replication
- MySQL Cluster
- Distributed Replicated Block Device (DRBD)
- Other high-availability technologies
Also, covered will be the fundamentals of how these technologies work and how they can be combined to create a more scalable and highly available database infrastructure. Several case studies will be presented to show how these technologies have been implemented in the real world.
Whether you are already using MySQL for your online application or considering it for a new project then register today to learn how you can make best use of the world’s most popular database for online applications.
WHO:
Andrew Morgan, Senior Product Manager, MySQL
WHAT:
High Availability Architectures for Online Applications web presentation.
WHEN:
Tuesday, September 29, 2009: 10:00 Pacific time (America)
Tue, Sep 29: 07:00 Hawaii time Tue, Sep 29: 11:00 Mountain time (America) Tue, Sep 29: 12:00 Central time (America) Tue, Sep 29: 13:00 Eastern time (America) Tue, Sep 29: 17:00 UTC Tue, Sep 29: 18:00 Western European time Tue, Sep 29: 19:00 Central European time Tue, Sep 29: 20:00 Eastern European time High Availability Architectures for Online Applications -
MySQL Cluster: Geographic Replication Deep-Dive
Posted on September 1st, 2009 No commentsFollowing requests received during earlier MySQL Cluster webinars, a new (and as always, free) webinar has been scheduled which focuses on MySQL Cluster Replication. The webinar is scheduled for Thursday 10 September and you can register at http://www.mysql.com/news-and-events/web-seminars/display-415.html
I’ll be on-line during the webinar, answering questions.
Details….
MySQL Cluster: Geographic Replication Deep-Dive
Thursday, September 10, 2009
MySQL Cluster has been deployed into some of the most demanding web, telecoms and enterprise / government workloads, supporting 99.999% availability with real time performance and linear write scalability.
Tune into this webinar where you can hear from the Director of MySQL Server Engineering provide a detailed “deep dive” into one of MySQL Cluster’s key capabilities – Geographic Replication.
In this session, you will learn how using Geographic Replication enables your applications to :
- achieve higher levels of availability within a data center or across a WAN
- locate data closer to users, providing lower latency access
- replicate to other MySQL storage engines for complex data analysis and reporting of real time data
- how to get started with Geographic Replication
WHO:
- Tomas Ulin, Director, MySQL Server Technologies
- Matthew Keep, MySQL Cluster Product Management
WHAT:
MySQL Cluster: Geographic Replication Deep-Dive web presentation.
WHEN:
Thursday, September 10, 2009: 09:30 Pacific time (America)
Thu, Sep 10: 06:30 Hawaii time Thu, Sep 10: 10:30 Mountain time (America) Thu, Sep 10: 11:30 Central time (America) Thu, Sep 10: 12:30 Eastern time (America) Thu, Sep 10: 16:30 UTC Thu, Sep 10: 17:30 Western European time Thu, Sep 10: 18:30 Central European time Thu, Sep 10: 19:30 Eastern European time The presentation will be approximately 45 minutes long followed by Q&A.
WHERE:
Simply access the web seminar from the comfort of your own office.
WHY:
To learn more about how you can use Geographic Replication in MySQL Cluster 7.0 to build real time, high performance applications delivering continuously available database services.
-
Using NDB API Events to mask/hide colum data when replicating
Posted on August 13th, 2009 No commentsIf you have asynchronous replication where the slave database is using MySQL Cluster then you can use the NDB API events functionality to mask/overwrite data. You might do this for example if the replica is to be used for generating reports where some of the data is sensitive and not relevant to those reports. Unlike stored procedures, NDB API events will be triggered on the slave.
The first step is to set up replication (master->slave rather than multi-master) as described in Setting up MySQL Asynchronous Replication for High Availability).
In this example, the following table definition is used:
mysql> use clusterdb; mysql> create table ASSETS (CODE int not null primary key, VALUE int) engine=ndb;
The following code should be compiled and then executed on a node within the slave Cluster:
#include <NdbApi.hpp> #include <stdio.h> #include <iostream> #include <unistd.h> #include <cstdlib> #include <string.h> #define APIERROR(error) \ { std::cout << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ << error.code << ", msg: " << error.message << "." << std::endl; \ exit(-1); } int myCreateEvent(Ndb* myNdb, const char *eventName, const char *eventTableName, const char **eventColumnName, const int noEventColumnName); static void do_blank(Ndb*, int); int main(int argc, char** argv) { if (argc < 1) { std::cout << "Arguments are <connect_string cluster>.\n"; exit(-1); } const char *connectstring = argv[1]; ndb_init(); Ndb_cluster_connection *cluster_connection= new Ndb_cluster_connection(connectstring); // Object representing the cluster int r= cluster_connection->connect(5 /* retries */, 3 /* delay between retries */, 1 /* verbose */); if (r > 0) { std::cout << "Cluster connect failed, possibly resolved with more retries.\n"; exit(-1); } else if (r < 0) { std::cout << "Cluster connect failed.\n"; exit(-1); } if (cluster_connection->wait_until_ready(30,30)) { std::cout << "Cluster was not ready within 30 secs." << std::endl; exit(-1); } Ndb* myNdb= new Ndb(cluster_connection, "clusterdb"); // Object representing the database if (myNdb->init() == -1) APIERROR(myNdb->getNdbError()); const char *eventName= "CHNG_IN_ASSETS"; const char *eventTableName= "ASSETS"; const int noEventColumnName= 2; const char *eventColumnName[noEventColumnName]= {"CODE", "VALUE"}; // Create events myCreateEvent(myNdb, eventName, eventTableName, eventColumnName, noEventColumnName); // Normal values and blobs are unfortunately handled differently.. typedef union { NdbRecAttr* ra; NdbBlob* bh; } RA_BH; int i; // Start "transaction" for handling events NdbEventOperation* op; printf("create EventOperation\n"); if ((op = myNdb->createEventOperation(eventName)) == NULL) APIERROR(myNdb->getNdbError()); printf("get values\n"); RA_BH recAttr[noEventColumnName]; RA_BH recAttrPre[noEventColumnName]; for (i = 0; i < noEventColumnName; i++) { recAttr[i].ra = op->getValue(eventColumnName[i]); recAttrPre[i].ra = op->getPreValue(eventColumnName[i]); } // set up the callbacks // This starts changes to "start flowing" if (op->execute()) APIERROR(op->getNdbError()); while (true) { int r = myNdb->pollEvents(1000); // wait for event or 1000 ms if (r > 0) { while ((op= myNdb->nextEvent())) { NdbRecAttr* ra = recAttr[0].ra; if (ra->isNULL() >= 0) { // we have a value if (ra->isNULL() == 0) { // we have a non-null value printf("CODE: %d ", ra->u_32_value()); do_blank(myNdb, ra->u_32_value()); } else printf("%-5s", "NULL"); } else printf("%-5s", "-"); // no value ra = recAttr[1].ra; printf("\n"); } } } } int myCreateEvent(Ndb* myNdb, const char *eventName, const char *eventTableName, const char **eventColumnNames, const int noEventColumnNames) { NdbDictionary::Dictionary *myDict= myNdb->getDictionary(); if (!myDict) APIERROR(myNdb->getNdbError()); const NdbDictionary::Table *table= myDict->getTable(eventTableName); if (!table) APIERROR(myDict->getNdbError()); NdbDictionary::Event myEvent(eventName, *table); myEvent.addTableEvent(NdbDictionary::Event::TE_INSERT); myEvent.addEventColumns(noEventColumnNames, eventColumnNames); // Add event to database if (myDict->createEvent(myEvent) == 0) myEvent.print(); else if (myDict->getNdbError().classification == NdbError::SchemaObjectExists) { printf("Event creation failed, event exists\n"); printf("dropping Event...\n"); if (myDict->dropEvent(eventName)) APIERROR(myDict->getNdbError()); // try again // Add event to database if ( myDict->createEvent(myEvent)) APIERROR(myDict->getNdbError()); } else APIERROR(myDict->getNdbError()); return 0; } static void do_blank(Ndb* myNdb, int code) { const NdbDictionary::Dictionary* myDict= myNdb->getDictionary(); const NdbDictionary::Table *myTable= myDict->getTable("ASSETS"); if (myTable == NULL) APIERROR(myDict->getNdbError()); NdbTransaction *myTransaction= myNdb->startTransaction(); if (myTransaction == NULL) APIERROR(myNdb->getNdbError()); printf("Replacing VALUE with 0 for CODE: %d ", code); NdbOperation *myOperation= myTransaction->getNdbOperation(myTable); if (myOperation == NULL) APIERROR(myTransaction->getNdbError()); myOperation->updateTuple(); myOperation->equal("CODE", code); myOperation->setValue("VALUE", 0); if (myTransaction->execute( NdbTransaction::Commit ) == -1) APIERROR(myTransaction->getNdbError()); myNdb->closeTransaction(myTransaction); } shell> slave_filter 127.0.0.1:1186From the master Cluster, insert some values (note that the example can easily be extended to cover updates too):
mysql> insert into ASSETS values (101, 50),(102, 40), (103, 99);
and then check that on the slave the value has been set to 0 for each of the entries:
mysql> select * from ASSETS; +------+-------+ | CODE | VALUE | +------+-------+ | 100 | 0 | | 103 | 0 | | 101 | 0 | | 102 | 0 | +------+-------+
How this works…. The table data is replicated as normal and the real values are stored in the slave. The “slave_filter” process has registered against insert operations on this table and when it’s triggered it sets the VALUE field to 0. The event is processes asynchronously from the replication and so there will be some very narrow window during which the true values would be stored in the slave.
-
Setting up MySQL Asynchronous Replication for High Availability
Posted on August 3rd, 2009 9 commentsMySQL replication is often positioned as a solution to provide extra throughput for your database (especially when dealing with high numbers of read operations). What tends to be overlooked is how it can be used to provide high availability (HA) – no matter how much redundancy you have at a local level, your system remains at risk from a single catastrophic failure – loss of power, earthquake, terrorist attack etc. By using MySQL asynchronous replication to maintain a geographically remote copy of that data, service can be maintained through any single site failure.
As this replication is asynchronous, there are no low latency demands on the network and so the two sites can be thousands of miles apart while utilising low-cost connections.
This article provides a simple example of how to set up asynchronous replication between 2 MySQL databases in order to provide a Highly Available solution. First of all, it will be 2 databases where the tables will be stored in the MyISAM storage engine and then between 2 MySQL Cluster databases where I also configure it for Multi-master replication where changes can be made at either site.
Subsequent articles will build on this to show:
- Collision detection and resolution when using MySQL Cluster multi-master asynchronous replication
- Introducing asynchronous replication to a running MySQL Cluster database
Throughout this article, two machines are used: ws1 (192.168.0.3) and ws2 (192.168.0.4). ws1 will be set up as the master and ws2 as the slave (in the multi-master configuration, both act as both master and slave).
Setting up replication for non-Cluster databases
Replication is performed from one MySQL Server to another; the master makes the changes available and then one or more other Servers pick up those changes and apply them to their own databases. In this example, both databases will store the table data using the same storage engine (MyISAM) but it’s possible to mix and match (for example, take a look at MySQL Cluster – flexibility of replication). As this is intended as a simple introduction to replication, I’m keeping life simple by assuming that this is all being set up before the database goes into production – if that isn’t the case for you and you need to cope with existing data then check out the MySQL documentation or subsequent articles on this site.
The my.cnf files can be set up as normal but the one for the MySQL Server that will act as the Master needs to have binary-logging enabled. Also, each of the server needs to have a unique server-id. Here are the my.cnf files used for this example:
my.cnf (Master)
[mysqld] datadir=/home/billy/mysql/myisam/data basedir=/usr/local/mysql port=3306 server-id=1 log-binmy.cnf (Slave)
[mysqld] datadir=/home/billy/mysql/myisam/data basedir=/usr/local/mysql port=3306 server-id=2Fire up the Master MySQL Server:
[billy@ws1 myisam]$ mysqld --defaults-file=my.cnf&The slave needs a userid/password in order to access the master server – best practice is to create a dedicated user with just the required privileges:
[billy@ws1 myisam]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> grant replication slave on *.* to 'repl'@'192.168.0.4' -> identified by 'repl'; Query OK, 0 rows affected (0.00 sec)The slave can now be told to start processing the replication data that will be staged by the master server:
[billy@ws2 myisam]$ mysqld --defaults-file=my.cnf& [billy@ws2 myisam]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.1.34-ndb-7.0.6-cluster-gpl MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.0.3', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='repl', -> MASTER_LOG_FILE='', -> MASTER_LOG_POS=4; 090803 15:48:09 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=ws2-relay-bin' to avoid this problem. Query OK, 0 rows affected (0.01 sec) mysql> start slave; 090803 15:51:24 [Note] Slave SQL thread initialized, starting replication in log 'FIRST' at position 0, relay log './ws2-relay-bin.000001' position: 4 Query OK, 0 rows affected (0.00 sec) 090803 15:51:24 [Note] Slave I/O thread: connected to master 'repl@192.168.0.3:3306',replication started in log 'FIRST' at position 4Now to test that replication is up and running, create a table on the master, add some data and then check that the table and data can be read from the slave:
[billy@ws1 myisam]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> create table numbers (num1 int, num2 int); Query OK, 0 rows affected (0.00 sec) mysql> insert into numbers values (1,10),(2,20),(3,30); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0[billy@ws2 myisam]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 5 Server version: 5.1.34-ndb-7.0.6-cluster-gpl MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use test; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from numbers; +------+------+ | num1 | num2 | +------+------+ | 1 | 10 | | 2 | 20 | | 3 | 30 | +------+------+ 3 rows in set (0.00 sec)Multi-Master Replication with MySQL Cluster
There are a few asynchronous replication capabilities that are unique to MySQL Cluster – one of those is that changes are replicated even if they are made directly to the data nodes using the NDB API, another is that replication can be performed in both directions i.e. multi-master. One of the advantages of this is you can share both read and write operations across both sites so that no capacity is wasted – it also gives you the confidence that either site is sane and ready to take over for the other at any point. You should aim to minimise how often the same rows are modified at the same time on both sites – conflict detection/resolution has been implemented but it can only roll-back the rows changes that conflict with other row changes rather than the full transaction.
It’s important to note that in this article, I’m not talking about the synchronous replication that takes place between data nodes within a single MySQL Cluster site (that happens in parallel and is orthogonal to the asynchronous replication to a remote site).
When performing multi-master asynchronous replication between 2 Clusters, 1 (or more) MySQL Servers in each Cluster is nominated as a master and 1 or more as slaves (it can be the same server that takes on both roles and you can have multiple channels set up in case a channel or MySQL Server is lost). Changes made to the data at either site through any of their MySQL Servers (or directly to the data nodes using the NDB API) will be replicated to the other site.
I will focus on setting up the replication, you can refer to Deploying MySQL Cluster over multiple hosts for the steps to configure and run each MySQL Cluster site.
Most of the steps are very similar to those in the first example – the main differences would come when introducing asynchronous replication to a MySQL Cluster instance that already contains data and is up and running (processing updates) which will be covered in a subsequent article.
Binary logging needs to be enabled on the MySQL Server(s) at each site that will act as a replication master:
my1.cnf (Master)
[mysqld] ndb-nodeid=4 ndbcluster datadir=/home/billy/mysql/replication/7_0_6/data basedir=/home/billy/mysql/replication/7_0_6 port=3306 server-id=1 log-binmy1.cnf (Slave)
[mysqld] ndb-nodeid=4 ndbcluster datadir=/home/billy/mysql/replication/7_0_6/data basedir=/home/billy/mysql/replication/7_0_6 port=3306 server-id=2 log-binThe MySQL Cluster nodes (including the MySQL Servers (mysqld) from both sites should be started up as normal.
In this case, the replication users should be set up for both Clusters:
[billy@ws1 7_0_6]$ mysqld --defaults-file=my.cnf& [billy@ws1 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> grant replication slave on *.* to 'repl'@'192.168.0.4' -> identified by 'repl'; Query OK, 0 rows affected (0.01 sec) [billy@ws2 7_0_6]$ mysqld --defaults-file=my.cnf& [billy@ws2 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> grant replication slave on *.* to 'repl'@'192.168.0.3' -> identified by 'repl'; Query OK, 0 rows affected (0.00 sec)
Replication can then be setup and started on each of the MySQL Servers (those acting as slaves for each Cluster):
[billy@ws1 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.0.4', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='repl', -> MASTER_LOG_FILE='', -> MASTER_LOG_POS=4; 090803 17:25:00 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=ws1-relay-bin' to avoid this problem. Query OK, 0 rows affected (0.01 sec) mysql> start slave; 090803 17:27:20 [Note] Slave SQL thread initialized, starting replication in log 'FIRST' at position 0, relay log './ws1-relay-bin.000001' position: 4 Query OK, 0 rows affected (0.02 sec) 090803 17:27:20 [Note] Slave I/O thread: connected to master 'repl@192.168.0.4:3306',replication started in log 'FIRST' at position 4 [billy@ws2 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CHANGE MASTER TO -> MASTER_HOST='192.168.0.3', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='repl', -> MASTER_LOG_FILE='', -> MASTER_LOG_POS=4; 090803 17:25:56 [Warning] Neither --relay-log nor --relay-log-index were used; so replication may break when this MySQL server acts as a slave and has his hostname changed!! Please use '--relay-log=ws2-relay-bin' to avoid this problem. Query OK, 0 rows affected (0.01 sec) mysql> start slave; 090803 17:27:25 [Note] Slave SQL thread initialized, starting replication in log 'FIRST' at position 0, relay log './ws2-relay-bin.000001' position: 4 Query OK, 0 rows affected (0.00 sec) 090803 17:27:25 [Note] Slave I/O thread: connected to master 'repl@192.168.0.3:3306',replication started in log 'FIRST' at position 4
This time, to make sure that replication is working in both directions, I make changes to both Clusters and then check that they appear at the other site:
[billy@ws1 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use test; Database changed mysql> create table numbers (num1 int, num2 int) engine=ndb; 090803 17:32:10 [Note] NDB Binlog: CREATE TABLE Event: REPL$test/numbers 090803 17:32:10 [Note] NDB Binlog: logging ./test/numbers (UPDATED,USE_WRITE) Query OK, 0 rows affected (0.62 sec) mysql> insert into numbers values (1,10),(2,20),(3,30); Query OK, 3 rows affected (0.04 sec) Records: 3 Duplicates: 0 Warnings: 0billy@ws2 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from numbers; +------+------+ | num1 | num2 | +------+------+ | 2 | 20 | | 3 | 30 | | 1 | 10 | +------+------+ 3 rows in set (0.01 sec) mysql> insert into numbers values (4,40),(5,50),(6,60); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0[billy@ws1 7_0_6]$ mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 5.1.34-ndb-7.0.6-cluster-gpl-log MySQL Cluster Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> use test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from numbers; +------+------+ | num1 | num2 | +------+------+ | 1 | 10 | | 6 | 60 | | 3 | 30 | | 5 | 50 | | 2 | 20 | | 4 | 40 | +------+------+ 6 rows in set (0.02 sec) -
MySQL Cluster – flexibility of replication
Posted on May 26th, 2009 9 commentsOne of the better kept secrets about MySQL Cluster appears to be the flexibility available when setting up replication. Rather than being constrained to implementing a single replication scheme, you can mix and match approaches.
Just about every Cluster deployment will use synchronous replication between the data nodes within a node group to implement High Availability (HA) by making sure that at the point a transaction is committed, the new data is stored in at least 2 physical hosts. Given that MySQL Cluster is usually used to store the data in main memory rather than on disk, this is pretty much mandatory (note that the data changes are still written to disk but that’s done asynchronously to avoid slowing down the database).
MySQL asynchronous replication is often used for MySQL Cluster deployments in order to provide Geographic Redundancy. At the same time as the synchronous replication within a Cluster, the changes can be replicated asynchronously to a second Cluster (or to more than one) at a remote location. Asynchronous rather than synchronous replication is used so that the transaction commit is not delayed while waiting for the remote (could be thousands of miles away, connected by a high latency WAN) Cluster to receive, apply and acknowledge the change. A common misconception is that changes being made through the NDB API will not be replicated to the remote site as this replication is handled by a MySQL Server instance – the reality is that the MySQL Replication implementation will pick up the changes even when they’re written directly to the data nodes through the NDB API.
A third use of replication is to store the Cluster’s data in a seperate database – for example to have a read-only, up-to-date copy of the data stored within the MyISAM storage engine so that complex reports can be generated from it. And the best news is that this can be done at the same time as the local HA and remote Geographic Redundancy replication!
Johan’s Blog provides the technical details around configuring replication in order to provide some extra scaling by setting up non-Cluster slave databases that pick up all changes from the Cluster database.


















