<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MySQL How 2 &#187; MySQL</title>
	<atom:link href="http://www.mysqlhow2.com/tag/mysql-general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlhow2.com</link>
	<description>MySQL DBA information and helpful tips and tricks to make life easier.</description>
	<lastBuildDate>Wed, 01 Sep 2010 18:15:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>MySQL Privileges Table</title>
		<link>http://www.mysqlhow2.com/2010/07/mysql-privileges-table/</link>
		<comments>http://www.mysqlhow2.com/2010/07/mysql-privileges-table/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 21:59:00 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[delete]]></category>
		<category><![CDATA[grants]]></category>
		<category><![CDATA[insert]]></category>
		<category><![CDATA[Privileges]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[super]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[users]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=475</guid>
		<description><![CDATA[Understand MySQL users and privileges]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>Many times am I asked what privileges do i need for this user. Explaining them can be confusing so I made this to share with everyone to help them understand MySQL users and privileges. Hopefully this will help you in deciding proper permissions for users. Click image below to download the pdf.</p>
<p>The attached pdf has aÂ  table that anticipates that you want to know two things about  privileges:</p>
<ul>
<li><strong>What action is permitted:</strong> Read either the &#8220;What action is  permitted&#8221; column, or the    &#8220;Privilege Column Name&#8221; column</li>
<li><strong>At what level of granularity can it be set:</strong> For the  privilege you&#8217;re interested in,    note the &#8220;X&#8221;&#8216;s, and read up the table to see which privilege tables  provide that privilege, and    then inspect their Key columns to understand the level of granularity.</li>
</ul>
<p><img src="file:///tmp/moz-screenshot.png" alt="" /><img src="file:///tmp/moz-screenshot-1.png" alt="" /><a href="http://www.mysqlhow2.com/wp-content/uploads/2010/07/MySQL_User_privileges_table.pdf"></a><a href="http://www.mysqlhow2.com/wp-content/uploads/2010/07/MySQL_User_privileges_table.pdf"><img class="aligncenter size-thumbnail wp-image-483" title="MySQL User Privileges" src="http://www.mysqlhow2.com/wp-content/uploads/2010/07/screenshotmysqlp-150x150.png" alt="" width="244" height="244" /></a></p>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/07/mysql-privileges-table/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Memory Settings</title>
		<link>http://www.mysqlhow2.com/2010/02/mysql-memory-settings/</link>
		<comments>http://www.mysqlhow2.com/2010/02/mysql-memory-settings/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 16:00:38 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[tuning]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=356</guid>
		<description><![CDATA[These are some settings values I look at when I start up a new MySQL instance. Not all instances of MySQL will have the same, so I tweak until I get optimal performance out of MySQL. Also remember not to go into swap when allocating memory.]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>These are some settings values I look at when I start up a new MySQL instance. Not all instances of MySQL will have the same, so I tweak until I get optimal performance out of MySQL. Also remember not to go into swap when allocating memory.</p>
<p><strong>General MySQL Settings</strong><br />
The Most important ones are:<br />
<strong>Key Buffer</strong><br />
The key buffer holds the indexes of tables in memory and a bigger key buffer results in faster row lookups. Adjust according to your own needs. Bigger is better, but prevent swapping at all costs. A good rule of thumb seems to be to use 1/4 of system memory.</p>
<p><strong>Query Cache</strong><br />
This is where the magic happens. Well, not magic really, just plain old caching. Keeping the result of queries in memory until they are invalidated by additional writes enhances performance by magnitudes. The query_cache_size, as the name suggests, is the total size of memory available to query caching. The value query_cache_limit is the maximum number of kilobytes one query may be in order to be cached. Setting this value too high might prevent a lot of smaller queries to be cached. Setting it too low will result in bigger queries to never be cached, and the smaller queries not being able to completely fill the cache size, which would be a waste of resources. Adjust according to your own needs and memory available:</p>
<p><strong>Table Cache</strong><br />
An important variable if your application accesses many tables. It is the number of tables a thread can keep open at the same time. A value of 512 should do no harm.</p>
<p><strong>Sort Buffers</strong><br />
sort_buffer_size (the variable previously known as sort_buffer), used for grouping and sorting and is a per-thread buffer. If the buffer can not hold the data to be sorted, a sort is performed on disk. Watch out for making this too large as the buffer is allocated for every thread that needs sorting and with many sorts it can easily consume all your memory.</p>
<p><strong>Binary Logging</strong><br />
MySQL has a few powerful features. Replicating data changes to a second server is one of them. MySQL keeps a log file of data changes which is used for this purpose. If you do not use replication or use the file as incremental backup, you can disable it. This will save you expensive disk write actions for every change to your data. For applications that have a lot of frequently updated data, this can be quite a performance boost. According to the official docs, this will generally result in just a 1% boost but itâ€™s an easy gain if you do not need the log. Read more about the binary log here. Comment the following line:<br />
log-bin = /var/log/mysql/mysql-bin.log</p>
<p><strong>Temporary Tables</strong><br />
Temporary tables are used for sorting and grouping. The buffer is created on demand so watch out for setting this too high here as well. If the buffer cannot accomodate the data, a temp file is used on disk instead.</p>
<p><strong>Delayed Writing</strong><br />
This setting can greatly improve writing or updating data to a table. Instead of directly committing data to the disk, MySQL queues writes and returns write queries immediately. Be very very careful with this, because this also means that in case of a power failure or crash, you lose data. You can use this for logging if you donâ€™t mind losing a couple of rows in case of a crash.</p>
<p><strong>Connection Timeout</strong><br />
This is a little tweak that determines the closing of sleeping connections. The default is one hour and is often too long for practical purposes. I often set this at one minute instead (60).<br />
wait_timeout = 60<br />
The above settings are just to make mysql a little faster in general. You can get much better speed improvements by optimizing the database itself. Setting the correct indexes on tables can be a life-saver.</p>
<p><strong>MySQL Innodb Settings</strong><br />
The most important ones are:</p>
<p><strong>innodb_buffer_pool_size</strong><br />
70-80% of memory is a safe bet. I set it to 12G on 16GB box.</p>
<p><strong>innodb_log_file_size</strong><br />
This depends on your recovery speed needs but 256M seems to be a good balance between reasonable recovery time and good performance</p>
<p><strong>innodb_log_buffer_size=4M</strong><br />
4M is good for most cases unless youâ€™re piping large blobs to Innodb in this case increase it a bit.</p>
<p><strong>innodb_flush_log_at_trx_commit=2</strong><br />
If youâ€™re not concern about ACID and can loose transactions for last second or two in case of full OS crash than set this value. It can dramatic effect especially on a lot of short write transactions.</p>
<p><strong>innodb_thread_concurrency=8</strong><br />
Even with current Innodb Scalability Fixes having limited concurrency helps. The actual number may be higher or lower depending on your application and default which is 8 is decent start</p>
<p><strong>innodb_flush_method=O_DIRECT</strong><br />
Avoid double buffering and reduce swap pressure, in most cases this setting improves performance. Though be careful if you do not have battery backed up RAID cache as when write IO may suffer.</p>
<p><strong>innodb_file_per_table</strong><br />
If you do not have too many tables use this option, so you will not have uncontrolled innodb main tablespace growth which you canâ€™t reclaim. This option was added in MySQL 4.1 and now stable enough to use.</p>
<p>Also check if your application can run in READ-COMMITED isolation mode â€“ if it does â€“ set it to be default as transaction-isolation=READ-COMMITTED. This option has some performance benefits, especially in locking in 5.0 and even more to come with MySQL 5.1 and row level replication.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/mysql-memory-settings/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Having is not a replacement for a where clause!</title>
		<link>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/</link>
		<comments>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 10:00:34 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[having]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[where]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=229</guid>
		<description><![CDATA[Even a query that is checking against an good index will result in a table scan if it is poorly written.Â  It seems some people think that HAVING can be a substitute for WHERE.Â  For example: SELECT word_id FROM forum.wordmatch GROUP BY word_id HAVING COUNT( word_id ) =53805; This seems pretty straightforward; the query is [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>Even a query that is checking against an good index will result in a table scan if it is poorly written.Â  It seems some people think that HAVING can be a substitute for WHERE.Â  For example:</p>
<pre class="brush: sql;">
SELECT word_id
FROM forum.wordmatch
GROUP BY word_id
HAVING COUNT( word_id ) =53805;
</pre>
<p>This seems pretty straightforward; the query is trying to display how many entries have a word_id (indexed) greater than 53805.Â  But an explain shows that this is a table scan:</p>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | index | NULL | word_id | 3 | NULL | 6374529 | Using index |
</pre>
<p>The problem is there is no WHERE clause, and HAVING just controls output.Â  So rewriting the query like so improves the performance by a factor of 10:</p>
<pre class="brush: sql;">
SELECT count( word_id )
FROM forum.wordmatch
WHERE word_id =53805;
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| wordmatch | range | word_id | word_id | 3 | NULL | 641340 | Using where; Using index |
</pre>
<p>To quote mysql.com:</p>
<p>&#8220;Do not use HAVING for items that should be in the WHERE clause&#8221;. For example, do not write the following:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name HAVING col_name = 0;
</pre>
<p>Write this instead:</p>
<pre class="brush: sql;">
SELECT col_name FROM tbl_name WHERE col_name = 0;
</pre>
<p>The HAVING clause can refer to aggregate functions, which the WHERE clause cannot:</p>
<pre class="brush: sql;">
SELECT user, MAX(salary) FROM users
GROUP BY user HAVING MAX(salary) ;
</pre>
<pre class="brush: sql;">
SELECT DISTINCT ac2.category, ac0.name
FROM snaggy.a2_category ac1, snaggy.a2_category ac2, snaggy.a2_catalog ac0
WHERE ac1.category = 'GAME'
AND ac2.vendor_code = ac1.vendor_code
AND ac2.item_id = ac1.item_id
AND ac0.category = ac2.category
ORDER BY ac0.name
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 |
| ac1 | ALL | category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort
| ac2 | ALL | category | NULL | NULL | NULL |2886 | Using where |
</pre>
<pre class="brush: sql;">
CREATE TABLE `a2_category` (
`vendor_code` varchar(4) default NULL,
`item_id` int(5) default NULL,
`category` varchar(8) default NULL,
FULLTEXT KEY `category` (`category`)
) TYPE=MyISAM
</pre>
<p>Just adding an index helps makes the same query complete in a realistic timeframe:</p>
<pre class="brush: sql;">
ALTER TABLE a2_category ADD INDEX (item_id);
</pre>
<pre class="brush: plain;">
| table | type | possible_keys | key | key_len | ref | rows | Extra |
| ac0 | ALL | NULL | NULL | NULL | NULL | 145 | Using where |
| ac1 | ALL | item_id,category | NULL | NULL | NULL | 2886 | Using where; Using temporary; Using filesort |
| ac2 | ref | item_id,category | item_id | 5 | ac1.item_id | 3 | Using where |
</pre>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/having-is-not-a-replacement-for-a-where-clause/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Regular Expressions</title>
		<link>http://www.mysqlhow2.com/2010/02/mysql-reg-expressions/</link>
		<comments>http://www.mysqlhow2.com/2010/02/mysql-reg-expressions/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:15:37 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[Formulas]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Regular expressions]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=237</guid>
		<description><![CDATA[I added a page with a reg expression cheat sheet, so I wanted to post how MySQL can use reg expressions in select queries. I use these and they can be powerful. Using reg expressions in selects is about as basic as it comes. The format for reg expression for a SELECT is: SELECT something [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>I added a page with a<a title="reg expression" href="http://www.mysqlhow2.com/reg-expression-cheat-sheet/"> reg expression cheat</a> sheet, so I wanted to post how MySQL can use reg expressions in select queries. I use these and they can be powerful. Using reg expressions in selects is about as basic as it comes.</p>
<p>The format for reg expression for a SELECT is:</p>
<pre class="brush: sql;">
SELECT something FROM table WHERE column REGEXP 'regexp'
</pre>
<p>For example, to select all columns from the table events where the values in the column id end with 5309, use:</p>
<pre class="brush: sql;">
SELECT * FROM events WHERE id REGEXP '5309$'
</pre>
<p>A more elaborate example selects all columns of the table reviews where the values in the column description contain the word &#8220;mysql&#8221;:</p>
<pre class="brush: sql;">
SELECT * FROM reviews WHERE description REGEXP '[[:&lt;:]]mysql[[:&gt;:]]'
</pre>
<p>MySQL allows the following regular expression metacharacters:. match any character</p>
<ul>
<li> ? match zero or one</li>
<li> * match zero or more</li>
<li> + match one or more</li>
<li> {n} match n times</li>
<li> {m,n} match m through n times</li>
<li> {n,} match n or more times</li>
<li> ^ beginning of line</li>
<li> $ end of line</li>
<li> [[:&lt;:]] match beginning of words [[:&gt;:]] match ending of words</li>
<li> [:class:] match a character class</li>
<li> i.e., [:alpha:] for letters</li>
<li> [:space:] for whitespace</li>
<li> [:punct:] for punctuation</li>
<li> [:upper:] for upper case letters</li>
<li> [abc] match one of enclosed chars</li>
<li> [^xyz] match any char not enclosed</li>
<li> | separates alternatives</li>
</ul>
<p>MySQL interprets a backslash (\) character as an escape character. To use a backslash in a regular expression, you must escape it with another backslash (\\).</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/mysql-reg-expressions/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Rotate Tables C program</title>
		<link>http://www.mysqlhow2.com/2010/02/mysql-rotate-tables-c-program/</link>
		<comments>http://www.mysqlhow2.com/2010/02/mysql-rotate-tables-c-program/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 18:24:56 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[C Programs]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[rotate]]></category>
		<category><![CDATA[tables]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=209</guid>
		<description><![CDATA[I have written a little c program that will rotate tables and keep older tables for specified time. I use this program in a few environments where we have data retention requirements. This is to allow the tables not to grow absurdly large. This is my first C program please leave me feedback thank you. [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>I have written a little c program that will rotate tables and keep older tables for specified time. I use this program in a few environments where we have data retention requirements. This is to allow the tables not to grow absurdly large. This is my first C program please leave me feedback thank you.</p>
<pre>USAGE:
Set up cron job to call the script once a week passing 3 variables
  1. Weeks to keep older tables
  2. Database Name
  3. Table Name
0 0 * * 0 /bin/lt_rotate_tables 3 testdb testing
</pre>
<pre class="brush: cpp;">

// This code written by Lee Thompson with debugging by Dave Allmon//
// This program will rotate definded table and keep backup tables for n ammount of weeks //
// The inital table must exist first!! //
// to compile **** gcc lt_rotate_tables.c -o lt_rotate_tables  `mysql_config --cflags --libs` ***//
// Cron ***  *** //

#include &lt;time.h&gt;
#include &lt;my_global.h&gt;
#include &lt;mysql.h&gt;

#define ONE_WEEK (86400 * 7)

// This code will create a new backup and delete the backup that is n weeks old.
// Ex: This is week 21. Running this code with weeks=4 will create a table_21 table and delete a writes_17 table.

char tableNameNew[64];
char tableNameDrop[64];
char tmpTable[64];
char tmpDBname[64];

// Creates two suffixes based on the week of the year:
//  1. This week for new backup.
//  2. (weeks) ago to be deleted.

void CreateTargetDateStrs( int weeks )
{
  time_t thisTime;
  struct tm * lt;

  memset( tableNameNew, 0, sizeof ( tableNameNew ));
  memset( tableNameDrop, 0, sizeof ( tableNameDrop ));

  thisTime = time( NULL );
  lt = localtime( &amp;thisTime );
  strftime(( char * ) &amp; tableNameNew, sizeof ( tableNameNew ), &quot;%B_%d&quot;, lt );

  thisTime -= ( ONE_WEEK * weeks );
  lt = localtime( &amp;thisTime );
  strftime(( char * ) &amp; tableNameDrop, sizeof ( tableNameDrop ), &quot;%B_%d&quot;, lt );
}

int main(int argc, char **argv)
{
  char tmpStr[256];
  MYSQL *conn;

  if ( argc == 4 )
  {
    CreateTargetDateStrs( atoi( argv[1] ));
    sprintf(tmpTable,(argv[3]));
    sprintf(tmpDBname,(argv[2]));
  }
  else
  {
    printf( &quot;\nUsage: ./lt_rotate_tables &lt;weeks&gt; &lt;database name&gt; &lt;table name&gt;\n&quot; );
    exit( 1 );
  }
  conn = mysql_init(NULL);
  /////////////// Make only change here ////////////////////////
  //Set connection here change &lt;user_name&gt;  &lt;password&gt;
  mysql_real_connect(conn, &quot;localhost&quot;, &quot;&lt;user_name&gt;&quot;, &quot;&lt;password&gt;&quot;, tmpDBname, 0, NULL, 0);

  // Drop oldest saved table.
  sprintf( tmpStr, &quot;DROP TABLE %s_%s&quot;, tmpTable, tableNameDrop );
  mysql_query(conn, tmpStr );

  // Rename current table to new name.
  sprintf( tmpStr, &quot;RENAME TABLE %s to %s_%s&quot;,tmpTable, tmpTable, tableNameNew );
  mysql_query(conn, tmpStr );

  // Create a new table like the last table.
  sprintf( tmpStr, &quot;CREATE TABLE %s like %s_%s&quot;, tmpTable, tmpTable, tableNameNew );
  mysql_query(conn, tmpStr );

  mysql_close(conn);
}
</pre>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/mysql-rotate-tables-c-program/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Following your replication flow</title>
		<link>http://www.mysqlhow2.com/2010/02/following-your-replication-flow/</link>
		<comments>http://www.mysqlhow2.com/2010/02/following-your-replication-flow/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 15:49:55 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PhP]]></category>
		<category><![CDATA[flow chart]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://www.mysqlhow2.com/?p=179</guid>
		<description><![CDATA[Many environments I manage are large and span over multiple data centers across the world. We replicate data across and sometimes need to have a visual aid to help look at the replication flow. This simple PhP script allows me to see the replication flow starting from master to all slaves connected. You can start [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>Many environments I manage are large and span over multiple data centers across the world. We replicate data across and sometimes need to have a visual aid to help look at the replication flow. This simple PhP script allows me to see the replication flow starting from master to all slaves connected. You can start from any server but the results will be master first.</p>
<pre class="brush: php;">
&lt;?

#################################
######  Mysql Replication Mapper #########
######     Lee Thompson ##############
######      Version 1.0   ###############
#################################

$user = &quot;&lt;username&gt;&quot;;
$pass = &quot;&lt;password&gt;&quot;;

$masterserver = $_REQUEST['master_server'];

$masterport = $_REQUEST['master_port'];
if ($masterport == '')
$masterport = '3306';

echo &quot;Please enter a master server&quot;;
echo &quot;&lt;form method='post' action='$php_self'&gt;&quot;;
echo &quot;Server: &lt;input type ='text' name='master_server' value='&quot; . $masterserver . &quot;'&gt;&lt;br /&gt;&quot;;
echo &quot;Port: &lt;input type ='text' name='master_port' value='3306'&gt;&lt;br /&gt;&quot;;
echo &quot;&lt;input type ='submit'&gt;&lt;hr /&gt;&quot;;

$serverlist = array();

// fill data
$serverlist = query_slave_server($masterserver.&quot;:&quot;.$masterport);

// print data
print &quot;&lt;b&gt;Master Server: &lt;/b&gt;&quot;.$serverlist.&quot; on Port: &quot;.$masterport . '&lt;br /&gt;';

$array = query_server($serverlist);
print_server($array, 0);

function query_slave_server($server)
{
  global $user, $pass, $masterport, $masterserver;

  $sql =&quot;show processlist&quot;;
        $foundmaster = FALSE;
        while ( $foundmaster === FALSE )
        {
    $con = mysql_connect($server.&quot;:&quot;.$masterport,$user,$pass) or die($server. mysql_error());
                $result = mysql_query($sql,$con);
                while ($row = mysql_fetch_array($result))
                {
                        $slaveuser = $row['User'];
                        if ($slaveuser=='system user')
                        {
                                $sql2 = &quot;show slave status&quot;;
                                $result = mysql_query($sql2,$con);
                                while ($row2 = mysql_fetch_array($result))
                                {
                                        $smasterserver = $row2['Master_Host'];
                                        $smasterport = $row2['Master_Port'];
                                        $server = $row2['Master_Host'];
                                        $masterport = $row2['Master_Port'];
                                }
                                break;
                        }
                }
                if ( $slaveuser != 'system user' )
                {
                        $foundmaster = TRUE;
                }
        }
        return $server;
}

function query_server($mserver)
{
  global $user, $pass, $masterport;

  $sql =&quot;show processlist&quot;;

  $con = @mysql_connect($mserver.&quot;:&quot;.$masterport,$user,$pass) or die(mysql_error());
  $result = @mysql_query($sql,$con);
  while ($row = @mysql_fetch_array($result))
  {
    $slave = $row['Host'];
    $slavehost = ereg_replace(&quot;:.*&quot;, &quot;&quot;, $slave);
    $slavecmd = $row['Command'];
    if ($slavecmd=='Binlog Dump')
    {
      $current[$slavehost] = query_server($slavehost.&quot;:&quot;.$masterport);
    }
  }
  return $current;
}

function print_server($current, $depth)
{
  global $user, $pass;

  foreach ($current as $slave =&gt; $ary)
  {
    $conn2 = mysql_connect($slave,$user,$pass);
    $sql2 = &quot;show slave status&quot;;
    $result2 = mysql_query($sql2, $conn2);
    while ($row2 = mysql_fetch_array($result2))
    {
      $slavecmd = $row2['Slave_IO_Running'];
      $slavecmd1 = $row2['Slave_SQL_Running'];
    }

      if ($slavecmd=='Yes' &amp;&amp; $slavecmd1=='Yes')
      {
        $slaverunning = &quot;Yes&quot;;
      }
      else
      {
        $slaverunning = &quot;&lt;font color ='red'&gt;No&lt;/font&gt;&quot;;
      }
    $local = &quot;localhost&quot;;
    $lconn = mysql_connect($local,$user,$pass);
    $lsql = &quot;select server_name from myman.server where primary_ip = '&quot;.ereg_replace(&quot;:.*&quot;, &quot;&quot;, $slave).&quot;'&quot;;
    $lresult = mysql_query($lsql, $lconn);
    while($lrow = mysql_fetch_array($lresult))
    {
      if ($depth &gt; 0) print str_repeat('&amp;nbsp;',10 * ($depth - 1));
      echo &quot;&amp;#160---&amp;gt;&amp;#160; &quot;;
      echo $lrow[0]. &quot; (&quot; . $slave . &quot;) Slave Running:&quot; . $slaverunning . &quot;(depth: $depth)&lt;br /&gt;\n&quot;;
      if ($ary) print_server($ary, $depth + 1);
    }
  }
}
?&gt;
</pre>
<p>Example Output:</p>
<pre>Master Server: 172.1.1.102 on Port: 3306
 ---&gt; testdb02 (172.1.1.103) Slave Running:Yes(depth: 0)
 ---&gt; testdb03 (172.1.1.104) Slave Running:Yes(depth: 0)
 ---&gt; testdb04 (172.1.1.105) Slave Running:Yes(depth: 0)
     ---&gt; testdb04-02 (172.1.1.106) Slave Running:Yes(depth: 1)
     ---&gt; devdb01 (172.1.1.107) Slave Running:Yes(depth: 1)
       ---&gt; dc2testdb (172.1.1.108) Slave Running:Yes(depth: 2)
	  ---&gt; dctestdb-02 (172.2.2.101) Slave Running:Yes(depth: 3)
	  ---&gt; dctestdb-03 (172.2.2.102) Slave Running:Yes(depth: 3)
       ---&gt; dc3testdb (172.1.1.108) Slave Running:Yes(depth: 2)
	 ---&gt; dctestdb-02 (172.2.2.103) Slave Running:Yes(depth: 3)
---&gt; devdb02 (172.3.3.101) Slave Running:Yes(depth: 0)
---&gt; devdb03 (172.3.4.101) Slave Running:Yes(depth: 0)
</pre>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2010/02/following-your-replication-flow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is MySQL</title>
		<link>http://www.mysqlhow2.com/2009/08/what-is-mysql/</link>
		<comments>http://www.mysqlhow2.com/2009/08/what-is-mysql/#comments</comments>
		<pubDate>Tue, 25 Aug 2009 15:23:53 +0000</pubDate>
		<dc:creator>Lee Thompson</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://mysqlhow2.com/wp/?p=38</guid>
		<description><![CDATA[MySQL is a relational database management system. A relational database stores data in separate tables rather than putting all the data in one big storeroom. This adds speed and flexibility. The SQL part of â€œMySQLâ€ stands for â€œStructured Query Language.â€ SQL is the most common standardized language used to access databases and is defined by [...]]]></description>
			<content:encoded><![CDATA[<!-- wp-jquery-lightbox, a WordPress plugin by ulfben --> <div class="KonaBody"><p>MySQL is a relational database management system.<a name="id3423578"></a> A relational database stores data in separate tables rather           than putting all the data in one big storeroom. This adds           speed and flexibility. The SQL part of â€œ<span>MySQL</span>â€           stands for â€œ<span>Structured Query Language.</span>â€ SQL is           the most common standardized language used to access databases           and is defined by the ANSI/ISO SQL Standard. The SQL standard           has been evolving since 1986 and several versions exist. In           this manual, â€œ<span>SQL-92</span>â€ refers to the standard           released in 1992, â€œ<span>SQL:1999</span>â€ refers to the           standard released in 1999, and â€œ<span>SQL:2003</span>â€ refers           to the current version of the standard. We use the phrase           â€œ<span>the SQL standard</span>â€ to mean the current version of           the SQL Standard at any time.</p>
</div>]]></content:encoded>
			<wfw:commentRss>http://www.mysqlhow2.com/2009/08/what-is-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
