<?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>code.openark.org &#187; Replication</title>
	<atom:link href="http://code.openark.org/blog/tag/replication/feed" rel="self" type="application/rss+xml" />
	<link>http://code.openark.org/blog</link>
	<description>Blog by Shlomi Noach</description>
	<lastBuildDate>Wed, 01 Feb 2012 08:19:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Problems with MMM for MySQL</title>
		<link>http://code.openark.org/blog/mysql/problems-with-mmm-for-mysql</link>
		<comments>http://code.openark.org/blog/mysql/problems-with-mmm-for-mysql#comments</comments>
		<pubDate>Mon, 16 May 2011 05:31:32 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[High availability]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=3625</guid>
		<description><![CDATA[I recently encountered troubling issues with MMM for MySQL deployments, leading me to the decision to cease using it on production. At the very same day I started writing about it, Baron published What's wrong with MMM?. I wish to present the problems I encountered and the reasons I find MMM is flawed. In a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently encountered troubling issues with MMM for MySQL deployments, leading me to the decision to cease using it on production.</p>
<p>At the very same day I started writing about it, Baron published <a href="http://www.xaprb.com/blog/2011/05/04/whats-wrong-with-mmm/">What's wrong with MMM?</a>. I wish to present the problems I encountered and the reasons I find MMM is flawed. In a period of two weeks, two different deployments presented me with <strong>4</strong> crashes, in <strong>3</strong> different scenarios.</p>
<p>In all the following scenarios, there is an Active/Passive Master-Master deployment, with one VIP (virtual IP) set for <em>writer</em> role, one VIP set for <em>reader</em> role.</p>
<h4>Problem #1: unjustified failover, broken replication</h4>
<p>Unjustified failover must be the common scenario. It's also a scenario I can live with. A few seconds of downtime are OK with me once in a couple of months.</p>
<p>But on two different installations, a few days apart, I had two seemingly unjustified failovers followed by a troubling issue: replication got broken.<span id="more-3625"></span></p>
<p>How broken? The previously active master, now turned inactive, suddenly changed master position to a roughly <strong>10</strong> days old position. I don't keep master logs for <strong>10</strong> days, so this led to an immediate replication fail.</p>
<p>Now, I cannot directly point my finger at MMM, but:</p>
<ul>
<li>There was no power failure</li>
<li>MySQL daemon did not go down</li>
<li>Replication was just fine both 	ways up to the failover moment</li>
<li>There was no human intervention on 	this (myself and once more person had access at that time).</li>
</ul>
<p>I know the above since I've got it all monitored. So I can't blame it on “replication not synching <strong>master.info</strong> file to disk when power went down”. I confess, this is very suspicious; but, <em>twice</em>, on two different deployments...</p>
<p>So much for suspicions. Now for the smoking guns.</p>
<h4>Problem #2: hanging master, no failover</h4>
<p>The active master went down. Either hardware or software problem caused it to freeze. It was not executing its chores; it became inaccessible by TCP/IP.</p>
<p>But not just inaccessible: freezing inaccessible. If you were to attempt an SSH connection, the connection would just hang; not refused. The SSH client would not terminate in any reasonable time.</p>
<p>Ahem, time to do failover?</p>
<p>Apparently not. Phones start ringing. Emails sent. Time for manual intervention. But, what does the MMM monitor have to say? Nothing. It's frozen. Now, I didn't read the source code; I'm not even competent with PERL; but is <em>seems</em> to me like the monitor daemon works single threaded: it attempts to connect all hosts on the same thread. But, connecting to active master makes for hanging connection, so the entire monitor goes down. Impossible to stop it gracefully, I had to kill it. I had the choice of reconfiguring it to ignore active master, but decided to try starting it up again. I had to do it twice before it started acting sanely again, and realized it was time for failover.</p>
<p>Why is this bad? Assuming my analysis is correct, this is a major design flaw. You must never do a single threaded monitoring on a multiple-machine deployment.</p>
<h4>Problem #3: no servers</h4>
<p>System is down! No access to the database. What does MMM monitor have to say?</p>
<p>Both machines are HARD_OFFLINE.</p>
<p>Ahem. Both machines are up and running; they are both replicating each other. They are both accessible. MySQL is accessible.</p>
<p>But neither machine has any VIP associated with.</p>
<p>Does it matter whether both agents fail to realize their associated MySQL servers were actually up and running, or whether the monitor fail to receive that information? It does not. MMM should not have removed all VIPs. OK, suppose it believes the two machines are down. So what? Just throw all VIPs on one of the machines. If it's inaccessible, then what's wrong with that? (assuming the previous problem never existed, that is).</p>
<p>You should always have <em>some</em> machine associated with the VIPs.</p>
<h4>Temper down</h4>
<p>None of the above is meant as offense to the creators of MMM, whom I greatly respect. This isn't an easy problem to solve, and it should be obvious there's no 100% guaranteed solution. But, for myself, I will not be using MMM as it stands right now anymore.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/problems-with-mmm-for-mysql/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Impressions from MySQL conf 2011, part III: BoF Replication</title>
		<link>http://code.openark.org/blog/mysql/impressions-from-mysql-conf-2011-part-iii-bof-replication</link>
		<comments>http://code.openark.org/blog/mysql/impressions-from-mysql-conf-2011-part-iii-bof-replication#comments</comments>
		<pubDate>Tue, 19 Apr 2011 04:11:14 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[mysqlconf]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=3528</guid>
		<description><![CDATA[This post continues my impressions from some of the talks I've been to. I'll dedicate this post to a single session. Wednesday BoF: Replication, Lars Thalmann, Mat Keep (Oracle) Lars Thallman presented the MySQL 5.5 replication features, as well as the expected 5.6 features. Among other features, one could notice parallel replication, binlog checksums, sub-second [...]]]></description>
			<content:encoded><![CDATA[<p>This post continues my impressions from some of the talks I've been to. I'll dedicate this post to a single session.</p>
<h4>Wednesday</h4>
<ul>
<li>BoF: Replication, Lars Thalmann<em>, </em>Mat Keep<em> (Oracle)</em></li>
</ul>
<p>Lars Thallman presented the MySQL 5.5 replication features, as well as the expected 5.6 features. Among other features, one could notice parallel replication, binlog checksums, sub-second resolution and more. There was an open discussion about these features, asking for comments; looking for new ideas and suggestion from the audience.</p>
<p>I can't possibly cover it all. I'll note two discussion I participated in, and which have interested me. This also serves for noting down to myself my ideas and thoughts.<span id="more-3528"></span></p>
<h4>Parallel replication</h4>
<p>As the trend goes, parallel replication will be implemented by having a thread per schema. My own contribution to the discussion is that with such paradigm, the slave may be at any state inconsistent with the master. That is, at any point in time it can be in such state that has never existed in any point in time on the master. This is because it is possible that one or more of the replication threads executes much faster than one or more of the others.</p>
<p>We have discussed the meaning of <strong>STOP SLAVE</strong>. I have suggested that <strong>STOP SLAVE</strong> works in such way that it stops in a consistent slave. Lars suggested there could be normal <strong>STOP SLAVE</strong> and <strong>STOP SLAVE CONSISTENT</strong>.</p>
<p>It has been noted that we may not care about the slave being inconsistent, as the prerequisite for parallel replication is that the distinct schemata are independent of one another. After some thought, I disagree. Today parallel replication may be implemented on different schemata; tomorrow - based on finer parameters. I think it's best to prepare for the inevitable future. Besides, <strong>STOP SLAVE INCONSISTENT</strong> is such an easy feature to implement!</p>
<h4>Slave analysis</h4>
<p>I also had a long time feature request. While writing management tools, I realized it is difficult to learn the topology of a replication environment by simple interrogation. If you connect to a master, you can either issue <strong>SHOW PROCESSLIST</strong> to detect the slaves, or <strong>SHOW SLAVE HOSTS</strong>.</p>
<p>The former does not tell you the port on which the slaves are listening. The latter requires that you <a href="http://code.openark.org/blog/mysql/the-importance-of-report_host-report_port">configure <strong>report_host</strong> and <strong>report_port</strong> properly</a>.</p>
<p>What I would like to see is a <strong>SHOW SLAVES STATUS</strong> command (or similar <strong>INFORMATION_SCHEMA</strong> table) <em>on the master</em>. Such that it lists connected slaves, one per row, with the following details:</p>
<ul>
<li><strong>Slave_host</strong> (this is easy, already exists in <strong>SHOW PROCESSLIST</strong>)</li>
<li><strong>Slave_port</strong> (slave should send this kind of information to master upon first connect)</li>
<li><strong>Slave_master_log_file</strong> (last log file requested by slave)</li>
<li><strong>Slave_master_log_pos</strong> (last log pos requested by slave)</li>
<li><strong>Slave_seconds_behind_master</strong> (slave should report this upon each request)</li>
<li><strong>Slave_server_id</strong> (slave should send this upon connect)</li>
</ul>
<p>By reading <strong>Slave_host</strong>, <strong>Slave_port</strong> &amp; <strong>Slave_server_id</strong>, it makes it easy for us to build replication topology. It's a single operation to detect a master's slaves. It takes recursive steps to build entire topology.</p>
<p>By reading the <strong>Slave_master_log_file</strong>, <strong>Slave_master_log_pos</strong>, we can easily determine that binary logs <em>up to that point</em> have already been written to the slave's relay log. This makes it easier to decide how to purge master logs. <strong>Slave_seconds_behind_master </strong>completes the replication picture.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/impressions-from-mysql-conf-2011-part-iii-bof-replication/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Recovering a MySQL `root` password: the fourth solution</title>
		<link>http://code.openark.org/blog/mysql/recovering-a-mysql-root-password-the-fourth-solution</link>
		<comments>http://code.openark.org/blog/mysql/recovering-a-mysql-root-password-the-fourth-solution#comments</comments>
		<pubDate>Tue, 22 Mar 2011 07:47:46 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=3412</guid>
		<description><![CDATA[Have just read Darren Cassar's Recovering a MySQL `root` password – Three solutions. There's a fourth solution: using an init-file, which leads to just one restart of the database instead of two. It also avoids the security issue involved with using skip-grant-tables. I've written all about it before on Dangers of skip-grant-tables. Darren's 1st advice [...]]]></description>
			<content:encoded><![CDATA[<p>Have just read Darren Cassar's <a title="Permanent Link to Recovering a MySQL `root` password – Three solutions" rel="bookmark" href="http://mysqlpreacher.com/wordpress/2011/03/recovering-a-mysql-root-password-three-solutions/">Recovering a MySQL `root` password – Three solutions</a>. There's a fourth solution: using an <strong>init-file</strong>, which leads to just one restart of the database instead of two. It also avoids the security issue involved with using <strong>skip-grant-tables</strong>.</p>
<p>I've written all about it before on <a title="Permanent Link to Dangers of skip-grant-tables" rel="bookmark" href="http://code.openark.org/blog/mysql/dangers-of-skip-grant-tables">Dangers of skip-grant-tables</a>.</p>
<p>Darren's 1st advice (look for password ini files, scripts, etc.) is a very good one. One password that can always be looked up in files is the replication's password.</p>
<p>Replication's password is easily forgotten: you only set it once and never use it again; never script it nor manually login with. When setting up new slaves, though, you suddenly need it.</p>
<p>Apparently not many realize that the replication password is written in plaintext in the <strong>master.info</strong> file. This file tells the slave all about it's master connection: host, port, user &amp; password are all there for you to read.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/recovering-a-mysql-root-password-the-fourth-solution/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Upgrading to Barracuda &amp; getting rid of huge ibdata1 file</title>
		<link>http://code.openark.org/blog/mysql/upgrading-to-barracuda-getting-rid-of-huge-ibdata1-file</link>
		<comments>http://code.openark.org/blog/mysql/upgrading-to-barracuda-getting-rid-of-huge-ibdata1-file#comments</comments>
		<pubDate>Tue, 15 Feb 2011 08:01:15 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[mysqldump]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=3304</guid>
		<description><![CDATA[Some of this is old stuff, but more people are now converting to InnoDB plugin, so as to enjoy table compression, performance boosts. Same holds for people converting to Percona's XtraDB. InnoDB plugin requires innodb_file_per_table. No more shared tablespace file. So your ibdata1 file is some 150GB, and it won't reduce. Really, it won't reduce. [...]]]></description>
			<content:encoded><![CDATA[<p>Some of this is old stuff, but more people are now converting to InnoDB plugin, so as to enjoy table compression, performance boosts. Same holds for people converting to Percona's XtraDB. InnoDB plugin requires <strong>innodb_file_per_table</strong>. No more shared tablespace file.</p>
<p>So your <strong>ibdata1</strong> file is some <strong>150GB</strong>, and it won't reduce. Really, it won't reduce. You set <strong>innodb_file_per_table=1</strong>, do <strong>ALTER TABLE t ENGINE=InnoDB</strong> (optionally <strong>ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8</strong>), and you get all your tables in file-per-table <strong>.ibd</strong> files.</p>
<p>But the original <strong>ibdata1</strong> file is still there. It has to be there, don't delete it! It contains more than your old data.</p>
<p>InnoDB tablespace files never reduce in size, it's an old-time annoyance. The only way to go round it, if you need the space, is to completely drop them and start afresh. That's one of the things so nice about file-per-table: an <strong>ALTER TABLE</strong> actually creates a new tablespace file and drops the original one.</p>
<h4>The procedure</h4>
<p>The procedure is somewhat painful:</p>
<ul>
<li>Dump everything logically (either use <em>mysqldump</em>, <a href="http://www.maatkit.org/doc/mk-parallel-dump.html">mk-parallel-dump</a>, or do it your own way)</li>
<li>Erase your data (literally, delete everything under your <strong>datadir</strong>)</li>
<li>Generate a new empty database</li>
<li>Load your dumped data.<span id="more-3304"></span></li>
</ul>
<h4>Using replication</h4>
<p>Replication makes this less painful. Set up a slave, have it follow up on the master.</p>
<ul>
<li>Stop your slave.</li>
<li>Make sure to backup the replication position (e.g. write <strong>SHOW SLAVE STATUS</strong> on a safe location, or copy <strong>master.info</strong> file).</li>
<li>Work out the dump-erase-generate-load steps on the slave.</li>
<li>Reattach the slave to the master using saved data.</li>
</ul>
<p>For this to succeed you must keep enough binary logs on the master for the entire dump-load period, which could be lengthy.</p>
<h4>Upgrading to barracuda</h4>
<p>If you wish to upgrade your InnoDB tables to <em>Barracuda</em> format, my advice is this:</p>
<ol>
<li>Follow the steps above to generate a file-per-table working slave</li>
<li>Stop the slave</li>
<li>Configure <strong>skip_slave_start</strong></li>
<li>Restart MySQL</li>
<li>One by one do the <strong>ALTER TABLE</strong> into <em>Barracuda</em> format (<strong>ROW_FORMAT=COMPACT</strong> or <strong>ROW_FORMAT=COMPRESSED</strong>)</li>
</ol>
<p>Note that if you're about to do table compression, the <strong>ALTER</strong> statements become <em>considerably</em> slower the better the compression is.</p>
<p>If your dataset is very large, and you can't keep so many binary logs, you may wish to break step <strong>5</strong> above into:</p>
<ul>
<li>ALTER a large table</li>
<li>Restart MySQL</li>
<li>Start slave, wait for it to catch up</li>
<li>Restart MySQL again</li>
</ul>
<p>and do the same for all large tables.</p>
<h4>Why all these restarts?</h4>
<p>I've been upgrading to Barracuda for a long time now. I have clearly noticed that <strong>ALTER</strong> into a <strong>COMPRESSED</strong> format works considerably slower after the slave has done some "real work". This in particular relates to the last "renaming table" stage. There was a bug with earlier InnoDB plugin versions which made this stage hang. It was solved. But it still takes some time for this last, weird stage, where the new replacement table is complete, and it's actually been renamed in place of the old table, and the old table renamed into something like "#sql-12345.ibd", and all that needs to be done is have it dropped, and... Well, it takes time.</p>
<p>My observation is it works faster on a freshly started server. Which is why I take the bother to restart MySQL before each large table conversion.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/upgrading-to-barracuda-getting-rid-of-huge-ibdata1-file/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>openark-kit (rev. 170): new tools, new functionality</title>
		<link>http://code.openark.org/blog/mysql/openark-kit-rev-170-new-tools-new-functionality</link>
		<comments>http://code.openark.org/blog/mysql/openark-kit-rev-170-new-tools-new-functionality#comments</comments>
		<pubDate>Wed, 15 Dec 2010 06:31:24 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Analysis]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[openark kit]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=3124</guid>
		<description><![CDATA[I'm pleased to announce a new release of the openark kit. There's a lot of new functionality inside; following is a brief overview. The openark kit is a set of utilities for MySQL. They solve everyday maintenance tasks, which may be complicated or time consuming to work by hand. It's been a while since the [...]]]></description>
			<content:encoded><![CDATA[<p>I'm pleased to announce a new release of the <a href="http://code.openark.org/forge/openark-kit">openark kit</a>. There's a lot of new functionality inside; following is a brief overview.</p>
<p>The <em>openark kit</em> is a set of utilities for MySQL. They  solve everyday maintenance tasks, which may be complicated or time  consuming to work by hand.</p>
<p>It's been a while since the last announced release. Most of my attention was on <a href="http://code.openark.org/forge/mycheckpoint">mycheckpoint</a>, building new features, writing documentation etc. However my own use of <em>openark kit</em> has only increased in the past few months, and there's new useful solutions to common problems that have been developed.</p>
<p>I've used and improved many tools over this time, but doing the final cut, along with proper documentation, took some time. Anyway, here are the highlights:</p>
<h4>New tool: oak-hook-general-log</h4>
<p><em>oak-hook-general-log</em> hooks up a MySQL server and dumps the general log based on filtering rules, applying to query role or execution plan. It is possible to only dump connect/disconnect entries, queries which make a full table scan, or use temporary tables, or scan more than X number of rows, or...</p>
<p>I'll write more on this tool shortly.</p>
<h4>New tool: oak-prepare-shutdown</h4>
<p>This tool makes for an orderly and faster shutdown by safely stopping replication, and flushing InnoDB pages to disk prior to shutting down (keeping server available for connections even while attempting to flush dirty pages to disk). A typical use case would be:</p>
<blockquote>
<pre>oak-prepare-shutdown --user=root --ask-pass --socket=/tmp/mysql.sock &amp;&amp; /etc/init.d/mysql stop</pre>
</blockquote>
<h4>New tool: oak-repeat query</h4>
<p><em>oak-repeat-query</em> repeats executing a given query until some condition holds. The condition can be:</p>
<ul>
<li>Number of given iterations has been reached</li>
<li>Given time has elapsed</li>
<li>No rows have been affected by query</li>
</ul>
<p>The tool comes in handy for cleanup jobs, warming up caches, etc.<span id="more-3124"></span></p>
<h4>New tool: oak-get-slave-lag</h4>
<p>This simple tool just returns the number of seconds a slave is behind master. But it also returns with an appropriate exit code, based on a given threshold: <strong>0</strong> when lag is good, <strong>1</strong> (error exit code) when lag is too great or slave fails to replicate.</p>
<p>This tool has been used by 3rd party applications, such as a load balancer, to determine whether a slave should be accessed.</p>
<h4>Updated tool: oak-chunk-update</h4>
<p>This extremely useful utility breaks down very long queries into smaller chunks. These could be queries which should affect a huge amount of rows, or queries which cannot utilize an index.</p>
<p>Updates to the tool include limiting the range of rows the tool scans, by specifying start and stop position (either by providing constant values or by SELECT query). Also added is auto-termination when no rows are found to be affected. Last, it is possible to override INFORMATION_SCHEMA lookup by explicitly specifying chunking key.</p>
<p>This tool works great for your daily/weekly/monthly batch jobs; in creating DWH tables; populating new columns; purging old entries; clearing data based on non-indexed values; generating summary tables; and more.</p>
<h4>Frozen tool: oak-apply-ri</h4>
<p>I haven't been using this tool for a while. The main work down by this tool can be done with <em>oak-chunk-update</em>. There are some additional safety checks <em>oak-apply-ri</em> provides; I'm thinking over if they justify the tool's existence.</p>
<h4>Frozen tool: oak-online-alter-table</h4>
<p>With the appearance of Facebook’s <a href="http://www.facebook.com/note.php?note_id=430801045932">Online Schema Change</a> (OSC) tool, which derives from <em>oak-online-alter-table</em>, I'm not sure I will continue developing the tool. I intend to wait for general feedback on OSC before making a decision.</p>
<h4>Documentation</h4>
<p><a href="http://openarkkit.googlecode.com/svn/trunk/openarkkit/doc/html/introduction.html">Documentation</a> is now part of <em>openark kit</em>'s SVN repository.</p>
<h4>Download</h4>
<p>The <em>openark kit</em> project is currently hosted by Google Code.  Downloads are available at the Google Code <a href="http://code.google.com/p/openarkkit/">openark kit project page</a>.</p>
<p>Downloads are available in the following packaging formats:</p>
<ul>
<li><strong>.deb</strong> package, to be installed on <em>debian</em>, <em>ubuntu</em> and otherwise debian based distributions.</li>
<li><strong>.rpm</strong> package, architecture free (<em>noarch</em>), for RPM supporting Linux distributions such as <em>RedHat</em>, <em>Fedora</em>, <em>CentOS</em> etc.</li>
<li><strong>.tar.gz</strong> using python's distutils installer.</li>
<li><strong>source</strong>, directly retrieved from SVN or from above python package.</li>
<li>Some distribution specific <a href="http://software.opensuse.org/search?baseproject=ALL&amp;p=1&amp;q=openark-kit">RPM packages</a>, courtesy Lenz Grimmer.</li>
</ul>
<h4>Feedback</h4>
<p>Your feedback is welcome! I may not always respond promptly; and I confess that some bugs were left open for more than I would have liked them to. I hope to make for good quality of code, and bug reporting is one major factor you can control.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/openark-kit-rev-170-new-tools-new-functionality/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MMM for MySQL single reader role</title>
		<link>http://code.openark.org/blog/mysql/mmm-for-mysql-single-reader-role</link>
		<comments>http://code.openark.org/blog/mysql/mmm-for-mysql-single-reader-role#comments</comments>
		<pubDate>Thu, 12 Aug 2010 12:12:16 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[High availability]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2824</guid>
		<description><![CDATA[The standard documentation and tutorials on MMM for MySQL, for master-master replication setup, suggest one Virtual IP for the writer role, and two Virtual IPs for the reader role. It can be desired to only have a single virtual IP for the reader role, as explained below. The two IPs for the reader role A [...]]]></description>
			<content:encoded><![CDATA[<p>The standard documentation and tutorials on <a href="http://mysql-mmm.org/">MMM for MySQL</a>, for master-master replication setup, suggest one Virtual IP for the <em>writer</em> role, and two Virtual IPs for the <em>reader</em> role. It can be desired to only have a single virtual IP for the reader role, as explained below.</p>
<h4>The two IPs for the reader role</h4>
<p>A simplified excerpt from the <strong>mmm_common.conf</strong> sample configuration file, as can be found on the project's site and which is most quoted:<span id="more-2824"></span></p>
<blockquote>
<pre>...
&lt;host db1&gt;
  ip                      192.168.0.11
  mode                    master
  peer                    db2
&lt;/host&gt;

&lt;host db2&gt;
  ip                      192.168.0.12
  mode                    master
  peer                    db1
&lt;/host&gt;
...
&lt;role writer&gt;
  hosts                   db1, db2
  ips                     192.168.0.100
  mode                    exclusive
&lt;/role&gt;

&lt;role reader&gt;
  hosts                   db1, db2
  ips                     192.168.0.101, 192.168.0.102
  mode                    balanced
&lt;/role&gt;
</pre>
</blockquote>
<p>In the above setup <strong>db1</strong> &amp; <strong>db2</strong> participate in master-master active-passive replication. Whenever you need to write something, you use <strong>192.18.0.100</strong>, which is the virtual IP for the writer role. Whenever you need to read something, you use either <strong>192.168.0.101</strong> or <strong>192.168.0.102</strong>, which are the virtual IPs of the two machines, this time in read role. Logic says one wishes to distribute reads between the two machines.</p>
<h4>One IP for reader role</h4>
<p>I have a few cases where the above setup is not satisfactory: there is a requirement to know the IP of the passive (read-only) master. Reason? There are queries which we only want to execute on the slave (reporting, long analysis), and only execute on the active master when this isn't possible. Sometimes we might even prefer waiting for a slave to come back up rather than execute a query on the master.</p>
<p>This may involve an application level solution, or a connection-pool level solution ("get me a slave's connection, or, if that's not possible, get me the master's").</p>
<p>Anyway, neither <strong>192.168.0.101</strong> nor <strong>192.168.0.102</strong> relate to a particular machine's role status. That is, the fact that one of the machines is in <em>writer</em> mode or not does not affect these virtual IPs.</p>
<p>The solution is a minor change to the configuration file. Real minor:</p>
<blockquote>
<pre>&lt;role reader&gt;
  hosts                   db1, db2
  ips                     192.168.0.101
  mode                    balanced
&lt;/role&gt;
</pre>
</blockquote>
<p>In this new setup the two nodes compete for a single <em>reader</em> role virtual IP. There is no <strong>192.168.0.102</strong> anymore. Although it does not reflect from the configuration file, it turns out MMM acts in a smart way; the way you would expect it to run.</p>
<p>There is nothing to suggest in the above that the IPs <strong>192.168.0.100</strong> &amp; <strong>192.168.0.101</strong> will be distributed between the two machines. But you would <em>like</em> them to. And MMM does that. It makes sure that, if possible, one of the machines (say <strong>db1</strong>) gets the <em>writer</em> role, hence <strong>192.168.0.100</strong>, and the other (<strong>db2</strong>) the <em>reader</em> role, hence <strong>192.168.0.101</strong>.</p>
<p>Moreover, it prefers that situation over a current known situation: say <strong>db1</strong> went down. The <em>writer</em> role moves to <strong>db2</strong>. When <strong>db1</strong> is up again, MMM acts smartly: it does <em>not</em> give it back the <em>writer</em> role (since moving the active master around is costly, after all), but <em>does</em> give it the <em>reader</em> role, along with the <strong>192.168.2.101</strong> IP. So it takes care not to leave a server without a role, while preferring to move the <em>writer</em> role as little as possible.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/mmm-for-mysql-single-reader-role/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Table refactoring &amp; application version upgrades, Part II</title>
		<link>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-ii</link>
		<comments>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-ii#comments</comments>
		<pubDate>Thu, 12 Aug 2010 03:24:06 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2801</guid>
		<description><![CDATA[Continuing Table refactoring &#38; application version upgrades, Part I, we now discuss code &#38; database upgrades which require DROP operations. As before, we break apart the upgrade process into sequential steps, each involving either the application or the database, but not both. As I'll show, DROP operations are significantly simpler than creation operations. Interestingly, it's [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing <a href="http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-i">Table refactoring &amp; application version upgrades, Part I</a>, we now discuss code &amp; database upgrades which require <strong>DROP</strong> operations. As before, we break apart the upgrade process into sequential steps, each involving either the application or the database, but not both.</p>
<p>As I'll show, DROP operations are significantly simpler than creation operations. Interestingly, it's the same as in life.</p>
<h4>DROP COLUMN</h4>
<p>A column turns to be redundant, unused. Before it is dropped from the database, we must ensure no one is using it anymore. The steps are:</p>
<ol>
<li>App: <strong>V1</strong> -&gt; <strong>V2</strong>. Remove all references to column; make sure no queries use said column.</li>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>DROP COLUMN</strong>.</li>
</ol>
<h4>DROP INDEX</h4>
<p>A possibly simpler case here. Why would you drop an index? Is it because you found out you never use it anymore? Then all you have to do is just drop it.</p>
<p>Or perhaps you don't need the functionality the index supports anymore? Then first drop the functionality:</p>
<ol>
<li>(optional) App: <strong>V1</strong> -&gt; <strong>V2</strong>. Discard using functionality which relies on index.</li>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>DROP INDEX</strong>. Check out InnoDB Plugin here.<span id="more-2801"></span></li>
</ol>
<h4>DROP UNIQUE INDEX</h4>
<p>When using Master-Slave failover for table refactoring, we're now removing a constraint from the slave. Since the master is more constrained than the slave, there is no problem here. It's mostly the same as with a normal DROP INDEX, with a minor addition:</p>
<ol>
<li>(optional) App: <strong>V1</strong> -&gt; <strong>V2</strong>. Discard using functionality which relies on index.</li>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>DROP INDEX</strong>.</li>
<li>(optional) App: <strong>V2</strong> -&gt; <strong>V3</strong>. Enable functionality that inserts duplicates.</li>
</ol>
<h4>DROP FOREIGN KEY</h4>
<p>Again, we are removing a constraint.</p>
<ol>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>DROP INDEX</strong>.</li>
<li>(optional) App: <strong>V2</strong> -&gt; <strong>V3</strong>. Enable functionality that conflicts with removed constraint. I mean, if you really know what you are doing.</li>
</ol>
<h4>DROP TABLE</h4>
<p>The very simple steps are:</p>
<ol>
<li>App: <strong>V1</strong> -&gt; <strong>V2</strong>. Make sure no reference to table is made.</li>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong>. Issue a <strong>DROP TABLE</strong>.</li>
</ol>
<p>With <strong>ext3</strong> dropping a large table is no less than a nightmare. Not only does the action take long time, it also locks down the table cache, which very quickly leads to having dozens of queries hang. <strong>xfs</strong> is a good alternative.</p>
<h4>Conclusion</h4>
<p>We looked at single table operations, coupled with application upgrades. By carefully looking at the process breakdown, multiple changes can be addressed with ease and safety. Not all operations are completely safe when used with replication failover. But they are mostly safe if you have some trust in your code.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-ii/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Table refactoring &amp; application version upgrades, Part I</title>
		<link>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-i</link>
		<comments>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-i#comments</comments>
		<pubDate>Tue, 10 Aug 2010 12:36:28 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Indexing]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2775</guid>
		<description><![CDATA[A developer's major concern is: How do I do application &#38; database upgrades with minimal downtime? How do I synchronize between a DB's version upgrade and an application's version upgrade? I will break down the discussion into types of database refactoring operations, and I will limit to single table refactoring. The discussion will try to [...]]]></description>
			<content:encoded><![CDATA[<p>A developer's major concern is: <em>How do I do application &amp; database upgrades with minimal downtime? How do I synchronize between a DB's version upgrade and an application's version upgrade?<br />
</em></p>
<p>I will break down the discussion into types of database refactoring operations, and I will limit to single table refactoring. The discussion will try to understand the need for refactoring and will dictate the steps towards a successful upgrade.</p>
<h4>Reader prerequisites</h4>
<p>I will assume MySQL to be the underlying database. To take a major component out of the equation: we may need to deal with very large tables, for which an <strong>ALTER</strong> command may take long hours. I will assume familiarity with Master-Master (Active-Passive) replication, with possible use of <a href="http://mysql-mmm.org/">MMM for MySQL</a>. When I describe "Failover from <strong>M1</strong> to <strong>M2</strong>", I mean "Make the <strong>ALTER</strong> changes on <strong>M2</strong> (passive), then switch your application from <strong>M1</strong> to <strong>M2</strong> (change of IPs, VIP, etc.), promoting <strong>M2</strong> to active position, then apply same changes on <strong>M1</strong> (now passive) or completely rebuild it".</p>
<p>Phew, a one sentence description of M-M usage...</p>
<p>I also assume the reader's understanding that a table's schema can be different on master &amp; slave, which is the basis for the "use replication for refactoring" trick. But it cannot be too different, or, to be precise, the two schemata must both support the ongoing queries for the table.</p>
<p>A full discussion of the above is beyond the scope of this post.</p>
<h4>Types of refactoring needs</h4>
<p>As I limit this discussion to single table refactoring,we can look at major refactoring operations and their impact on application &amp; upgrades. We will discuss ADD/DROP COLUMN, ADD/DROP INDEX, ADD/DROP UNIQUE INDEX, ADD/DROP FOREIGN KEY, ADD/DROP TABLE.</p>
<p>We will assume the database and application are both in Version #1 (<strong>V1</strong>), and need to be upgraded to <strong>V2</strong> or greater.<span id="more-2775"></span></p>
<h4>ADD INDEX</h4>
<p>Starting with the easier actions. Why would you add an index? Either:</p>
<ol>
<li>There is some existing query which can be optimized by the new query</li>
<li>Or there is some new functionality which issues a query for which the new index is required.</li>
</ol>
<p>Adding an index is an easy action in that the table's data does not really change.</p>
<p>In case <strong>#1</strong>, all you need to do is to add the new index (if the table is large, fail over from <strong>M1</strong> to <strong>M2</strong>). There is no application upgrade, so all that happens is that the database upgrades <strong>V1 </strong>-&gt;<strong> V2</strong>.</p>
<p>In case <strong>#2</strong>, the database must be prepared with new schema before the new functionality/query is introduced (since it depends on the existence of the index). The steps, therefore, are:</p>
<ol>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>)</li>
<li>(Sometime later) App: <strong>V1</strong> -&gt; <strong>V2</strong>. Application will issue queries which utilize the new index.</li>
</ol>
<p>The application does not have to be upgraded at the same instant the DB gets upgraded. In fact, we'll see that this is a typical scenario: we can separate upgrades into smaller steps, which allow for time lapse. One <em>could</em> work out steps <strong>1</strong> &amp; <strong>2</strong> together, but that would take an extra effort.</p>
<h4>ADD COLUMN</h4>
<p>This must be one of the most common table schema upgrades: a new property is needed on the application side. It must be supported by the database. Perhaps a new field in some Java Object, with Hibernate mapping that field onto a new column. Or maybe the new column is there for purpose of de-normalization.</p>
<p>This is also a more complicated task. Let's look at the required steps:</p>
<ol>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>ADD COLUMN</strong>.</li>
<li>App: <strong>V1</strong> -&gt; <strong>V2</strong>. Change is: provide column value for newly <strong>INSERT</strong>ed rows.</li>
<li>If needed, retroactively update column values for all pre-existing rows.</li>
<li>App: <strong>V2</strong> -&gt; <strong>V3</strong>. Application begins to use (read, <strong>SELECT</strong>) new column.</li>
</ol>
<p>The above procedure assumes that the new column must have some calculated value. A 10-million rows table must now be updated, to have the correct values filled in. So we ask of the application to start filling in data for new rows, which makes the invalid row set static. We can just take a "from row" and a "to row" and fill in the missing column's value for those rows. Only when all rows contain valid values can we let the application start using that row. This makes for <em>two</em> application upgrades.</p>
<p>If you're content with just a static <strong>DEFAULT</strong> value, then step <strong>3</strong> can be skipped, and step <strong>4</strong> can be merged with step <strong>2</strong>.</p>
<h4>ADD UNIQUE INDEX</h4>
<p>This is an altogether different case than the normal <strong>ADD INDEX</strong>, even though they may seem similar. And the case is particularly different when using Master-Slave failover for rebuilding the table.</p>
<p>Consider the case where we add a <strong>UNIQUE INDEX</strong> on a slave. Some <strong>INSERT</strong> query executes on the master, successfully, and is logged to the binary log. The slave picks it up, tries to execute it, to find that it fails on a DUPLICATE KEY error.</p>
<p>The <strong>UNIQUE INDEX</strong> is a constraint, and it makes the slave more constrained than the master. This is a delicate situation. Here how to (mostly) work it out:</p>
<ol>
<li>App: <strong>V1</strong> -&gt; <strong>V2</strong>. Change <strong>INSERT</strong> queries on relevant table to <strong>INSERT IGNORE</strong> or <strong>REPLACE</strong> queries, whichever is more appropriate.</li>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>ADD UNIQUE KEY</strong> (and while at it, a tip: are you aware of <a href="http://dev.mysql.com/doc/refman/5.1/en/alter-table.html">ALTER IGNORE TABLE</a>?)</li>
</ol>
<p>The change of query ensures that the query will succeed on the slave (either by silently doing nothing or by actually replacing content). It also means that the slave can now have different data than the master. Of course, it you trust your application to never <strong>INSERT</strong> duplicates, you can sleep better.</p>
<p>We do not handle <strong>UPDATE</strong> statements here.</p>
<h4>ADD CONSTRAINT FOREIGN KEY</h4>
<p>As with <strong>ADD UNIQUE INDEX</strong>, there is a new constraint here. A slave becomes more constrained than the master. But we now have to make sure <strong>INSERT</strong>, <strong>UPDATE</strong> and <strong>DELETE</strong> statements all go peacefully (well, it also depends on the type of <strong>ON DELETE</strong> and <strong>ON UPDATE</strong> property of the FK).</p>
<p>The steps would be:</p>
<ol>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (possibly failover from <strong>M1</strong> to <strong>M2</strong>), change is <strong>ADD CONSTRAINT FOREIGN KEY</strong>.</li>
</ol>
<p>And then cross your fingers or have trust in your application. If the table is small enough, one does not have to use replication to do the refactoring, and life is simpler. Just execute the <strong>ALTER</strong> on the active master, and continue with your life.</p>
<h4>CREATE TABLE</h4>
<p>This is a simple case, since the table is new. The steps are:</p>
<ol>
<li>DB: <strong>V1</strong> -&gt; <strong>V2</strong> (no need to use slaves here)</li>
<li>App: <strong>V1</strong> -&gt; <strong>V2</strong>. Application will start using new table.</li>
</ol>
<h4>Conslusion</h4>
<p>Having such steps formalized help with development management and database management. It makes clear what is expected of the application, and what is expected of the database. The breaking down of these operations into sequential steps allows us to work more slowly; make preparation work; work within our own working hours; get a chance to see the family.</p>
<p>In this post we took a look at "creation" refactoring changes. New columns, new keys, new constraints. In the next part of this article, we'll discuss <strong>DROP</strong> operations.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/table-refactoring-application-version-upgrades-part-i/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Replication configuration checklist</title>
		<link>http://code.openark.org/blog/mysql/replication-configuration-checklist</link>
		<comments>http://code.openark.org/blog/mysql/replication-configuration-checklist#comments</comments>
		<pubDate>Tue, 18 May 2010 07:27:06 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2357</guid>
		<description><![CDATA[This post lists the essential and optional settings for a replication environment. It does not explain how to create replicating slaves. See How To Setup Replication for that. However, not all configuration options are well understood, and their roles in varying architectures can change. Here are the settings for a basic Master/Slave(s) replication architecturee. Essential [...]]]></description>
			<content:encoded><![CDATA[<p>This post lists the essential and optional settings for a replication environment.</p>
<p>It does not explain how to create replicating slaves. See <a href="http://dev.mysql.com/doc/refman/5.1/en/replication-howto.html">How To Setup Replication</a> for that. However, not all configuration options are well understood, and their roles in varying architectures can change.</p>
<p>Here are the settings for a basic Master/Slave(s) replication architecturee.</p>
<h4>Essential</h4>
<ul>
<li><strong>log-bin</strong>: enable binary logs on the master. Replication is based on the master logging all modifying queries (<strong>INSERT</strong>/<strong>CREATE</strong>/<strong>ALTER</strong>/<strong>GRANT</strong> etc.), and the slaves being able to replicate them.</li>
<li><strong>server-id</strong>: each machine must have a <em>unique</em> <strong>server-id</strong>. A slave will not replay queries originating from a server with the same <strong>server-id</strong> as its own.</li>
<li><strong>GRANT</strong>: grant a user with <strong>REPLICATION SLAVE</strong>. The host list must include all replication slave hosts.</li>
<li><strong>expire-logs-days</strong>: automatically clean up master's binary logs older than given value. By default, binary logs are never removed.</li>
</ul>
<p>When working with Master/Slaves replication, one should be prepared to master failure and slave promotion to master. It may be desirable to identify a particular slave as primary candidate for promotion.</p>
<p><span id="more-2357"></span>Just setting up the <strong>log-bin</strong> will yield with warnings in the MySQL's error log. The binary logs are named, by default, after the host's name. If that should change - MySQL will not be able to find the binary logs anymore (expecting a name which does previous logs did not use). It is therefore recommended to use:</p>
<blockquote>
<pre>log-bin=mychachine-bin</pre>
</blockquote>
<p>or</p>
<blockquote>
<pre>log-bin=mysql-bin</pre>
</blockquote>
<h4>Essential/Optional</h4>
<ul>
<li><strong>log-bin</strong>: enable on a slave, so that in case it is promoted to master, the rest of the slaves can replicate using its binary logs. Enabling binary logging cannot be done on a live server: this parameter requires MySQL restart.</li>
<li><strong>GRANT</strong>: include the master's host, so that when a slave promotes to master, the master can become a slave and continue replicating.</li>
<li><strong>log-slave-updates</strong>: together with <strong>log-bin</strong>, enable on slave so that master's binary logs are propagated and logged by the slave. This is required if the slave takes the role of a master in a chained replication setup.</li>
<li><strong>expire-logs-days</strong>: set this flag on slave as well [tnx Sheeri].</li>
<li><strong>read-only</strong>: set on slave(s). Refuses any modifying query (INSERT, DELETE, ALTER, DROP etc.) for non-<strong>SUPER</strong> privileged users [tnx Ryan].</li>
<li><strong>sync-binlog</strong>: flush binary log to disk per transaction commit. Use this on master for safer replication; however note that increased I/O is expected [tnx Harrison].</li>
</ul>
<h4>Extra</h4>
<ul>
<li><strong>report-host</strong>, <strong>report-port</strong>: the host and port identifying the slave when looking at SHOW SLAVE HOSTS on master. Set this up on all hosts. See <a href="http://code.openark.org/blog/mysql/the-importance-of-report_host-report_port">further discussion here</a>.</li>
<li><strong>max-binlog-size</strong>: the maximum size for a binary log / relay log file, after which it is rotated.</li>
</ul>
<h4>Expert</h4>
<ul>
<li><strong>binlog-do-db</strong>, <strong>binlog-do-table</strong>, <strong>replicate-do-db</strong>, <strong>...</strong>: filter queries by either not writing them to binary log, or not reading them from the logs.</li>
</ul>
<p>The reason I list the above as "Expert" is not because one must have a super-brain to set them up. That part is easy enough. But they lead to some dangerous situations, sometimes seemingly harmless. It takes great care to control the application and developers from creating those situations. See <a href="http://dev.mysql.com/doc/refman/5.1/en/replication-rules.html">documentation here</a>. See also discussion <a href="http://code.openark.org/blog/mysql/quick-reminder-avoid-using-binlog-do-db">here</a> and <a href="http://www.mysqlperformanceblog.com/2009/05/14/why-mysqls-binlog-do-db-option-is-dangerous/">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/replication-configuration-checklist/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Quick reminder: avoid using binlog-do-db</title>
		<link>http://code.openark.org/blog/mysql/quick-reminder-avoid-using-binlog-do-db</link>
		<comments>http://code.openark.org/blog/mysql/quick-reminder-avoid-using-binlog-do-db#comments</comments>
		<pubDate>Tue, 02 Mar 2010 19:03:50 +0000</pubDate>
		<dc:creator>shlomi</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Replication]]></category>

		<guid isPermaLink="false">http://code.openark.org/blog/?p=2077</guid>
		<description><![CDATA[Nothing new about this warning; but it's worth repeating: Using binlog-do-db is dangerous to your replication. It means the master will not write to binary logs any statement not in the given database. Ahem. Not exactly. It will not write to binary logs any statement which did not originate from the given database. Which is [...]]]></description>
			<content:encoded><![CDATA[<p>Nothing new about this warning; but it's worth repeating:</p>
<p>Using <a href="http://dev.mysql.com/doc/refman/5.1/en/replication-options-binary-log.html#option_mysqld_binlog-do-db"><strong>binlog-do-db</strong></a> is dangerous to your replication. It means the master will not write to binary logs any statement not in the given database.</p>
<p>Ahem. Not exactly. It will not write to binary logs any statement which did not originate from the given database.</p>
<p>Which is why a customer, who was using <strong>Toad for MySQL</strong> as client interface to MySQL, and by default connected to the <strong>mysql</strong> schema, did not see his queries being replicated. In fact, he later on got replication errors. If you do:</p>
<blockquote>
<pre>USE test;
INSERT INTO world.City VALUES (...)</pre>
</blockquote>
<p>Then the statement is assumed to be in the <strong>test</strong> database, not in the <strong>world</strong> database.</p>
<p>Slightly better is using <strong>replicate-do-db</strong> on the slave machines. At least we allow the master to write everything. But still, for the same reasons, slaves may fail to repeat a perfectly valid query, just because it has been issued in the context of the wrong database. <strong>replicate-ignore-db</strong> is somewhat safer yet, but the trap is still there.</p>
<p>My advice is that replication should replicate <em>everything</em>. Make sure you and everyone else you work with understand the implications of <strong>binlog-do-db</strong> and <strong>replicate-do-db</strong> before implementing it.</p>
]]></content:encoded>
			<wfw:commentRss>http://code.openark.org/blog/mysql/quick-reminder-avoid-using-binlog-do-db/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

