<?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>Edward A. Webb (.com) &#187; Database Tips</title>
	<atom:link href="http://www.edwardawebb.com/category/database-tips/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.edwardawebb.com</link>
	<description>get all his digital goodness 24/7</description>
	<lastBuildDate>Mon, 07 May 2012 12:58:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Books I recommend</title>
		<link>http://www.edwardawebb.com/linux/books-recommend</link>
		<comments>http://www.edwardawebb.com/linux/books-recommend#comments</comments>
		<pubDate>Wed, 08 Jul 2009 21:43:13 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=509</guid>
		<description><![CDATA[Amazon.com Widgets]]></description>
			<content:encoded><![CDATA[<p><OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab" id="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804"  WIDTH="500px" HEIGHT="175px"> <PARAM NAME="movie" VALUE="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=GetDisplayTemplate"><PARAM NAME="quality" VALUE="high"><PARAM NAME="bgcolor" VALUE="#FFFFFF"><PARAM NAME="allowscriptaccess" VALUE="always"><embed src="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=GetDisplayTemplate" id="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804" quality="high" bgcolor="#ffffff" name="Player_2c0bc29f-ccdb-489a-ac1e-da93c888b804" allowscriptaccess="always"  type="application/x-shockwave-flash" align="middle" height="175px" width="500px"></embed></OBJECT> <NOSCRIPT><a href="http://ws.amazon.com/widgets/q?ServiceVersion=20070822&#038;MarketPlace=US&#038;ID=V20070822%2FUS%2Fedawe-20%2F8010%2F2c0bc29f-ccdb-489a-ac1e-da93c888b804&#038;Operation=NoScript" rel="nofollow" >Amazon.com Widgets</a></NOSCRIPT></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/books-recommend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle SQL: Use sysdate for start and end of previous month and year</title>
		<link>http://www.edwardawebb.com/database-tips/sysdate-determine-start-previous-month-year-oracle-sql</link>
		<comments>http://www.edwardawebb.com/database-tips/sysdate-determine-start-previous-month-year-oracle-sql#comments</comments>
		<pubDate>Mon, 30 Mar 2009 22:47:59 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=454</guid>
		<description><![CDATA[Wow, that title is a mouthful. Basically i figured out how to use SYSDATE and some other temporal methods to automatically determine the first and last day of the previous month, or previous year. I needed this to hand off  a canned query that can be used by many users without the need to constantly [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, that title is a mouthful.<br />
Basically i figured out how to <strong>use SYSDATE and some other temporal methods to automatically determine the first and last day of the previous month, or previous year</strong>.</p>
<p>I needed this to hand off  a canned query that can be used by many users without the need to constantly update the date parameters of the query.  For instance &#8220;<strong>Show me sales totals for the previous month!</strong>&#8220;  or &#8221; <strong>What was the total number of transactions last year?</strong>&#8221;</p>
<p>You could just type something like </p>
<pre> Date >= to_date('11-01-2009', 'MM-DD-YYYY')</pre>
<p>But that need users to change every month or year&#8230; boooo.</p>
<p>The solutions are not too pretty, but they work, And if you have a better way I would love to hear.. Googling proved no avail, and I had to dig this combination from various pieces in an O&#8217;Reilly Oracle book.</p>
<p>Without further delay..<span id="more-454"></span></p>
<h2>Oracle SQL Query using start and end of Last Month as Dates</h2>
<h4> Basic Use<br />
<h4>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'MM'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">,</span> LAST_DAY<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #993333; font-weight: bold;">TABLE</span></pre></div></div>

<h4>Sample Use<br />
<h4>
In this example we will get the sales total by agent and region for last month.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*
*  This query will retrieve all session summary records that occurred in the previous month
* Do not adjust the date fields, it should calculate correctly based on today's date.
*
* @Author Eddie Webb
*
*/</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* add TRUNC(ADD_MONTHS(SYSDATE, -1),'MM') , LAST_DAY(ADD_MONTHS(SYSDATE,-1))  to select to test dates */</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span>  AGENT_NAME<span style="color: #66cc66;">,</span> REGION<span style="color: #66cc66;">,</span> SALE_DATE<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">SUM</span><span style="color: #66cc66;">&#40;</span>SALE_VALUE<span style="color: #66cc66;">&#41;</span> total <span style="color: #993333; font-weight: bold;">FROM</span> TRS<span style="color: #66cc66;">.</span>SALES
&nbsp;
&nbsp;
<span style="color: #993333; font-weight: bold;">WHERE</span>
    <span style="color: #808080; font-style: italic;">/* first day of previous month*/</span>
    <span style="color: #808080; font-style: italic;">/* adjust the -1 to adjust months back */</span>
    <span style="color: #808080; font-style: italic;">/* default:   TRUNC(ADD_MONTHS(SYSDATE, -1),'MM')    */</span>
    SALE_DAY <span style="color: #66cc66;">&gt;=</span> TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'MM'</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #993333; font-weight: bold;">AND</span>
    <span style="color: #808080; font-style: italic;">/*last day of last month*/</span>
    <span style="color: #808080; font-style: italic;">/* adjust the -1 to adjust months back */</span>
    <span style="color: #808080; font-style: italic;">/* default:    LAST_DAY(ADD_MONTHS(SYSDATE, -1))   */</span>
    SALE_DAY <span style="color: #66cc66;">&lt;=</span> LAST_DAY<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">/* group sums by Client IDs Requestor, then system */</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> ROLLUP<span style="color: #66cc66;">&#40;</span> AGENT_NAME<span style="color: #66cc66;">,</span> AGENT_NAME<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h4>How&#8217;s that work?</h4>
<p>If we focus on the basic use above you&#8217;ll notice two manipulations.<br />
The first one is the first day of the month.</p>
<pre> TRUNC(ADD_MONTHS(SYSDATE, -1),'MM') </pre>
<p>Start with today&#8217;s date using sysdate (3/27) and subtracts one month (2/27). We then Truncate the result using MM for the numerical value of the month(2).  This will represent the first day of last month (2/1).<br />
The second manipulation requires the use of LAST_DAY instead of TRUNC.</p>
<pre> LAST_DAY(ADD_MONTHS(SYSDATE, -1)) </pre>
<p>Start with today&#8217;s date using sysdate (3/27) and subtracts one month (2/28). We then obtain the LAST_DAY (2/28).</p>
<p>Note: no, there isnt a FIRST_DAY function or I would have used it.<br />
No, there isn&#8217;t a SUBTRACT_MONTHS function &#8220;&#8221;  &#8220;&#8221; &#8220;&#8221;.<br />
<strong>Instead you can pass positive or negative numbers to ADD_MONTHS.  0 will get the dates for the current month.</strong></p>
<h2>Oracle SQL Query using start and end of Last Year as Dates</h2>
<p>OK same basic premises here but extended.</p>
<h4> Basic Use<br />
<h4>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>     
TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'SYYYY'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
LAST_DAY<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'SYYYY'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #993333; font-weight: bold;">TABLE</span></pre></div></div>

<h4>Sample Use<br />
<h4>
In this example we will get the sales total by agent and region for last month.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/*
*  This query will retrieve all session summary records that occurred in the previous YEAR
* and provide a total count by client
* Do not adjust the date fields, it should calculate correctly based on today's date.
*
* @Author Eddie Webb
*
*/</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span>  REQUESTOR_ID<span style="color: #66cc66;">,</span> SYSTEM_ID<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">SUM</span><span style="color: #66cc66;">&#40;</span>SESSION_COUNT<span style="color: #66cc66;">&#41;</span> total <span style="color: #993333; font-weight: bold;">FROM</span> EBR<span style="color: #66cc66;">.</span>SESSION_SUMM
&nbsp;
&nbsp;
<span style="color: #993333; font-weight: bold;">WHERE</span>
    <span style="color: #808080; font-style: italic;">/* first day of previous YEAR*/</span>
    SERVICE_DAY <span style="color: #66cc66;">&gt;=</span> TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'SYYYY'</span><span style="color: #66cc66;">&#41;</span> 
&nbsp;
&nbsp;
<span style="color: #993333; font-weight: bold;">AND</span>
    <span style="color: #808080; font-style: italic;">/*last day of last YEAR*/</span>
    SERVICE_DAY <span style="color: #66cc66;">&lt;=</span> LAST_DAY<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>TRUNC<span style="color: #66cc66;">&#40;</span>ADD_MONTHS<span style="color: #66cc66;">&#40;</span>SYSDATE<span style="color: #66cc66;">,</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'SYYYY'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">11</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">/* group sums by Client IDs Requestor, then system */</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> ROLLUP<span style="color: #66cc66;">&#40;</span> REQUESTOR_ID<span style="color: #66cc66;">,</span> SYSTEM_ID<span style="color: #66cc66;">&#41;</span></pre></div></div>

<h4>How&#8217;s that work?</h4>
<p>If we focus on the basic use above you&#8217;ll notice two manipulations.<br />
The first one is the first day of the year, also very simialr to the first day of last month, but different.</p>
<pre> TRUNC(ADD_MONTHS(SYSDATE, -12),'SYYYY')  </pre>
<p>Start with today&#8217;s date using sysdate (3/27/09) and subtracts 12 months (3/27/08). We then Truncate the result using SYYYY for the numerical value of the year(2008).  Again, because of TRUNC&#8217;s behavior it will default to January 1st, 12:00 am of the truncated year. This will represent the first day of last year (1/1/2008).<br />
The second manipulation is ugly at best, and depends on calculating the first day of the year.</p>
<pre> LAST_DAY(ADD_MONTHS(TRUNC(ADD_MONTHS(SYSDATE, -12),'SYYYY'), 11)) </pre>
<p>OR</p>
<pre> ADD_MONTHS(TRUNC(ADD_MONTHS(SYSDATE, -12),'SYYYY'), 12) </pre>
<p>Again we start with today&#8217;s date using sysdate (3/27/09) and subtracts 12 months (3/27/08). We then Truncate the result using SYYYY for the numerical value of the year(2008).  Again, because of TRUNC&#8217;s behavior it will default to January 1st, 12:00 am of the truncated year. This will represent the first day of last year (1/1/2008).</p>
<p>Now we go a step further by adding 11 months to the first day of last year (12/1/2008) and finally get the last day of that month using LAST_DAY (12/31/2008 12:00 am)</p>
<p>More Notes: Don&#8217;t rely on 365 days because some years have 366 (leap years) all years however have 12 months.<br />
<strong>You may instead consider adding 12 months to 1/1/2008, and remove the LAST_DAY function  will give you 1/1/2009 12:00 am, which may be your goal&#8230; (moments after 12/31/08 11:59 pm)</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/database-tips/sysdate-determine-start-previous-month-year-oracle-sql/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Drop all tables from a MySQL Database without deletion</title>
		<link>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion</link>
		<comments>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion#comments</comments>
		<pubDate>Fri, 13 Feb 2009 22:25:52 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=425</guid>
		<description><![CDATA[This solution allows you to purge all tables from a database without actually deleting the database. This may not seem practical to those that have full rights and wonder.. &#8220;Why not just create a new DB?&#8221;. For others that are using a hosting plan or work for a large company with restrictive bureaucracy will appreciate [...]]]></description>
			<content:encoded><![CDATA[<p><strong>This solution allows you to purge all tables from a database without actually deleting the database.</strong><br />
This may not seem practical to those that have full rights and wonder.. &#8220;Why not just create a new DB?&#8221;.<br />
For others that are using a hosting plan or work for a large company with restrictive bureaucracy will appreciate this simple tip.  The reason is that <strong>your account may only have specific rights on that Database</strong> and absolutely no rights on the hosting server.  Even if you had permission to delete the old DB, you would have to jump through hoops to get a new one created.  So in short, &#8220;Because we can&#8217;t&#8221;</p>
<p>It has also been pointed out as a way to maintain the schema.</p>
<p><span id="more-425"></span></p>
<h2>Write a script to loop through all current tables and drop them? &#8211; NO!</h2>
<p>You could get a listing of all tables, iterate through an loop and drop the tables, but let&#8217;s see if we can&#8217;t think of a one liner&#8230;</p>
<h2>Rely on mysqldump and mysql to do all the work? &#8211; YES!</h2>
<p>We need to drop tables, that&#8217;s obvious.  But how to get all the tables with drop command in hand.  What about our ever so faithful and functional friend mysqldump? Of course! Not only can mysqldump handle giving us the names of all the tables, but it can also hand us the drop command.</p>
<p><strong>You&#8217;ll need to execute this command where mysqldump and mysql binaries live, typically this is /usr/bin.</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysqldump -uuser_name <span style="color: #660033;">-psecretpassword</span> <span style="color: #660033;">--add-drop-table</span> database_name <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> ^DROP <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql  -uuser_name <span style="color: #660033;">-psecretpassword</span> database_name</pre></div></div>

<p>SO we pump out all the table and data from the database,use grep to trash everything but the lines that begin with the drop commands and pass that right back into mysql.  Works, but should we be passing and parsing all the data just to trash it? Probably not.</p>
<h2>Keeping the workload small &#8211; no data!</h2>
<p>Particularly for those of you that have rather large Databases we don&#8217;t want to waste time passing around data, so let&#8217;s leave it out entirely.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysqldump -uuser_name <span style="color: #660033;">-psecretpassword</span> <span style="color: #660033;">--no-data</span> <span style="color: #660033;">--add-drop-table</span> database_name <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> ^DROP <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql  -uuser_name <span style="color: #660033;">-psecretpassword</span> database_name</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/linux/drop-tables-mysql-database-deletion/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Simple shell script to backup multiple mysql databases</title>
		<link>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases</link>
		<comments>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases#comments</comments>
		<pubDate>Thu, 12 Feb 2009 23:32:32 +0000</pubDate>
		<dc:creator>Eddie</dc:creator>
				<category><![CDATA[Database Tips]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqldump]]></category>

		<guid isPermaLink="false">http://edwardawebb.com/?p=306</guid>
		<description><![CDATA[To backup a mysql database from a unix command line is relatively simple.  It is equally easy to automate this task with a shell script and a crontab (cron jobs).  In my case I needed to backup ~15 unique databases and I despise repetitious code, so here&#8217;s what I came up with. **Update Added means [...]]]></description>
			<content:encoded><![CDATA[<p>To<strong> backup a mysql database from a unix command</strong> line is relatively simple.  It is equally easy to automate this task with a shell script and a crontab (cron jobs).  In my case I needed to backup ~15 unique databases and I despise repetitious code, so here&#8217;s what I came up with.<br />
**Update<br />
Added means to allow different User and password based on current DB.<br />
** ANother Update! &#8211; better <a href="#error-handling" rel="nofollow" >error handling</a>.<br />
<span id="more-306"></span></p>
<h2>The problem</h2>
<p>I have multiple databases that need to be backed up into different archive folders. Each database requires a unique host, username and password.</p>
<h2>THe solution</h2>
<p>The bash shell of course! First off we should all be familiar with mysqldump.  It lives idle in nearly every &#8216;nix box just waiting to dump a mysql database onto the screen, or file. ANd unless you want your mysqldump binary to be sad you should take full well use of it.</p>
<p>The most basic use of the program couldn&#8217;t be simpler, but it is happy to meet more complex needs as well. FOr this article we&#8217;ll keep it simple.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">mysqldump <span style="color: #660033;">-h</span> HOSTNAME <span style="color: #660033;">-u</span> USERAME <span style="color: #660033;">-pPASSWORD</span> DATABASE <span style="color: #000000; font-weight: bold;">&gt;</span> OUTPUTFILE</pre></div></div>

<p>now you can of course add additional switches, c and e are two I use pretty frequently. See your machine&#8217;s man pages to learn more.</p>
<p>But wait that only handles 1 DB on 1 host with 1 user and password. True. SO here&#8217;s where we take use of a script to make this puppy work overtime.</p>
<h2>The Shell Scripts</h2>
<h3>Many mysql Databases on one host</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#####</span>
<span style="color: #666666; font-style: italic;"># Set these values!</span>
<span style="color: #666666; font-style: italic;">####</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># space seperated list of domain names (will be used as part of the output path)</span>
<span style="color: #007800;">domains</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> name4subfolders inSQLfolderabove canbedomains orsomethingelse <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #666666; font-style: italic;">#list of corresponding DB names</span>
<span style="color: #007800;">sqldbs</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> fulldbname1 db2 db3 db4 <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#list of IDs and passwords</span>
<span style="color: #007800;">usernames</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> user1 user2 user3 user <span style="color: #000000;">4</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">passwords</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span> pass1 pass2 pass3 pass4 <span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#Directory to save generated sql files (domain name is appended)</span>
<span style="color: #007800;">opath</span>=<span style="color: #007800;">$HOME</span><span style="color: #000000; font-weight: bold;">/</span>sql_dumps<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># your mysql host</span>
<span style="color: #007800;">mysqlhost</span>=mysql.webbmaster.org
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#####</span>
<span style="color: #666666; font-style: italic;"># End of config values</span>
<span style="color: #666666; font-style: italic;">#####</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#date to append</span>
<span style="color: #007800;">suffix</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>Y-<span style="color: #000000; font-weight: bold;">%</span>m-<span style="color: #000000; font-weight: bold;">%</span>d<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">#run on each domain</span>
<span style="color: #000000; font-weight: bold;">for</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span> i = <span style="color: #000000;">0</span> ; i <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #800000;">${#domains[@]}</span> ; i++ <span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #666666; font-style: italic;">#set current output path</span>
	<span style="color: #007800;">cpath</span>=<span style="color: #007800;">$opath</span><span style="color: #800000;">${domains[$i]}</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#check if we need to make path</span>
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$cpath</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #666666; font-style: italic;"># direcotry exists, we're good to continue</span>
		<span style="color: #007800;">filler</span>=<span style="color: #ff0000;">&quot;just some action to prevent syntax error&quot;</span>
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #666666; font-style: italic;">#we need to make the directory</span>
		<span style="color: #7a0874; font-weight: bold;">echo</span> Creating <span style="color: #007800;">$cpath</span>
		<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #007800;">$cpath</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#now do the backup</span>
	<span style="color: #007800;">SQLFILE</span>=<span style="color: #800000;">${cpath}</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #800000;">${sqldbs[$i]}</span>_<span style="color: #007800;">$suffix</span>.sql.gz
&nbsp;
	mysqldump <span style="color: #660033;">-c</span> <span style="color: #660033;">-h</span> <span style="color: #007800;">$mysqlhost</span> <span style="color: #660033;">--user</span> <span style="color: #800000;">${usernames[$i]}</span> <span style="color: #660033;">--password</span>=<span style="color: #800000;">${passwords[$i]}</span> <span style="color: #800000;">${sqldbs[$i]}</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span>error <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">gzip</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #007800;">$SQLFILE</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-s</span> error <span style="color: #7a0874; font-weight: bold;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">then</span>	   
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;WARNING: An error occured while attempting to backup %s  <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>Error:<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span>&quot;</span> <span style="color: #800000;">${sqldbs[$i]}</span> 
		<span style="color: #c20cb9; font-weight: bold;">cat</span> error
		<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-f</span> er
	<span style="color: #000000; font-weight: bold;">else</span>
		<span style="color: #7a0874; font-weight: bold;">printf</span> <span style="color: #ff0000;">&quot;%s was backed up successfully to %s<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #800000;">${sqldbs[$i]}</span> <span style="color: #007800;">$SQLFILE</span>
	<span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>In either case you&#8217;ll want to save it to a file, let&#8217;s say&#8230;    daily_sql_backup.sh<br />
And then make the script executable</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#chmod 0750 daily_sql_backup.sh</span></pre></div></div>

<p>Now you can test the script by calling it by name</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># daily_sql_backup.sh</span></pre></div></div>

<p><strong><br />
Sweet, a single command will backup any databases we include in the script. And we can call it again and again</strong>.</p>
<p>A simple output reports the results;</p>

<div class="wp_syntax"><div class="code"><pre class="unix" style="font-family:monospace;">database1 was backed up successfully to /home/YOURNAME/sql_dumps/site1.com/database1_2009-01-14.sql.gz
&nbsp;
taskfreak_database was backed up successfully to /home/YOURNAME/sql_dumps/taskfreak.sitetwo.com/taskfreak_database_2009-01-14.sql.gz
&nbsp;
mantis_database was backed up successfully to /home/YOURNAME/sql_dumps/mantios.yetanother.org/mantis_database_2009-01-14.sql.gz</pre></div></div>

<h3>Error Reporting<a name="error-handling">&nbsp;</a></h3>
<p>I recently had to update the error handling because it was letting failures pass by!</p>
<p>That was because mysqldump would fail, throw an error to stderr, but  gzip would then come along and happily report that is successfully compressed nothing!</p>
<p>The new model outputs any errors to a file named &#8220;error&#8221; before everything is piped into gzip and the error code is lost.  We then check for the file, and if present show it to the user (log it) before deleting the file and moving on.</p>
<p>So in a bad scenario I would now see:</p>
<pre>
Attempting to run MySQL dump on 2 databases
domain1.com
domain2.com

domain1_com was backed up successfully to /home/user/sql_dumps/
domain1/domain1_com_2011_05_05.sql.gz

WARNING: An error occured while attempting to backup domain2
        Error:
        mysqldump: Got error: 1045: Access denied for user 'domain2_com'@'domain2.com' (using password: YES) when trying to connect
</pre>
<p>&nbsp;</p>
<p>But wait! We wanted to automate this whole thing right? And so we shall.</p>
<h2>Using Cron to automate the process</h2>
<p>If your using a webhost they likely provide a GUI to add cron jobs. If that&#8217;s the case you can just point to the full path where you saved the above script, select the interval and your good to go.</p>
<p>If your using this on your own server you&#8217;ll need to get your hands dirty with a crontab. You can open the crontab file in your editor of choice, or call it from the command line. IN this example we&#8217;ll rely in vi, my systems default editor.<br />
Create a crontab file if it does not already exist and open it for edit</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">crontab <span style="color: #660033;">-e</span></pre></div></div>

<p>You may see some existing lines or you may not. Just remember one job per line. THe layout may seem overwhelming at first, but its quite simple, and breaks down like this</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">min     hour     day    month    weekday     job_to_Run</pre></div></div>

<p>The values are in the respective ranges for day of week 0 is Sunday.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000;">0</span>-<span style="color: #000000;">59</span>    <span style="color: #000000;">0</span>-<span style="color: #000000;">23</span>     <span style="color: #000000;">1</span>-<span style="color: #000000;">31</span>    <span style="color: #000000;">1</span>-<span style="color: #000000;">12</span>     <span style="color: #000000;">0</span>-<span style="color: #000000;">6</span>        filename</pre></div></div>

<p>To omit a field replace it with an asterisk (*) which means all values. Alternately you may use comma separated lists. Although I believe it will treat any whitespace as a delimiter I use tabs to make the organization a little nicer.</p>
<p>So let&#8217;s suppose I want to run this job nightly, it is after all named DAILY sql backup <img src='http://www.edwardawebb.com/wp-includes/images/smilies/icon_smile.gif' alt="icon smile Simple shell script to backup multiple mysql databases" class='wp-smiley' title="Simple shell script to backup multiple mysql databases" /><br />
I will add the following line to my crontab</p>
<pre>
15    0     *    *   *     $HOME/scripts/daily_sql_backup.sh > logfile.log
</pre>
<p>This means every day @ 00:15 a.k.a 15 minutes past midnight it will run the script and print any output into the specified logfile.<br />
If you leave off the redirect to logfile it will email the user with the results. To omit any output use the handy standby
<pre>>/dev/null 2>&#038;1</pre>
<p>.</p>
<p>well I think that covers it. THere&#8217;s tons of good resources to learn more about any particular topic, but I would be happy to field comments.</p>
<h3>The End Result</h3>
<p>After your newly created cron jobs have the chance to run for a few days you&#8217;ll end up with a nice and neat directory structure like this;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">sql_dumps<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb.com
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">`</span>-- edwardawebb_wordpress_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>-- mantis.mainsite.org
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_mantis_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000; font-weight: bold;">`</span>-- mainsite_mantis_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz
<span style="color: #000000; font-weight: bold;">`</span>-- taskfreak.mainsite.org
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">11</span>-<span style="color: #000000;">2009</span>
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">11</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">12</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">13</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">14</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">15</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">16</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">17</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">|</span>-- mainsite_taskfreak_01-<span style="color: #000000;">18</span>-<span style="color: #000000;">2009</span>.sql.gz
    <span style="color: #000000; font-weight: bold;">`</span>-- mainsite_taskfreak_01-<span style="color: #000000;">19</span>-<span style="color: #000000;">2009</span>.sql.gz</pre></div></div>

<p>Note: this example would generate 3 files each night. After 1 month thats ~150 files depending on the month. That&#8217;s why I also wrote a simple <a href="http://edwardawebb.com/linux/log-recycler-script" rel="nofollow" >Recycler script</a> to purge all old files. <del datetime="2009-01-18T01:16:12+00:00">As soon as I draft that article I&#8217;ll ad the link here.</del></p>
]]></content:encoded>
			<wfw:commentRss>http://www.edwardawebb.com/web-development/simple-shell-script-backup-multiple-mysql-databases/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
