Linux.com

Feature

Running MySQL queries on multiple servers

By on March 01, 2006 (8:00:00 AM)

Share    Print    Comments   

You may know how to use SQL to extract data from a table in a MySQL database, and how to run a query that combines data from more than one table. But what about multiple databases? Or even multiple databases on multiple servers?

Let's start by looking at the simplest example -- running a query on a single table. All you have to do is connect to the database, enter the query, and press Enter.

By the way, I'm using David Nash's HYG Databases of stellar data in the following examples. I downloaded Nash's CSV files, wrote a shell script to format them, then created the databases on three of my servers -- Acamas, Cassandra, and Hector.

$ MySQL -s -uusername -ppassword stellar
MySQL> select propername from hygfull where propername  '';
propername
268 G. Cet
33 G. Lib
82 G. Eri
96 G. Psc
Achernar
Acrux
Adhara
Alcyone
...
MySQL>

OK -- no surprises there. The next stage is to run query that uses data from two tables. You can move from using a single database to multiple databases easily, provided that they are on the same server:

MySQL> select count(hygfull.starid)
    -> from hygfull left join hyg85
    -> on hygfull.starid = hyg85.starid
    -> where hyg85.starid is null;
+-----------------------+
| count(hygfull.starid) |
+-----------------------+
|                 21084 |
+-----------------------+
1 row in set (1.50 sec)

MySQL>

Wouldn't it be nice if you could just carry on in this way and tag the server name on in the same way that you can add the database? But life's not like that. If you come from an Oracle background then you'll be used to the concept of the database link, which allows you to set up a link and then access tables (which can be on different servers) in a similar way to the example above. Unfortunately you can't do that on MySQL.

That's not to say that you can't access data on other servers. To do so, use the -h flag and supply the server name:

$ MySQL -s -uusername -ppassword -hservername astellar

or:

$ MySQL -s -uusername -ppassword -h192.169.0.3 hstellar

Now you can easily run a query on any MySQL database on any server. Not enough? You need to be able to create a query that gets information from more than one server? You can use MySQL's database replication to help you run queries on data spread over different servers.

With database replication, one server is set up as a master and a second as a slave. Data from the master is then replicated on the slave, and any subsequent changes are automatically passed through. You must remember, however, that this is replication rather than a direct connection, meaning that the slave database is not updated immediately when records in the master database change.

To set up a master server, edit the /etc/MySQL/my.cnf file so that it includes the lines:

#bind-address            = 127.0.0.1
log-bin = /var/log/MySQL/MySQL-bin.log
binlog-do-db = hstellar
server-id = 1

Then restart MySQL with the appropriate command for your system. For example, on Debian it's:

/etc/init.d/MySQL restart

Log on to the MySQL database to complete the master setup. Add a user account for the slave to use:

GRANT REPLICATION SLAVE
ON *.* TO 'slave_user'@'%'
IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

USE hstellar;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

The final command reports some details that you will use when setting up the slave. It will look something like:

+---------------+----------+--------------+------------------+
| File          | Position | Binlog_do_db | Binlog_ignore_db |
+---------------+----------+--------------+------------------+
| MySQL-bin.018 | 79       | hstellar     |                  |
+---------------+----------+--------------+------------------+
1 row in set (0.00 sec)

You're now ready to move onto the slave. You need to edit its /etc/MySQL/my.cnf file, modifying it so that it contains the lines:

server-id=2
master-host=hector
master-user=slave_user
master-password=password
master-connect-retry=60
replicate-do-db=hstellar

Next you'll need to create a dababase on your slave server -- but don't add any tables into it. Tables will come automatically from the master server.

CREATE DATABASE hstellar;

Once you've created the database, restart MySQL. Log back on to MySQL on the slave as root and update the master details (using the information you obtained by running show master status on the master:

CHANGE MASTER TO MASTER_HOST='hector', MASTER_USER='slave_user', 
MASTER_PASSWORD='password', MASTER_LOG_FILE='MySQL-bin.018', MASTER_LOG_POS=79;

You can now replicate the data from the master onto the slave:

LOAD DATA FROM MASTER;

Don't forget, this is not a direct link to the database -- it is a copy. Any changes made on the master will be passed automatically to the slave, but it's a one-way transaction. However, it does allow you to run queries using the data from both databases. For example:

MySQL> select count(*) from cstellar.chyg85;
+----------+
| count(*) |
+----------+
|    66391 |
+----------+
1 row in set (0.01 sec)

MySQL> select count(*) from hstellar.hhyg80;
+----------+
| count(*) |
+----------+
|    46785 |
+----------+
1 row in set (0.00 sec)

MySQL> select count(*)
    -> from cstellar.chyg85 c
    -> left join hstellar.hhyg80 h on c.StarID=h.StarID
    -> where h.StarID is null;
+----------+
| count(*) |
+----------+
|    19606 |
+----------+
1 row in set (3.14 sec)

Once you have your slave working with one master, you'll probably want to add in more databases from other servers. Unfortunately you can't. You are limited to only one master for the slave. You can access as many databases on the master as you want by adding further binlog-do-db fields to the master's my.cnf file and replicate-do-db lines to the slave's my.cnf file. However, you can't add in another master-host on the slave to access two masters.

Fortunately there is a simple solution -- you can set the slave up as a master for a third server.

You'll need to modify the old slave's my.cnf file so that it can it can become a master:

log-bin = /var/log/MySQL/MySQL-bin.log
binlog-do-db = cstellar
binlog-do-db = hstellar

As before you'll have to create a user account (slave_user), and you will have to modify the new slave's my.cnf file (remembering to give the slave server a unique id):

