<?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>Sandeep Ghael &#187; Databases</title>
	<atom:link href="http://sandeepghael.com/category/databases/feed/" rel="self" type="application/rss+xml" />
	<link>http://sandeepghael.com</link>
	<description>acts_as_blog</description>
	<lastBuildDate>Wed, 20 Apr 2011 14:48:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Ultimate Snow Leopard Web Development machine (part 3) &#8211; Databases</title>
		<link>http://sandeepghael.com/2009/10/ultimate-snow-leopard-web-development-machine-part-3-databases/</link>
		<comments>http://sandeepghael.com/2009/10/ultimate-snow-leopard-web-development-machine-part-3-databases/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 18:37:28 +0000</pubDate>
		<dc:creator>sghael</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[64bit]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Postgres]]></category>
		<category><![CDATA[Snow Leopard]]></category>

		<guid isPermaLink="false">http://sandeepghael.com/?p=295</guid>
		<description><![CDATA[Depending on the webapp project I&#8217;m working on, I flip back and forth between MySQL and PostgresSQL, generally using Postgres for anything that needs spatial or mapping related functionality. One pain point I encountered with Snow Leopard is getting everything compiled for true 64bit, and then getting the appropriate bindings for MySQL or Postgres to [...]]]></description>
			<content:encoded><![CDATA[<p>Depending on the webapp project I&#8217;m working on, I flip back and forth between MySQL and PostgresSQL, generally using Postgres for anything that needs spatial or mapping related functionality.</p>
<p>One pain point I encountered with Snow Leopard is getting everything compiled for true 64bit, and then getting the appropriate bindings for MySQL or Postgres to work with frameworks like Rails (Ruby) or Django (Python).  I work with both, so by the end of the post you&#8217;ll be prepared to use both DB servers for either framework.</p>
<h1>Step 1: Install MySQL from source</h1>
<p>We refer here, again to the excellent tutorial from HiveLogic:</p>
<p><a href="http://hivelogic.com/articles/compiling-mysql-on-snow-leopard/"> http://hivelogic.com/articles/compiling-mysql-on-snow-leopard/</a></p>
<p>After completing the install, set up your root password:</p>
<p>[cci lang="bash"]</p>
<p>$ mysqladmin -u root password NEWPASSWORD</p>
<p>[/cci]</p>
<h1>Step 2: Install PostgreSQL from source</h1>
<p>As for Postgres, I found these instructions found on InvisionPower as a good basis to start my install from. </p>
<p><a href="http://community.invisionpower.com/topic/292849-installing-postgresql-server-on-mac-os-x-snow-leopard/">http://community.invisionpower.com/topic/292849-installing-postgresql-server-on-mac-os-x-snow-leopard/</a></p>
<p>Couple of note regarding Postgres.</p>
<p>1) the instructions in the link above seem to provide a dead link for the Postgres source.  You can <strong>try this curl command instead of theirs</strong>:</p>
<p>[cci lang="bash"]<br />
$ curl http://ftp9.us.postgresql.org/pub/mirrors/postgresql/source/v8.4.1/postgresql-8.4.1.tar.gz -O<br />
[/cci]</p>
<p>2) <strong>Make sure to compile as a 64 bit application</strong>, using the &#8220;ARCH=x86_64&#8243; and other flags specified during your &#8220;make&#8221; step.</p>
<p>3) when creating and setting user/group info, I found an error in the 8th command line instructions.  The original command references a group &#8220;_postgres&#8221; before it has been created.  Do this instead:</p>
<p>Enough changes were required to make things compile and work on my new system, that I&#8217;ll simply transcribe my exact steps here: </p>
<p>[cci lang="bash"]<br />
$ sudo mkdir /usr/local/src<br />
$ cd /usr/local/src</p>
<p>$ sudo su</p>
<p>$ curl http://ftp9.us.postgresql.org/pub/mirrors/postgresql/source/v8.4.1/postgresql-8.4.1.tar.gz -O<br />
$ tar -zvxf postgresql-8.4.1.tar.gz<br />
$ rm postgresql-8.4.1.tar.gz<br />
$ cd postgresql-8.4.1</p>
<p>$ ./configure &#8211;prefix=/usr/local/postgresql-8.4.1</p>
<p>$ ARCH=x86_64 CFLAGS=&#8221;-arch x86_64&#8243; LDFLAGS=&#8221;-arch x86_64&#8243; make<br />
$ make install</p>
<p>$ ln -s /usr/local/postgresql-8.4.1 /usr/local/pgsql<br />
$ echo &#8220;PATH=/usr/local/pgsql/bin:$PATH&#8221; >> ~/.profile<br />
$ source ~/.profile<br />
$ mkdir /usr/local/pgsql/data/</p>
<p>$ dscl . list /Users UniqueID<br />
[/cci]</p>
<p>I use &#8221; dscl . list /Users UniqueID | grep <##>&#8221; to find the first available number past 75.  For me it was 80.</p>
<p>[cci lang="bash"]<br />
$ dscl localhost create /Local/Default/Users/_postgres<br />
$ dscl localhost create /Local/Default/Users/_postgres PrimaryGroupID 0<br />
$ dscl localhost create /Local/Default/Users/_postgres UniqueID 80<br />
$ dscl localhost create /Local/Default/Users/_postgres UserShell /bin/bash<br />
$ dscl localhost passwd /Local/Default/Users/_postgres<br />
$ dscl localhost create /Local/Default/Users/_postgres NFSHomeDirectory /var/home/_postgres<br />
$ mkdir -p /var/home/_postgres<br />
$ chown -Rf _postgres /var/home/_postgres<br />
$ dscl localhost create /Local/Default/Groups/_postgres<br />
$ dscl localhost create /Local/Default/Groups/_postgres UniqueID 80<br />
$ dscl localhost append /Local/Default/Groups/_postgres GroupMembership _postgres<br />
$ chown -Rf _postgres:_postgres /var/home/_postgres</p>
<p>$ defaults write /Library/Preferences/com.apple.loginwindow.plist Hide500Users -bool TRUE<br />
$ chown -R _postgres /usr/local/postgresql-8.4.1/<br />
[/cci]</p>
<p>I did not exit su at this point, as suggested in the original InvisionPower article.  I needed to be su to change to user &#8220;_postgres&#8221;.</p>
<p>[cci lang="bash"]<br />
$ su &#8211; _postgres<br />
$ /usr/local/pgsql/bin/initdb -E UTF8 -D /usr/local/pgsql/data/<br />
$ /usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data/ -l /usr/local/pgsql/data/postgresql.log start<br />
[/cci]</p>
<p>Now test creating a new DB:</p>
<p>[cci lang="bash"]<br />
$ /usr/local/pgsql/bin/createdb test<br />
$ /usr/local/pgsql/bin/psql test<br />
[/cci]</p>
<p>Type \q to quit.</p>
<p>[cci lang="bash"]<br />
$ exit<br />
$ sudo su<br />
$ rm -rf /var/home<br />
$ dscl localhost delete /Local/Default/Users/_postgres NFSHomeDirectory<br />
$ dscl localhost passwd /Local/Default/Users/_postgres<br />
$ exit<br />
[/cci]</p>
<p>At this point your server is installed and tested.  The InvisionPower post provides a great script that you can use to start/stop/restart the server from the command line.  See the bottom of <a href="http://community.invisionpower.com/topic/292849-installing-postgresql-server-on-mac-os-x-snow-leopard/">their article.</a></p>
<p><em></em></p>
]]></content:encoded>
			<wfw:commentRss>http://sandeepghael.com/2009/10/ultimate-snow-leopard-web-development-machine-part-3-databases/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Backup script for MySQL (onsite and offsite)</title>
		<link>http://sandeepghael.com/2009/08/backup-script-for-mysql-onsite-and-offsite/</link>
		<comments>http://sandeepghael.com/2009/08/backup-script-for-mysql-onsite-and-offsite/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 20:11:32 +0000</pubDate>
		<dc:creator>sghael</dc:creator>
				<category><![CDATA[Databases]]></category>

		<guid isPermaLink="false">http://sandeepghael.com/?p=132</guid>
		<description><![CDATA[In the previous post, I provide a backup script for PostgreSQL. As promised, here is the same script written for MySQL. Below are the setup instructions. Copy the contents below into a file named mysql-backup.sh placed in the root account home (on Ubuntu it&#8217;s &#8216;/root&#8217;). For simplicity, I&#8217;m using the root account, but on your [...]]]></description>
			<content:encoded><![CDATA[<p>In the previous post, I provide a backup script for PostgreSQL.  As promised, here is the same script written for MySQL.</p>
<p>Below are the setup instructions.</p>
<ol>
<li>
        Copy the contents below into a file named mysql-backup.sh placed in the root account home (on Ubuntu it&#8217;s &#8216;/root&#8217;).  For simplicity, I&#8217;m using the root account, but on your production servers, you may want to create a dedicated &#8220;backupuser&#8221; account that executes these actions.<br />
        <br/></p>
<div style="background-color: #F1F1F1;">
        [cci lang="bash"]</p>
<p>#!/bin/sh</p>
<p>DATE=`date &#8220;+%Y-%m-%d-%I-%M-%S&#8221;`<br />
BACKUP_DIR=&#8221;mysqlbackups&#8221;</p>
<p>#DO NOT CHANGE ANYTHING BELOW THIS LINE<br />
DUMP=&#8221;mysqldump&#8221;<br />
REMOTE=&#8221;"</p>
<p>usage() {<br />
echo Usage:<br />
echo &#8220;\t$0 [options]&#8221;<br />
echo<br />
echo &#8220;Where options is as follows:&#8221;<br />
echo &#8220;\t-r\t&#8211;remote\t\tThe remote host to copy the DB backup to (mandatory)&#8221;<br />
echo &#8220;\t-u\t&#8211;user\t\t\tDatabase user name; defaults to the current linux user&#8221;<br />
echo &#8220;\t-d\t&#8211;database\t\tDatabase name; defaults to the database user name&#8221;<br />
echo &#8220;\t-p\t&#8211;password\t\tDatabase password; if none is specified you will be prompted to enter one&#8221;<br />
echo &#8220;\t-R\t&#8211;remote&#8211;destination\tThe directory on the remote host to upload the DB backup to; defaults to ~/$BACKUP_DIR&#8221;<br />
echo &#8220;\t-L\t&#8211;local&#8211;destination\tThe directory on local host to save the DB backup; defaults to $HOME/$BACKUP_DIR&#8221;<br />
}</p>
<p>while [ "$1" != "" ]; do<br />
	case $1 in<br />
		-h | &#8211;help ) 		usage<br />
					exit<br />
					;;<br />
		-u | &#8211;user ) 		shift<br />
					USER=$1<br />
					;;<br />
		-d | &#8211;database ) 	shift<br />
					DB=$1<br />
					;;<br />
		-p | &#8211;password ) 	shift<br />
					PASS=$1<br />
					;;<br />
		-r | &#8211;remote ) 	shift<br />
					REMOTE=$1<br />
					;;<br />
		-R | &#8211;remote-destination ) shift<br />
					REMOTE_DIR=$1<br />
					;;<br />
		-L | &#8211;local-destination ) shift<br />
					LOCAL_DIR=$1<br />
					;;<br />
	esac<br />
	shift<br />
done<br />
if [ "$REMOTE" = "" ]; then<br />
	usage<br />
	exit<br />
fi</p>
<p>LOCAL_DIR=${LOCAL_DIR:=&#8221;$HOME/$BACKUP_DIR&#8221;}<br />
REMOTE_DIR=${REMOTE_DIR:=&#8221;~/$BACKUP_DIR&#8221;}<br />
USER=${USER:=`whoami`}<br />
DB=${DB:=$USER}<br />
DEST=&#8221;$LOCAL_DIR/$DB.$DATE.bz2&#8243;</p>
<p>mkdir -p $LOCAL_DIR 2>/dev/null<br />
if [ "$PASS" ]; then<br />
	`$DUMP -u$USER -p$PASS $DB | bzip2 > $DEST`<br />
else<br />
	`$DUMP -u $USER -p $DB | bzip2 > $DEST`<br />
fi<br />
scp $DEST $REMOTE:$REMOTE_DIR</p>
<p>	[/cci]
</p></div>
<p>   	<br/>
   </li>
<li>
        Make the file executable:<br/><br />
[cci lang="bash"]<br />
chmod 755 mysql-backup.sh<br />
[/cci]<br />
        <br/>
   </li>
<li>
	If you don&#8217;t have one already, create an ssh key pair for the account that will be running the cron (&#8216;root&#8217; in mycase).  I set the key type to RSA / 2048 bits.  When prompted for a password by the keygen creator, leave it blank.<br/><br />
[cci lang="bash"]<br />
ssh-keygen -t rsa -b 2048<br />
[/cci]<br />
   	<br/>
   </li>
<li>
	Now take the id_rsa.pub key that was created in the previous step ( by default, it is placed in ~/.ssh/ ) and put it on the remote machine that we want to copy the backups to.  It will need to be placed in a specific file called &#8220;authorized_keys&#8221; in the &#8216;.ssh&#8217; directory of the user you will be ssh-ing in as.  Thus, if you are ssh-ing into the remote machine as &#8220;jsmith&#8221;, put the key in a file called &#8220;authorized_keys&#8221; in /home/jsmith/.ssh/.  The key should be placed into &#8216;authorized_keys&#8217; as one line.  Make sure to also enable passwordless ssh on the remote box, else the script won&#8217;t automatically be able to scp the file over.<br/><br />
	You can test this users ability to ssh into the remote machine without being prompted by a password using simple ssh test:<br/><br />
[cci lang="bash"]<br />
ssh jsmith@[remoteserver.com]<br />
[/cci]<br/><br />
Only continue to the next step when you get password-less ssh working!<br />
<br/>
   </li>
<li>
        Next, create a cronjob to execute the script periodically.  As root, you can use the &#8220;crontab -e&#8221; command to edit/create a crontab account.  I&#8217;ve chosen every hour, on the 15th minute:<br/><br />
[cci lang="bash"]<br />
15 */1 * * * sh /root/mysql-backup.sh -r [username]@[offsite.com] -u [dbusr] -p [dbpass] -d [dbname] -R [remote server path]<br />
[/cci]<br />
   	<br/>
   </li>
<li>
        You may want to confirm that your server time is correct, as the backup file names will be date stamped with their time of creation.   Also confirm that the backup files made it into the local and remote machine directories.  And ofcourse, test the integrity of the created backup files by untaring/ un-bzipping them and restoreing them in a scratch database.<br />
   	<br/>
   </li>
</ol>
<p><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://sandeepghael.com/2009/08/backup-script-for-mysql-onsite-and-offsite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Backup script for PostgreSQL (onsite and offsite)</title>
		<link>http://sandeepghael.com/2009/08/backup-script-for-postgresql-onsite-and-offsite/</link>
		<comments>http://sandeepghael.com/2009/08/backup-script-for-postgresql-onsite-and-offsite/#comments</comments>
		<pubDate>Fri, 14 Aug 2009 21:14:48 +0000</pubDate>
		<dc:creator>sghael</dc:creator>
				<category><![CDATA[Databases]]></category>

		<guid isPermaLink="false">http://sandeepghael.com/?p=79</guid>
		<description><![CDATA[Somethings never change. Needing to backup data is one of those things. Since webapps are constantly in development, and new features often means changes to the database schema, I find it super useful (and comforting) to do hourly backups of my applications database. If I make some boneheaed mistake, at most I&#8217;ll only lose 1 [...]]]></description>
			<content:encoded><![CDATA[<p>Somethings never change.  Needing to backup data is one of those things.  Since webapps are constantly in development, and new features often means changes to the database schema, I find it super useful (and comforting) to do hourly backups of my applications database.  If I make some boneheaed mistake, at most I&#8217;ll only lose 1 hour of work.  And because I&#8217;m super paranoid, I put the output of the backup in two locations&#8230; the local server and a physically remote server (incase of massive datacenter failure at one location).  </p>
<p>To save disk space, this script will automatically bzip the sql dump file.  Your mileage will vary depending on how big your database is, but on a small webapp I can usually run this thing hourly, 24/7 and only use 1% of the available drive space after a year.  Point being that you can backup as often as your disk space allocation will allow&#8230; and usually it will allow for more than you can imagine.  One thing to note is that this script may not be the best strategy for high-volume sites, since it assumes you will lock the database while doing the dump.</p>
<p>Below are the setup instructions.</p>
<ol>
<li>
        Copy the contents below into a file named pg-backup.sh placed in the root account home (on Ubuntu it&#8217;s &#8216;/root&#8217;).  For simplicity, I&#8217;m using the root account, but on your production servers, you may want to create a dedicated &#8220;backupuser&#8221; account that executes these actions.<br />
        <br/></p>
<div style="background-color: #F1F1F1;">
        [cci lang="bash"]</p>
<p>#!/bin/sh</p>
<p>DATE=`date &#8220;+%Y-%m-%d-%H-%M-%S&#8221;`<br />
BACKUP_DIR=&#8221;pgbackups&#8221;</p>
<p>#DO NOT CHANGE ANYTHING BELOW THIS LINE<br />
DUMP=&#8221;pg_dump&#8221;<br />
REMOTE=&#8221;"</p>
<p>usage() {<br />
echo Usage:<br />
echo &#8220;\t$0 [options]&#8221;<br />
echo<br />
echo &#8220;Where options is as follows:&#8221;<br />
echo &#8220;\t-r\t&#8211;remote\t\tThe remote host to copy the DB backup to (mandatory)&#8221;<br />
echo &#8220;\t-u\t&#8211;user\t\t\tDatabase user name; defaults to the current linux user&#8221;<br />
echo &#8220;\t-d\t&#8211;database\t\tDatabase name; defaults to the database user name&#8221;<br />
echo &#8220;\t-p\t&#8211;password\t\tDatabase password; if none is specified you will be prompted to enter one&#8221;<br />
echo &#8220;\t-R\t&#8211;remote&#8211;destination\tThe directory on the remote host to upload the DB backup to; defaults to ~/$BACKUP_DIR&#8221;<br />
echo &#8220;\t-L\t&#8211;local&#8211;destination\tThe directory on local host to save the DB backup; defaults to $HOME/$BACKUP_DIR&#8221;<br />
}</p>
<p>while [ "$1" != "" ]; do<br />
	case $1 in<br />
		-h | &#8211;help ) 		usage<br />
					exit<br />
					;;<br />
		-u | &#8211;user ) 		shift<br />
					USER=$1<br />
					;;<br />
		-d | &#8211;database ) 	shift<br />
					DB=$1<br />
					;;<br />
		-p | &#8211;password ) 	shift<br />
					export PGPASSWORD=$1<br />
					;;<br />
		-r | &#8211;remote ) 	shift<br />
					REMOTE=$1<br />
					;;<br />
		-R | &#8211;remote-destination ) shift<br />
					REMOTE_DIR=$1<br />
					;;<br />
		-L | &#8211;local-destination ) shift<br />
					LOCAL_DIR=$1<br />
					;;<br />
	esac<br />
	shift<br />
done<br />
if [ "$REMOTE" = "" ]; then<br />
	usage<br />
	exit<br />
fi</p>
<p>LOCAL_DIR=${LOCAL_DIR:=&#8221;$HOME/$BACKUP_DIR&#8221;}<br />
REMOTE_DIR=${REMOTE_DIR:=&#8221;~/$BACKUP_DIR&#8221;}<br />
USER=${USER:=`whoami`}<br />
DB=${DB:=$USER}<br />
DEST=&#8221;$LOCAL_DIR/$DB.$DATE.bz2&#8243;</p>
<p>mkdir -p $LOCAL_DIR 2>/dev/null<br />
`$DUMP -U $USER $DB | bzip2 > $DEST`<br />
ssh $REMOTE mkdir -p $REMOTE_DIR 2>/dev/null<br />
scp $DEST $REMOTE:$REMOTE_DIR</p>
<p>	[/cci]
</p></div>
<p>   	<br/>
   </li>
<li>
        Make the file executable:<br/><br />
[cci lang="bash"]<br />
chmod 755 pg-backup.sh<br />
[/cci]<br />
        <br/>
   </li>
<li>
	If you don&#8217;t have one already, create an ssh key pair for the account that will be running the cron (&#8216;root&#8217; in mycase).  I set the key type to RSA / 2048 bits.  When prompted for a password by the keygen creator, leave it blank.<br/><br />
[cci lang="bash"]<br />
ssh-keygen -t rsa -b 2048<br />
[/cci]<br />
   	<br/>
   </li>
<li>
	Now take the id_rsa.pub key that was created in the previous step ( by default, it is placed in ~/.ssh/ ) and put it on the remote machine that we want to copy the backups to.  It will need to be placed in a specific file called &#8220;authorized_keys&#8221; in the &#8216;.ssh&#8217; directory of the user you will be ssh-ing in as.  Thus, if you are ssh-ing into the remote machine as &#8220;jsmith&#8221;, put the key in a file called &#8220;authorized_keys&#8221; in /home/jsmith/.ssh/.  The key should be placed into &#8216;authorized_keys&#8217; as one line.  Make sure to also enable passwordless ssh on the remote box, else the script won&#8217;t automatically be able to scp the file over.<br/><br />
	You can test this users ability to ssh into the remote machine without being prompted by a password using simple ssh test:<br/><br />
[cci lang="bash"]<br />
ssh jsmith@[remoteserver.com]<br />
[/cci]<br/><br />
Only continue to the next step when you get password-less ssh working!<br />
<br/>
   </li>
<li>
        Next, create a cronjob to execute the script periodically.  As root, you can use the &#8220;crontab -e&#8221; command to edit/create a crontab account.  I&#8217;ve chosen every hour, on the 15th minute:<br/><br />
[cci lang="bash"]<br />
15 */1 * * * sh /root/pg-backup.sh -r [username]@[offsite.com] -u [dbusr] -p [dbpass] -d [dbname] -R [remote server path]<br />
[/cci]<br />
   	<br/>
   </li>
<li>
        You may want to confirm that your server time is correct, as the backup file names will be date stamped with their time of creation.   Also confirm that the backup files made it into the local and remote machine directories.  And ofcourse, test the integrity of the created backup files by untaring/ un-bzipping them and restoreing them in a scratch database.<br />
   	<br/>
   </li>
</ol>
<p>Hope this was helpful!  I&#8217;ll be back next week with a similar script solution for MySQL users.<br />
<br/></p>
]]></content:encoded>
			<wfw:commentRss>http://sandeepghael.com/2009/08/backup-script-for-postgresql-onsite-and-offsite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

