<?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>CB1, INC. &#187; mysql</title>
	<atom:link href="http://www.cb1inc.com/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cb1inc.com</link>
	<description></description>
	<lastBuildDate>Wed, 28 Sep 2011 17:54:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Intro to PECL/mysqlnd_ms Presentation Slides</title>
		<link>http://www.cb1inc.com/2011/04/12/intro-to-peclmysqlnd_ms-presentation-slides/</link>
		<comments>http://www.cb1inc.com/2011/04/12/intro-to-peclmysqlnd_ms-presentation-slides/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 10:43:03 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[presentations]]></category>

		<guid isPermaLink="false">http://www.cb1inc.com/?p=1585</guid>
		<description><![CDATA[Last week I presented on the super cool PECL/mysqlnd_ms PHP extension at the Minnesota PHP User Group. In short, mysqlmd_ms will provide some transparency for PHP web applications to interact with master and slave MySQL database setups. Here&#8217;s my slide deck: Intro to PECL/mysqlnd_ms (4/7/2011) There&#8217;s a couple things mysqlnd_ms needs to support before I [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I presented on the super cool <a href="http://svn.php.net/viewvc/pecl/mysqlnd_ms/">PECL/mysqlnd_ms</a> PHP extension at the <a href="http://www.mnphp.org/">Minnesota PHP User Group</a>. In short, mysqlmd_ms will provide some transparency for PHP web applications to interact with master and slave MySQL database setups.</p>
<p>Here&#8217;s my slide deck:</p>
<div style="margin:0 auto;width:425px" id="__ss_7557068"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/cb1kenobi/intro-to-peclmysqlndms-472011" title="Intro to PECL/mysqlnd_ms (4/7/2011)">Intro to PECL/mysqlnd_ms (4/7/2011)</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/7557068" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></div>
<p>There&#8217;s a couple things mysqlnd_ms needs to support before I can use it such as support for single master (i.e. local dev) environments and detection of &#8220;dead&#8221; MySQL servers so traffic isn&#8217;t passed to them over and over again.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2011/04/12/intro-to-peclmysqlnd_ms-presentation-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CB1 Ubuntu 10.10 Linux Development Setup</title>
		<link>http://www.cb1inc.com/2010/10/16/cb1-ubuntu-10-10-linux-development-setup/</link>
		<comments>http://www.cb1inc.com/2010/10/16/cb1-ubuntu-10-10-linux-development-setup/#comments</comments>
		<pubDate>Sun, 17 Oct 2010 02:36:52 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.cb1inc.com/?p=1375</guid>
		<description><![CDATA[I use a MacBook Pro for my day-to-day operations here at CB1, INC. I&#8217;m a huge believer that a development environment should mimic the production environment, so I find myself running a couple virtual machines in VMware Fusion. The following guide is a reference for myself as well as possibly a helpful resource for setting [...]]]></description>
			<content:encoded><![CDATA[<p>I use a MacBook Pro for my day-to-day operations here at CB1, INC.  I&#8217;m a huge believer that a development environment should mimic the production environment, so I find myself running a couple virtual machines in VMware Fusion.</p>
<p>The following guide is a reference for myself as well as possibly a helpful resource for setting up your own Linux development environment. Here&#8217;s an checklist of the tasks to perform and software to install:</p>
<ul>
<li>Operating System
<ul>
<li><a href="http://www.ubuntu.com/" target="_blank">Ubuntu 10.10 64-bit</a>: I use Ubuntu Desktop in dev and Ubuntu Server in production</li>
<li>Package updates and upgrades</li>
<li>Network configuration (at least 2 static IP addresses)</li>
</ul>
</li>
<li>Development Tools
<ul>
<li>C/C++ development environment</li>
<li>Autotools</li>
<li>Sun Java JDK</li>
<li><a href="http://valgrind.org/" target="_blank">Valgrind</a></li>
<li>Version control: <a href="http://subversion.tigris.org/" target="_blank">Subversion</a>, <a href="http://bazaar.canonical.com/en/" target="_blank">Bazaar</a>, <a href="http://git-scm.com/" target="_blank">git</a></li>
<li><a href="http://developer.android.com/">Android SDK</a></li>
</ul>
</li>
<li>Servers
<ul>
<li><a href="http://www.samba.org/" target="_blank">Samba</a> (file sharing)</li>
<li>SSH (remote shell access)</li>
<li><a href="http://httpd.apache.org/" target="_blank">Apache 2.2</a> (web server)</li>
<li><a href="http://nginx.org/" target="_blank">nginx 0.8</a> (web server)</li>
<li><a href="http://www.php.net/" target="_blank">PHP 5.3.3</a> (application server)</li>
<li><a href="http://php-fpm.org/" target="_blank">PHP-FPM</a> (PHP&#8217;s FastCGI process manager)</li>
<li><a href="http://www.mysql.com/" target="_blank">MySQL 5.1</a> (database server)</li>
<li><a href="http://www.postgresql.org/" target="_blank">PostgreSQL</a> (database server)</li>
<li><a href="http://memcached.org/" target="_blank">memcached 1.4.5</a> (caching layer)</li>
<li><a href="http://gearman.org/" target="_blank">Gearman</a> (job queue manager)</li>
</ul>
</li>
<li>PHP Extensions
<ul>
<li><a href="http://pecl.php.net/package/memcached" target="_blank">memcached</a></li>
<li><a href="http://xdebug.org/" target="_blank">Xdebug</a></li>
<li><a href="http://pecl.php.net/package/gearman" target="_blank">Gearman</a></li>
<li><a href="http://pecl.php.net/package/APC" target="_blank">APC</a></li>
</ul>
</li>
<li>Desktop Applications
<ul>
<li><a href="http://www.google.com/chrome">Google Chrome</a></li>
<li>KCachegrind</li>
<li><a href="http://www.appcelerator.com/products">Appcelerator Titanium</a></li>
</ul>
</li>
</ul>
<h3>Operating System</h3>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/ubuntu.png"/></p>
<p>Start by installing Ubuntu 10.10 Desktop (or server). I&#8217;m not going to cover installing Ubuntu since there are already several other resources out there. Once Ubuntu is installed, open a <strong>Terminal</strong>:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo passwd root</span>
[sudo] password for user: &lt;type your password&gt;
Enter new UNIX password: &lt;type new root password&gt;
Retype new UNIX password: &lt;type new root password again&gt;
passwd: password updated successfully

user@ubuntu:~# <span class="cmd">sudo apt-get update</span>
user@ubuntu:~# <span class="cmd">sudo apt-get upgrade</span>

user@ubuntu:~# <span class="cmd">mkdir ~/src</span>
</pre>
<h3>New File Permissions</h3>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo pico /etc/profile</span>
</pre>
<p>Change 022 to 002. This setting controls the default permissions when a new file or directory is created.  This is mostly useful when managing files over Samba.</p>
<h3>Network IP Addresses</h3>
<p>Optionally, you may want to assign a static IP address. I set up one IP address for Apache and another for nginx.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo pico /etc/network/interfaces</span>
</pre>
<p>The following is a reference for adding two static IPs.  Change the IPs to meet your needs.</p>
<pre class="brush: plain; title: ;">
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
	address 192.168.1.200
	netmask 255.255.255.0
	gateway 192.168.1.1

auto eth0:1
iface eth0:1 inet static
	address 192.168.1.201
	netmask 255.255.255.0
</pre>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo /etc/init.d/networking restart</span>
</pre>
<h3>Packages</h3>
<p>Here&#8217;s a bunch of packages that will set up compilers, version control, Java, MySQL, Apache, PHP, Memcache, Gearman, Samba, and more.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo apt-get install build-essential autotools-dev autoconf \
 autoconf2.13 openssh-server ethtool traceroute openjdk-6-jdk \
 mysql-server-5.1 bzr subversion subversion-tools ntp ntpdate \
 libpcre3-dev libevent-dev automake bison libtool scons  g++ \
 ncurses-dev libreadline-dev libz-dev libssl-dev  libcurl4-openssl-dev \
 ruby rubygems libzip-ruby1.8 libzip-ruby1.9.1 python-dev ruby-dev \
 libdbus-glib-1-dev uuid-dev libpam0g libpam0g-dev gperf samba valgrind \
 libxml2-dev libfreetype6-dev curl libcurl4-openssl-dev \
 libjpeg62-dev libpng12-dev sqlite3 libsqlite3-dev git-core \
 postgresql postgis gearman libgearman-dev php5 \
 libapache2-mod-php5 php5-dev memcached php5-memcached \
 php5-curl php5-gd php5-mysql php5-pgsql php-apc \
 php5-xdebug php5-fpm libapache2-mod-fastcgi</span>
</pre>
<h3>MySQL</h3>
<p>During the package install above, MySQL will prompt you for the root password.</p>
<p>After the packages are installed, we need to allow remote MySQL connections.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo pico /etc/mysql/my.cnf</span>
</pre>
<p>Comment out the <em>bind-address</em> line.</p>
<pre class="brush: plain; title: ;">
# bind-address          = 127.0.0.1
</pre>
<h3>SSH</h3>
<p>Next, you may optionally increase the connection keep alive interval for remote ssh connections. Timeouts aren&#8217;t really an issue for SSH&#8217;ing into a local VM, but really helps for remote installs.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo echo &quot;ClientAliveInterval 60&quot; &gt;&gt; /etc/ssh/sshd_config</span>
</pre>
<h3>Samba</h3>
<p>Samba allows me to drag and drop files between my Mac and Linux VM. I personally do <strong>not</strong> enable/install Samba on production servers.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.orig</span>
user@ubuntu:~# <span class="cmd">sudo pico /etc/samba/smb.conf</span>
</pre>
<p>You can add a share such as the following:</p>
<pre class="brush: plain; title: ;">
[ubuntu]
        force user = &lt;your username&gt;
        writeable = yes
        create mode = 644
        path = /home/&lt;your username&gt;
        directory mode = 755
        force group = &lt;your username&gt;
</pre>
<p>Then create yourself a Samba user:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo smbpasswd -a &lt;your username&gt;</span>
</pre>
<h4>Apache 2</h4>
<p>Apache is mostly configured out of the box, but I like to enable rewrite and SSL so I can test production features.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo a2enmod rewrite</span>
user@ubuntu:~# <span class="cmd">sudo a2enmod ssl</span>
</pre>
<p>Since I&#8217;m going to run Apache and nginx, I&#8217;m going bind Apache to <em>eth0</em>.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo pico /etc/apache2/ports.conf</span>
</pre>
<pre class="brush: plain; title: ;">
NameVirtualHost 192.168.1.200:80
Listen 192.168.1.200:80

&lt;IfModule mod_ssl.c&gt;
    Listen 192.168.1.200:443
&lt;/IfModule&gt;
</pre>
<p>Now we need to add <em>eth0</em>&#8216;s IP to the default host:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo pico /etc/apache2/sites-enabled/000-default</span>
</pre>
<pre class="brush: plain; title: ;">
&lt;VirtualHost 192.168.1.200:80&gt;
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www
        &lt;Directory /&gt;
                Options FollowSymLinks
                AllowOverride None
        &lt;/Directory&gt;
        &lt;Directory /var/www/&gt;
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        &lt;/Directory&gt;

        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined
&lt;/VirtualHost&gt;
</pre>
<p>Restart Apache for the changes to take effect.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo apache2ctl restart</span>
</pre>
<h3>Gearman</h3>
<p>By default, Gearman uses memory to store pending jobs in the queue, but I prefer to use MySQL for persistent storage.  To do this, first create the queue database and table:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">mysqladmin -uroot -p123123 create gearman</span>
user@ubuntu:~# <span class="cmd">mysql -uroot -p123123 -e "CREATE TABLE gearman.gearman_queue (
  unique_key VARCHAR(64) NOT NULL,
  function_name VARCHAR(255) NULL,
  priority INT NULL,
  data LONGBLOB NULL,
  PRIMARY KEY (unique_key)
) ENGINE = InnoDB;"</span>
</pre>
<p>Next update the init script to tell Gearman to use the database:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo mv /etc/default/gearman-job-server /etc/default/gearman-job-server.bak</span>
user@ubuntu:~# <span class="cmd">sudo echo &quot;PARAMS=\&quot;-q libdrizzle --libdrizzle-host=127.0.0.1&quot; \
   &quot;--libdrizzle-user=root --libdrizzle-password=123123 --libdrizzle-db=gearman&quot; \
   &quot;--libdrizzle-table=gearman_queue --libdrizzle-mysql\&quot;&quot; &gt; /etc/default/gearman-job-server</span>
user@ubuntu:~# <span class="cmd">sudo /etc/init.d/gearman-job-server restart</span>
</pre>
<h3>Gearman PHP Extension</h3>
<p>We need to download and install the Gearman PHP extension if we want to write PHP workers or post jobs to the queue.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">cd ~/src</span>
user@ubuntu:~/src# <span class="cmd">wget http://pecl.php.net/get/gearman-0.7.0.tgz</span>
user@ubuntu:~/src# <span class="cmd">tar xzf gearman-0.7.0.tgz</span>
user@ubuntu:~/src# <span class="cmd">rm gearman-0.7.0.tgz package.xml</span>
user@ubuntu:~/src# <span class="cmd">cd gearman-0.7.0</span>
user@ubuntu:~/src# <span class="cmd">phpize</span>
user@ubuntu:~/src# <span class="cmd">./configure</span>
user@ubuntu:~/src# <span class="cmd">make</span>
user@ubuntu:~/src# <span class="cmd">sudo make install</span>
</pre>
<p>Next, add the config file to load the Gearman PHP extension:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo echo &quot;extension=gearman.so&quot; &gt;&gt; /etc/php5/conf.d/gearman.ini</span>
</pre>
<h3>memcached PHP Extension</h3>
<p>Since we have memcached and the memcached PHP extension install, let&#8217;s use it for storing session data:</p>
<pre class="terminal">
user@ubuntu:~/src# <span class="cmd">sudo echo &quot;session.save_handler = memcached
session.save_path = \&quot;127.0.0.1:11211\&quot;&quot; &gt;&gt; /etc/php5/conf.d/memcached.ini</span>
</pre>
<h3>nginx</h3>
<p>nginx is web server that is really fast.  I use nginx as my primary development web server unless I&#8217;m running a web app that only works with Apache. You can choose to install nginx from package, but I like to live life on the bleeding edge, so I&#8217;ll be building nginx from source. To install nginx, we need to download the source, compile it, install it, and configure it.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">cd ~/src</span>
user@ubuntu:~/src# <span class="cmd">wget http://nginx.org/download/nginx-0.8.52.tar.gz</span>
user@ubuntu:~/src# <span class="cmd">tar xzf nginx-0.8.52.tar.gz</span>
user@ubuntu:~/src# <span class="cmd">rm nginx-0.8.52.tar.gz</span>
user@ubuntu:~/src# <span class="cmd">cd nginx-0.8.52</span>
user@ubuntu:~/src# <span class="cmd">mkdir /var/lib/nginx</span>
user@ubuntu:~/src# <span class="cmd">./configure \
    --sbin-path=/usr/sbin \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/lock/nginx.lock \
    --http-log-path=/var/log/nginx/access.log \
    --http-client-body-temp-path=/var/lib/nginx/body \
    --http-proxy-temp-path=/var/lib/nginx/proxy \
    --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
    --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
    --http-scgi-temp-path=/var/lib/nginx/scgi \
    --with-http_stub_status_module</span>
user@ubuntu:~/src# <span class="cmd">make</span>
user@ubuntu:~/src# <span class="cmd">sudo make install</span>

user@ubuntu:~# <span class="cmd">sudo pico /etc/init.d/nginx</span>
</pre>
<p>Here&#8217;s the init script that will start nginx for us:</p>
<pre class="brush: bash; title: ;">
#! /bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/nginx
NAME=nginx
DESC=nginx
test -x $DAEMON || exit 0
case &quot;$1&quot; in
  start)
        echo -n &quot;Starting $DESC: &quot;
        start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
        echo &quot;$NAME.&quot;
        ;;
  stop)
        echo -n &quot;Stopping $DESC: &quot;
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON
        echo &quot;$NAME.&quot;
        ;;
  restart|force-reload)
        echo -n &quot;Restarting $DESC: &quot;
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON
        sleep 1
        start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
        echo &quot;$NAME.&quot;
        ;;
  reload)
        echo -n &quot;Reloading $DESC configuration: &quot;
        start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid --exec $DAEMON
        echo &quot;$NAME.&quot;
        ;;
  *)
        echo &quot;Usage: /etc/init.d/$NAME {start|stop|restart|reload|force-reload}&quot; &gt;&amp;2
        exit 1
        ;;
esac
exit 0
</pre>
<p>Now we need to make the init script executable and enable it:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo chmod +x /etc/init.d/nginx</span>
user@ubuntu:~# <span class="cmd">sudo update-rc.d nginx defaults</span>

user@ubuntu:~# <span class="cmd">sudo pico /etc/nginx/nginx.conf</span>
</pre>
<p>Here&#8217;s a starter nginx.conf with some basic settings:</p>
<pre class="brush: plain; title: ;">
user  www-data www-data;
worker_processes  2;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile                on;
    tcp_nodelay             on;
    tcp_nopush              on;
    keepalive_timeout       65;
    server_name_in_redirect off;
    server_tokens           off;

    add_header Strict-Transport-Security max-age=1800;
    add_header X-Frame-Options deny;

    gzip            on;
    gzip_buffers    16 8k;
    gzip_comp_level 9;
    gzip_types      text/plain text/xml application/x-javascript text/css;

    include /etc/nginx/sites/*;
}
</pre>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo mkdir /etc/nginx/sites</span>
user@ubuntu:~# <span class="cmd">sudo pico /etc/nginx/sites/default</span>
</pre>
<p>Now we need to set up a default host that supports PHP (via <a href="http://php-fpm.org/" target="_blank">PHP-FPM, PHP&#8217;s FastCGI Process Manager</a>) and we want the default host to use the <em>eth0:1</em> IP address:</p>
<pre class="brush: plain; title: ;">
server {
    listen       192.168.1.201:80 default;
    server_name  _;
    root   /var/www;
    index  index.php;
    location / {
        if (!-e $request_filename) {
            rewrite ^/(.*)$ /index.php?q=$1 last;
            break;
        }
    }
    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www$fastcgi_script_name;
        include        fastcgi_params;
    }
    location ~* (\.(htaccess|engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)|code-style\.pl|Entries.*|Repository|Root|Tag|Template)$ {
        deny all;
    }
}
</pre>
<p>After the config files are good to go, start nginx:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo /etc/init.d/nginx start</span>
</pre>
<h3>Service Names</h3>
<p>I also like to add service names so I can see what ports are in use when I run <em>netstat</em>. I added drizzle and Cassandra for fun despite this post not including them.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo cp /etc/services /etc/services.bak</span>
user@ubuntu:~# <span class="cmd">su</span>
root@ubuntu:~# <span class="cmd">echo &quot;drizzle     4427/tcp
drizzle     4427/udp
memcached   11211/tcp
memcached   11211/udp
gearmand    4730/tcp
gearmand    4730/udp
fastcgi     9000/tcp
cassandra   9160/tcp&quot; &gt;&gt; /etc/services</span>
root@ubuntu:~# <span class="cmd">exit</span>
</pre>
<h3>Android SDK</h3>
<p>The Android SDK is unfortunately not in package, so you&#8217;ll need to download it from the Android Developer site: <a href="http://developer.android.com/sdk/index.html">http://developer.android.com/sdk/index.html</a>.</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">wget http://dl.google.com/android/android-sdk_r07-linux_x86.tgz</span>
user@ubuntu:~# <span class="cmd">tar xzf android-sdk_r07-linux_x86.tgz</span>
user@ubuntu:~# <span class="cmd">rm android-sdk_r07-linux_x86.tgz</span>
user@ubuntu:~# <span class="cmd">sudo mv android-sdk-linux_x86 /usr/local</span>
user@ubuntu:~# <span class="cmd">sudo find /usr/local/android-sdk-linux_x86 -type d -exec chmod 777 {} \;</span>
</pre>
<p>You&#8217;ll need to add the Android SDK path near the top of your <code>~/.bash_profile</code> <em>or</em> <code>~/.bashrc</code>:</p>
<pre class="brush: plain; title: ;">
export PATH=${PATH}:/usr/local/android-sdk-linux_x86/tools
</pre>
<p>To manage your Android SDK packages and virtual devices, you&#8217;ll need to run the <em>android</em> app:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">android</span>
</pre>
<p>First go to <em>Available Packages</em> and download version <strong>1.6</strong> <em>and</em> <strong>2.2</strong> Android SDK packages.  You can also choose to download the documentation, samples, and Google APIs.</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/android4.jpg"/></p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/android5.jpg"/></p>
<p>Downloading the package may take several minutes. You don&#8217;t have to create a virtual device right now if you are planning on installing Appcelerator&#8217;s Titanium platform.  You can exit the Android app when you&#8217;re done.</p>
<h3>Desktop Apps</h3>
<p>If you&#8217;re running Ubuntu Desktop, there are a couple handy apps I install.  The first is Google Chrome and can be directly downloaded from the <a href="http://www.google.com/chrome/eula.html">Google Chrome download page</a>.</p>
<p>I find <em>KCachegrind</em> and <em>GHex</em> to be useful:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo apt-get install kcachegrind ghex</span>
</pre>
<h3>Appcelerator Titanium</h3>
<p>Titanium is an awesome platform for developing desktop applications for Linux, Mac OS X, and Windows as well as mobile apps for iPhone and Android. We use Titanium Developer to create Titanium projects. Begin by downloading the 64-bit version of Titanium:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">wget -O titanium.tgz http://www.appcelerator.com/download-linux64</span>
</pre>
<p>There&#8217;s also a 32-bit version available at <code>http://www.appcelerator.com/download-linux32</code>.</p>
<p>Next we unpack Titanium Developer and move it to a safe place:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">tar xzf titanium.tgz</span>
user@ubuntu:~# <span class="cmd">rm titanium.tgz</span>
</pre>
<p>Next you need to run the installer by double-clicking the <em>Titanium Developer</em> executable. Run the executable and then click the <em>Install</em> button. You can try installing to <code>/opt/titanium</code>, but you might need root privileges.</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/titanium1.jpg"/></p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/titanium2.jpg"/></p>
<p>Next, there are a few issues with outdated libraries, so we simply delete them:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">rm ~/.titanium/runtime/linux/1.0.0/libgobject-2.0.*</span>
user@ubuntu:~# <span class="cmd">rm ~/.titanium/runtime/linux/1.0.0/libglib-2.0.*</span>
user@ubuntu:~# <span class="cmd">rm ~/.titanium/runtime/linux/1.0.0/libgio-2.0.*</span>
user@ubuntu:~# <span class="cmd">rm ~/.titanium/runtime/linux/1.0.0/libgthread-2.0.*</span>
</pre>
<p>Titanium Developer also complains if <em>/bin/java</em> doesn&#8217;t exist, so create a quick link:</p>
<pre class="terminal">
user@ubuntu:~# <span class="cmd">sudo ln -s /usr/bin/java /bin/java</span>
</pre>
<p>Relaunch Titanium Developer and enter your login credentials.  If you don&#8217;t have a login, you can get a free account.</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/titanium3.jpg"/></p>
<p>After signing in, you may notice there are some updates available in the upper right corner of the window. Click in the box and the updates will be downloaded and installed.</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/titanium4.jpg"/></p>
<p>Optionally you can create a launcher icon for your GNOME panel. Don&#8217;t forget to escape spaces in the command with a backslash!</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/titanium5.jpg"/></p>
<h3>Finishing Touches</h3>
<p>Lastly, I like to re-arrange my desktop to maximize my coding real estate.</p>
<p><img class="aligncenter" src="http://cb1inc.com/wp-content/uploads/2010/10/ubuntu_10-10.jpg"/></p>
<h3>Conclusion</h3>
<p>That should get you up and running with a neato dev environment.  If you need to run SSL, I wrote a post on <a href="http://www.cb1inc.com/2007/05/13/creating-self-signed-certs-on-apache-2-2/">Creating Self-Signed Certs on Apache 2.2</a> and <a href="http://www.cb1inc.com/2008/09/11/virtual-hosts-and-wildcard-ssl-certificates-with-apache-2-2/">Virtual Hosts and Wildcard SSL Certificates with Apache 2.2</a>.</p>
<p>If you find any typos or additions, please feel free to sound off in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2010/10/16/cb1-ubuntu-10-10-linux-development-setup/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>High Availability with DRBD and Heartbeat Presentation</title>
		<link>http://www.cb1inc.com/2008/06/10/high-availability-with-drbd-and-heartbeat-presentation/</link>
		<comments>http://www.cb1inc.com/2008/06/10/high-availability-with-drbd-and-heartbeat-presentation/#comments</comments>
		<pubDate>Tue, 10 Jun 2008 16:51:55 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[drbd]]></category>
		<category><![CDATA[heartbeat]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Here's my presentation I gave June 9, 2008, at the <a href="http://mysql.meetup.com/92/">Twin Cities MySQL and PHP User Group</a> about my highly available cluster using <a href="http://www.drbd.org">DRBD</a> and <a href="http://www.linux-ha.org/Heartbeat">Heartbeat</a>.

<div style="width:425px;text-align:left" id="__ss_458973"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-availability-with-drbd-heartbeat-1213116273279688-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-availability-with-drbd-heartbeat-1213116273279688-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>

I added a few slides and cleaned things up a bit.  The presentation went well and we had a lot of good questions.

The MySQL and PHP User Group will be taking some time off over the summer.  There will be another meetup mid-summer to come up with some ideas for future meetings.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my presentation I gave June 9, 2008, at the <a href="http://mysql.meetup.com/92/">Twin Cities MySQL and PHP User Group</a> about my highly available cluster using <a href="http://www.drbd.org">DRBD</a> and <a href="http://www.linux-ha.org/Heartbeat">Heartbeat</a>.</p>
<div style="margin:0 auto;width:425px;"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-availability-with-drbd-heartbeat-1213116273279688-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-availability-with-drbd-heartbeat-1213116273279688-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>I added a few slides and cleaned things up a bit.  The presentation went well and we had a lot of good questions.</p>
<p>The MySQL and PHP User Group will be taking some time off over the summer.  There will be another meetup mid-summer to come up with some ideas for future meetings.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/06/10/high-availability-with-drbd-and-heartbeat-presentation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>2008 MySQL Conference Recap Presentation</title>
		<link>http://www.cb1inc.com/2008/05/13/2008-mysql-conference-recap-presentation/</link>
		<comments>http://www.cb1inc.com/2008/05/13/2008-mysql-conference-recap-presentation/#comments</comments>
		<pubDate>Tue, 13 May 2008 21:17:39 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Here's my presentation I gave May 12, 2008, at the <a href="http://mysql.meetup.com/92/">Twin Cities MySQL and PHP User Group</a> about my experience at the <a href="http://www.mysqlconf.com">2008 MySQL Conference and Expo</a>.

<div style="width:425px;text-align:left" id="__ss_402936"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mysql-conference-2008-edition-1210700836718054-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=mysql-conference-2008-edition-1210700836718054-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>

Thanks to all of those that came.  I had a great time!]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my presentation I gave May 12, 2008, at the <a href="http://mysql.meetup.com/92/">Twin Cities MySQL and PHP User Group</a> about my experience at the <a href="http://www.mysqlconf.com">2008 MySQL Conference and Expo</a>.</p>
<div style="margin:0 auto;width:425px;"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=mysql-conference-2008-edition-1210700836718054-9"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=mysql-conference-2008-edition-1210700836718054-9" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p>Thanks to all of those that came.  I had a great time!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/05/13/2008-mysql-conference-recap-presentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Memcached and MySQL Presentation</title>
		<link>http://www.cb1inc.com/2008/05/10/memcached-and-mysql-presentation/</link>
		<comments>http://www.cb1inc.com/2008/05/10/memcached-and-mysql-presentation/#comments</comments>
		<pubDate>Sat, 10 May 2008 14:16:08 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Here's my presentation on Memcached and MySQL:

<div style="width:425px;text-align:left" id="__ss_397558"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcached-and-mysql-1210410989510525-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcached-and-mysql-1210410989510525-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>

You can download the sample files here:

<ul>
<li><a href="http://www.cb1inc.com/sites/default/memcached-demo.tar.gz">memcached-demo.tar.gz [4MB]</a></li>
</ul>
]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s my presentation on Memcached and MySQL:</p>
<div style="width:425px;text-align:left" id="__ss_397558"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcached-and-mysql-1210410989510525-8"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=memcached-and-mysql-1210410989510525-8" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/05/10/memcached-and-mysql-presentation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MinneBar 2008 This Weekend!</title>
		<link>http://www.cb1inc.com/2008/05/08/minnebar-2008-this-weekend/</link>
		<comments>http://www.cb1inc.com/2008/05/08/minnebar-2008-this-weekend/#comments</comments>
		<pubDate>Thu, 08 May 2008 04:12:41 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[memcached]]></category>
		<category><![CDATA[minnebar]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[This Saturday, May 10th, is <a href="http://barcamp.org/MinneBar">MinneBar</a>, Minnesota's BarCamp. MinneBar is described as an "(un)Conference" which means it's a free, ad-hoc gathering of technology folks where everyone is encouraged to contribute.

<div align="center"><a href="http://barcamp.org/MinneBar"><img alt="MinneBar" src="/sites/default/blog/20070420-minnebar.png" /></a></div>

There are a lot of great <a href="http://barcamp.org/MinneBarSessions">sessions</a> this year.  I'll be giving a presentation titled "Memcached &#38; MySQL Sitting in a Tree." The talk is about the new <a href="http://tangent.org/586/Memcached_Functions_for_MySQL.html">Memcached Functions for MySQL</a>.  I'll talk a bit about the what, why, and how about this set of awesome UDFs.

I'm not sure what time I present and I think I have 50 minutes, but I don't know for sure.  I'm trying something new this time around; I'll be publishing my presentation on <a href="http://www.slideshare.net">SlideShare</a>.

We are still 3 days away and there are currently 356 people signed up which is right around how many people were signed up last year.  If you are in the Minneapolis/St. Paul area, you should come to participate and learn!

To register, visit their <a href="http://barcamp.org/MinneBar">website</a>, click the "login" link in the top right, use the password "c4mp" to login, then edit the main page, and add yourself to the bottom.  Registration starts at 8:00am, so remember to set an alarm. :)

Hope to see you there!]]></description>
			<content:encoded><![CDATA[<p>This Saturday, May 10th, is <a href="http://barcamp.org/MinneBar">MinneBar</a>, Minnesota&#8217;s BarCamp. MinneBar is described as an &#8220;(un)Conference&#8221; which means it&#8217;s a free, ad-hoc gathering of technology folks where everyone is encouraged to contribute.</p>
<div align="center"><a href="http://barcamp.org/MinneBar"><img alt="MinneBar" src="/wp-content/uploads/2009/12/20070420-minnebar.png" /></a></div>
<p>There are a lot of great <a href="http://barcamp.org/MinneBarSessions">sessions</a> this year.  I&#8217;ll be giving a presentation titled &#8220;Memcached &amp; MySQL Sitting in a Tree.&#8221; The talk is about the new <a href="http://tangent.org/586/Memcached_Functions_for_MySQL.html">Memcached Functions for MySQL</a>.  I&#8217;ll talk a bit about the what, why, and how about this set of awesome UDFs.</p>
<p>I&#8217;m not sure what time I present and I think I have 50 minutes, but I don&#8217;t know for sure.  I&#8217;m trying something new this time around; I&#8217;ll be publishing my presentation on <a href="http://www.slideshare.net">SlideShare</a>.</p>
<p>We are still 3 days away and there are currently 356 people signed up which is right around how many people were signed up last year.  If you are in the Minneapolis/St. Paul area, you should come to participate and learn!</p>
<p>To register, visit their <a href="http://barcamp.org/MinneBar">website</a>, click the &#8220;login&#8221; link in the top right, use the password &#8220;c4mp&#8221; to login, then edit the main page, and add yourself to the bottom.  Registration starts at 8:00am, so remember to set an alarm. <img src='http://www.cb1inc.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Hope to see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/05/08/minnebar-2008-this-weekend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mod_dbd MySQL Driver Woes With Ubuntu 7.04</title>
		<link>http://www.cb1inc.com/2008/04/22/mod-dbd-mysql-driver-woes-with-ubuntu-7-04/</link>
		<comments>http://www.cb1inc.com/2008/04/22/mod-dbd-mysql-driver-woes-with-ubuntu-7-04/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 16:58:53 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[apache]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Apache has a neat module called <a href="http://httpd.apache.org/docs/2.2/mod/mod_dbd.html">mod_dbd</a> that allows your Apache modules to connect to a database.  mod_dbd interfaces with apr_dbd, an Apache Portable Runtime (APR) abstraction layer around database specific drivers.

Back when Ubuntu 7.04 (fiesty) was released, a MySQL driver was not bundled with Apache for licensing concerns.  So, in order to use mod_dbd to connect to a MySQL database, you need to get the MySQL driver source code from WebThing (<a href="http://apache.webthing.com/svn/apache/apr/apr_dbd_mysql.c">apr_dbd_mysql.c</a>) and manually re-compile apr-utils.

You also need the source code for Apache 2.2.3 (which includes <a href="http://packages.ubuntu.com/gutsy/i386/libaprutil1/filelist">apr-utils</a> 1.2.7) from the Ubuntu 7.04 repositories, then copy the apr_dbd_mysql.c file into the Apache source apr-utils/dbd directory.  The Ubuntu guys made a nice INSTALL.MySQL file in the apr-utils with some basic instructions.

What they don't tell you is you need to install the MySQL source.  To make matters worse, once you install it, the apr-utils 1.2.7 configure script can't find it, even if you tell it where it is.

<pre>&#60;snip&#62;
configure: checking for mysql in /usr/src/mysql-dfsg-5.0-5.0.38/include
checking mysql.h usability... no
checking mysql.h presence... no
checking for mysql.h... no
&#60;snip&#62;</pre>

This apparently was a <a href="http://www.techlists.org/archives/web/apache-users/2006-09/msg00540.shtml">known issue</a> and was fixed in apr-utils 1.2.8.

Starting with <a href="http://svn.apache.org/viewvc/apr/apr-util/tags/1.2.11/dbd/">apr-utils 1.2.11</a>, the MySQL driver is bundled with it.  Unfortunately, even Ubuntu 7.10 (gutsy) still ships with apr-utils 1.2.7.  So, you are forced to download the source and compile.

Or, you can wait a couple days and Ubuntu 8.04 (hardy) which has <a href="http://packages.ubuntu.com/hardy/web/apache2">Apache 2.2.8</a> and <a href="http://packages.ubuntu.com/hardy/amd64/libaprutil1/filelist">apr-utils 1.2.11</a>.  In theory the MySQL driver will work out of the box.

As for me, I'll be compiling Apache, PHP, MySQL, memcached, and &#60;insert essential infrastructure software&#62; from source like I should have done in the beginning.]]></description>
			<content:encoded><![CDATA[<p>Apache has a neat module called <a href="http://httpd.apache.org/docs/2.2/mod/mod_dbd.html">mod_dbd</a> that allows your Apache modules to connect to a database.  mod_dbd interfaces with apr_dbd, an Apache Portable Runtime (APR) abstraction layer around database specific drivers.</p>
<p>Back when Ubuntu 7.04 (fiesty) was released, a MySQL driver was not bundled with Apache for licensing concerns.  So, in order to use mod_dbd to connect to a MySQL database, you need to get the MySQL driver source code from WebThing (<a href="http://apache.webthing.com/svn/apache/apr/apr_dbd_mysql.c">apr_dbd_mysql.c</a>) and manually re-compile apr-utils.</p>
<p>You also need the source code for Apache 2.2.3 (which includes <a href="http://packages.ubuntu.com/gutsy/i386/libaprutil1/filelist">apr-utils</a> 1.2.7) from the Ubuntu 7.04 repositories, then copy the apr_dbd_mysql.c file into the Apache source apr-utils/dbd directory.  The Ubuntu guys made a nice INSTALL.MySQL file in the apr-utils with some basic instructions.</p>
<p>What they don&#8217;t tell you is you need to install the MySQL source.  To make matters worse, once you install it, the apr-utils 1.2.7 configure script can&#8217;t find it, even if you tell it where it is.</p>
<pre>&lt;snip&gt;
configure: checking for mysql in /usr/src/mysql-dfsg-5.0-5.0.38/include
checking mysql.h usability... no
checking mysql.h presence... no
checking for mysql.h... no
&lt;snip&gt;</pre>
<p>This apparently was a <a href="http://www.techlists.org/archives/web/apache-users/2006-09/msg00540.shtml">known issue</a> and was fixed in apr-utils 1.2.8.</p>
<p>Starting with <a href="http://svn.apache.org/viewvc/apr/apr-util/tags/1.2.11/dbd/">apr-utils 1.2.11</a>, the MySQL driver is bundled with it.  Unfortunately, even Ubuntu 7.10 (gutsy) still ships with apr-utils 1.2.7.  So, you are forced to download the source and compile.</p>
<p>Or, you can wait a couple days and Ubuntu 8.04 (hardy) which has <a href="http://packages.ubuntu.com/hardy/web/apache2">Apache 2.2.8</a> and <a href="http://packages.ubuntu.com/hardy/amd64/libaprutil1/filelist">apr-utils 1.2.11</a>.  In theory the MySQL driver will work out of the box.</p>
<p>As for me, I&#8217;ll be compiling Apache, PHP, MySQL, memcached, and &lt;insert essential infrastructure software&gt; from source like I should have done in the beginning.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/04/22/mod-dbd-mysql-driver-woes-with-ubuntu-7-04/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Conference Day 4 Thoughts</title>
		<link>http://www.cb1inc.com/2008/04/17/mysql-conference-day-4-thoughts/</link>
		<comments>http://www.cb1inc.com/2008/04/17/mysql-conference-day-4-thoughts/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 18:59:03 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<h4>Scaling out MySQL: Hardware Today and Tomorrow</h4>
<a href="http://jcole.us/blog/">Jeremy Cole</a> and Eric Bergen over at <a href="http://provenscaling.com/">Proven Scaling LLC</a> gave a <a href="http://jcole.us/blog/archives/2008/04/17/scaling-out-mysql-hardware-today-and-tomorrow/">talk</a> about the hardware side of MySQL.  They covered pretty much every aspect of hardware.

For starters, Jeremy said go 64-bit hardware and operating system.  For CPU, faster is better.  The current versions of MySQL and InnoDB don't take full advantage of 8 core servers, so unless you have the budget, Jeremy recommended a single quad-core or a dual dual-core setup.  He recommended getting as much RAM as possible.  RAM is cheap so go for 32GB, or at least 16GB.

For storage, Jeremy discussed the many options including direct attached storage (DAS), SAN, NAS, and the various hard drive interfaces.  From what I gathered, they prefer configuring each DB server with RAID 10.  If the RAID controller has battery backed cache, then you should do "write back", otherwise "write through".  Write back offers faster performance since it caches the data and doesn't make the system wait for the data to be written to disk.  The battery backed cache means that you won't lose the data pending to be written if the system loses power.  There was a brief discussion of SATA vs. SAS.  SAS offers faster drives (15,000 RPM) and have processors to handle commands just as SCSI has which improves performance.  SAS has another interesting feature where a single drive can be hooked up to two separate SAS controllers in the event one controller should become unavailable.

They buy all of their gear from Dell, but HP, Sun, and IBM are good too.  Dell just happens to be significantly cheaper, especially when you go through a sales rep.  They mentioned some of the smaller guys including <a href="http://www.supermicro.com">SuperMicro</a> and <a href="http://www.siliconmechanics.com">Silicon Mechanics</a>.  I personally really like <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16816101142">SuperMicro's 6015T</a> server because it has 2 nodes in a 1U chassis.  This is actually denser than any blade server solution I've ever seen.  Each node is capable of two quad-core processors and 32GB of RAM.  The only downside is you can only have 2 hard drives and both nodes share a single non-redundant power supply.  So this would make a decent slave, but you would need to architect your application so it could quickly pick another slave if/when it goes down or use <a href="http://forge.mysql.com/wiki/MySQL_Proxy">MySQL Proxy</a>.

For databases using InnoDB, they said the InnoDB buffer pools should be 2GB less than to total system memory, so 14GB on a 16GB system.  Jeremy mentioned special hardware to speed things up, specifically <a href="http://www.kickfire.com/">Kickfire</a> and <a href="http://www.violin-memory.com/">Violin Memory</a>.  Kickfire is a SQL appliance that includes a special SQL chip to speed up operations significantly.  Violin Memory's 1010 memory appliance is sweet.  For only $170k you can add 512GB of DRAM in 2U to your database server of a PCI-Express bus.  It holds 84 x 6GB chips that can be hot swapped.  You can lose 2 sticks before you're screwed.

<div align="center"><a href="http://www.flickr.com/photos/fallenpegasus/2424290836/"><img src="http://farm3.static.flickr.com/2070/2424290836_9b38b756ba.jpg?v=0"/></a></div>

Jeremy concluded with high-speed interconnects including <a href="http://en.wikipedia.org/wiki/InfiniBand">InfiniBand</a> and <a href="http://www.dolphinics.com/">Dolphin Interconnect</a>.  InfiniBand is fast and you can hook them all into a switch.  Dolphin's interconnect is also fast and are chained together in a loop similar to external SCSI devices, but you need to make sure they have a driver for your hardware.

I talked to Jeremy after his talk and asked him about diskless slaves which would basically have a RAM drive for the data.  While it would be fast, it would take memory that would otherwise be used by MySQL and would be a pain to manage when they come online.  So scratch that idea.

<h4>Helping InnoDB Scale on Servers with Many CPU Cores and Disks</h4>
One of the more popular talks was by Mark Callaghan at Google who talked about ways they managed to get InnoDB to take advantage of system with more than 4 cores and many disks.  The primary change they made was to InnoDB's mutex code used to control concurrent read/writes to pages.

They replaced the existing pthreads mutex code with a more efficient platform specific <a href="http://en.wikipedia.org/wiki/Compare_and_swap">compare and swap</a> CPU instruction (CAS).  They managed to get much better performance.  He said they are hoping to get a patch out by the end of the year with their changes.  They don't want to release it until they know it is rock solid.

<h4>Scaling Heavy Concurrent Writes In Real Time</h4>
Dathan Pattishall, formerly with <a href="http://www.flickr.com">Flickr</a>, and now with <a href="http://www.rockyou.com/">RockYou.com</a> talked about an analytics system he helped build for Flickr.  Flickr keeps track of each photos stats including external links.  Whenever someone directly embeds a picture from a Flickr Pro user, they record that information, then make those stats available in near realtime.

The old design basically involved inserting records as they came in, but it was killing the servers, especially since those servers were also handling reads for people viewing the stats.  Their solution was to create a separate Java daemon that queues up pending inserts.  This means only a single thread is used on the MySQL server and it doesn't block the web servers from serving up the information.

They are inserting the stats into 3 tables, one for daily, weekly, and monthly stats.  To keep things in order, they tried a VARCHAR of the URL as the primary key, but ran into major performance issues.  So instead they decided to store a hash as bigint:

<pre>// php
$id = hexdec(substr(md5(url),0,16),16,10);</pre>

This code generates a 32 character MD5 of the URL, then takes the first 16 characters and converts them from string of hex numbers to base 10 number.  The resulting number fits perfectly in a bigint.

He also mentioned using <a href="http://www.innodb.com/hot-backup/">ibbackup</a> for backing up the databases, but it is not a free solution.

<h4>Geo Distance Search with MySQL</h4>
Ever since Google Maps API was released, I've had an interest in playing around with it.  Alexander Rubin of MySQL talked about ways of querying for locations within a given distance of a lat/lng.  He first abstracts the distance math into a user-defined function (UDF).  Then just calls the UDF from within the query.

I've already played with geo searching before, so it was mostly review.  He didn't go into much depth such as MySQL's <a href="http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html">spatial extensions</a>.

<h4>Dinner at the Tied House</h4>
We had a great turnout of around 18 people at the <a href="http://www.tiedhouse.com/">Tied House</a> in Mountain View.  We had a number of people from places including MySQL, PrimeBase, and Facebook.

<div align="center"><a href="http://www.primebase.com"><img src="http://www.primebase.com/images/pbt_logo.jpg"/></a></div>

Thanks to the <a href="http://www.primebase.com/">PrimeBase</a> guys!  They have a neat transaction storage engine that supports streaming blob data.  Normal blobs in MySQL are held in memory during the transaction.  The <a href="http://dev.mysql.com/tech-resources/articles/pbxt-storage-engine.html">PBXT Storage Engine</a> is designed to stream blob data in and out very efficiently.

I'd like to give a special thanks to <a href="http://www.jpipes.com">Jay Pipes</a> for getting me to come to the conference this year.  I truly had a great time.  Thanks!]]></description>
			<content:encoded><![CDATA[<h4>Scaling out MySQL: Hardware Today and Tomorrow</h4>
<p><a href="http://jcole.us/blog/">Jeremy Cole</a> and Eric Bergen over at <a href="http://provenscaling.com/">Proven Scaling LLC</a> gave a <a href="http://jcole.us/blog/archives/2008/04/17/scaling-out-mysql-hardware-today-and-tomorrow/">talk</a> about the hardware side of MySQL.  They covered pretty much every aspect of hardware.</p>
<p>For starters, Jeremy said go 64-bit hardware and operating system.  For CPU, faster is better.  The current versions of MySQL and InnoDB don&#8217;t take full advantage of 8 core servers, so unless you have the budget, Jeremy recommended a single quad-core or a dual dual-core setup.  He recommended getting as much RAM as possible.  RAM is cheap so go for 32GB, or at least 16GB.</p>
<p>For storage, Jeremy discussed the many options including direct attached storage (DAS), SAN, NAS, and the various hard drive interfaces.  From what I gathered, they prefer configuring each DB server with RAID 10.  If the RAID controller has battery backed cache, then you should do &#8220;write back&#8221;, otherwise &#8220;write through&#8221;.  Write back offers faster performance since it caches the data and doesn&#8217;t make the system wait for the data to be written to disk.  The battery backed cache means that you won&#8217;t lose the data pending to be written if the system loses power.  There was a brief discussion of SATA vs. SAS.  SAS offers faster drives (15,000 RPM) and have processors to handle commands just as SCSI has which improves performance.  SAS has another interesting feature where a single drive can be hooked up to two separate SAS controllers in the event one controller should become unavailable.</p>
<p>They buy all of their gear from Dell, but HP, Sun, and IBM are good too.  Dell just happens to be significantly cheaper, especially when you go through a sales rep.  They mentioned some of the smaller guys including <a href="http://www.supermicro.com">SuperMicro</a> and <a href="http://www.siliconmechanics.com">Silicon Mechanics</a>.  I personally really like <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16816101142">SuperMicro&#8217;s 6015T</a> server because it has 2 nodes in a 1U chassis.  This is actually denser than any blade server solution I&#8217;ve ever seen.  Each node is capable of two quad-core processors and 32GB of RAM.  The only downside is you can only have 2 hard drives and both nodes share a single non-redundant power supply.  So this would make a decent slave, but you would need to architect your application so it could quickly pick another slave if/when it goes down or use <a href="http://forge.mysql.com/wiki/MySQL_Proxy">MySQL Proxy</a>.</p>
<p>For databases using InnoDB, they said the InnoDB buffer pools should be 2GB less than to total system memory, so 14GB on a 16GB system.  Jeremy mentioned special hardware to speed things up, specifically <a href="http://www.kickfire.com/">Kickfire</a> and <a href="http://www.violin-memory.com/">Violin Memory</a>.  Kickfire is a SQL appliance that includes a special SQL chip to speed up operations significantly.  Violin Memory&#8217;s 1010 memory appliance is sweet.  For only $170k you can add 512GB of DRAM in 2U to your database server of a PCI-Express bus.  It holds 84 x 6GB chips that can be hot swapped.  You can lose 2 sticks before you&#8217;re screwed.</p>
<div align="center"><a href="http://www.flickr.com/photos/fallenpegasus/2424290836/"><img src="http://farm3.static.flickr.com/2070/2424290836_9b38b756ba.jpg?v=0"/></a></div>
<p>Jeremy concluded with high-speed interconnects including <a href="http://en.wikipedia.org/wiki/InfiniBand">InfiniBand</a> and <a href="http://www.dolphinics.com/">Dolphin Interconnect</a>.  InfiniBand is fast and you can hook them all into a switch.  Dolphin&#8217;s interconnect is also fast and are chained together in a loop similar to external SCSI devices, but you need to make sure they have a driver for your hardware.</p>
<p>I talked to Jeremy after his talk and asked him about diskless slaves which would basically have a RAM drive for the data.  While it would be fast, it would take memory that would otherwise be used by MySQL and would be a pain to manage when they come online.  So scratch that idea.</p>
<h4>Helping InnoDB Scale on Servers with Many CPU Cores and Disks</h4>
<p>One of the more popular talks was by Mark Callaghan at Google who talked about ways they managed to get InnoDB to take advantage of system with more than 4 cores and many disks.  The primary change they made was to InnoDB&#8217;s mutex code used to control concurrent read/writes to pages.</p>
<p>They replaced the existing pthreads mutex code with a more efficient platform specific <a href="http://en.wikipedia.org/wiki/Compare_and_swap">compare and swap</a> CPU instruction (CAS).  They managed to get much better performance.  He said they are hoping to get a patch out by the end of the year with their changes.  They don&#8217;t want to release it until they know it is rock solid.</p>
<h4>Scaling Heavy Concurrent Writes In Real Time</h4>
<p>Dathan Pattishall, formerly with <a href="http://www.flickr.com">Flickr</a>, and now with <a href="http://www.rockyou.com/">RockYou.com</a> talked about an analytics system he helped build for Flickr.  Flickr keeps track of each photos stats including external links.  Whenever someone directly embeds a picture from a Flickr Pro user, they record that information, then make those stats available in near realtime.</p>
<p>The old design basically involved inserting records as they came in, but it was killing the servers, especially since those servers were also handling reads for people viewing the stats.  Their solution was to create a separate Java daemon that queues up pending inserts.  This means only a single thread is used on the MySQL server and it doesn&#8217;t block the web servers from serving up the information.</p>
<p>They are inserting the stats into 3 tables, one for daily, weekly, and monthly stats.  To keep things in order, they tried a VARCHAR of the URL as the primary key, but ran into major performance issues.  So instead they decided to store a hash as bigint:</p>
<pre class="brush: php; title: ;">
// php
$id = hexdec(substr(md5(url),0,16),16,10);
</pre>
<p>This code generates a 32 character MD5 of the URL, then takes the first 16 characters and converts them from string of hex numbers to base 10 number.  The resulting number fits perfectly in a bigint.</p>
<p>He also mentioned using <a href="http://www.innodb.com/hot-backup/">ibbackup</a> for backing up the databases, but it is not a free solution.</p>
<h4>Geo Distance Search with MySQL</h4>
<p>Ever since Google Maps API was released, I&#8217;ve had an interest in playing around with it.  Alexander Rubin of MySQL talked about ways of querying for locations within a given distance of a lat/lng.  He first abstracts the distance math into a user-defined function (UDF).  Then just calls the UDF from within the query.</p>
<p>I&#8217;ve already played with geo searching before, so it was mostly review.  He didn&#8217;t go into much depth such as MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html">spatial extensions</a>.</p>
<h4>Dinner at the Tied House</h4>
<p>We had a great turnout of around 18 people at the <a href="http://www.tiedhouse.com/">Tied House</a> in Mountain View.  We had a number of people from places including MySQL, PrimeBase, and Facebook.</p>
<div align="center"><a href="http://www.primebase.com"><img src="/wp-content/uploads/2009/12/primebase_logo.jpg"/></a></div>
<p>Thanks to the <a href="http://www.primebase.com/">PrimeBase</a> guys!  They have a neat transaction storage engine that supports streaming blob data.  Normal blobs in MySQL are held in memory during the transaction.  The <a href="http://dev.mysql.com/tech-resources/articles/pbxt-storage-engine.html">PBXT Storage Engine</a> is designed to stream blob data in and out very efficiently.</p>
<p>I&#8217;d like to give a special thanks to <a href="http://www.jpipes.com">Jay Pipes</a> for getting me to come to the conference this year.  I truly had a great time.  Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/04/17/mysql-conference-day-4-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Conference Day 3 Thoughts</title>
		<link>http://www.cb1inc.com/2008/04/16/mysql-conference-day-3-thoughts/</link>
		<comments>http://www.cb1inc.com/2008/04/16/mysql-conference-day-3-thoughts/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 17:54:58 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<h4>Keynotes</h4>
The conference committee managed to get Rick Falkvinge of the <a href="http://www.piratpartiet.se/international/english">Swedish Pirate Party</a> to speak.  I heard him speak at OSCON 2007.  What I took away from his talk is copyright is evil.  Copyright is the excuse industries (i.e. the music industry) are using as a tool to justify monitoring all of your communications.  Not only do they want to monitor you, but prohibit certain kinds of communications.  What it comes down to is your privacy vs. copyright.  It's scary stuff.

<div align="center"><a href="http://www.flickr.com/photos/x180/2419466880/"><img src="http://farm4.static.flickr.com/3127/2419466880_80bfef25fa.jpg?v=0"/></a></div>

The second part of the keynote was a panel consisting of a representative from <a href="http://www.mysql.com">MySQL</a>, <a href="http://www.sun.com">Sun</a>, <a href="http://www.flickr.com">flickr</a>, <a href="http://www.fotolog.com">FotoLog</a>, <a href="http://www.wikipedia.com">Wikipedia</a>, <a href="http://www.facebook.com">Facebook</a>, and <a href="http://www.youtube.com">YouTube</a>.  They were discussing scaling at each of their sites.  It was a great discussion.  Informative and funny.  Paul Tuckfield of YouTube had a great saying: "Replication is the answer.  You just need to rephrase the question."  Farhan “Frank” Mashraqi of FotoLog made an interesting observation where Sun Sparc Niagara 1 servers make great master servers due to their high speed and Sun Sparc Niagara 2 servers make great slave servers due to their large concurrency.

<h4>Grand Tour of the information_schema</h4>
The information_schema database is a built-in database that contains metadata about data including tables, partitions, privileges, character sets, constraints, indexes, server settings, server status, and routines.  This database is an alternative to MySQL's proprietary SHOW commands.

I see a real utility being able to query the information_schema database to check server status.  Another interesting use is to auto-generate schema documentation.  I'm curious what kind of user metadata you can associate to objects.

<h4>Applied Partitioning and Scaling Your Database System</h4>
Phil Hildebrand gave his talk about the different ways of partitioning your data.  The types are range, hash, key, and list.  You can read more about partitioning types in <a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html">MySQL's documentation</a>.

<h4>MySQL Performance Under a Microscope: The Tobias and Jay Show</h4>
This was an entertaining talk by MySQL's Tobias Asplund and Jay Pipes.  They showed the results of a few benchmarks comparing multiple ways to do something.

In the first test, they wanted to see what was the fastest way for getting the total count of records.  They tried a handful of ways, but COUNT(*) when query caching was enabled was the fastest.

On of the other interesting tests they did was DATETIME vs. INT UNSIGNED for storing a date.  The best method was to use an INT UNSIGNED and do the date to int conversion on the application tier.  In PHP, use the <a href="http://us3.php.net/strtotime">strtotime()</a> function.

<h4>The MySQL Query Cache</h4>
Query caching can bring huge performance gains to your web application.  <a href="http://www.xaprb.com/">Baron Schwartz</a> of <a href="http://www.percona.com/">Percona</a> gave a talk describing why query cache rocks.

MySQL caches query results, not execution plans.  It stores the results in a big hash table where the key is the query.  They key is case-sensitive and whitespace-sensitive.  Only SELECT statement results are cached since it doesn't make a whole lot of sense to cache INSERT or UPDATE results.  Only deterministic queries are cached.  If the query contains a non-deterministic function call, such as a function that returns the current time, then it cannot cache the results.

You can display the query cache information by executing the following:

<pre>
SHOW GLOBAL STATUS LIKE 'qcache%';
SHOW GLOBAL STATUS LIKE 'query_cache%';
</pre>

The way the query cache memory is allocated can potentially cause fragmentation.  You can get a feel for how bad it is by comparing the number of free blocks to the number of total blocks.  If you are running out of free blocks, you either have filled your cache or you have bad fragmentation.

<h4>Grazr: Lessons Learned Building a Web 2.0 Application Using MySQL</h4>
The talk about <a href="http://www.grazr.com">Grazr</a> was given by Patrick Galbraith and Michael Kowalchik.  Patrick is one of the fellows that showed of some awesome memcached stuff at tutorial and the BOF.  Grazr filters out feeds to only the information it thinks you'd be interested in.  This was a pretty general discussion and they managed to get through their slides pretty quickly.  Since the talk was winding down early, I headed over to Eli's talk.

<h4>Help, My Website has been Hacked! Now What?</h4>
If you have a popular site, you are going get people attempt to hack your site.  <a href="http://www.eliw.com">Eli White</a> of <a href="http://www.digg.com">digg</a> talked about some of the ways your site can get hacked.

One thing he pointed out that I didn't think about was you can't just block someone's IP address.  If there is a proxy between the user and the web server, then IP address you get is the proxy's, not the user's.  You need to check the <a href="http://en.wikipedia.org/wiki/X-Forwarded-For">x-forwarded-for</a> HTTP header.  If there are more than one proxies involved, the x-forwarded-for will contain a comma separated list of addresses.

I talked to Eli after his session and he recommended blocking the IPs on the firewall instead of the PHP code.  This is means less load on the app server, but unless you have a fancy firewall, I would be curious to know how often a particular IP is trying to attack me.

<h4>Performing MySQL Backups Using LVM Snapshots</h4>
The last session of the day was by Lenz Grimmer of MySQL.  LVM snapshots can be a great way to backup your databases, especially InnoDB.  The basic procedure is:

<ul>
<li>flush tables</li>
<li>flush tables with read lock</li>
<li>lvcreate -s</li>
<li>show master/slave status</li>
<li>unlock tables</li>
<li>mount snapshot, perform backup</li>
<li>unmount and discard the snapshot</li>
</ul>

InnoDB ignores the "flush tables with read lock" step, but if you have any MyISAM tables, you'll still need to do it.  Flushing the tables does impact performance, especially while the snapshot is active.  As soon as you mount the LVM partition snapshot, you can back it up and then unmount and discard the snapshot.

There is a Perl script called <a href="http://lenz.homelinux.org/mylvmbackup/">mylvmbackup</a> which can help with these procedures.

An alternative to LVM snapshots for backups is to replicate to a slave server, stop the replication, perform the backup on the slave, then start replication again.  The downside is it requires an extra machine as the slave in which MySQL can be stopped so that InnoDB tables can be properly flushed.

<h4>MySQL Quiz Show and Sun party</h4>

<iframe src="http://rcm.amazon.com/e/cm?t=ci09-20&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596101716&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=999999&#038;bg1=F6F6F6&#038;f=ifr" style="float:right;width:120px;height:240px;margin-left:10px;margin-bottom:10px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>

The quiz show is a absolute blast.  The show is moderated by the infamous <a href="http://www.jpipes.com/">Jay Pipes</a>.  <a href="http://www.facebook.com">Facebook</a> was kind enough to sponsor the quiz show this year.  There was plenty of beer and popcorn to go around.  People won a ton of books and <a href="http://www.sheeri.com/">Sheeri Kritzer Cabral</a> won the grand prize: an Apple iPhone.  Lucky!

Everybody ended up coming out of the wood work for the Sun after party.  It was nice to finally get to meet <a href="http://www.xaprb.com/blog/">Baron Schwartz</a>.  Everybody should go by his book!  <a href="http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1208539069&#038;sr=8-1">High Performance MySQL</a>.

I also had a chat with Brian Moon of <a href="http://dealnews.com/">dealnews.com</a>.  He claims PHP can be made to work with the Apache worker MPM.  Hmm, looks like I have a new project!

<div style="clear:both;"></div>]]></description>
			<content:encoded><![CDATA[<h4>Keynotes</h4>
<p>The conference committee managed to get Rick Falkvinge of the <a href="http://www.piratpartiet.se/international/english">Swedish Pirate Party</a> to speak.  I heard him speak at OSCON 2007.  What I took away from his talk is copyright is evil.  Copyright is the excuse industries (i.e. the music industry) are using as a tool to justify monitoring all of your communications.  Not only do they want to monitor you, but prohibit certain kinds of communications.  What it comes down to is your privacy vs. copyright.  It&#8217;s scary stuff.</p>
<div align="center"><a href="http://www.flickr.com/photos/x180/2419466880/"><img src="http://farm4.static.flickr.com/3127/2419466880_80bfef25fa.jpg?v=0"/></a></div>
<p>The second part of the keynote was a panel consisting of a representative from <a href="http://www.mysql.com">MySQL</a>, <a href="http://www.sun.com">Sun</a>, <a href="http://www.flickr.com">flickr</a>, <a href="http://www.fotolog.com">FotoLog</a>, <a href="http://www.wikipedia.com">Wikipedia</a>, <a href="http://www.facebook.com">Facebook</a>, and <a href="http://www.youtube.com">YouTube</a>.  They were discussing scaling at each of their sites.  It was a great discussion.  Informative and funny.  Paul Tuckfield of YouTube had a great saying: &#8220;Replication is the answer.  You just need to rephrase the question.&#8221;  Farhan “Frank” Mashraqi of FotoLog made an interesting observation where Sun Sparc Niagara 1 servers make great master servers due to their high speed and Sun Sparc Niagara 2 servers make great slave servers due to their large concurrency.</p>
<h4>Grand Tour of the information_schema</h4>
<p>The information_schema database is a built-in database that contains metadata about data including tables, partitions, privileges, character sets, constraints, indexes, server settings, server status, and routines.  This database is an alternative to MySQL&#8217;s proprietary SHOW commands.</p>
<p>I see a real utility being able to query the information_schema database to check server status.  Another interesting use is to auto-generate schema documentation.  I&#8217;m curious what kind of user metadata you can associate to objects.</p>
<h4>Applied Partitioning and Scaling Your Database System</h4>
<p>Phil Hildebrand gave his talk about the different ways of partitioning your data.  The types are range, hash, key, and list.  You can read more about partitioning types in <a href="http://dev.mysql.com/doc/refman/5.1/en/partitioning-types.html">MySQL&#8217;s documentation</a>.</p>
<h4>MySQL Performance Under a Microscope: The Tobias and Jay Show</h4>
<p>This was an entertaining talk by MySQL&#8217;s Tobias Asplund and Jay Pipes.  They showed the results of a few benchmarks comparing multiple ways to do something.</p>
<p>In the first test, they wanted to see what was the fastest way for getting the total count of records.  They tried a handful of ways, but COUNT(*) when query caching was enabled was the fastest.</p>
<p>On of the other interesting tests they did was DATETIME vs. INT UNSIGNED for storing a date.  The best method was to use an INT UNSIGNED and do the date to int conversion on the application tier.  In PHP, use the <a href="http://us3.php.net/strtotime">strtotime()</a> function.</p>
<h4>The MySQL Query Cache</h4>
<p>Query caching can bring huge performance gains to your web application.  <a href="http://www.xaprb.com/">Baron Schwartz</a> of <a href="http://www.percona.com/">Percona</a> gave a talk describing why query cache rocks.</p>
<p>MySQL caches query results, not execution plans.  It stores the results in a big hash table where the key is the query.  They key is case-sensitive and whitespace-sensitive.  Only SELECT statement results are cached since it doesn&#8217;t make a whole lot of sense to cache INSERT or UPDATE results.  Only deterministic queries are cached.  If the query contains a non-deterministic function call, such as a function that returns the current time, then it cannot cache the results.</p>
<p>You can display the query cache information by executing the following:</p>
<pre class="brush: sql; title: ;">
SHOW GLOBAL STATUS LIKE 'qcache%';
SHOW GLOBAL STATUS LIKE 'query_cache%';
</pre>
<p>The way the query cache memory is allocated can potentially cause fragmentation.  You can get a feel for how bad it is by comparing the number of free blocks to the number of total blocks.  If you are running out of free blocks, you either have filled your cache or you have bad fragmentation.</p>
<h4>Grazr: Lessons Learned Building a Web 2.0 Application Using MySQL</h4>
<p>The talk about <a href="http://www.grazr.com">Grazr</a> was given by Patrick Galbraith and Michael Kowalchik.  Patrick is one of the fellows that showed of some awesome memcached stuff at tutorial and the BOF.  Grazr filters out feeds to only the information it thinks you&#8217;d be interested in.  This was a pretty general discussion and they managed to get through their slides pretty quickly.  Since the talk was winding down early, I headed over to Eli&#8217;s talk.</p>
<h4>Help, My Website has been Hacked! Now What?</h4>
<p>If you have a popular site, you are going get people attempt to hack your site.  <a href="http://www.eliw.com">Eli White</a> of <a href="http://www.digg.com">digg</a> talked about some of the ways your site can get hacked.</p>
<p>One thing he pointed out that I didn&#8217;t think about was you can&#8217;t just block someone&#8217;s IP address.  If there is a proxy between the user and the web server, then IP address you get is the proxy&#8217;s, not the user&#8217;s.  You need to check the <a href="http://en.wikipedia.org/wiki/X-Forwarded-For">x-forwarded-for</a> HTTP header.  If there are more than one proxies involved, the x-forwarded-for will contain a comma separated list of addresses.</p>
<p>I talked to Eli after his session and he recommended blocking the IPs on the firewall instead of the PHP code.  This is means less load on the app server, but unless you have a fancy firewall, I would be curious to know how often a particular IP is trying to attack me.</p>
<h4>Performing MySQL Backups Using LVM Snapshots</h4>
<p>The last session of the day was by Lenz Grimmer of MySQL.  LVM snapshots can be a great way to backup your databases, especially InnoDB.  The basic procedure is:</p>
<ul>
<li>flush tables</li>
<li>flush tables with read lock</li>
<li>lvcreate -s</li>
<li>show master/slave status</li>
<li>unlock tables</li>
<li>mount snapshot, perform backup</li>
<li>unmount and discard the snapshot</li>
</ul>
<p>InnoDB ignores the &#8220;flush tables with read lock&#8221; step, but if you have any MyISAM tables, you&#8217;ll still need to do it.  Flushing the tables does impact performance, especially while the snapshot is active.  As soon as you mount the LVM partition snapshot, you can back it up and then unmount and discard the snapshot.</p>
<p>There is a Perl script called <a href="http://lenz.homelinux.org/mylvmbackup/">mylvmbackup</a> which can help with these procedures.</p>
<p>An alternative to LVM snapshots for backups is to replicate to a slave server, stop the replication, perform the backup on the slave, then start replication again.  The downside is it requires an extra machine as the slave in which MySQL can be stopped so that InnoDB tables can be properly flushed.</p>
<h4>MySQL Quiz Show and Sun party</h4>
<p><iframe src="http://rcm.amazon.com/e/cm?t=ci09-20&#038;o=1&#038;p=8&#038;l=as1&#038;asins=0596101716&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;lc1=0000FF&#038;bc1=999999&#038;bg1=F6F6F6&#038;f=ifr" style="float:right;width:120px;height:240px;margin-left:10px;margin-bottom:10px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>The quiz show is a absolute blast.  The show is moderated by the infamous <a href="http://www.jpipes.com/">Jay Pipes</a>.  <a href="http://www.facebook.com">Facebook</a> was kind enough to sponsor the quiz show this year.  There was plenty of beer and popcorn to go around.  People won a ton of books and <a href="http://www.sheeri.com/">Sheeri Kritzer Cabral</a> won the grand prize: an Apple iPhone.  Lucky!</p>
<p>Everybody ended up coming out of the wood work for the Sun after party.  It was nice to finally get to meet <a href="http://www.xaprb.com/blog/">Baron Schwartz</a>.  Everybody should go by his book!  <a href="http://www.amazon.com/High-Performance-MySQL-Optimization-Replication/dp/0596101716/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1208539069&#038;sr=8-1">High Performance MySQL</a>.</p>
<p>I also had a chat with Brian Moon of <a href="http://dealnews.com/">dealnews.com</a>.  He claims PHP can be made to work with the Apache worker MPM.  Hmm, looks like I have a new project!</p>
<div style="clear:both;"></div>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/04/16/mysql-conference-day-3-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Conference Day 2 Thoughts</title>
		<link>http://www.cb1inc.com/2008/04/16/mysql-conference-day-2-thoughts/</link>
		<comments>http://www.cb1inc.com/2008/04/16/mysql-conference-day-2-thoughts/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 15:20:03 +0000</pubDate>
		<dc:creator>Chris Barber</dc:creator>
				<category><![CDATA[ec2]]></category>
		<category><![CDATA[gearman]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[<h4>Keynotes</h4>
The keynote was kick started by Marten Mickos.  If you've never met Marten, he is, on a personal note, one of the greatest CEOs I've ever met.  The keynotes were especially interesting for me because it was the first time I've had the opportunity to listen to <a href="http://blogs.sun.com/jonathan/">Jonathan Schwartz</a>, the CEO of <a href="http://www.sun.com">Sun Microsystems</a>.  Jonathan seems like a great guy who gives the impression he &#34;gets it&#34;.

The last keynote was by Werner Vogels of Amazon.  His talk covered Amazon's growth and the new services they offer including EC2.  He announced that EC2 now supports persistent storage, which is a huge improvement, but doesn't quite solve all of the problems.

<h4>Testing PHP/MySQL Applications with PHPUnit/DbUnit</h4>
I've never been big into testing, but I'm trying to change that.  <a href="http://sebastian-bergmann.de">Sebastian Bergmann</a>, the author of <a href="http://www.amazon.com/PHPUnit-Pocket-Guide-Guides/dp/0596101031/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1208361914&#038;sr=8-1">PHPUnit Pocket Reference</a> (<a href="http://www.phpunit.de/pocket_guide/3.2/en/index.html">free online version</a>), talked about <a href="http://phpun.it/">PHPUnit</a> and DbUnit and why I should use them.  Installing PHPUnit is extremely simple if you have pear installed:
<pre>pear channel-discover pear.phpunit.de
pear install phpunit/PHPUnit</pre>Once installed, just require PHPUnit:
<pre>require_once 'PHPUnit/Framework.php';</pre>He just scratched the surface on writing unit tests.  One thing he pointed out was using <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> for automated testing.  What's really cool is you can fire off CruiseControl from Subversion commit hooks.  If the testing fails, CruiseControl can send an email with the results and who is to blame.

<h4>Practical MySQL for Web Applications</h4>
<a href="http://dammit.lt/">Domas Mituzas</a> of MySQL and Wikipedia fame gave a good talk that covered practical design of web applications.  The talk covered simple stuff, so I didn't learn a whole lot.  Nevertheless, Domas sometimes says some funny things that make the talk enjoyable.

<h4>EXPLAIN Demystified</h4>
<a href="http://www.xaprb.com/blog/">Baron Schwartz</a> gave a talk about the <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html">EXPLAIN</a> statement.  EXPLAIN is run by prepending the word EXPLAIN to your SELECT statements.  It only works on SELECT statements.  When the query is run, it outputs an execution plan.

After running through the output of the EXPLAIN statement, he showed us mk-visual-explain which is one of the tools in <a href="http://www.maatkit.org/">Maatkit</a>.  It is a neato command line tool that takes the EXPLAIN output and reformats it as a tree structure.  It's a great way to visualize the execution plan.  Now if only there was a GUI version...

<h4>Upgrading to Elegant Versatile Database Architecture using PHP5 Data Objects</h4>
This talk was given by Sigurd Magnusson of <a href="http://www.silverstripe.com/">SilverStripe</a> and covered PDO.  I already researched and used PDO, so it was mostly review.

After talking to some of the other people at the conference, I've been seriously thinking of moving away from PDO and using MySQL specific functions because they expose some *really* cool debugging and profiling information.

<h4>Exploring Amazon EC2 for Scale-out Applications</h4>
The thought of EC2 sounds really cool.  The ability to create a server instance and host your stuff on it within minutes is sweet.  Need more servers, no problem, add another instance.  The speakers, Morgan Tocker of MySQL and Carl Mercier of Defensio, talked about their experience with EC2.

There are some serious data and management issues.  Until the other day, there wasn't any kind of persistent storage, meaning when the server went offline, you lost all your data.  Now you can mount a drive that persists across restarts.  But one issue for critical business transactions is how and when data is written to disk.  Is the data written immediately to disk or is buffered in the kernel or in some RAID card's cache?

Another issue they ran into is when a new machine is created, there's remnants of the previous machine's instance's data.  So they need to zero out the drive which takes 5 hours on single instance.

What I took away from the talk is EC2 is great if your app is simple and relies on 3rd party services (i.e. Facebook, Google, etc) that are more reliable than EC2.

<h4>Service Oriented Architecture with PHP and MySQL</h4>
<a href="http://www.joestump.com/">Joe Stump</a>, a PHP hacker at Digg, gave a talk about SOA.  It wasn't as much about "web services" as it is managing tasks and processing them asynchronously.

After talking to Joe, he highly recommended <a href="http://www.danga.com/gearman/">Gearman</a> to manage tasks.  From the Gearman site: "Gearman is a system to farm out work to other machines, dispatching function calls to machines that are better suited to do work, to do work in parallel, to load balance lots of function calls, or to call functions between languages."

So, if a user uploads an image, you can add the task of resizing the image to a backend processing mechanism.  This allows for a responsive front-end for the user.

Joe, along with Chris Goffinet, are working on <a href="http://code.google.com/p/netgearman/">netgearman</a> which is a PEAR package for interfacing with Gearman.

<h4>Memcached Hackathon BOF</h4>
This was a birds of a feature session where a bunch of people informally got together to discuss all things memcached.  Patrick Galbraith of <a href="http://www.grazr.com/">Grazr</a> showed off <a href="http://tangent.org/586/Memcached_Functions_for_MySQL.html">Memcached Functions for MySQL</a>.  This is super cool.  It allows you to set and get data in memcached within your SQL code via user defined functions.

So instead of pulling data from the DB to the app, then pushing it to memcached, you can just have a trigger or stored procedure store the value directly to memcached.  One caveat is when you rollback a transaction, it won't unset the value from memcached.

There was some discussion about the <a href="http://tangent.org/index.pl?node_id=506">memcached MySQL storage engine</a>.  After listening to them discuss it, I have to wonder if it is really worth it.  It acts like a distributed memory table, except when a server in a cluster goes down, it will affect all the other servers.]]></description>
			<content:encoded><![CDATA[<h4>Keynotes</h4>
<p>The keynote was kick started by Marten Mickos.  If you&#8217;ve never met Marten, he is, on a personal note, one of the greatest CEOs I&#8217;ve ever met.  The keynotes were especially interesting for me because it was the first time I&#8217;ve had the opportunity to listen to <a href="http://blogs.sun.com/jonathan/">Jonathan Schwartz</a>, the CEO of <a href="http://www.sun.com">Sun Microsystems</a>.  Jonathan seems like a great guy who gives the impression he &quot;gets it&quot;.</p>
<p>The last keynote was by Werner Vogels of Amazon.  His talk covered Amazon&#8217;s growth and the new services they offer including EC2.  He announced that EC2 now supports persistent storage, which is a huge improvement, but doesn&#8217;t quite solve all of the problems.</p>
<h4>Testing PHP/MySQL Applications with PHPUnit/DbUnit</h4>
<p>I&#8217;ve never been big into testing, but I&#8217;m trying to change that.  <a href="http://sebastian-bergmann.de">Sebastian Bergmann</a>, the author of <a href="http://www.amazon.com/PHPUnit-Pocket-Guide-Guides/dp/0596101031/ref=pd_bbs_sr_1?ie=UTF8&#038;s=books&#038;qid=1208361914&#038;sr=8-1">PHPUnit Pocket Reference</a> (<a href="http://www.phpunit.de/pocket_guide/3.2/en/index.html">free online version</a>), talked about <a href="http://phpun.it/">PHPUnit</a> and DbUnit and why I should use them.  Installing PHPUnit is extremely simple if you have pear installed:</p>
<p>pear channel-discover pear.phpunit.de<br />
pear install phpunit/PHPUnit</p>
<p>Once installed, just require PHPUnit:</p>
<pre class="brush: php; title: ;">
// php
require_once 'PHPUnit/Framework.php';
</pre>
<p>He just scratched the surface on writing unit tests.  One thing he pointed out was using <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a> for automated testing.  What&#8217;s really cool is you can fire off CruiseControl from Subversion commit hooks.  If the testing fails, CruiseControl can send an email with the results and who is to blame.</p>
<h4>Practical MySQL for Web Applications</h4>
<p><a href="http://dammit.lt/">Domas Mituzas</a> of MySQL and Wikipedia fame gave a good talk that covered practical design of web applications.  The talk covered simple stuff, so I didn&#8217;t learn a whole lot.  Nevertheless, Domas sometimes says some funny things that make the talk enjoyable.</p>
<h4>EXPLAIN Demystified</h4>
<p><a href="http://www.xaprb.com/blog/">Baron Schwartz</a> gave a talk about the <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html">EXPLAIN</a> statement.  EXPLAIN is run by prepending the word EXPLAIN to your SELECT statements.  It only works on SELECT statements.  When the query is run, it outputs an execution plan.</p>
<p>After running through the output of the EXPLAIN statement, he showed us mk-visual-explain which is one of the tools in <a href="http://www.maatkit.org/">Maatkit</a>.  It is a neato command line tool that takes the EXPLAIN output and reformats it as a tree structure.  It&#8217;s a great way to visualize the execution plan.  Now if only there was a GUI version&#8230;</p>
<h4>Upgrading to Elegant Versatile Database Architecture using PHP5 Data Objects</h4>
<p>This talk was given by Sigurd Magnusson of <a href="http://www.silverstripe.com/">SilverStripe</a> and covered PDO.  I already researched and used PDO, so it was mostly review.</p>
<p>After talking to some of the other people at the conference, I&#8217;ve been seriously thinking of moving away from PDO and using MySQL specific functions because they expose some *really* cool debugging and profiling information.</p>
<h4>Exploring Amazon EC2 for Scale-out Applications</h4>
<p>The thought of EC2 sounds really cool.  The ability to create a server instance and host your stuff on it within minutes is sweet.  Need more servers, no problem, add another instance.  The speakers, Morgan Tocker of MySQL and Carl Mercier of Defensio, talked about their experience with EC2.</p>
<p>There are some serious data and management issues.  Until the other day, there wasn&#8217;t any kind of persistent storage, meaning when the server went offline, you lost all your data.  Now you can mount a drive that persists across restarts.  But one issue for critical business transactions is how and when data is written to disk.  Is the data written immediately to disk or is buffered in the kernel or in some RAID card&#8217;s cache?</p>
<p>Another issue they ran into is when a new machine is created, there&#8217;s remnants of the previous machine&#8217;s instance&#8217;s data.  So they need to zero out the drive which takes 5 hours on single instance.</p>
<p>What I took away from the talk is EC2 is great if your app is simple and relies on 3rd party services (i.e. Facebook, Google, etc) that are more reliable than EC2.</p>
<h4>Service Oriented Architecture with PHP and MySQL</h4>
<p><a href="http://www.joestump.com/">Joe Stump</a>, a PHP hacker at Digg, gave a talk about SOA.  It wasn&#8217;t as much about &#8220;web services&#8221; as it is managing tasks and processing them asynchronously.</p>
<p>After talking to Joe, he highly recommended <a href="http://www.danga.com/gearman/">Gearman</a> to manage tasks.  From the Gearman site: &#8220;Gearman is a system to farm out work to other machines, dispatching function calls to machines that are better suited to do work, to do work in parallel, to load balance lots of function calls, or to call functions between languages.&#8221;</p>
<p>So, if a user uploads an image, you can add the task of resizing the image to a backend processing mechanism.  This allows for a responsive front-end for the user.</p>
<p>Joe, along with Chris Goffinet, are working on <a href="http://code.google.com/p/netgearman/">netgearman</a> which is a PEAR package for interfacing with Gearman.</p>
<h4>Memcached Hackathon BOF</h4>
<p>This was a birds of a feature session where a bunch of people informally got together to discuss all things memcached.  Patrick Galbraith of <a href="http://www.grazr.com/">Grazr</a> showed off <a href="http://tangent.org/586/Memcached_Functions_for_MySQL.html">Memcached Functions for MySQL</a>.  This is super cool.  It allows you to set and get data in memcached within your SQL code via user defined functions.</p>
<p>So instead of pulling data from the DB to the app, then pushing it to memcached, you can just have a trigger or stored procedure store the value directly to memcached.  One caveat is when you rollback a transaction, it won&#8217;t unset the value from memcached.</p>
<p>There was some discussion about the <a href="http://tangent.org/index.pl?node_id=506">memcached MySQL storage engine</a>.  After listening to them discuss it, I have to wonder if it is really worth it.  It acts like a distributed memory table, except when a server in a cluster goes down, it will affect all the other servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cb1inc.com/2008/04/16/mysql-conference-day-2-thoughts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