server-id=3
master-host=cassandra
master-user=slave_user
master-password=password
master-connect-retry=60
replicate-do-db=cstellar
replicate-do-db=hstellar

Once you've completed the process you will be able log on to the new slave and run queries on data from all three servers. Any updates that you carry out on the master and sub-master will automatically be fed through to the slave.

And there you have it -- some simple but effective ways of accessing multiple MySQL databases across different servers. With these techniques you can go off and do some data mining, check distributed versions of the same database, or improve the security for your online shop.

Share    Print    Comments   

Comments

on Running MySQL queries on multiple servers

Note: Comments are owned by the poster. We are not responsible for their content.

Why even bother with Mysql?

Posted by: Anonymous Coward on March 02, 2006 01:17 AM
Guess what? you can do db links with Postgresql, and the latest version (8.1) really is great and in real world web applications no one would even notice that Mysql is now gone.

#

Re:Why even bother with Mysql?

Posted by: Anonymous Coward on March 05, 2006 01:56 AM
MySQL-5.0 has "database links" as well:

<a href="http://dev.mysql.com/doc/refman/5.0/en/federated-storage-engine.html" title="mysql.com">http://dev.mysql.com/doc/refman/5.0/en/federated-<nobr>s<wbr></nobr> torage-engine.html</a mysql.com>

#

ravindra mudumby

Posted by: Administrator on March 02, 2006 03:03 AM
On the 1st December, 2004, MySQL AB released a new version of MySQL Administrator (version 1.0.17). I had not previously used this tool, but with some time on my hands and the work crisis averted thanks to the installation of our new database server, I thought I would see how it shapes up. Since we use PHP as a scripting language, we have always used phpMyAdmin, but the web interface can be frustratingly slow. MySQL Administrator is installed on your client, and so it responds quickly. It can be installed on a Linux machine with a graphical desktop, or Windows (NT, 2000, XP, or 2003 only). This month I give a quick tour, see how you could use it, and highlight some of the places where you can find useful data to help optimize your databases.
Features

Once installed, open MySQL Administrator and it will ask for a connection. Enter your login details (the server can be remote or local - connecting remotely disables some of the features, though many will not be running GTK on their lean and mean database servers, so local installation may not be an option). Your server connection can be saved under Tools/Save current connection. Once connected (and you can connect to multiple servers at the same time), navigation is simple - there is a sidebar with various main sections, and options within these. These are the sidebar options.

* Server Information: High-level overview with information about the user, host, port, MySQL client and server versions, and general client and server information.
* Service Control: Only available when you are connecting to a database server on the local host, this allows you to start and stop the MySQL server, and configure the MySQL service (on Windows).
* Startup Variables: Also only available when connected to localhost, this allows you to set startup variables for the MySQL server.
* User Administration: An easier way to administer privileges, you can fully control user access to the MySQL server in this section.
* Server Connections: Useful when the server is taking strain, here you can list the threads, as well as see how many instances of each user is connected to the server. You can also kill individual threads or all connections from a user.
* Health: In-depth data about your connections, memory usage, status variables and system variables.
* Server Logs: If connected to localhost, you can view entries from the error, slow and general logs
* Replication Status: View information about replicated slaves and masters.
* Backup: Backup, or schedule backups
* Restore: Restore backed up databases.
* Catalogs: Information about databases, as well as the ability to create and edit tables and perform routine maintenance, such as optimizing and checking.

Server Health

Most administrators will find the health feature particularly useful, so let's start with that one. At first you'll be presented with the connection health, which consists of three graphs: connections (a graphic of the percentage of total available connections used, as well as figures for the current, minimum, maximum and average number of connections), traffic (a graphic of kB being sent, as well as current, minimum, maximum and average kB sent) and number of SQL queries (again a graphic of the number of queries, and figures for the current, minimum, maximum and average number of queries).

So what does this tell us? I am going to use a live server as an example, with the data taken from off-peak hours. Let's look at a screenshot.

Firstly, the number of connections is not a problem. It may be off-peaks, but the maximum is still way below the limit. The database server has recently been upgraded, and the previous maximum connection limit has been maintained. Because the server processes the queries much more quickly now, the connections have not been building up nearly as much.

Secondly, the bytes sent are running at about one sixth of the maximum, but slightly above average, as one would expect from an off-peak server (remembering that excessive highs or lows skew averages).

Finally, the number of queries running is quite low, again corresponding to the time of day. The main probable call to action from this screen would be if the connection usage were approaching 100%, indicating one should up the max_connections in the config file.

#

Re:ravindra mudumby

Posted by: Anonymous Coward on March 02, 2006 07:50 AM
some line breaks helped here.

#

Perl SQL Cluster Module

Posted by: Administrator on March 03, 2006 06:19 PM


Have a look at <a href="http://search.cpan.org/~arak/DBIx-DBCluster-0.01/DBCluster.pm" title="cpan.org">DBIx::DBCluster</a cpan.org> for load balancing your queries between the master and slave node(s).

#

I had an error.

Posted by: Administrator on September 04, 2006 05:42 PM
Before this step:
Once you've created the database, restart MySQL. Log back on to MySQL on the slave as root and update the master details (using the information you obtained by running show master status on the master:

CHANGE MASTER TO MASTER_HOST='hector', MASTER_USER='slave_user',
MASTER_PASSWORD='password', MASTER_LOG_FILE='MySQL-bin.018', MASTER_LOG_POS=79;

I had to put this command in the slave: STOP SLAVE;

The problem is that I can't do this if the slave is running:
Error: 1198 SQLSTATE: HY000 (ER_SLAVE_MUST_STOP)

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya