The MySQL general log is one of my favorite features for a quick debug. I especially like the ability of starting and stopping it on demand, which was introduced in MySQL 5.1.
However, using the general log has its drawbacks.
Today I was debugging a nasty bug that results from two statements that should be applied sequentially, but that were instead concurrent. These kind of problems are hard to cope with, as they are intermittent. Sometimes all goes well, and you get the expected result. And then, sometimes the statements fly on different directions and I stare at the screen, trying to understand where did they stray.
After some try-and-fail, I decided to enable the general log just before the offending statements, and to turn it down immediately after. Guess what? With the general log on, the test never failed. What was an intermittently failing test became an always succeeding test.
What happened is that the general log delayed the query execution just enough for the following statement to arrive when it was expected.
In the end, the bug had to be unveiled using white box techniques.
Moral of the story: using a general log alters the status of the server. If you use it, be prepared to deal with its side effects.
Wednesday, March 02, 2011
Friday, February 25, 2011
Advanced replication for the masses - Part II - Parallel replication
| I hope you liked the first part of this series of lessons. And I really hope that you have followed the instructions and got your little replication cluster up and working. |
For the sake of the diligent readers who have followed the instructions with the first lessons, I won't repeat them, but I'll invite you to set the environment as explained in the first part.
Once you have a cluster up and running, and you can confirm that replication is indeed working with Tungsten, you can remove all with the
clear_cluster.sh script, and launch again the set_installation.sh script, with the tiny detail we have mentioned above.The astute readers may have noticed that the installation script contains these lines:
...
MORE_OPTIONS=$1
./configure-service --create --role=master $MORE_OPTIONS logos1
./tungsten-replicator/bin/trepctl -service logos1 start
./configure-service --create --role=slave --master-host=QA2 \
--service-type=remote $MORE_OPTIONS logos2
...
This means that you can start set_replication.sh with one additional option, which will be passed to the creation of the Tungsten service. Without further suspense, the addition that you need is --channels=5.Yep. It was that easy.
./set_replication.sh --channels=5This little addition will start your Tungsten replicator, apparently in the same way it did before. But there is a substantial difference. While the data is funneled from the master to the slaves in the usual way, the applier splits the data by database. You can see the difference as soon as you send some data through the pipeline.
#master mysql -h tungsten1 -e 'create schema mydb1' mysql -h tungsten1 -e 'create schema mydb2' mysql -h tungsten1 -e 'create schema mydb3' mysql -h tungsten1 -e 'create table mydb1.t1 (i int)' mysql -h tungsten1 -e 'create table mydb2.t1 (i int)' mysql -h tungsten1 -e 'create table mydb3.t1 (i int)' mysql -h tungsten1 -e 'select seqno,source_id,eventid from tungsten_logos.trep_commit_seqno' +-------+-----------+----------------------------+ | seqno | source_id | eventid | +-------+-----------+----------------------------+ | 6 | tungsten1 | 000002:0000000000000939;43 | +-------+-----------+----------------------------+Everything under control. The master has sent 6 events through the pipeline. Now, let's see what the slave has to say:
# slave mysql -h tungsten2 -e 'select seqno,source_id,eventid from tungsten_logos.trep_commit_seqno' +-------+-----------+----------------------------+ | seqno | source_id | eventid | +-------+-----------+----------------------------+ | 0 | tungsten1 | 000002:0000000000000426;34 | | 0 | tungsten1 | 000002:0000000000000426;34 | | 4 | tungsten1 | 000002:0000000000000763;41 | | 5 | tungsten1 | 000002:0000000000000851;42 | | 6 | tungsten1 | 000002:0000000000000939;43 | +-------+-----------+----------------------------+Notice, at first sight, that there are five rows instead of one. Each row is a channel. Since the master has used three databases, you see three channels occupied, each one showing the latest sequence that was applied. Now, if we do something to database mydb2, we should see one of these channels change, while the others stay still.
# master mysql -h tungsten1 -e 'insert into mydb2.t1 values (1)' mysql -h tungsten1 -e 'insert into mydb2.t1 values (2)' # slave mysql -h tungsten2 -e 'select seqno,source_id,eventid from tungsten_logos.trep_commit_seqno' +-------+-----------+----------------------------+ | seqno | source_id | eventid | +-------+-----------+----------------------------+ | 0 | tungsten1 | 000002:0000000000000426;34 | | 0 | tungsten1 | 000002:0000000000000426;34 | | 4 | tungsten1 | 000002:0000000000000763;41 | | 8 | tungsten1 | 000002:0000000000001124;45 | | 6 | tungsten1 | 000002:0000000000000939;43 | +-------+-----------+----------------------------+The channel used by mydb2 had previously applied the sequence number 5. The latest sequence number was previously 6, used in another channel. After two more events in this database, the sequence number has jumped to 8.
The eventID has also changed. The first part of the eventID is the binary log number (as in mysql-bin.000002), the second is the log position (1124), and the third one is the session ID (45).
Enough of peeking over the replicator's shoulder. There are more tools that let you inspect the status of the operations.
We have seen
trepctl services, which keeps some of its usefulness also with parallel replication. In the master, it says:trepctl -host tungsten1 services NAME VALUE ---- ----- appliedLastSeqno: 8 appliedLatency : 0.834 role : master serviceName : logos serviceType : local started : true state : ONLINEWhich is mostly all we need to know.
Since the slave has more than one channel, though, we need more specialized information on that side of the applier. For this reason, we use a more specialized view. We may start with
trepctl status, which has information that is roughly equivalent to "SHOW SLAVE STATUS" in MySQL native replication.trepctl -host tungsten2 status NAME VALUE ---- ----- appliedLastEventId : 000002:0000000000000426;34 appliedLastSeqno : 0 appliedLatency : 0.846 clusterName : currentEventId : NONE currentTimeMillis : 1298626724016 dataServerHost : tungsten2 extensions : host : null latestEpochNumber : 0 masterConnectUri : thl://tungsten1:2112/ masterListenUri : thl://tungsten2:2112/ maximumStoredSeqNo : 8 minimumStoredSeqNo : 0 offlineRequests : NONE pendingError : NONE pendingErrorCode : NONE pendingErrorEventId : NONE pendingErrorSeqno : -1 pendingExceptionMessage: NONE resourcePrecedence : 99 rmiPort : -1 role : slave seqnoType : java.lang.Long serviceName : logos serviceType : local simpleServiceName : logos siteName : default sourceId : tungsten2 state : ONLINE timeInStateSeconds : 3483.836 uptimeSeconds : 3489.47Also this command, which is perfectly useful in single channel replication, lacks the kind of detail that we are after. Tungsten 2.0 introduces two variations of this command, with more detailed metadata.
trepctl -host tungsten2 status -name tasks Processing status command (tasks)... NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000001305;46 appliedLastSeqno : 8 appliedLatency : 0.84 cancelled : false eventCount : 9 stage : remote-to-thl taskId : 0 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000001305;46 appliedLastSeqno : 8 appliedLatency : 0.841 cancelled : false eventCount : 9 stage : thl-to-q taskId : 0 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000426;34 appliedLastSeqno : 0 appliedLatency : 8.422 cancelled : false eventCount : 2 stage : q-to-dbms taskId : 0 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000426;34 appliedLastSeqno : 0 appliedLatency : 8.424 cancelled : false eventCount : 1 stage : q-to-dbms taskId : 1 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000763;41 appliedLastSeqno : 4 appliedLatency : 0.242 cancelled : false eventCount : 3 stage : q-to-dbms taskId : 2 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000001305;46 appliedLastSeqno : 8 appliedLatency : 0.846 cancelled : false eventCount : 5 stage : q-to-dbms taskId : 3 NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000939;43 appliedLastSeqno : 6 appliedLatency : 0.296 cancelled : false eventCount : 3 stage : q-to-dbms taskId : 4The
-name tasks command gives you a list of the latest tasks that were happening.This is probably more information that you want to know about, but in case of troubleshooting it may become a blessing. Let's follow for a moment what's going on to appliedLastSeqno 8. You will find three tasks with this sequance number. The first one has stage "remote-to-thl", which is the stage where the transaction is transported from the master to the Transaction History List (THL, which is Tungsten lingo to what you may also call a relay log.). The second task that mentions appliedLastSeqno 8 is in stage "thl-to-q", which is the phase where a transaction is assigned to a given shard. The third occurrence happens in stage "q-to-dbms", which is where the transaction is executed in the slave.
For a different view of what is going on, you may use
trepctl status -name shards. A Shard, in this context, is the criteria used to split the transactions across channels. By default, it happens by database. We will inspect its mechanics more closely in another post. For now, let's have a look at what shards we have in our slave:trepctl -host tungsten2 status -name shards NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000763;41 appliedLastSeqno : 4 appliedLatency : 0.0 eventCount : 2 shardId : mydb1 stage : q-to-dbms NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000001305;46 appliedLastSeqno : 8 appliedLatency : 0.0 eventCount : 4 shardId : mydb2 stage : q-to-dbms NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000939;43 appliedLastSeqno : 6 appliedLatency : 0.0 eventCount : 2 shardId : mydb3 stage : q-to-dbms NAME VALUE ---- ----- appliedLastEventId: 000002:0000000000000426;34 appliedLastSeqno : 0 appliedLatency : 0.0 eventCount : 6 shardId : tungsten_logos stage : q-to-dbmsYou may read the information quite easily. Each shard tells you by which key it was identified (
shardID), and this is the same as the database name. The appliedLastSeqno and stage we have met already. The appliedLatency is roughly equivalent to MySQL's seconds behind master, but more granular than that. And eventCount tells you how many transactions went through this shard.If you are the adventurous type, you may have a look at the THL itself, and get a glimpse of how the replication and the parallelism works.
In the slave, type the following
# slave thl -service logos list |lessThen look for "SEQ#" and you will find the global transaction IDs, or look for "shard=", and you will see the split by database.
More goodies will come next week. Until then, happy hacking!
Labels:
advanced,
clustering,
continuent,
mysql,
parallel,
replication,
shards,
status,
tasks,
trepctl,
tungsten
Tuesday, February 22, 2011
Advanced replication for the masses - Part I - Getting started with Tungsten Replicator
| MySQL DBAs and developers: oil your fingers and get ready to experience a new dimension of data replication. I am pleased to announce that Continuent has just released Tungsten Replicator 2.0, an open source data replication engine that can replace MySQL native replication with a set of advanced features. A note about the source code. The current version of Tungsten Replicator available in the web site is free to use, but it is not yet the open source version. We need a few weeks more to extract the code from the enterprise tree and make a new build. But we did not want to delay the user experience. So everything that is in this build will come with the source code in a short while. In the meantime, enjoy what is available there and have as much fun as we are having. |
Why you will want to install Tungsten Replicator 2.0
Tungsten Replicator has a real cool list of features. I am sure that most MySQL DBAs would find something in that list that makes their mouth water in expectation.Among my favorite features, there is one that looks so innocently non-important that you may be tempted to dismiss it. I am talking about global transaction ID, which is paramount in helping the DBA in switching from master to slave in case of failure or maintenance. I will show an example of a seamless failover in this article.
More things to get excited about: Tungsten allows multiple master replication, i.e. one slave receiving data from several sources, and parallel replication, meaning that a slave can apply changes from the master using many parallel threads. I will talk about all of those features in my blog. But to get to that point, I will need to start by covering the basic installation first. Since Tungsten is much more powerful than MySQL native replication, it also comes with greater complexity. We are working at reducing such complexity. In the meantime, you can start with the instructions that come in this post.
Getting ready
You will need at least two servers, with Java 1.6, Ruby 1.8, and MySQL 5.1 installed.You may use your own virtual machines, or spare servers, or you can use a pre-defined VMWare image that you can use with VMware player (or VMware Fusion on Mac).
The following instructions refer to the pre-configured VM. You may skip the initial steps if you are using your own servers.
- download a pre-configured image
https://files.continuent.com.s3.amazonaws.com/Tungsten_MySQL_CentOS_5_5_VMWare_Image.7z
Warning: it's 1.5 GB, and it expands to 5.5 GB - Expand the VM
- Make a copy of the VM. Change the directory names so that you will refer to them as tungsten_vm1 and tungsten_vm2
- launch both VMs
- Connect to each VM. User names and password for root are in a .doc file within the VM directory.
- Change the hostname of the VMs to tungsten1 and tungsten2 (don't forget to modify /etc/sysconfig/network to make the name sticky)
- Update /etc/hosts/ with the IP address and hostname of both servers
- Switch to the tungsten user
su - tungsten
- Create a directory $HOME/replicator
- Get the Tungsten package into that directory
cd replicator wget https://s3.amazonaws.com/releases.continuent.com/tungsten-replicator-2.0.0.tar.gz
- Get the setup scripts from Tungsten Replicator home .
wget http://tungsten-replicator.googlecode.com/files/simple_install_master_slave.tar.gz
- unpack the scripts in $HOME/replicator
I know this was a long list, but it is not terribly difficult. More difficult would be setting all the above manually. As it is today, all you need to do is running the "set_replication.sh" script and Tungsten will come alive to your server in less than one minute.
To do things properly, you will need to do the same operations on both servers. So, assuming that you have done everything in tungsten1, you can easily mirror the operations to tungsten2. The virtual machines come with an already installed public SSH key that makes your installation life easier.
# in tungsten1 cd $HOME/replicator ssh tungsten2 mkdir replicator scp simple_install_master_slave.tar.gz tungsten2:$PWD scp tungsten-replicator-2.0.0.tar.gz tungsten2:$PWD ssh tungsten2 'cd replicator; tar -xzf simple_install_master_slave.tar.gz 'Now that you have the same set of files in both machines, you can trust the wisdom of the installation files and run:
# tungsten1 ./set_replication.sh ssh tungsten2 $PWD/set_replication.shThis will start the Tungsten replicator in both servers.
Cleaning up
The sample scripts come with one that is dedicated to cleaning up. There is a "clear_cluster.sh" script that will remove all test data from the database, sweep the tungsten directory away, leaving your system ready to start afresh. As this is a testing environment, this strategy is not so bad. But be aware of the potentially destructive nature of this script, and don't use it in a production environment.Under the hood
Tungsten replicator is a complex piece of software, and it's easy to get lost. So here are a few tips on how to get your bearings.You will find a log file under $HOME/replicator/tungsten/tungsten-replicator/logs/.
This is quite a noisy log, which is supposed to give the developers all information about what's going on in case of a failure. For newcomers, it is quite intimidating, but we are working at making it easier to read. (Be aware that you may find some references to "tungsten-enterprise" in the logs. Don't let this fact deter you. We are working at splitting the former name associations from the packages, and eventually you will only find references to modules named "tungsten-replicator-something" in the logs.)
At the end of the installation, you should have seen a line inviting you to modify your path to get the replication tools available at your fingertips. Most notable is
Using this tool, you can get some information about the replicator status, and perform administrative tasks. A glimpse at the Tungsten Replicator Guide 2.0 will give you an idea of what you can do.
For now, suffices to say that you can use trepctl to get the state of the replicator.
Try, for example, the following:
$ trepctl -host tungsten1 services
NAME VALUE
---- -----
appliedLastSeqno: 0
appliedLatency : 0.933
role : master
serviceName : logos
serviceType : local
started : true
state : ONLINE
$ trepctl -host tungsten2 services
NAME VALUE
---- -----
appliedLastSeqno: 0
appliedLatency : 0.966
role : slave
serviceName : logos
serviceType : local
started : true
state : ONLINE
The most important things here are the "state" field, and the "appliedLastSeqno", which is the global transaction ID that we have mentioned before.If you create or modify something in the master and issue this command again, you will see that the appliedLastSeqno will increment.
You can get some of this information from the MySQL database, where Tungsten keeps a table with the latest status. You may say that this table is roughly equivalent, at least in principle, to the information in SHOW SLAVE STATUS available with native replication.
$ mysql -h tungsten1 -u tungsten -psecret \
-e 'select * from tungsten_logos.trep_commit_seqno\G'
*************************** 1. row ***************************
task_id: 0
seqno: 0
fragno: 0
last_frag: 1
source_id: tungsten1
epoch_number: 0
eventid: 000002:0000000000000416;102
applied_latency: 0
What is this "tungsten_logos' database? It is the database that Tungsten creates for each service that was installed. In this case, 'logos' is the service name contained in this sample installation. If you modify the scripts in both servers, and replace 'logos' with 'ripe_mango', you will see that Tungsten creates a 'tungsten_ripe_mango' database, with the same kind of information.The basic principle to acquire before moving to more complex topics is that replication in Tungsten is a collection of services. While the native MySQL replication is a simple pipeline from master to slave, without deviations, Tungsten implements several pipelines, which you can use one by one or in combination. It looks more complex than necessary, but in reality it makes your planning of complex topologies much easier. Instead of making basic replication more complex, Tungsten adopt the principle of deploying the appropriate pipeline or pipelines for the task.
I leave to Robert Hodges, CEO and main architect of Tungsten, the task of explaining the nuts and bolts.
A sample of Tungsten power: switching from master to slave
It is probably too much information already for a blog post, but I would like to leave you with the feeling that you are dealing with an extremely powerful tool.The instructions below will perform a seamless switch between the master and the slave.
Please follow these steps, but make sure there is no traffic hitting the old master during this time, or you may experience consistency issues:
#first, we tell both servers to stop replicating
$ trepctl -service logos -host tungsten2 offline
$ trepctl -service logos -host tungsten1 offline
# Now that they are offline, we tell each server its new role
# tungsten2 becomes the new master
$ trepctl -service logos -host tungsten2 setrole -role master
# and then we tell tungsten1 that it's going to be a slave,
# listening to tungsten2 for data
$ trepctl -service logos -host tungsten1 setrole -role slave -uri thl://tungsten2
# now we put both servers online with the new instructions
$ trepctl -service logos -host tungsten2 online
$ trepctl -service logos -host tungsten1 online
# and we check that indeed they are both online with the new roles.
$ trepctl -host tungsten1 services
$ trepctl -host tungsten2 services
After this set of instructions, tungsten2 is the master, and if we write to it, we will see the changes replicating to tungsten1.That's it for today. In the next articles, we will take a look at parallel replication.
We want to hear from you
We have released Tungsten Replicator as open source because we believe this will improve the quality of our product. We are looking for bug reports, cooperation, suggestions, patches, and anything that can make the product better. You can report bugs at the project home.We are particularly eager to hear about user experience. We are aware that the user interface can be better, and we need some input on this matter from interested users.
A note about security
What is described in this article is for testing purposes only. Please use the virtual machines that were mentioned in this article behind a firewall. The VM was designed with friendliness in mind, but as it is, it's far from secure.
Labels:
advanced,
clustering,
continuent,
multi-master,
mysql,
parallel,
replication,
tungsten
Monday, February 14, 2011
How to detect if a MySQL server is an active replication slave
Sometimes you know for sure. And sometimes you wonder: Is this server part of a replication system? And, most specifically, is it an active slave?
The completeness of the answer depends on how much visibility you have on the server.
If you can ask the DBA, and possibly have access to the server data directory and configuration file, you can get a satisfactory answer. But if your access is limited to SQL access, things get a bit more complicated.
If you have the SUPER or REPLICATION_CLIENT privilege, then it's easy, at least in the surface.
SHOW SLAVE STATUS will tell you if the slave is running. An empty set means that the server was not configured as a slave.
The answer is not absolute, though. You need to read the output of SHOW SLAVE STATUS to understand if replication is under way.
For example, what is the difference between these two listings?
The second listing is what you get immediately after a call to RESET SLAVE. The crucial difference is that RESET SLAVE removes the two .info files containing replication credentials and positions. A call to START SLAVE in this scenario will only get you an error, as the slave does not know where and how to connect.
So, in this case, SQL visibility does only tell you that the server is not receiving replication date, and that it was at least once configured as a slave. The telltale detail is the user name ("test") that should give you a hint of something fishy going on. Unless you have called your user "test", in which case you were asking for trouble. I would say that this situation is a bug. RESET SLAVE should remove every memory of the slave configuration, and instead it keeps only the host name. Although it is not clear in this particular example, it also forgets the master connection port.
Now, if your purpose was to set replication with different coordinates, the good news is that in both cases a well formed call (*) to CHANGE MASTER TO will do what you expect, i.e. it will establish the credentials to the master, so that a further invocation of START SLAVE will let replication data flow.
(*) By "well formed" I mean a call that includes host, port, username, password, binary log file and position, and eventually all the information that you need to get the slave at work.
The completeness of the answer depends on how much visibility you have on the server.
If you can ask the DBA, and possibly have access to the server data directory and configuration file, you can get a satisfactory answer. But if your access is limited to SQL access, things get a bit more complicated.
If you have the SUPER or REPLICATION_CLIENT privilege, then it's easy, at least in the surface.
SHOW SLAVE STATUS will tell you if the slave is running. An empty set means that the server was not configured as a slave.
The answer is not absolute, though. You need to read the output of SHOW SLAVE STATUS to understand if replication is under way.
For example, what is the difference between these two listings?
## listing 1
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: QA1
Master_User: tungsten_slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File:
Read_Master_Log_Pos: 4
Relay_Log_File: QA2-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File:
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 0
Relay_Log_Space: 106
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
## Listing 2
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: QA1
Master_User: test
Master_Port: 3306
Connect_Retry: 60
Master_Log_File:
Read_Master_Log_Pos: 4
Relay_Log_File: QA2-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File:
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 0
Relay_Log_Space: 125
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
They look almost the same, and yet the similarity is deceiving. The first listing is what you get immediately after a call to CHANGE MASTER TO. If you run START SLAVE at this point, replication will start flowing.The second listing is what you get immediately after a call to RESET SLAVE. The crucial difference is that RESET SLAVE removes the two .info files containing replication credentials and positions. A call to START SLAVE in this scenario will only get you an error, as the slave does not know where and how to connect.
So, in this case, SQL visibility does only tell you that the server is not receiving replication date, and that it was at least once configured as a slave. The telltale detail is the user name ("test") that should give you a hint of something fishy going on. Unless you have called your user "test", in which case you were asking for trouble. I would say that this situation is a bug. RESET SLAVE should remove every memory of the slave configuration, and instead it keeps only the host name. Although it is not clear in this particular example, it also forgets the master connection port.
Now, if your purpose was to set replication with different coordinates, the good news is that in both cases a well formed call (*) to CHANGE MASTER TO will do what you expect, i.e. it will establish the credentials to the master, so that a further invocation of START SLAVE will let replication data flow.
(*) By "well formed" I mean a call that includes host, port, username, password, binary log file and position, and eventually all the information that you need to get the slave at work.
Labels:
database,
detect,
monitoring,
mysql,
replication,
tungsten
Tuesday, February 08, 2011
Webinar: Percona and Continuent on backup and replication with huge data
On Thursday, February 10, at 10am PST, there is a free webinar about Managing Big Data with Percona Server, XtraBackup and Tungsten. Quoting from the announcement:
The presenters are representatives of both Percona and Continuent,
Vadim Tkachenko, Percona Co-Founder & CTO,
Robert Hodges, Continuent CEO
Edward Archibald, Continuent CTO
The event will showcase Xtrabackup and Tungsten features in an interesting combined view.
The event is free, but registration is required.
Big data is a big problem for growing SaaS businesses and large web applications. In this webinar, we'll teach you how to set up Percona Server, XtraBackup, and Tungsten to manage Terabyte+ databases and scale to millions of transactions a day. We'll discuss the latest features for high transaction performance like InnoDB buffer pool dump/restore and HandlerSocket, our favorite tricks for backup, restore, and provisioning of large data sets, and how to replicate scalably and safely using Tungsten Replicator with parallel apply.
The presenters are representatives of both Percona and Continuent,
Vadim Tkachenko, Percona Co-Founder & CTO,
Robert Hodges, Continuent CEO
Edward Archibald, Continuent CTO
The event will showcase Xtrabackup and Tungsten features in an interesting combined view.
The event is free, but registration is required.
Labels:
backup,
continuent,
mysql,
percona,
replication,
speaking,
tungsten,
webinar,
xtrabackup
Monday, February 07, 2011
Evolution of MySQL metadata
I was looking at the latest MySQL versions, and I happened to notice that there has been a great increment in the number of metadata tables, both in the information_schema and performance_schema databases. So I made a simple count of both schemas in the various versions, and draw a graph. The advance looks straightforward.

The difference between 5.0 and 5.6 is staggering. We came from 17 to 71 metadata total tables. A stacked bar chart helps visualize the changes.

I noticed, BTW, that MySQL 5.0.92, which is not in active support, was released without the binaries for Mac OSX. If this kind of edition is limited to the versions in extended support, that's fine with me. I hope the habit does not contaminate the regular builds.
| version | Information_schema | performance_schema |
|---|---|---|
| 5.0.92 | 17 | 0 |
| 5.1.54 | 28 | 0 |
| 5.1.54 with innodb plugin | 35 | 0 |
| 5.5.8 | 37 | 17 |
| 5.6.2 | 48 | 23 |
The difference between 5.0 and 5.6 is staggering. We came from 17 to 71 metadata total tables. A stacked bar chart helps visualize the changes.
I noticed, BTW, that MySQL 5.0.92, which is not in active support, was released without the binaries for Mac OSX. If this kind of edition is limited to the versions in extended support, that's fine with me. I hope the habit does not contaminate the regular builds.
Labels:
binaries,
information_schema,
metadata,
mysql,
performance_schema
Thursday, February 03, 2011
Open Database Camp - Accommodation and Sponsoring
The Open Database Camp 2011 is shaping up nicely. The logistics is being defined and local and international volunteers are showing up for help. (Thanks, folks!) If you want to start booking, there is a list of hotels in the Accommodation page. And don't forget to sign up in the Attendees list. Local travel information will be released as soon as we finish cranking up the plan. Open Database camp is free, but we still have expenses to get the job done. We need both official sponsors and personal donations. No minimum amount required. You can donate painlessly online through the nonprofit organization Technocation. (Thanks!) Please see the Sponsors page for more info. |
Labels:
camp,
conference,
database,
firebird,
ingres,
mysql,
nosql,
open source,
opendatabasecamp,
opensqlcamp,
postgresql,
sardinia,
sqlite
Sunday, January 30, 2011
A first look at delayed replication in MySQL 5.6
| If you like fresh features, you should not miss this one. MySQL 5.6.2 includes, among other improvements, the implementation of Time delayed replication, a feature that lets you tell the slave not to apply changes from the master immediately, but to wait N seconds. |
Since as of today there are no binaries for MySQL 5.6.x, you need to get the code and compile it yourself. Just get the code from https://code.launchpad.net/mysql-server and compile it using the instructions in building MySQL 5.5 with cmake.
To get a taste of this new feature, the quickest way is to set up replication using the binaries that you have built and MySQL Sandbox.
make_replication_sandbox mysql-5.6.2-m5-osx10.6-.tar.gz # the file name may change, depending on the operating system you are usingSoon you will have one master and two slaves in $HOME/sandboxes/rsandbox_5_6_2.
What you have to do is connect to one of the slaves and enter these commands:
STOP SLAVE;
change master to master_delay=60;
START SLAVE;
Let's say that you did this to slave #2.Now whatever you do in the master will be replicated immediately in slave #1, but it will executed with 60 seconds delay in slave #2.
To be clear, the IO_THREADs of both slaves keep getting data from the master as fast as they can, same as they did until version 5.5, but slave #2 will hold the SQL_THREAD for the defined amount of seconds.
This new state is visible in the output of the SHOW SLAVE STATUS command, which lists this information after you do something in the master like creating a table or inserting data:
SQL_Delay: 60
SQL_Remaining_Delay: 43
Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
The main purpose of delayed replication is to protect the server against human mistakes. If I accidentally drop a table, the statement is instantly replicated to all the slaves, but it is not executed to the delayed slaves.
$ ./m -e 'drop table test.t1 '
$ ./use_all 'show tables from test'
# master
# server: 1:
# server: 2:
Tables_in_test
t1
The table is gone in the master, and it is gone in the regular slave, but it is still there in the delayed slave. And if I detect the problem before the delayed statement gets executed (a delay time longer than 60 seconds would be advisable in this case, 3600=1 hour, seems healthier), then I may be able to recover the data.I notice en passant that there is much more than delayed replication going on in MySQL 5.6. For example, the information_schema tables related to InnoDB have increased from 7 to 18:
show tables from information_schema like 'innodb%';
+----------------------------------------+
| Tables_in_information_schema (innodb%) |
+----------------------------------------+
| INNODB_CMPMEM |
| INNODB_TRX |
| INNODB_BUFFER_PAGE | *
| INNODB_LOCK_WAITS |
| INNODB_SYS_TABLESTATS | *
| INNODB_CMP |
| INNODB_SYS_COLUMNS | *
| INNODB_CMPMEM_RESET |
| INNODB_SYS_FOREIGN_COLS | *
| INNODB_BUFFER_PAGE_LRU | *
| INNODB_BUFFER_POOL_STATS | *
| INNODB_CMP_RESET |
| INNODB_SYS_FOREIGN | *
| INNODB_METRICS | *
| INNODB_SYS_INDEXES | *
| INNODB_LOCKS |
| INNODB_SYS_FIELDS | *
| INNODB_SYS_TABLES | *
+----------------------------------------+
18 rows in set (0.00 sec)
# (*) new tables marked with a star
What they do and how to play with them will be matter for some more investigation.
Friday, January 28, 2011
The MySQL Council is up and running. We want to hear from you!
The Independent Oracle User Group (IOUG) has formed the MySQL Council, with the purpose of addressing the interests and needs of MySQL users.
The current Council members are:
The IOUG is not looking for assimilation. While Oracle business strategy calls for full integration, the IOUG recognizes that users come in different sizes and shapes, and they cannot be forced into the institution. Instead, the IOUG want to understand the newcomers and offer their services to help out towards the common goals. The IOUG people also know that many old Oracle users are also MySQL users. By facilitating the integration of the MySQL community they are serving the needs of a wider population than the traditional set of MySQL users.
The MySQL community has never been organized as a whole. There id nothing comparable to the massive presence of the Oracle user group. MySQL users are mostly isolated. When they convene into social entities, they identify themselves either by town boundaries or by being member of some group that has some interest in MySQL (Linux distributions, PHP developers, CMS framework users). There is no unified view of what users represent or want, and a difficult dialog between the user base and the company that produces the software.
With Oracle, this lack of unity is yet another obstacle in the path to a good understanding. Oracle is used to talk to a large entity representing its users, and it has not the patience or the skills to deal with such a distributed presence as the MySQL community. For this reason I believe that the MySQL Council is a good idea. It provides a tool for the will of the MySQL community to be conveyed to the company, using the IOUG, one of the channels that are familiar to Oracle, and that are more likely to reach the decision makers.
The main goal of the council should be to mend fences. There is much to be done. The culture of traditional Oracle users and that of MySQL users are different and sometimes hard to reconcile. Oracle strategies that were tuned towards pleasing their traditional customers may not suit the needs of the newcomers. All this needs to be addressed, and the MySQL Council could be the first step to the solution.
For this reason, the council members want to hear from the community. What are the main pain points and issues that you want addressed? What is Oracle doing right with MySQL? Where could it improve?
If you know one or more of us, please contact us by email. Or write a blog post about the issues to address. Or comment in our blogs. We want to hear from you. We feel that we must represent the larger MySQL community and bridge the gaps between the company and the user base.
The roles of the MySQL Council is not only to be a diplomatic channel of communication between users and company. It will also help with the diffusion of MySQL culture among Oracle users, with articles, conferences, meetings, and whatever the imagination provides to achieve the goal of spreading the word.
Also for this goal we welcome your input. Make your voice heard. It's time to boost the technical writing in Planet MySQL and in the rest of the net. Let MySQL be known!
The current Council members are:
- Sarah Novotny, Blue Gecko, Council Chair
- Sheeri Cabral, PalominoDB
- Bradley Kuszmaul, Tokutek
- Giuseppe Maxia, Continuent
- Rob Wultsch, GoDaddy.com
- Matt Yonkovit, Percona
The IOUG is not looking for assimilation. While Oracle business strategy calls for full integration, the IOUG recognizes that users come in different sizes and shapes, and they cannot be forced into the institution. Instead, the IOUG want to understand the newcomers and offer their services to help out towards the common goals. The IOUG people also know that many old Oracle users are also MySQL users. By facilitating the integration of the MySQL community they are serving the needs of a wider population than the traditional set of MySQL users.
The MySQL community has never been organized as a whole. There id nothing comparable to the massive presence of the Oracle user group. MySQL users are mostly isolated. When they convene into social entities, they identify themselves either by town boundaries or by being member of some group that has some interest in MySQL (Linux distributions, PHP developers, CMS framework users). There is no unified view of what users represent or want, and a difficult dialog between the user base and the company that produces the software.
With Oracle, this lack of unity is yet another obstacle in the path to a good understanding. Oracle is used to talk to a large entity representing its users, and it has not the patience or the skills to deal with such a distributed presence as the MySQL community. For this reason I believe that the MySQL Council is a good idea. It provides a tool for the will of the MySQL community to be conveyed to the company, using the IOUG, one of the channels that are familiar to Oracle, and that are more likely to reach the decision makers.
The main goal of the council should be to mend fences. There is much to be done. The culture of traditional Oracle users and that of MySQL users are different and sometimes hard to reconcile. Oracle strategies that were tuned towards pleasing their traditional customers may not suit the needs of the newcomers. All this needs to be addressed, and the MySQL Council could be the first step to the solution.
For this reason, the council members want to hear from the community. What are the main pain points and issues that you want addressed? What is Oracle doing right with MySQL? Where could it improve?
If you know one or more of us, please contact us by email. Or write a blog post about the issues to address. Or comment in our blogs. We want to hear from you. We feel that we must represent the larger MySQL community and bridge the gaps between the company and the user base.
The roles of the MySQL Council is not only to be a diplomatic channel of communication between users and company. It will also help with the diffusion of MySQL culture among Oracle users, with articles, conferences, meetings, and whatever the imagination provides to achieve the goal of spreading the word.
Also for this goal we welcome your input. Make your voice heard. It's time to boost the technical writing in Planet MySQL and in the rest of the net. Let MySQL be known!
Tuesday, January 25, 2011
Joining the Oracle ACE program
| A few days ago I received an invitation to join the Oracle ACE program, which is a group of strong community enthusiasts and advocate of Oracle products. Since I have been a vocal member of the MySQL community for years, I welcome this acknowledgment as well as I appreciated being nominated MySQL Community Contributor of the Year in 2006. Unlike that award, which came from inside the MySQL company, the Oracle ACE nomination came from my peers in the community, to whom I address my thanks and appreciation. The nomination comes from the community, but the title is granted by the company, as recognition for good work. Therefore, thanks also to my former colleagues at Oracle who have approved my current status. |
What you can expect is for me to be my usual self, the guy who is enthusiast about cool technology, no matter where it comes from, and critical or appreciative depending on merit.
Now, back to hacking!
Saturday, January 22, 2011
Pitfalls of monitoring MySQL table activity with stored routines
SELECT update_ratio();
He went to make a simple function, following the four steps described above.
delimiter //
drop function if exists update_ratio //
create function update_ratio()
RETURNS INT
begin
declare sleep_wait int default 5;
declare start int default 1;
declare finish int default 1;
set start = (select counter from mytable);
do sleep(sleep_wait);
set finish = (select counter from mytable);
return (finish-start)/sleep_wait;
end $$
delimiter ;
It seems OK. The function runs without errors, but it always returns zero.Mystery! Running the statements manually gives always a sensible result. Using triggers to monitor the table shows that indeed it is updated many times per second, but the function returns always zero.
More puzzling is the fact that if we convert the function to a procedure, it gives the wanted result.
The solution to the mystery is found in the MySQL online manual
A stored function acquires table locks before executing, to avoid inconsistency in the binary log due to mismatch of the order in which statements execute and when they appear in the log.
In other words, it means that all tables referenced in a stored functions are locked when the function starts. Therefore the external procedures that were updating the table will have to wait until the function's end before updating. When the function reads from the table, it gets always the same record counter, because no updates were happening in the meantime. That's why the second read is the same as the first one, and the result is zero.
What should you do then?
One option is to convert the function into a procedure:
delimiter //
drop procedure if exists show_update_ratio //
create procedure show_update_ratio()
begin
declare sleep_wait int default 5;
declare start int default 1;
declare finish int default 1;
select counter into start from mytable;
do sleep(sleep_wait);
select counter into finish from mytable;
SET @UPS := (finish-start)/sleep_wait;
end //
That gets the job done. If you want to get the result into a variable, you can do it with two statements.
call show_update_ratio();
select @UPS;
If you don't change the last SET into a SELECT and just display the value.Another option is using several SQL commands from your application. Also in this case, make sure that you are NOT wrapping this code inside a transaction, or you will get the same result in both queries
# WRONG!
set autocommit=0;
BEGIN;
select counter into @start from mytable;
set @start = start;
do sleep(5);
select counter into @finish from mytable;
select (@finish - @start) / 5 as UPS;
If you go for this solution (or even the stored procedure), make sure that you are either using autocommit, or commit after each query if you must use a transaction.
Labels:
functions,
lock,
monitoring,
mysql,
stored procedures,
stored routines,
update
Monday, January 10, 2011
Continuent is hiring - Support and QA engineers wanted
| Continuent is hiring. The business is growing, the opportunities are piling up nicely, and we need to beef up the team with the addition of some new professionals. The mist urgent posts to fill are a QA Engineer and a Support Engineer, both experts of their specific trades and of database clustering. We are looking at the matter without borders. Although it would be preferable to find candidates in the US, and in the West Coast in particular, we are really looking for the best people in the market, regardless of their location. Both jobs are challenging, they are both MySQL related, and both require experience with QA and support respectively, in addition to development background. If you are a super star in either QA or support, contact resumes AT continuent DOT com. Also, feel free to contact me, should you need further information. |
Thursday, January 06, 2011
Announcing the Open Database Camp - Sardinia, May 2011
| I have been traveling to many conferences in the last 10 years, and many times I have been asked to organize an event in my native land, Sardinia. After delaying the inevitable for long time, here I can announce it. The Open Database Camp 2011 will take place in Sardinia, hosted by the Sardinia Technology Park, a local scientific and business institution with international links. Mark your calendars: the Open Database Camp will be held in Sardinia on May 6-7-8, 2011. I have already confirmed the venue, and I will have full cooperation from Sardegna Ricerche about the conference logistics. I will meet the organizers on January 27th to get in touch with nearby hotels and restaurants and negotiate rates. The place is a beautiful and modern compound, built in the middle of a forest. About 40 Km from Cagliari and its airport. There is a public bus service to reach the venue, and there will be an integrative bus during the conference. The place is a few kilometers from the sea resort of Pula, near the archeological beauty of Nora. |
There are cheap direct flights from several European airports with EasyJet, Ryanair, TUIFly, Air Berlin, and probably a few more.
For example, you can fly to Cagliari from Paris, Frankfurt, Berlin, Cologne, Munich, Stuttgart, London, Edinburgh, Brussels, Madrid, Barcelona, Seville, Valencia, Venice, Rome, Milan, Turin, Basel, Geneva, Krakow, and probably more by the time you come.
If you book now, you should be able to get a good price.
The weather in Sardinia is mild. May is almost summertime. If you live in cold places like the North of the USA, Canada, Scandinavia, May in Sardinia is definitely warmer.
More logistics information will come.
Why Open Database Camp, and not Open SQL Camp like before?
The Open SQL Camp tradition has evolved since its inception in 2008. It has now become a gathering of database professionals and enthusiasts, not necessarily identifiable with the SQL constraint.
So, the conference welcomes everyone who deals with open databases, regardless of the languages used to interface them.
Stay tuned for more info. In the meantime, you can discuss this matter in the opensqlcamp Google Group.
Labels:
conference,
database,
innodb,
mysql,
nosql,
postgresql,
sqlite,
tungsten
Monday, December 20, 2010
Looking for a hack - Passing comment-like info through the binary log
Background
Normally, I would use a comment. The first thing I would think isCREATE PROCEDURE p1(i int) select "hello" /* This is my text */But most client libraries will strip it.
There was a clever trick by Roland Bouman that allowed users to bypass this limitation. You could use a qualified comment such as
/*!999999 This is my test */, but unfortunately it only works in MySQL 5.0.x, while MySQL 5.1 strips everything down, even if the comment is a legitimate keyword.
create procedure p9 (j int) insert /*!50000 INTO */ t1 values (j) ;
Query OK, 0 rows affected (0.00 sec)
show create procedure p9\G
*************************** 1. row ***************************
Procedure: p9
sql_mode:
Create Procedure: CREATE DEFINER=`msandbox`@`%` PROCEDURE `p9`(j int)
insert INTO t1 values (j)
character_set_client: latin1
collation_connection: latin1_swedish_ci
Database Collation: latin1_swedish_ci
1 row in set (0.00 sec)
Other tricks
Something else that I have tried: I can inject a query before or after the one that I need to monitor.create table if not exists comments (t varchar(100)) engine=blackhole; update comments set t='the next statement is what I need'; create procedure p1(i int) insert into t1 values (j); update comments set t='the previous statement is what I need';This approach does possibly introduce some overhead.
Or I can add a comment clause in the statement.
create procedure p1(i int) comment="this is what I need" insert into t1 values (j);This approach requires parsing the SQL, and dealing with artistic indentation and usage of other options in the query. And if I need to deal with commands that don't support the "comment" option, I am back to square one.
Advice wanted
So far, the only method that works almost always is the blackhole trick (1)I would like to know if there is any method of introducing a piece of information related to a given statement, in such a way that the comment survives after one of the following:
- The binary log is converted to queries and passed to a MySQL client that applies the stream of queries to another server.
- The binary log is associated with another master, and then passed to a slave through regular replication.
As a related matter, I know that MySQL, in regular replication, passes some information across binary logs, and that information is the server-id. If I set an intermediate server as relay slave, the server-id of the original master is associated with the query recorder in the binary log of every slave. I don't know if I can use this information for my purposes, but I would like to know how does the replication process maintain the server ID across servers.
Maybe it's too late for me and I can't see an obvious solution. I will appreciate any suggestion. Thanks in advance
(1) If the blackhole is disabled, the method fails, or introduce unacceptable overhead.
Labels:
binary log,
hack,
mysql,
replication
Thursday, December 16, 2010
Some hidden goods in MySQL 5.5
| The announcement of MySQL 5.5 released as GA has outlined the improvements in this version, which indeed has enough good new features to excite most any user. There are two additions, though, that were lost in the noise of the bigger features, and I would like to spend a few words for each of them. |
Let's see an example, with a simple procedure that uses three parameters.
drop procedure if exists add_to_date ;
create procedure add_to_date(in d date, in i int, out nd date)
deterministic
set nd = d + interval i day;
This works as expected in both 5.1 and 5.5. (Never mind that it's redundant. I know it. It's only for the sake of keeping the example short).
call add_to_date('2010-12-15',10,@new_date);
Query OK, 0 rows affected (0.00 sec)
select @new_date;
+------------+
| @new_date |
+------------+
| 2010-12-25 |
+------------+
1 row in set (0.00 sec)
The difference starts to show when you want to deal with this procedure programmatically. If you need to find out which parameters are expected by this procedure, your only option in MySQL 5.1 is parsing the result of SHOW CREATE PROCEDURE add_to_date. Not terribly difficult in any scripting language, but a hassle in SQL.In MySQL 5.5, instead, you can easily get the routine parameters with a simple query:
select parameter_name, parameter_mode,data_type from information_schema. parameters where specific_schema='test' and specific_name= 'add_to_date' order by ordinal_position;
+----------------+----------------+-----------+
| parameter_name | parameter_mode | data_type |
+----------------+----------------+-----------+
| d | IN | date |
| i | IN | int |
| nd | OUT | date |
+----------------+----------------+-----------+
3 rows in set (0.00 sec)
Speaking of the information_Schema, there are more goodies that were not emphasized enough. The Innodb engine that you find in the server is the evolution of the InnoDB plugin that ships with MySQL 5.1. Only that it is now built-in. What many people forget to mention is that the plugin (and thus the current InnoDB engine in 5.5) comes provided with its own InnoDB-specific instrumentation tables in the information_schema.
show tables like 'innodb%';
+----------------------------------------+
| Tables_in_information_schema (innodb%) |
+----------------------------------------+
| INNODB_CMP_RESET |
| INNODB_TRX |
| INNODB_CMPMEM_RESET |
| INNODB_LOCK_WAITS |
| INNODB_CMPMEM |
| INNODB_CMP |
| INNODB_LOCKS |
+----------------------------------------+
7 rows in set (0.00 sec)
This is the same set of tables that you may have seen if you have worked with the InnoDB plugin in 5.1. In short, you can get a lot of the info that you used to look at in the output of SHOW ENGINE INNODB STATUS. For more information, you should look at what the InnoDB plugin manual says on this topic.I don't know if the tables can replace the SHOW ENGINE INNODB STATUS. Perhaps someone can comment on this issue and provide more information?
Labels:
5.5,
GA,
information_schema,
innodb,
mysql,
stored procedures
Thursday, December 09, 2010
Speaking at the O'Reilly MySQL Conference - April 2011
I will present two talks at the MySQL Conference next April.
One is a three hours tutorial on Advanced MySQL Replication Techniques, and the other is a normal session on The art of sandboxing. Reducing Complex Systems to Manageable Boxes.
The first topic is not a first to me. But the contents are going to be fresh and new. There has been so much going on in the replication field, that the talk on this topic that I presented in 2007 looks like ancient history.
The second topic is completely new. I have often presented the result of my sandboxing efforts, but I have never thought of explaining the techniques themselves. Now that I have got some experience at reducing differently complex systems to sandboxes, I want to share the knowledge, to promote more work in this field.
One is a three hours tutorial on Advanced MySQL Replication Techniques, and the other is a normal session on The art of sandboxing. Reducing Complex Systems to Manageable Boxes.
The first topic is not a first to me. But the contents are going to be fresh and new. There has been so much going on in the replication field, that the talk on this topic that I presented in 2007 looks like ancient history.
The second topic is completely new. I have often presented the result of my sandboxing efforts, but I have never thought of explaining the techniques themselves. Now that I have got some experience at reducing differently complex systems to sandboxes, I want to share the knowledge, to promote more work in this field.
Labels:
conference,
mysql,
oreilly,
replication,
speaking
Monday, December 06, 2010
Excluding databases from mysqldump
A question that came up during the MySQL track at the UKOUG conference in Birmingham was "Can I exclude only a few databases from mysqldump? Let's say that I have 50 databases, and I want to dump all of them, except a few."
As many know, mysqldump has an option to ignore specific tables. SO if you have 1,000 tables in a databases, you can tell mysqldump to dump all the tables except a few ones.
There is no corresponding option to exclude one or more databases.
However, if you know your command line tools, the solution is easy:
First, we get the list of all databases:
Now, let's say that we want to exclude databases four, five, and six. And since we want to avoid unpleasant side effects, also information_schema and performance_schema.
Thus, we pipe the previous data through a filter. I use Perl, but sed or grep could get the job done.
Update: Thanks to Shantanu, who pointed that the regexp does not filter properly. So I added the boundary checks (\b) to make my words match the result.
As many know, mysqldump has an option to ignore specific tables. SO if you have 1,000 tables in a databases, you can tell mysqldump to dump all the tables except a few ones.
There is no corresponding option to exclude one or more databases.
However, if you know your command line tools, the solution is easy:
First, we get the list of all databases:
mysql -B -N -e 'show databases' information_schema employees five four mysql one performance_schema six test three two-B forces batch mode (no dashes box around the data), while -N gets the result without the headers.
Now, let's say that we want to exclude databases four, five, and six. And since we want to avoid unpleasant side effects, also information_schema and performance_schema.
Thus, we pipe the previous data through a filter. I use Perl, but sed or grep could get the job done.
mysql -B -N -e 'show databases' | \ perl -ne 'print unless /\b(?:four|five|six|_schema)\b/' employees mysql one test three twoNow that we have the list of databases that we need, we can tell mysqldump to backup the databases from such list. All we need is converting the vertical list into a horizontal one using xargs
mysql -B -N -e 'show databases' | \ perl -ne 'print unless /\b(?:four|five|six|_schema)\b/' \ xargs echo mysqldump -B mysqldump -B employees mysql one test three twoThat's it. The last line is the resulting command. Once you are sure that it is what you want, remove the "echo" after xargs, and the command will be executed.
Update: Thanks to Shantanu, who pointed that the regexp does not filter properly. So I added the boundary checks (\b) to make my words match the result.
Friday, December 03, 2010
My picks for PGDay-EU 2010
On Sunday I will be in Stuttgart with the double purpose of attending the annual European PostrgreSQL conference and the technical meeting of my company that will be held after the normal proceedings of PGDay-EU.
For the first time in several years I am attending a conference where I am not a speaker. In my previous job I did not have much opportunity to attend PostgreSQL meetings, and I welcome this opportunity. The schedule is quite interesting, and I have made my personal picks:
- Monday:
- 09:45 - 10:45 Keynote: Back To The Future of Open Source.
Simon Phipps has always an interesting way of making a topic interesting. Looking forward to hearing what he has to say. - 11:10 - 12:00 Play chess against PostgreSQL (and get beaten).
For a chess enthusiast and database professional, this talk is going to be doubly interesting! - 12:10 - 13:00 Managing PostgreSQL Replication.
In my new job, this topic is going to be paramount. - 14:00 - 14:50 Liberating Your Data From MySQL: Cross-Database Replication to the Rescue!.
This will be a presentation of Tungsten cross DBMS replication, therefore interesting for many personal reasons! - 15:20 - 16:10 Concurrency & PostgreSQL.
Undoubtedly a topic that will become quite useful when dealing with PG replication issues that I will be facing in my job.
- 09:45 - 10:45 Keynote: Back To The Future of Open Source.
- Tuesday:
- 14:10 - 15:00 PostgreSQL extension's development.
I know a lot about extensions in MySQl. It's time to start learning similar about PG! - 15:30 - 16:20 Closing keynote: PostgreSQL's Time to Shine: The most disruptive force in open source since Linux
This sounds like a juicy strategic talk.
- 14:10 - 15:00 PostgreSQL extension's development.
Labels:
conference,
continuent,
mysql,
open source,
postgresql,
stuttgart
Who's afraid of MySQL forks?
| There is much talk about MySQL forks and how they are going to replace MySQL, or take over MySQL user base, or become more powerful/profitable/popular/you-name-it than MySQL itself. Let's clear some air on this topic. There is more about forks than meets the eye, especially if you think about a few obvious facts. What's a fork? According to Wikipedia a project fork happens when developers take a legal copy of source code from one software package and start independent development on it, creating a distinct piece of software. |
Why am I approaching the issue from this angle? Because, apart from Windows users, who mostly download MySQL from the official site, the majority of users get MySQL through a Linux distribution or some other project. And most of the time such packages are different from the ones built by the MySQL team. There is nothing wrong with that. The differences are sometimes minimal packaging changes done to adapt MySQL to the specific distribution, and sometimes they are a cherry-picking application of patches to an old version that needs to be maintained so that the package is unlike any other MySQL version that you may find in the wild. Even if the version is the same, depending on the distribution and the age of the server, the code beneath could be wildly different from the official versions.
Thus, it turns out that many users, possibly the majority, are using a MySQL fork, albeit a very minor one.
But when people talk about forks, they often refer to three main projects:
- The Percona distribution. This is a collection of a few distinct patches in the server, coupled with a fork of the InnoDB plugin, named XtraDB, and an independent tool for backup (XtraBackup). This fork has a solid business background. Every patch has been developed to meet user requests, and the engineers at Percona maintain them appropriately.
- Then we have the MariaDB fork, which is a series of changes to the MySQL core, motivated by the desire of the developers to build a rich set of feature enhancements while being backward compatible to the main distribution. The business model is thus a fast track of new features and bug fixes to customers.
- And then there is Drizzle, which has even less business traction than MariaDB, but a very well defined goal of creating a lightweight database by re-engineering a bare bones stripped down version of MySQL that is now very distant from its origins.
Not so fast. There is something that few people take into account when listening to this too often repeated tale.
What most observers miss is that the forks' original code (with the exception of Drizzle) is very marginal. The bulk of the distribution is still the code produced by the MySQL team, which is merged at every minor release, and integrated with the patches produced by Percona and MariaDB. So, while technically they are forks of MySQL, they can't live independently from the official MySQL distribution. Both Percona and MariaDB don't have the manpower to maintain the server by handling the huge amount of bugs that the MySQL team is fixing every month.
There is also a matter of skill set. Percona has talented InnoDB experts, while MariaDB has mostly core server experts (and some are among the top ones, I may add). They could complement each other, although it seems that cooperation between the two projects is not as good as it used to be. (Could be my personal impression.)
The bottom line, though, is if both projects are able to survive should the main project become unavailable. I am not suggesting that Oracle wants to make MySQL scarce. On the contrary, all the information at my disposal suggest that Oracle will keep MySQL publicly available for long time.
This state of affair seems to indicate that Drizzle is, instead, a true fork that does not depend on MySQL health. To some extent, this is true. However, the main storage engine in Drizzle is InnoDB. Therefore, at least today, Drizzle is as dependent on Oracle as Percona and MariaDB.
What would happen tomorrow, if the disaster depicted by doomsday advocates comes true and MySQL actually disappears? I don't honestly know, but I would love to have a public commitment from the major players, about what they are prepared to do in terms of maintaining that huge chunk of code that today they take from Oracle releases on a monthly basis.
This is all matter of thought for MySQL users.
About adoption of the forks today, I have seen five types of arguments in favor of a MySQL fork:
Argument #1 is a solid business backed reason for adopting some software. The risk is often well calculated, especially if the evaluation can be backed by performance and functional tests.
- I need the feature provided by Percona or MariaDB, or I need a quick bug fix that I can't get from the slow roadmap at Oracle. I trust that this handful of people are able to maintain that little code that differs from MySQL and matters to me. So I don't care if they don't have 100 developers on the task.
- Given Oracle's track record in other Open Source projects, I don't trust them to deliver MySQL according to FOSS principles, so let's go for true Open Source alternatives.
- Most MySQL developers have now left Oracle, and so the forks have more chances of being higher quality.
- Cool! MariaDB/Percona has a bunch of features more than MySQL. It must be better. Let's use it.
- I like new technology. Let's plunge into them!
Argument #2 is frivolous, as it mixes subjective feelings into business matters. And so is argument #4. Yet, these two types of advocacy are quite popular and spread much faster than the more reasonable approach seen at #1.
Argument #3 is debatable. MySQL developers at Oracle outnumber all forks easily. The idea that the departure of a few core developers can alter the system in such a way that the whole project crumble has been already negated by facts: MySQL 5.5 is an excellent release, with enthusiastic appreciation from power users. While I agree that top MySQL talents work at the forks, I consider the MySQL team to be still in excellent shape.
Argument #5 is reasonable, if it is followed by cool judgment and backed by facts. I am one who is always ready to try new solutions, and love experimenting with cool technology. But adoption is different from proof of concept. I am happy to see that Drizzle can replace MySQL in some applications, but would I trust it in its present beta stage? Certainly not. So, I am happy to test, but I trust my valuable data to more stable solutions.
What's for you, the final user? My personal advice is: don't adopt blindly because of some enthusiastic advertising. But test the product thoroughly, and if it fits your needs, by all means, go for it. But if you don't have a specific reason, I recommend staying with the official branch, because, despite the change in affiliation, there is still a well experienced team behind it.
Sunday, November 28, 2010
Dispelling some unintentional MySQL FUD
| | There are three types of FUD: the first and more genuine is (#1) the intentional spreading of falsehood, mostly to gain some marketing advantage over a competing product. While I despise this practice, I understand it. Then there is (#2) FUD spread by ignorance, when the originators are so blindly enraged by their hatred for a product that they don't care about getting the facts straight. And finally, there is a third kind, not less dangerous, which is (#3) the spreading of FUD with good intentions, when the authors believe that they have the facts straight and they want to help. |
MySQL is not ACID complaint
This surprising piece of news came in the blog of a company that calls itself the remote DBA experts.The claim is this: if I insert a record in a table and then issue a ROLLBACK command, the record is not rolled back.
Anyone who has a minimal knowledge of MySQL knows about InnoDB tables (luckily for the poster, InnoDB is default in MySQL 5.5.6, which he was testing) and autocommit.
Reading through the example, one sees that the poster did not know about this piece of information. In MySQL,
autocommit is ON by default. So if you want to rollback a record, you need to deactivate it. This is not optimal, and it can be debated, but if you read the docs, you don't claim something that is simply the result of your lack of knowledge. MySQL has shortcomings, but being unable to rollback a record is not one of them. Hence, this is FUD type #2.Why I am writing all this here and not as a comment in that blog? Because I did post a comment, on November 23rd, but as of today, it has not been approved yet. The same is true for comments posted by other more knowledgeable people.
MySQL licenses. When it's free and when you need to pay for one.
This article is well intentioned. MySQL Licenses: The Do's and Don'ts of Open Source, or What's All the Fuss About? is a well thought piece, with practical examples, to help users decide what to do with MySQL licensing, i.e. when they need to pay and when they don't. Unfortunately, the article contains some unintentional confusion, and therefore leaves the readers with more wrong ideas than they had before.I left a long comment on that blog, but for some unfathomable reason it was reduced to a tiny piece, and thus the need for explaining the matter here again.
The poster says this:
I make commercial software, which needs to have MySQL installed. My customers can use my commercial software, for which they do need to buy a license, in combination with the MySQL database engine, for which they don't need to pay. Because the MySQL engine is not embedded in my commercial software and I don't redistribute MySQL together with my software, I don't need a commercial license for MySQL and neither do my customers.I am afraid that this wishful information is not correct. The GPL FAQ states it clearly:
If a library is released under the GPL (not the LGPL), does that mean that any program which uses it has to be under the GPL or a GPL-compatible license?
Yes, because the program as it is actually run includes the library.
Another quote:
However... as long as I have no desire to sell the embedded MySQL source code commercially, I can let the GPL license apply.Also this is not true. The GPL does not regulate commercial transactions. It only deals with distribution of software. If I want to distribute a public domain but GPL-incompatible software linked to a GPL application or library, I am violating the GPL, even if I don't charge anything.
Another source of disinformation is "If you decide to pay for a MySQL license, you don't actually pay for the software."
This is also incorrect. Oracle sells two kind of things with MySQL. One thing is a subscription to services (MySQL Enterprise). If you buy this, you are not getting a license (unless you ask for it explicitly) but an agreement about services for a given periods.
The other thing that Oracle sells is licenses. They can do it because they own the source code, and they can decide to release it either as GPL (which is what you download from the MySQL site) or with a commercial license. If you ask for a license, you will most definitely get one. You can also get a license together with a subscription, if you are so inclined, but that doesn't mean that you aren't buying a license.
The important thing to understand to put the matter in perspective, is that the above information about licensing was still true before 2008, when MySQL was owned by MySQL AB, and it is still true today. Oracle, despite all the preemptive accusations of being ill intentioned, has not changed the rules of the game.
Labels:
acid,
autocommit,
fud,
innodb,
licensing,
mysql,
myth,
transactions
Subscribe to:
Posts (Atom)
