<?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>Computer Solutions Blog &#187; MySQL</title>
	<atom:link href="http://www.computersolutions.cn/blog/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.computersolutions.cn/blog</link>
	<description>Whats happening at Computer Solutions</description>
	<lastBuildDate>Fri, 13 Jan 2012 02:32:34 +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>Behind the scenes &#8211; Backups at Computer Solutions</title>
		<link>http://www.computersolutions.cn/blog/2010/03/behind-the-scenes-backups-at-computer-solutions/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=behind-the-scenes-backups-at-computer-solutions</link>
		<comments>http://www.computersolutions.cn/blog/2010/03/behind-the-scenes-backups-at-computer-solutions/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 14:35:46 +0000</pubDate>
		<dc:creator>Lawrence Sheed</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Technical Mumbo Jumbo]]></category>
		<category><![CDATA[automysqlbackup]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[restore]]></category>

		<guid isPermaLink="false">http://www.computersolutions.cn/blog/?p=385</guid>
		<description><![CDATA[I was reading a post up at Carsonified (http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/), which talked about MySQL backups. While he slightly re-invents the wheel, its fairly similar to what we do over at Computer Solutions as a solution for Backup. How do we do it? Step 1 &#8211; Database backups (snapshot dump of the database) First is to backup [...]]]></description>
			<content:encoded><![CDATA[<p>I was reading a post up at Carsonified (<a href="http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/">http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/</a>), which talked about MySQL backups.</p>
<p>While he slightly re-invents the wheel, its fairly similar to what we do over at Computer Solutions as a solution for Backup.</p>
<p>How do we do it?</p>
<p><span id="more-385"></span></p>
<h1>Step 1 &#8211; Database backups (snapshot dump of the database)</h1>
<p>First is to backup the database(s) to the filesystem in a common folder.<br />
We run MySQL daily backups to a folder under /home/dbbackup on all our servers using an easy to install backup shell script:</p>
<p><a href="http://sourceforge.net/projects/automysqlbackup/">http://sourceforge.net/projects/automysqlbackup/</a></p>
<p>Debian users can easily install via:</p>
<p><code>apt-get install automysqlbackup</code></p>
<p>On our servers we run automysqlbackup at midnight; and it automatically handles daily, weekly, monthly folders + rotation (no need to reinvent the wheel).<br />
Thanks to the wonders of logging, we can spot a visual effect of whats happening on our daily logs.</p>
<p><a href="http://www.computersolutions.cn/blog/wp-content/uploads/2010/03/mail.computersolutions.cn-mysql_bytes-day.png"><img src="http://www.computersolutions.cn/blog/wp-content/uploads/2010/03/mail.computersolutions.cn-mysql_bytes-day.png" alt="" title="mail.computersolutions.cn-mysql_bytes-day" width="495" height="271" class="alignnone size-full wp-image-388" /></a></p>
<p>The astute will notice that mysql usage goes a little ballistic as the script kicks in.<br />
A weekly view shows this in a clear manner also.</p>
<p><a href="http://www.computersolutions.cn/blog/wp-content/uploads/2010/03/mail.computersolutions.cn-mysql_bytes-week.png"><img src="http://www.computersolutions.cn/blog/wp-content/uploads/2010/03/mail.computersolutions.cn-mysql_bytes-week.png" alt="" title="mail.computersolutions.cn-mysql_bytes-week" width="495" height="271" class="alignnone size-full wp-image-389" /></a></p>
<p>The backup script runs on all our servers daily.  This essentially provides a daily snapshot of all the databases on that server.  If any issues occur during the backup, I get emailed a copy of the problems.<br />
This is useful for letting me know when a database table is corrupt, or something else went wonky.</p>
<p>Sample errors below:</p>
<blockquote><p>mysqldump: Got error: 1044: Access denied for user &#8216;debian-sys-maint&#8217;@'localhost&#8217; to database &#8216;information_schema&#8217; when using LOCK TABLES<br />
mysqldump: Got error: 1146: Table &#8216;consumer_aware.mw_category&#8217; doesn&#8217;t exist when using LOCK TABLES<br />
mysqldump: Got error: 1146: Table &#8216;counselasia.wp_email&#8217; doesn&#8217;t exist when using LOCK TABLES<br />
mysqldump: Got error: 1146: Table &#8216;joomla_versatility.jos_bannertrack&#8217; doesn&#8217;t exist when using LOCK TABLES<br />
mysqldump: Got error: 1146: Table &#8216;wp_counselasia.wp_counselterm_taxonomy&#8217; doesn&#8217;t exist when using LOCK TABLES</p></blockquote>
<p>(Errors above were corrupt tables, and a MySQL 5.1 issue that AutoMySQLBackup needs a small change for)</p>
<p>(We use the debian-sys-maint as backup user, so it needs lock tables privileges for information_schema)<br />
<code><br />
mysql -u root -p<br />
use mysql;<br />
update user set lock_tables_priv='Y' where host='localhost' and user='debian-sys-maint';<br />
exit;</code></p>
<p>That works for me, but others have also had to do this small addition to their automysqlbackup config file:</p>
<p><code># OPT string for use with mysqldump ( see man mysqldump )<br />
OPT="--quote-names --skip-opt --add-drop-table --create-options --disable-keys --extended-insert --quick --set-charset" </code></p>
<p>It doesn&#8217;t cover all issues that might occur though (see my notes at the bottom for things that have/can happen)</p>
<h1>Step 2 &#8211; RSync</h1>
<p>We then rsync the entire home folder system (which is where I store all the user specific data) to another pseudo-dedicated backup server.<br />
The rsync is setup to run an hour or two after the mysql backup script.  From experience, the MySQL backup usually takes about 15 minutes max even on the largest MySQL database server we have (mostly as clients DB&#8217;s compress nicely, and the total data size is usually a few hundred megabytes at max per user).</p>
<p>Rsync runs daily (usually in our early 2am &#8211; 4am period).<br />
Its setup as a service on each of our servers, and I have 3 separate folders we backup.</p>
<p>/etc<br />
[I've found it useful to backup conf specific stuff, and it typically runs in less than a second]</p>
<p>/var/qmail<br />
[We use qmail, so I backup the entire qmail folder structure.  The queue will need to be rebuilt in case of a hardware failure, but configuration, and other settings are nice to have.   Our user mail is actually stored in /home/vpopmail (as are user accounts), so that goes in a separate backup.  This usually completes in a few seconds]</p>
<p>/home<br />
[As we also run backups across multiple servers I specifically exclude any /home/backup folder, as this is usually my dumping ground for the backups.  This backup typically takes anywhere from 5 minutes to a few days depending on the amount of changes to be synced over.]</p>
<p>rsync is set to run via cron in /etc/cron.daily or /etc/cron.weekly or /etc/cron.monthly as applicable.</p>
<p>In our case we have a number of servers to backup over a few continents, and web + mysql takes roughly 600GB in total (still fairly easy to stick onto a single drive though).<br />
As machines are scattered around different / regions  it can take a few days to complete an initial backup if I deploy a new backup server.<br />
To avoid issues, I do a simple file test in my rsync cron script which gets deleted at the finish of the script.  If the script gets run a second time it checks for the file, and aborts if found.  This prevents multiple instances being run each day, which can cause issues for the initial long running backup.</p>
<h1>Step 3 &#8211; Backing up the backups!</h1>
<p>I also do a weekly backup of the complete backup folder to a different server so I have some &#8220;history&#8221;.<br />
This is fairly easy to setup &#8211; I just backup the backup folder from our &#8220;central&#8221; backup to a different server by sticking an rsync script in an appropriate folder &#8211; /etc/cron.weekly/monthly&#8230;,<br />
To facilitate, I setup, stick a spare 1TB or larger drive in mounted at /home/backup, and let it run.</p>
<p>As I&#8217;m still a little paranoid, to make it _even_ safer, I also do a monthly off-site of the backups.  This sits in a live-spare server in our office.</p>
<p>I also maintain multiple backup copies of certain data in different locations, just in case(tm).<br />
These are all kept in non user accessible drives on specific servers.  </p>
<p>As mentioned in the blog post I linked to, no backup regimen is actually useful until you&#8217;ve actually had to use it!<br />
We get at least 1 request a month to restore data or database(s), so I get to use this quite often.</p>
<p>The only time I&#8217;ve really needed multiple levels of backup was during our week of repeated Seagate drives failures (multiple hardware failures due to a faulty batch of bad drives); we got to test the backup infrastructure repeatedly, so I know that it all works well!</p>
<h1>Notes</h1>
<p>If your database is in iffy condition  &#8211; eg latin1 encoding, with UTF-8 data, or similar, the backup will be what MySQL thinks the encoding is.<br />
This may not mesh with what it actually is.<br />
Corrupt tables or filesystem issues can also cause errors.</p>
<p>AutoMySQLBackup can be configured to email you on issues, as can Rsync.<br />
Encoding related ones will not be seen until a restore is attempted, but other issues will be.<br />
I have successfully restored databases even with &#8220;corrupt&#8221; encoding data, whether it was latin1 -> utf8 or utf8 double encoding.<br />
MySQL does need some handholding though if that needs to happen though. </p>
<p>Having different snapshots of your data from different time periods (eg, daily, weekly, monthly) is important (and thats why I do it!).<br />
The number of times clients have come back with &#8220;oh I deleted something 2 weeks ago&#8221;, and I&#8217;ve been able to restore it has meant that they&#8217;re happy.</p>
<p>That said, it does mean you need to use a whack of drives for backup purposes.<br />
Luckily drive sizes get larger each year, and prices drop, so its an acceptable expense!</p>
<p>Some of you may question why we don&#8217;t use RAID for the above.<br />
We do use RAID hardware in some of our servers (usually 3ware 9000 series controllers), however RAID only protects against hardware failure, not against user mishap, or malicious intent.  RAID is not a replacement for backup!</p>
<p>Lawrence.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computersolutions.cn/blog/2010/03/behind-the-scenes-backups-at-computer-solutions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UTF-8, MySQL woes and how to force it to work!</title>
		<link>http://www.computersolutions.cn/blog/2009/02/utf-8-mysql-woes-and-how-to-force-it-to-work/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utf-8-mysql-woes-and-how-to-force-it-to-work</link>
		<comments>http://www.computersolutions.cn/blog/2009/02/utf-8-mysql-woes-and-how-to-force-it-to-work/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 06:03:31 +0000</pubDate>
		<dc:creator>Lawrence Sheed</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Useful Info]]></category>

		<guid isPermaLink="false">http://www.computersolutions.cn/blog/?p=73</guid>
		<description><![CDATA[As other web developers in China (and other non-latin language locations) probably know, UTF-8 is something that we need for Chinese to work correctly, however despite asking for UTF8 in the table structure, it doesn&#8217;t mean that MySQL or PHP is going to accede to our wishes. Here is how we at Computer Solutions cope [...]]]></description>
			<content:encoded><![CDATA[<p>As other web developers in China (and other non-latin language locations) probably know, UTF-8 is something that we need for Chinese to work correctly, however despite asking for UTF8 in the table structure, it doesn&#8217;t mean that MySQL or PHP is going to accede to our wishes.</p>
<p><span id="more-73"></span>Here is how we at Computer Solutions cope with forcing MySQL to UTF-8, despite its unwillingness!</p>
<p>First off, we need to configure the MySQL config via the my.cnf file to force the defaults to utf-8, instead of latin1.</p>
<p>Most systems my.cnf should be in either /etc/my.cnf or /etc/mysql/my.cnf (assuming *nix)</p>
<p>Make sure the following lines are added under mysqld:</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">[mysqld]
default-character-set=utf8
character-set-server=utf8
collation-server=utf8_general_ci</pre>
</blockquote>
<p>Restart mysql (debian or similar init.d should be /etc/init.d/mysql restart)</p>
<p>Lets check that worked -</p>
<pre class="wp-code-highlight prettyprint">mysql -u root -p
show variables like &quot;%character%&quot;;</pre>
<p>If you see results like this:</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">show variables like &quot;%character%&quot;;</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">| Variable_name            | Value                      |</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">| character_set_client     | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_connection | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_database   | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_filesystem | binary                     |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_results    | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_server     | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_system     | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_sets_dir       | /usr/share/mysql/charsets/ |</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">8 rows in set (0.00 sec)</pre>
</blockquote>
<p><strong>Then it worked</strong>.   If it <strong>doesn&#8217;t</strong> and you see something similar to below</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">mysql&amp;gt; show variables like &quot;%character%&quot;;</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">| Variable_name            | Value                      |</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">| character_set_client     | latin1                     |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_connection | latin1                     |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_database   | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_filesystem | binary                     |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_results    | latin1                     |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_server     | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_set_system     | utf8                       |</pre>
<pre class="wp-code-highlight prettyprint">| character_sets_dir       | /usr/share/mysql/charsets/ |</pre>
<pre class="wp-code-highlight prettyprint">+--------------------------+----------------------------+</pre>
<pre class="wp-code-highlight prettyprint">8 rows in set (0.00 sec)</pre>
</blockquote>
<p>Then we need to re-edit /etc/my.cnf</p>
<p>Add this under the [mysqld] lines we edited earlier.</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">skip-character-set-client-handshake</pre>
</blockquote>
<p>then restart mysql (/etc/init.d/mysql restart )   and recheck.</p>
<p>That forces MySQL to *use* what we &lt;expletive deleted&gt; well told it too!</p>
<p>That unfortunately isn&#8217;t the end of the story.  If like us, you&#8217;ve been merrily using UTF-8 data inside Latin1 encoded tables accidentally, you&#8217;ll still need to export your data in the correct format, and reimport it.</p>
<p>This can be done as follows:</p>
<p>Use MySQLDump with an explicit encoding passed to it:</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">&lt;span class=&quot;ident&quot;&gt;mysqldump&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;latin1 \
&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;skip&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;charset&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;myscrewedupdb&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;sql&lt;/span&gt;</pre>
</blockquote>
<p>This will give us a dump of the data in the correct format, albeit with the wrong encoding specified in the file.  You&#8217;ll need to edit the file to change latin1 to utf8   eg</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">&lt;span class=&quot;ident&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;s/latin1/utf8/g&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;sql&lt;/span&gt;</pre>
</blockquote>
<p>..and then re-import the data (I *strongly* suggest you do this to a NEW db for testing, as you <strong>DON&#8217;T</strong> want to lose data now, do you!)</p>
<blockquote>
<pre class="wp-code-highlight prettyprint">&lt;span class=&quot;ident&quot;&gt;mysql&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;utf8&lt;/span&gt; \
&lt;span class=&quot;ident&quot;&gt;newtestdbname&lt;/span&gt; &lt;span class=&quot;punct&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;ident&quot;&gt;dump&lt;/span&gt;&lt;span class=&quot;punct&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;ident&quot;&gt;sql&lt;/span&gt;</pre>
</blockquote>
<p>With a bit of luck, your data should be intact, and you should now be basking in the glory of UTF-8&#8242;ness, ready for the 20th Century etc!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.computersolutions.cn/blog/2009/02/utf-8-mysql-woes-and-how-to-force-it-to-work/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

