<?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>Looking for the paradigm &#187; work</title>
	<atom:link href="http://www.evanhoffman.com/evan/tag/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.evanhoffman.com/evan</link>
	<description>So I can pass it off</description>
	<lastBuildDate>Thu, 26 Jan 2012 22:17:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Load balancing in EC2 with Nginx and HAProxy</title>
		<link>http://www.evanhoffman.com/evan/2012/01/09/load-balancing-in-ec2-with-nginx-and-haproxy/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=load-balancing-in-ec2-with-nginx-and-haproxy</link>
		<comments>http://www.evanhoffman.com/evan/2012/01/09/load-balancing-in-ec2-with-nginx-and-haproxy/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 22:00:22 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[elastic loadbalancer]]></category>
		<category><![CDATA[elb]]></category>
		<category><![CDATA[gslb]]></category>
		<category><![CDATA[haproxy]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[load balancer]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[proxy]]></category>
		<category><![CDATA[reverse proxy]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1764</guid>
		<description><![CDATA[TweetWe wanted to setup a loadbalanced web cluster in AWS for expansion. My first inclination was to use ELB for this, but I soon learned that ELB doesn&#8217;t let you allocate a static IP, requiring you to refer to it only by DNS name. This would be OK except for the fact that our current [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2012/01/09/load-balancing-in-ec2-with-nginx-and-haproxy/&via=EvanHoffman&text=Load balancing in EC2 with Nginx and HAProxy&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2012/01/09/load-balancing-in-ec2-with-nginx-and-haproxy/"></g:plusone></div><p>We wanted to setup a loadbalanced web cluster in AWS for expansion.  My first inclination was to use <a href="http://aws.amazon.com/elasticloadbalancing/">ELB</a> for this, but I soon learned that ELB doesn&#8217;t let you allocate a static IP, requiring you to refer to it only by DNS name.  This would be OK except for the fact that our current DNS provider, <a href="http://dyn.com/dns/dynect-managed-dns/">Dyn</a>, requires IP addresses when using their GSLB (geo-based load balancer) service.</p>
<p>Rather than let this derail the whole project, I decided to look into the software options available for loadbalancing in EC2.  I&#8217;ve been a fan of hardware load balancers for a while, sort of looking down at software-based solutions without any real rationale, but in this case I really had no choice so I figured I&#8217;d give it a try.</p>
<p>My first stop was Nginx.  I&#8217;ve used it before in a reverse-proxy scenario and like it.  The problem I had with it was that it doesn&#8217;t support active polling of nodes &#8211; the ability to send requests to the webserver and mark the node as up or down based on the response.  As far as I can tell, using <a href="http://wiki.nginx.org/HttpUpstreamModule">multiple upstream servers</a> in Nginx allows you to specify <tt>max_fails</tt> and <tt>fail_timeout</tt>, however a &#8220;fail&#8221; is determined when a real request comes in.  I don&#8217;t want to risk losing a real request &#8211; I like active polling.<br />
<span id="more-1764"></span><br />
This led me to HAProxy.  I&#8217;d never used HAProxy before but it seemed to be ideally suited to this (since it&#8217;s exclusively a load balancer).  The <tt>option httpchk</tt> even allows for active polling of nodes &#8211; yay!</p>
<p>Unfortunately, HAProxy doesn&#8217;t support SSL.  From <a href="http://haproxy.1wt.eu/">the HAProxy site</a>:</p>
<blockquote><p>People often ask for SSL and Keep-Alive support. Both features will complicate the code and render it fragile for several releases. By the way, both features have a negative impact on performance :</p>
<p>    Having SSL in the load balancer itself means that it becomes the bottleneck. When the load balancer&#8217;s CPU is saturated, the overall response times will increase and the only solution will be to multiply the load balancer with another load balancer in front of them. the only scalable solution is to have an SSL/Cache layer between the clients and the load balancer. Anyway for small sites it still makes sense to embed SSL, and it&#8217;s currently being studied. There has been some work on the CyaSSL library to ease integration with HAProxy, as it appears to be the only one out there to let you manage your memory yourself. </p></blockquote>
<p>Poop!  I figured out a workaround however, by using both Nginx and HAProxy on the same instance.  HAProxy listens on port 80 and 8443 (so that it can relay decrypted SSL traffic to the nodes on a separate port, so that the nodes are aware that it was originally SSL traffic).  Nginx is configured as a reverse proxy, listens on port 443 only, and has the SSL cert &#038; key.  The upstream for the Nginx is just localhost:8443 &#8211; HAProxy.  </p>
<p>This was pretty easy to setup and works very well.  I benchmarked HAProxy on an EC2 t1.micro instance (in front of two m1.large instances running our webapp) using <tt>ab -n 5000 -c 50 -t 60</tt> and found it actually performed better than one of our hardware load balancers.  That was pretty eye-opening (and sad).</p>
<p>The HAProxy and Nginx configs are below, in the hopes that it helps someone.  The main warning I&#8217;d give is that using this will cause the logs on your nodes to interpret all requests as coming from the IP of the load balancer.  I had to rewrite some code to have the app use the X-Forwarded-For address rather than the <a href="http://docs.oracle.com/javaee/5/api/javax/servlet/ServletRequest.html#getRemoteAddr%28%29">REMOTE_ADDR</a>, but other than that this has been working out pretty well.</p>
<p>/etc/nginx/nginx.conf<br />
Main thing is to make sure the server isn&#8217;t listening on port 80 (since HAProxy needs to).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
</pre></td><td class="code"><pre class="txt" style="font-family:monospace;">user              nginx;
worker_processes  1;
&nbsp;
error_log  /var/log/nginx/error.log;
&nbsp;
pid        /var/run/nginx.pid;
&nbsp;
events {
    worker_connections  1024;
}
&nbsp;
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
&nbsp;
    log_format  main  '$remote_addr - $remote_user [$time_local] &quot;$request&quot; '
                      '$status $body_bytes_sent &quot;$http_referer&quot; '
                      '&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;';
&nbsp;
    access_log  /var/log/nginx/access.log  main;
&nbsp;
    sendfile        on;
    keepalive_timeout  65;
&nbsp;
    #
    # The default server
    #
    server {
        listen       81;
        server_name  _;
&nbsp;
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
        }
&nbsp;
        error_page  404              /404.html;
        location = /404.html {
            root   /usr/share/nginx/html;
        }
&nbsp;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
&nbsp;
    }
&nbsp;
    # Load config files from the /etc/nginx/conf.d directory
    include /etc/nginx/conf.d/*.conf;
&nbsp;
}</pre></td></tr></table></div>

<p>/etc/nginx/conf.d/ssl-offloader.conf</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="txt" style="font-family:monospace;">upstream haproxy {
        server localhost:8443 ;
}
&nbsp;
server {
        listen       443;
        server_name f.q.d.n 1.2.3.4 ; # I put the FQDN and IP here, but maybe &quot;_&quot; will work too
#  server_name  _;
&nbsp;
        ssl                  on;
        ssl_certificate      /etc/nginx/ssl-cert/cert.pem;
        ssl_certificate_key  /etc/nginx/ssl-cert/cert.key;
&nbsp;
        ssl_session_timeout  5m;
&nbsp;
        ssl_protocols  SSLv3 TLSv1;
        ssl_ciphers     ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM;
        ssl_prefer_server_ciphers   on;
&nbsp;
        location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
&nbsp;
                proxy_pass http://haproxy/;
                proxy_redirect default;
                proxy_redirect http://$host/ https://$host/;
                proxy_redirect http://hostname/ https://$host/;
&nbsp;
                proxy_read_timeout 15s;
                proxy_connect_timeout 15s;
        }
&nbsp;
}</pre></td></tr></table></div>

<p>/etc/haproxy/haproxy.cfg</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
</pre></td><td class="code"><pre class="txt" style="font-family:monospace;">#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2
&nbsp;
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
&nbsp;
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
&nbsp;
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    3s
    timeout queue           1m
    timeout connect         2s
    timeout client          5s
    timeout server          5s
    timeout http-keep-alive 1s
    timeout check           10s
    maxconn                 3000
&nbsp;
       stats enable
       stats auth evan:change_me_brother
&nbsp;
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  main_http *:80
        option forwardfor except 127.0.0.1  
        option httpclose
        default_backend         web_http
&nbsp;
frontend main_https *:8443
        option forwardfor except 127.0.0.1  
        option httpclose
        default_backend         web_https
&nbsp;
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend web_http
    balance     roundrobin
#       option httpchk GET / HTTP/1.1\r\nHost:\ host.com
        option httpchk
    server  node1 192.168.1.20:80 check port 80
    server  node2 192.168.1.30:80 check port 80
    server  node3 192.168.1.40:80 check port 80
&nbsp;
&nbsp;
backend web_https
    balance     roundrobin
#       option httpchk GET / HTTP/1.1\r\nHost:\ host.com
        option httpchk
    server  node1 192.168.1.20:8443 check port 8443
    server  node2 192.168.1.30:8443 check port 8443
    server  node3 192.168.1.40:8443 check port 8443</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2012/01/09/load-balancing-in-ec2-with-nginx-and-haproxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing Sun (Oracle) JDK 1.5 on an EC2 instance</title>
		<link>http://www.evanhoffman.com/evan/2011/11/16/installing-sun-oracle-jdk-1-5-on-an-ec2-instance/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installing-sun-oracle-jdk-1-5-on-an-ec2-instance</link>
		<comments>http://www.evanhoffman.com/evan/2011/11/16/installing-sun-oracle-jdk-1-5-on-an-ec2-instance/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 16:52:55 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[1.5]]></category>
		<category><![CDATA[alternatives]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[JAVA_HOME]]></category>
		<category><![CDATA[jdk]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sun]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[x86_64]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1675</guid>
		<description><![CDATA[TweetI&#8217;m currently working on moving a Tomcat-based application into EC2. The code was written for Java 5.0. While Java 6 would probably work, I&#8217;d like to keep everything as &#8220;same&#8221; as possible, since EC2 presents its own challenges. I spun up a couple of t1.micro instances and copied everything over, including the Java 5 JDK, [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/11/16/installing-sun-oracle-jdk-1-5-on-an-ec2-instance/&via=EvanHoffman&text=Installing Sun (Oracle) JDK 1.5 on an EC2 instance&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/11/16/installing-sun-oracle-jdk-1-5-on-an-ec2-instance/"></g:plusone></div><p>I&#8217;m currently working on moving a Tomcat-based application into EC2. The code was written for Java 5.0. While Java 6 would probably work, I&#8217;d like to keep everything as &#8220;same&#8221; as possible, since EC2 presents its own challenges. I spun up a couple of t1.micro instances and copied everything over, including the Java 5 JDK, <tt><a href="http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase5-419410.html#jdk-1.5.0_22-oth-JPR">jdk-1_5_0_22-linux-amd64.rpm</a></tt>. Installing from RPM was easy, but the EC2 instance defaults to using OpenJDK 1.6:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>ec2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># java -version</span>
java version <span style="color: #ff0000;">&quot;1.6.0_20&quot;</span>
OpenJDK Runtime Environment <span style="color: #7a0874; font-weight: bold;">&#40;</span>IcedTea6 1.9.10<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>amazon-52.1.9.10.40.amzn1-x86_64<span style="color: #7a0874; font-weight: bold;">&#41;</span>
OpenJDK <span style="color: #000000;">64</span>-Bit Server VM <span style="color: #7a0874; font-weight: bold;">&#40;</span>build <span style="color: #000000;">19.0</span>-b09, mixed mode<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>There were a couple of things I had to do to get the system to accept the Sun JDK as its &#8220;real&#8221; java.</p>
<h3>Alternatives</h3>
<p>Red Hat&#8217;s &#8220;alternatives&#8221; system is designed to allow a system to have multiple versions of a program installed and make it easy to choose which one you want to run.  Unfortunately I&#8217;ve found the syntax a bit strange and always have to Google it, so I figured I&#8217;d document it here for posterity.</p>
<p>So here&#8217;s the default:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>ec2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># alternatives --config java</span>
&nbsp;
There is <span style="color: #000000;">1</span> program that provides <span style="color: #ff0000;">'java'</span>.
&nbsp;
  Selection    Command
<span style="color: #660033;">-----------------------------------------------</span>
<span style="color: #000000; font-weight: bold;">*</span>+ <span style="color: #000000;">1</span>           <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>jvm<span style="color: #000000; font-weight: bold;">/</span>jre-1.6.0-openjdk.x86_64<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>java
&nbsp;
Enter to keep the current selection<span style="color: #7a0874; font-weight: bold;">&#91;</span>+<span style="color: #7a0874; font-weight: bold;">&#93;</span>, or <span style="color: #7a0874; font-weight: bold;">type</span> selection number:</pre></div></div>

<p>Here&#8217;s how to add Sun java, assuming the java binary is in <tt>/usr/java/jdk1.5.0_22/jre/bin/java</tt> (where the RPM puts it).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>ec2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># alternatives --install /usr/bin/java java /usr/java/jdk1.5.0_22/jre/bin/java 1</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>ec2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># alternatives --config java</span>
There are <span style="color: #000000;">2</span> programs <span style="color: #c20cb9; font-weight: bold;">which</span> provide <span style="color: #ff0000;">'java'</span>.
&nbsp;
  Selection    Command
<span style="color: #660033;">-----------------------------------------------</span>
<span style="color: #000000; font-weight: bold;">*</span>+ <span style="color: #000000;">1</span>           <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>jvm<span style="color: #000000; font-weight: bold;">/</span>jre-1.6.0-openjdk.x86_64<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>java
   <span style="color: #000000;">2</span>           <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>java<span style="color: #000000; font-weight: bold;">/</span>jdk1.5.0_22<span style="color: #000000; font-weight: bold;">/</span>jre<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>java
&nbsp;
Enter to keep the current selection<span style="color: #7a0874; font-weight: bold;">&#91;</span>+<span style="color: #7a0874; font-weight: bold;">&#93;</span>, or <span style="color: #7a0874; font-weight: bold;">type</span> selection number: <span style="color: #000000;">2</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>ec2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># java -version</span>
java version <span style="color: #ff0000;">&quot;1.5.0_22&quot;</span>
Java<span style="color: #7a0874; font-weight: bold;">&#40;</span>TM<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000;">2</span> Runtime Environment, Standard Edition <span style="color: #7a0874; font-weight: bold;">&#40;</span>build 1.5.0_22-b03<span style="color: #7a0874; font-weight: bold;">&#41;</span>
Java HotSpot<span style="color: #7a0874; font-weight: bold;">&#40;</span>TM<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000;">64</span>-Bit Server VM <span style="color: #7a0874; font-weight: bold;">&#40;</span>build 1.5.0_22-b03, mixed mode<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Yay!  Unfortunately this doesn&#8217;t help with the other problem I had with Tomcat, which was that EC2 instances set the JAVA_HOME var to OpenJDK as well (<tt>/usr/lib/jvm/jre</tt>).  Fortunately this is an easy fix as well.</p>
<h3>Setting JAVA_HOME</h3>
<p>The JAVA_HOME var is set in <tt>/etc/profile.d/aws-apitools-common.sh</tt>.  Comment out this line:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">JAVA_HOME</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>jvm<span style="color: #000000; font-weight: bold;">/</span>jre</pre></div></div>

<p>Create a new file, <tt>/etc/profile.d/sun-java.sh</tt>, and put this in it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">JAVA_HOME</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>java<span style="color: #000000; font-weight: bold;">/</span>jdk1.5.0_22<span style="color: #000000; font-weight: bold;">/</span>jre</pre></div></div>

<p>Also in that file I added the following to instruct the JVM to process all dates in America/New_York, since that&#8217;s the timezone all of our other servers use, and it makes reading log files easier when all dates are in the same tz:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">TZ</span>=America<span style="color: #000000; font-weight: bold;">/</span>New_York</pre></div></div>

<p>(I found I had to do this even after pointing /etc/localtime to the correct zoneinfo &#8211; Java was stuck on UTC even after the rest of the system was using America/New_York.)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/11/16/installing-sun-oracle-jdk-1-5-on-an-ec2-instance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rescan SATA bus (aka hot-adding a SATA disk on a Linux guest in VMware without rebooting)</title>
		<link>http://www.evanhoffman.com/evan/2011/10/24/rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting</link>
		<comments>http://www.evanhoffman.com/evan/2011/10/24/rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 19:20:51 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bus]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[command]]></category>
		<category><![CDATA[dmesg]]></category>
		<category><![CDATA[hot-add]]></category>
		<category><![CDATA[hot-plug]]></category>
		<category><![CDATA[hotadd]]></category>
		<category><![CDATA[hotplug]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[rescan]]></category>
		<category><![CDATA[sata]]></category>
		<category><![CDATA[scsi]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1655</guid>
		<description><![CDATA[TweetLinux supports hot-adding disks but whenever I add a new vdisk in VMware the new disk doesn&#8217;t show up unless I reboot, which defeats the purpose of hot-add. This command forces a rescan of the bus: echo &#34;- - -&#34; &#62; /sys/class/scsi_host/host0/scan dmesg shows the new disk has been found: Vendor: VMware Model: Virtual disk [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/10/24/rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting/&via=EvanHoffman&text=Rescan SATA bus (aka hot-adding a SATA disk on a Linux guest in VMware without rebooting)&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/10/24/rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting/"></g:plusone></div><p>Linux supports hot-adding disks but whenever I add a new vdisk in VMware the new disk doesn&#8217;t show up unless I reboot, which defeats the purpose of hot-add.  This command forces a rescan of the bus:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;- - -&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>sys<span style="color: #000000; font-weight: bold;">/</span>class<span style="color: #000000; font-weight: bold;">/</span>scsi_host<span style="color: #000000; font-weight: bold;">/</span>host0<span style="color: #000000; font-weight: bold;">/</span>scan</pre></div></div>

<p><tt>dmesg</tt> shows the new disk has been found:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  Vendor: VMware    Model: Virtual disk      Rev: <span style="color: #000000;">1.0</span> 
  Type:   Direct-Access                      ANSI SCSI revision: 02
 target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>: Beginning Domain Validation
 target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>: Domain Validation skipping <span style="color: #c20cb9; font-weight: bold;">write</span> tests
 target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>: Ending Domain Validation
 target0:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>: FAST-<span style="color: #000000;">40</span> WIDE SCSI <span style="color: #000000;">80.0</span> MB<span style="color: #000000; font-weight: bold;">/</span>s ST <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">25</span> ns, offset <span style="color: #000000;">127</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
SCSI device sdd: <span style="color: #000000;">1048576000</span> <span style="color: #000000;">512</span>-byte hdwr sectors <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">536871</span> MB<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sdd: Write Protect is off
sdd: Mode Sense: 03 00 00 00
sdd: cache data unavailable
sdd: assuming drive cache: <span style="color: #c20cb9; font-weight: bold;">write</span> through
SCSI device sdd: <span style="color: #000000;">1048576000</span> <span style="color: #000000;">512</span>-byte hdwr sectors <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">536871</span> MB<span style="color: #7a0874; font-weight: bold;">&#41;</span>
sdd: Write Protect is off
sdd: Mode Sense: 03 00 00 00
sdd: cache data unavailable
sdd: assuming drive cache: <span style="color: #c20cb9; font-weight: bold;">write</span> through
 sdd: unknown partition table
sd <span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>:<span style="color: #000000;">0</span>: Attached scsi disk sdd
sd <span style="color: #000000;">0</span>:<span style="color: #000000;">0</span>:<span style="color: #000000;">2</span>:<span style="color: #000000;">0</span>: Attached scsi generic sg3 <span style="color: #7a0874; font-weight: bold;">type</span> <span style="color: #000000;">0</span></pre></div></div>

<p>Now, why there&#8217;s no &#8220;rescan_sata&#8221; command is something I can&#8217;t fathom, but that&#8217;s Linux for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/10/24/rescan-sata-bus-aka-hot-adding-a-sata-disk-on-a-linux-guest-in-vmware-without-rebooting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making sure SSLv2 is disabled in Apache (and Nginx)</title>
		<link>http://www.evanhoffman.com/evan/2011/09/20/making-sure-sslv2-is-disabled-in-apache/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=making-sure-sslv2-is-disabled-in-apache</link>
		<comments>http://www.evanhoffman.com/evan/2011/09/20/making-sure-sslv2-is-disabled-in-apache/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 18:06:38 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[beast]]></category>
		<category><![CDATA[cipher]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[httpd]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mitm]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[openssl]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[ssl]]></category>
		<category><![CDATA[sslciphersuite]]></category>
		<category><![CDATA[sslv2]]></category>
		<category><![CDATA[tls]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1606</guid>
		<description><![CDATA[Tweet Edit Jan 24, 2012: Deleted all the crap from this story and just left the recommended Apache and Nginx SSL cipher suites for maximum security without SSLv2 and without BEAST vulnerability (at least according to Qualys). Apache httpd SSLProtocol -ALL +SSLv3 +TLSv1 SSLCipherSuite ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM; SSLHonorCipherOrder on nginx ssl_protocols SSLv3 TLSv1; ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM; ssl_prefer_server_ciphers on; [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/09/20/making-sure-sslv2-is-disabled-in-apache/&via=EvanHoffman&text=Making sure SSLv2 is disabled in Apache (and Nginx)&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/09/20/making-sure-sslv2-is-disabled-in-apache/"></g:plusone></div><p><ins datetime="2012-01-24T03:50:52+00:00"><br />
<strong>Edit Jan 24, 2012: </strong> Deleted all the crap from this story and just left the recommended Apache and Nginx SSL cipher suites for maximum security without SSLv2 and without BEAST vulnerability (at least according to Qualys).<br />
</ins><br />
<strong>Apache httpd</strong></p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM;
SSLHonorCipherOrder on</pre></div></div>

<p><strong>nginx</strong></p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">        ssl_protocols  SSLv3 TLSv1;
        ssl_ciphers     ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM;
        ssl_prefer_server_ciphers   on;</pre></div></div>

<p>Source: </p>
<ul>
<li>
<a href="https://community.qualys.com/blogs/securitylabs/2011/10/17/mitigating-the-beast-attack-on-tls">Qualys</a></li>
<li><a href="https://www.ssllabs.com/ssldb/">SSL checker</a></li>
</ul>
<p><a target="_blank" href="http://affiliate.godaddy.com/redirect/5F43C3ECBA841ACFC3859F4F4E6CA7DA64C271385B2D61A3AD6F3CCE83EB1DD8235E60DCD7D63BCD92E2429E79A75FAC"><img src="http://affiliate.godaddy.com/ads/5F43C3ECBA841ACFC3859F4F4E6CA7DA64C271385B2D61A3AD6F3CCE83EB1DD8235E60DCD7D63BCD92E2429E79A75FAC" border="0" width="468"  height="60" alt="Go Daddy $12.99 SSL Sale!"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/09/20/making-sure-sslv2-is-disabled-in-apache/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exchange (OWA) CAS crashes with 503 error &#8211; again</title>
		<link>http://www.evanhoffman.com/evan/2011/09/18/exchange-owa-cas-crashes-with-503-error-again/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exchange-owa-cas-crashes-with-503-error-again</link>
		<comments>http://www.evanhoffman.com/evan/2011/09/18/exchange-owa-cas-crashes-with-503-error-again/#comments</comments>
		<pubDate>Sun, 18 Sep 2011 16:22:46 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[0xe053534f]]></category>
		<category><![CDATA[503]]></category>
		<category><![CDATA[appcrash]]></category>
		<category><![CDATA[crash]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[exchange]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[KERNELBASE.dll]]></category>
		<category><![CDATA[MSExchangeOWAAppPool]]></category>
		<category><![CDATA[owa]]></category>
		<category><![CDATA[w3wp.exe]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1599</guid>
		<description><![CDATA[TweetThis just started happening again, with these errors appearing in the event viewer: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/09/18/exchange-owa-cas-crashes-with-503-error-again/&via=EvanHoffman&text=Exchange (OWA) CAS crashes with 503 error - again&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/09/18/exchange-owa-cas-crashes-with-503-error-again/"></g:plusone></div><p>This just started happening <a href="http://www.evanhoffman.com/evan/?p=986">again</a>, with these errors appearing in the event viewer:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;">Log Name: System
Source: Microsoft-Windows-WAS
Date: 9/18/2011 11:16:33 AM
Event ID: 5011
Task Category: None
Level: Warning
Keywords: Classic
User: N/A
Computer: exch2010fe1
Description:
A process serving application pool 'MSExchangeOWAAppPool' suffered a
fatal communication error with the Windows Process Activation Service.
The process id was '3760'. The data field contains the error number.
&nbsp;
Log Name: System
Source: Microsoft-Windows-WAS
Date: 9/17/2011 6:47:07 AM
Event ID: 5009
Task Category: None
Level: Warning
Keywords: Classic
User: N/A
Computer: exch2010fe1
Description:
A process serving application pool 'MSExchangeOWAAppPool' terminated
unexpectedly. The process id was '3108'. The process exit code was
'0x800703e9'.
&nbsp;
Log Name: Application
Source: Application Error
Date: 9/17/2011 6:46:30 AM
Event ID: 1000
Task Category: (100)
Level: Error
Keywords: Classic
User: N/A
Computer: exch2010fe1
Description:
Faulting application name: w3wp.exe, version: 7.5.7600.16385, time
stamp: 0x4a5bd0eb
Faulting module name: KERNELBASE.dll, version: 6.1.7600.16385, time
stamp: 0x4a5bdfe0
Exception code: 0xe053534f
Fault offset: 0x000000000000aa7d
Faulting process id: 0x%9
Faulting application start time: 0x%10
Faulting application path: %11
Faulting module path: %12
Report Id: %13</pre></td></tr></table></div>

<p>After reviewing the IIS logs and the event logs, I think it has to do with the WebReady document viewer &#8211; the thing in OWA that renders and lets you view .doc attachments within the browser rather than forcing you to open Word or Excel.  I think users were attempting to open corrupted files and that was causing it to crash.  I&#8217;ve disabled Webready in EMC (Server Config -> CAS) and I&#8217;ll see what happens.  </p>
<p><a target="_blank" href="http://affiliate.godaddy.com/redirect/5F43C3ECBA841ACFC3859F4F4E6CA7DA64C271385B2D61A3AD6F3CCE83EB1DD8235E60DCD7D63BCD92E2429E79A75FAC"><img src="http://affiliate.godaddy.com/ads/5F43C3ECBA841ACFC3859F4F4E6CA7DA64C271385B2D61A3AD6F3CCE83EB1DD8235E60DCD7D63BCD92E2429E79A75FAC" border="0" width="468"  height="60" alt="Go Daddy $12.99 SSL Sale!"/></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/09/18/exchange-owa-cas-crashes-with-503-error-again/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>64-bit Firefox 6 on CentOS 6 x86_64 (or Fedora) with Flash 11</title>
		<link>http://www.evanhoffman.com/evan/2011/08/31/64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11</link>
		<comments>http://www.evanhoffman.com/evan/2011/08/31/64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 20:15:14 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[64]]></category>
		<category><![CDATA[64-bit]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[redhat]]></category>
		<category><![CDATA[rpm]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[x86_64]]></category>
		<category><![CDATA[yum]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1583</guid>
		<description><![CDATA[TweetSo I&#8217;ve gone back to Linux from Mac, due to the SSD issues I had with my Macbook Pro basically making VMware unusable. A Win7 VM would grind the guest and host to a halt on the 7200 RPM SATA OEM drive, and the SSD wouldn&#8217;t work, so I put the SSD back in my [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/08/31/64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11/&via=EvanHoffman&text=64-bit Firefox 6 on CentOS 6 x86_64 (or Fedora) with Flash 11&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/08/31/64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11/"></g:plusone></div><p>So I&#8217;ve gone back to Linux from Mac, due to the SSD issues I had with my Macbook Pro basically making VMware unusable. A Win7 VM would grind the guest and host to a halt on the 7200 RPM SATA OEM drive, and the SSD wouldn&#8217;t work, so I put the SSD back in my HP and installed CentOS 6 x86_64. Not really ideal, but at least it works.</p>
<p>CentOS 6 ships with Firefox 3.6.9, which is really old by now. Fine for a server, but I wanted FF6. I grabbed the Firefox 6.0.1 bz2 from <a href="http://www.mozilla.org/community/mirrors.html">VoxCast</a>, unzipped it and copied it to <tt>/usr/lib64/firefox-6</tt>. Then I ran <tt>yum remove firefox</tt> to remove 3.6.9 and avoid any issues. I tried the instructions from <a href="http://www.evanhoffman.com/evan/?p=407">my older post</a> on this subject but for whatever reason it didn&#8217;t work &#8211; I&#8217;m guessing because I&#8217;m not using the distro&#8217;s Firefox RPM.</p>
<p>I followed <a href="http://fedoraproject.org/wiki/Multimedia/Flash#64-bit_Preview_Release">these instructions</a> to get the Flash 11 64-bit plugin installed. It still wasn&#8217;t working though.</p>
<p>I ended up creating a symlink:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib64<span style="color: #000000; font-weight: bold;">/</span>mozilla<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>libflashplayer.so <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>evan<span style="color: #000000; font-weight: bold;">/</span>.mozilla<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>libflashplayer.so</pre></div></div>

<p>When I started up Firefox after creating the symlink, Flash worked.</p>
<p>Additionally, to set Firefox 6 as the default browser, run <tt>gnome-default-applications-properties</tt>, select Custom, and paste <tt>/usr/lib64/firefox-6/firefox %s</tt> in the Command: field.</p>
<p><ins datetime="2011-09-17T21:54:13+00:00">Update:</ins> I upgraded my home desktop PC from FC12 to FC14 last night and used the above procedure to install Firefox 6.0.2 on it with Flash 11.  So, in case anyone was wondering, the above works for Fedora as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/08/31/64-bit-firefox-6-on-centos-6-x86_64-or-fedora-with-flash-11/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Macbook Pro locks up with SSD installed.</title>
		<link>http://www.evanhoffman.com/evan/2011/08/23/macbook-pro-locks-up-with-ssd-installed/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=macbook-pro-locks-up-with-ssd-installed</link>
		<comments>http://www.evanhoffman.com/evan/2011/08/23/macbook-pro-locks-up-with-ssd-installed/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 16:04:54 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[beach ball]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[disk]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[macbook]]></category>
		<category><![CDATA[MC118LL/A]]></category>
		<category><![CDATA[pro]]></category>
		<category><![CDATA[slow]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[spinning]]></category>
		<category><![CDATA[ssd]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1563</guid>
		<description><![CDATA[TweetA few weeks ago I switched from my trusty old HP nc8430 to a Macbook Pro (MC118LL/A) that was left spare when another employee left. I mostly enjoyed using Linux but I was tired of dealing with weird quirks like having X lock up, essentially forcing me to do a hard reboot. To transition, I [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/08/23/macbook-pro-locks-up-with-ssd-installed/&via=EvanHoffman&text=Macbook Pro locks up with SSD installed.&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/08/23/macbook-pro-locks-up-with-ssd-installed/"></g:plusone></div><p>A few weeks ago I switched from my trusty old <a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16834147346">HP nc8430</a> to a <a href="http://www.amazon.com/gp/product/B002C744K6/ref=as_li_ss_tl?ie=UTF8&#038;tag=evanhoffmasho-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399369&#038;creativeASIN=B002C744K6">Macbook Pro</a> (MC118LL/A) that was left spare when another employee left.  I mostly enjoyed using Linux but I was tired of dealing with weird quirks like having X lock up, essentially forcing me to do a hard reboot.  </p>
<p>To transition, I copied my documents from Linux to Mac, then turned off the Linux laptop.  Surprisingly I found I didn&#8217;t need to turn Linux back on at all.<br />
<span id="more-1563"></span><br />
Last week, I decided to put the final nail in Linux&#8217;s coffin by taking the SSD (<a href="http://www.amazon.com/gp/product/B002CI41US/ref=as_li_ss_tl?ie=UTF8&#038;tag=evanhoffmasho-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399369&#038;creativeASIN=B002CI41US">Corsair CMFSSD-128GBG2D</a>)out of it and putting it in my Macbook.  The Macbook was pretty fast (Core 2 Duo @ 2.5 GHz) but some things were noticeably slower on its 7200RPM disk than on Linux with an SSD, especially running Windows VMs.</p>
<p>I booted Linux to Knoppix and zeroed out the disk, then removed it.  I backed my Mac up with Time Machine, shut it down, then undid the ~12 tiny screws, removed the bottom plate of the Macbook and popped the SSD in.  I booted from the Mac DVD, restored from Time Machine and went home (it took ~4 hours to restore).</p>
<p>When I got in the next day, the restore was complete, though I had to click &#8220;Restart&#8221; to finish, which was annoying.  Everything worked fine, and I was pretty impressed.  The machine was kind of sluggish due to Spotlight indexing but once that was done I was pretty amazed at the transformation.  Every app opened in under 1 second.  Windows VMs were super snappy.  Things were going well.  </p>
<p>But then I started noticing periods of extended hanging.  In the middle of some task, I&#8217;d get the <b>beachball</b> and the whole computer would become unresponsive (cursor would spin &#038; move around but I couldn&#8217;t click anything).  This would last about 30-60 seconds.  I assumed it was some behind-the-scenes optimization, or some residual spotlight indexing.  </p>
<p>Unfortunately, it hasn&#8217;t gone away.  Earlier today I copied a 3 GB zip file from our file server to my laptop and it beachballed me on and off (about 60-70% of the time) for about 15 minutes as it copied.  What&#8217;s odd is that the transfer speeds were pretty good, it appeared to be my computer itself that was bottlenecking it.  After the download completed, I attempted to unzip it and was beachballed again.  I checked Activity Monitor and it was peaking at 30 MB/s, but had extended periods of zeroes.  I ran iostat and got basically the same information:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
</pre></td><td class="code"><pre class="log" style="font-family:monospace;">EvanMBP:~ root# iostat -Kw 3
          disk0           disk1       cpu     load average
    KB/t tps  MB/s     KB/t tps  MB/s  us sy id   1m   5m   15m
    9.33   3  0.03     0.00   0  0.00   9  4 87  0.25 0.28 0.32
    0.00   0  0.00     0.00   0  0.00  13  5 82  0.23 0.27 0.32
   20.00   0  0.01     0.00   0  0.00  15  5 80  0.23 0.27 0.32
   36.00   1  0.02     0.00   0  0.00  16  6 77  0.21 0.27 0.32
    0.00   0  0.00     0.00   0  0.00  12  5 83  0.21 0.27 0.32
   20.02  60  1.18     0.00   0  0.00  17 10 74  0.19 0.26 0.32
   24.60 363  8.72     0.00   0  0.00  18 13 69  0.17 0.26 0.31
   25.40 307  7.60     0.00   0  0.00  14 11 75  0.17 0.26 0.31
   21.95 426  9.14     0.00   0  0.00  15 12 73  0.32 0.29 0.32
   82.50 352 28.35     0.00   0  0.00  17 11 73  0.32 0.29 0.32
  809.70  84 66.41     0.00   0  0.00  22  9 69  0.29 0.28 0.32
    0.00   0  0.00     0.00   0  0.00   9  5 86  0.27 0.28 0.32
    0.00   0  0.00     8.89  11  0.09   9  5 86  0.27 0.28 0.32
    0.00   0  0.00     0.00   0  0.00   9  5 87  0.33 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  12  7 81  0.33 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  14  8 78  0.38 0.30 0.33
    0.00   0  0.00     0.00   0  0.00  11  6 83  0.35 0.29 0.33
    0.00   0  0.00     0.00   0  0.00  10  6 84  0.35 0.29 0.33
    0.00   0  0.00     0.00   0  0.00  10  5 84  0.32 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  11  6 84  0.32 0.29 0.32
          disk0           disk1       cpu     load average
    KB/t tps  MB/s     KB/t tps  MB/s  us sy id   1m   5m   15m
    0.00   0  0.00     0.00   0  0.00  10  5 84  0.30 0.28 0.32
    0.00   0  0.00     0.00   0  0.00  11  6 84  0.27 0.28 0.32
    0.00   0  0.00     0.00   0  0.00  11  5 84  0.27 0.28 0.32
    0.00   0  0.00     0.00   0  0.00   9  5 85  0.25 0.27 0.32
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.25 0.27 0.32
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.31 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.45 0.31 0.33
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.45 0.31 0.33
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.41 0.31 0.33
    0.00   0  0.00     0.00   0  0.00  10  5 85  0.41 0.31 0.33
  384.49  10  3.85    10.00   0  0.00  12  6 82  0.32 0.29 0.32
  291.73 126 35.78     0.00   0  0.00  23 13 64  0.38 0.31 0.33
  236.65 338 78.20     0.00   0  0.00  30 17 53  0.34 0.30 0.33
  397.61  21  8.02     0.00   0  0.00  15  8 77  0.34 0.30 0.33
    0.00   0  0.00     0.00   0  0.00  11  6 83  0.32 0.30 0.32
    0.00   0  0.00     0.00   0  0.00  12  7 81  0.32 0.30 0.32
    0.00   0  0.00     0.00   0  0.00  12  6 82  0.29 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  11  6 83  0.35 0.30 0.33
    0.00   0  0.00     0.00   0  0.00  13  6 80  0.35 0.30 0.33
    0.00   0  0.00     0.00   0  0.00  11  6 83  0.32 0.30 0.32
          disk0           disk1       cpu     load average
    KB/t tps  MB/s     KB/t tps  MB/s  us sy id   1m   5m   15m
    0.00   0  0.00     0.00   0  0.00  13  8 78  0.32 0.30 0.32
    0.00   0  0.00     0.00   0  0.00  11  7 82  0.29 0.29 0.32
    0.00   0  0.00     0.00   0  0.00  10  5 86  0.35 0.30 0.33
  148.94 124 18.03     0.00   0  0.00  18  8 73  0.35 0.30 0.33
  267.73 121 31.72     0.00   0  0.00  17  8 76  0.32 0.30 0.32
  355.54 162 56.35     0.00   0  0.00  22  8 69  0.32 0.30 0.32
  738.07  38 27.38     0.00   0  0.00  16  6 78  0.30 0.29 0.32
  512.42  67 33.52     0.00   0  0.00  20  7 73  0.27 0.29 0.32
  835.74  61 50.05     0.00   0  0.00  19  7 73  0.27 0.29 0.32
  536.83  69 36.17     0.00   0  0.00  17  6 76  0.49 0.33 0.34
  543.89  83 43.90     0.00   0  0.00  20  8 72  0.49 0.33 0.34
  720.70  59 41.74     0.00   0  0.00  18  7 76  0.45 0.33 0.33
  541.23 124 65.70     0.00   0  0.00  22  9 70  0.41 0.32 0.33
  260.54 210 53.37     0.00   0  0.00  22  9 70  0.41 0.32 0.33
  806.93  73 57.78     0.00   0  0.00  20  8 72  0.46 0.33 0.34
  874.98  43 37.02     0.00   0  0.00  13  7 80  0.46 0.33 0.34
    0.00   0  0.00     0.00   0  0.00  11  4 85  0.42 0.33 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.39 0.32 0.33
    0.00   0  0.00     0.00   0  0.00   9  4 87  0.39 0.32 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.44 0.33 0.33
          disk0           disk1       cpu     load average
    KB/t tps  MB/s     KB/t tps  MB/s  us sy id   1m   5m   15m
    0.00   0  0.00     0.00   0  0.00  11  5 84  0.44 0.33 0.33
    0.00   0  0.00     0.00   0  0.00  13  6 81  0.48 0.34 0.34
    0.00   0  0.00     0.00   0  0.00  10  4 86  0.44 0.34 0.34
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.44 0.34 0.34
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.41 0.33 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.41 0.33 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 87  0.38 0.32 0.33
    0.00   0  0.00     0.00   0  0.00   7  4 89  0.35 0.32 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 87  0.35 0.32 0.33
    0.00   0  0.00     0.00   0  0.00   7  3 89  0.32 0.31 0.33
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.32 0.31 0.33
    0.00   0  0.00     0.00   0  0.00   7  3 90  0.29 0.31 0.33
  347.11  92 31.29     0.00   0  0.00  20  8 72  0.43 0.34 0.33
   49.98 656 32.03     0.00   0  0.00  32 10 59  0.43 0.34 0.33
  113.45 351 38.90     0.00   0  0.00  40 15 45  0.47 0.35 0.34
  819.41  34 27.20     0.00   0  0.00  26 12 63  0.47 0.35 0.34
  686.99  50 33.76     0.00   0  0.00  18  7 76  0.52 0.36 0.34
  878.17  23 20.01     0.00   0  0.00  20  8 72  0.47 0.35 0.34
    0.00   0  0.00     0.00   0  0.00   8  4 87  0.47 0.35 0.34
    0.00   0  0.00     0.00   0  0.00   8  4 88  0.44 0.34 0.34</pre></td></tr></table></div>

<p>You can see in the MB/s column, lots of &#8220;0.00&#8243; followed by some bursts of ~30 MB/s.  The zeros didn&#8217;t actually print at the time, but flooded the screen in bursts when the bottleneck cleared up.  It seems to me like it might be some problem with queueing or caching, or maybe the SATA controller on this Mac just isn&#8217;t up to the task of SSDs.  I&#8217;m not sure, but at this point I&#8217;m afraid I might have to go back to the 7200 RPM Seagate that came with the Mac.  30-second hangups are far more annoying than having lots of things be slower.  Kind of a strange amortization, if you think about it.  Anyway, I&#8217;ll keep looking into it, now that I know how to reproduce the problem (unzip a huge file).</p>
<p><ins datetime="2011-08-23T20:19:03+00:00">Updated</ins>: A quick Google search for &#8220;beach ball mac SSD&#8221; turned up  <a href="http://crucial.lithium.com/t5/Solid-State-Drives-SSD/MacBook-Pro-Spinning-Beach-Ball-Help/td-p/42328">this thread</a> which seems to be about this same problem, with a different model SSD.  Also referenced in <a href="https://discussions.apple.com/thread/3110516?start=0&#038;tstart=0">this thread</a> on Apple.com.  It feels like the problem may be due to an &#8220;old&#8221; SSD.</p>
<p><ins datetime="2011-08-24T13:04:41+00:00">Updated again</ins>: Here&#8217;s someone having the problem with a Corsair 128 GB SSD: <a href="http://forum.corsair.com/v3/showthread.php?t=91061">http://forum.corsair.com/v3/showthread.php?t=91061</a>.</p>
<p><ins datetime="2011-08-24T16:48:08+00:00">Updated again</ins>: According to <a href="http://forum.crucial.com/t5/Solid-State-Drives-SSD/M4-SSD-with-8GB-DDR3-PC3-8500-on-MBP-5-5-13-2-53-GHz-Mid-2009/m-p/58702/highlight/true#M18141">this post</a>, this appears to be a problem with the SATA controller in the 2009 Macbooks.  Bah.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/08/23/macbook-pro-locks-up-with-ssd-installed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logging RT username in Apache access_log</title>
		<link>http://www.evanhoffman.com/evan/2011/08/08/logging-rt-username-in-apache-access_log/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=logging-rt-username-in-apache-access_log</link>
		<comments>http://www.evanhoffman.com/evan/2011/08/08/logging-rt-username-in-apache-access_log/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 21:34:18 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[access_log]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[httpd]]></category>
		<category><![CDATA[httpd.conf]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[mod_perl]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[rt]]></category>
		<category><![CDATA[rtuser]]></category>
		<category><![CDATA[username]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1513</guid>
		<description><![CDATA[TweetRT has its own internal accounting &#038; tracking system for logging activity, but I was interested in even more granular stuff, like seeing who looked at which tickets. I figured it wouldn&#8217;t be that hard to log this in Apache. Well, I was kind of right, in that it wasn&#8217;t &#8220;hard,&#8221; but it took me [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/08/08/logging-rt-username-in-apache-access_log/&via=EvanHoffman&text=Logging RT username in Apache access_log&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/08/08/logging-rt-username-in-apache-access_log/"></g:plusone></div><p><a href="http://bestpractical.com/rt/">RT</a> has its own internal accounting &#038; tracking system for logging activity, but I was interested in even more granular stuff, like seeing who looked at which tickets.  I figured it wouldn&#8217;t be that hard to log this in Apache.  Well, I was kind of right, in that it wasn&#8217;t &#8220;hard,&#8221; but it took me a long time to find the right place to do it.  I did finally get it though.<br />
<span id="more-1513"></span></p>
<h3>httpd.conf</h3>
<p>In <code>httpd.conf</code> I created a new LogFormat:</p>

<div class="wp_syntax"><div class="code"><pre class="conf" style="font-family:monospace;">LogFormat &quot;%h %l %{RTUSER}e %t \&quot;%r\&quot; %&gt;s %b \&quot;%{Referer}i\&quot; \&quot;%{User-Agent}i\&quot;&quot; combined-rt</pre></div></div>

<p>So instead of the HTTP-auth user, it puts the RT user in this field.  Make sure to update your VirtualHost config to use the combined-rt LogFormat.</p>
<h3>/usr/share/rt3/html/autohandler</h3>
<p>In <code>/usr/share/rt3/html/autohandler</code>, right under this section:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># If we've got credentials, let's serve the file up.</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>    <span style="color: #009900;">&#40;</span> <span style="color: #000066;">defined</span> <span style="color: #0000ff;">$session</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'CurrentUser'</span><span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span>
    <span style="color: #b1b100;">and</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$session</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'CurrentUser'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">Id</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span></pre></div></div>

<p>Add this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">        <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'RTUSER'</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$session</span><span style="color: #009900;">&#123;</span><span style="color: #ff0000;">'CurrentUser'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">UserObj</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">EmailAddress</span><span style="color: #339933;">;</span></pre></div></div>

<p>This populates the RTUSER environment variable with the currently-logged-in user&#8217;s email address.</p>
<p>Restart httpd and the RT user&#8217;s email address should now appear in <code>access_log</code>.  Note that it will only appear for Perl pages (not gifs/jpgs or other static content, since Perl doesn&#8217;t process those):</p>

<div class="wp_syntax"><div class="code"><pre class="log" style="font-family:monospace;">10.0.0.10 - evan@example.com [08/Aug/2011:17:30:34 -0400] &quot;GET /rt3/index.html HTTP/1.1&quot; 200 46809 &quot;-&quot; &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0.1) Gecko/20100101 Firefox/5.0.1&quot;
10.0.0.10 - - [08/Aug/2011:17:30:34 -0400] &quot;GET /rt3/NoAuth/images//css/rolldown-arrow.gif HTTP/1.1&quot; 200 83 &quot;https://help.example.com/rt3/NoAuth/css/3.5-default/main-squished.css&quot; &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:5.0.1) Gecko/20100101 Firefox/5.0.1&quot;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/08/08/logging-rt-username-in-apache-access_log/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Amazon SES: &#8220;illegal headers&#8221; with ses-send-email.pl (followup)</title>
		<link>http://www.evanhoffman.com/evan/2011/08/02/amazon-ses-illegal-headers-with-ses-send-email-pl-followup/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=amazon-ses-illegal-headers-with-ses-send-email-pl-followup</link>
		<comments>http://www.evanhoffman.com/evan/2011/08/02/amazon-ses-illegal-headers-with-ses-send-email-pl-followup/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 18:39:45 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[auto-submitted]]></category>
		<category><![CDATA[bugzilla]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[errors]]></category>
		<category><![CDATA[illegal headers]]></category>
		<category><![CDATA[organization]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[ses]]></category>
		<category><![CDATA[ses-send-email.pl]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[smtp headers]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[x-header]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1486</guid>
		<description><![CDATA[TweetA few people have emailed me asking me to integrate the perl code snippet into I wrote to strip illegal headers when sending email via Amazon SES into something actually usable. I&#8217;ve done so! I haven&#8217;t really tested this beyond sending some test emails, but here it is. Use this at your own risk, I [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/08/02/amazon-ses-illegal-headers-with-ses-send-email-pl-followup/&via=EvanHoffman&text=Amazon SES: "illegal headers" with ses-send-email.pl (followup) &related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/08/02/amazon-ses-illegal-headers-with-ses-send-email-pl-followup/"></g:plusone></div><p>A few people have emailed me asking me to integrate <a href="http://www.evanhoffman.com/evan/?p=1270">the perl code snippet into I wrote to strip illegal headers</a> when sending email via Amazon SES into something actually usable.  I&#8217;ve done so!  I haven&#8217;t really tested this beyond sending some test emails, but here it is.  Use this at your own risk, I make no warranty, blah blah blah.<br />
<span id="more-1486"></span><br />
This fix requires editing <code>ses-send-email.pl</code>, so I&#8217;d advise making a backup copy, though I imagine you can always get a fresh version from Amazon if necessary.</p>
<p>Open ses-send-email.pl in a text editor and find the <code>read_message</code> method.  It should look like this:<br />
<script src="https://gist.github.com/1120804.js?file=ses-send-email.pl"></script></p>
<p>Delete that and paste this in its place:<br />
<script src="https://gist.github.com/1120804.js?file=evan-ses-send-email.pl"></script></p>
<p>I tried it on the command line and it gave the output I expected &#8211; I haven&#8217;t tried integrating it with sendmail/postfix since I haven&#8217;t encountered this problem.  Here&#8217;s the test message I attempted to send:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">From: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
To: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
Subject: Email
Chicken: yummy
Cats: yucky
X-Zombies: <span style="color: #c20cb9; font-weight: bold;">kill</span> them<span style="color: #000000; font-weight: bold;">!</span>
&nbsp;
Now we<span style="color: #ff0000;">'re out of the header, into the body.  Grand!</span></pre></div></div>

<p><code>From</code>, <code>To</code>, and <code>Subject</code> are required headers.  <code>Chicken</code> &#038; <code>Cats</code> are illegal, <code>X-Zombies</code> should be ok since it&#8217;s X-ified.  Here&#8217;s what happened when I tried to send with the unmodified ses-send-email.pl:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>Tue Aug 02 <span style="color: #000000;">14</span>:<span style="color: #000000;">14</span>:<span style="color: #000000;">51</span> evan<span style="color: #000000; font-weight: bold;">@</span>EvanMBP <span style="color: #000000;">62</span> amazon-email<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ .<span style="color: #000000; font-weight: bold;">/</span>ses-send-email.pl <span style="color: #660033;">--verbose</span> <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-r</span>
From: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
To: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
Subject: Email
Chicken: yummy
Cats: yucky
X-Zombies: <span style="color: #c20cb9; font-weight: bold;">kill</span> them<span style="color: #000000; font-weight: bold;">!</span>
&nbsp;
Now we<span style="color: #ff0000;">'re out of the header, into the body.  Grand!
&nbsp;
&nbsp;
&lt;ErrorResponse xmlns=&quot;http://ses.amazonaws.com/doc/2010-12-01/&quot;&gt;
  &lt;Error&gt;
    &lt;Type&gt;Sender&lt;/Type&gt;
    &lt;Code&gt;InvalidParameterValue&lt;/Code&gt;
    &lt;Message&gt;Illegal header '</span>Chicken<span style="color: #ff0000;">'.&lt;/Message&gt;
  &lt;/Error&gt;
  &lt;RequestId&gt;5ffad294-bd33-11e0-b6e3-affca9ad1eb5&lt;/RequestId&gt;
&lt;/ErrorResponse&gt;
Illegal header '</span>Chicken<span style="color: #ff0000;">'.</span></pre></div></div>

<p>Illegal header error.  Now with the modified version:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>Tue Aug 02 <span style="color: #000000;">14</span>:<span style="color: #000000;">15</span>:<span style="color: #000000;">17</span> evan<span style="color: #000000; font-weight: bold;">@</span>EvanMBP <span style="color: #000000;">63</span> amazon-email<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ .<span style="color: #000000; font-weight: bold;">/</span>ses-send-email-x-headers.pl <span style="color: #660033;">--verbose</span> <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-r</span>
From: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
To: evan<span style="color: #000000; font-weight: bold;">@</span>example.com
Subject: Email
Chicken: yummy
Cats: yucky
X-Zombies: <span style="color: #c20cb9; font-weight: bold;">kill</span> them<span style="color: #000000; font-weight: bold;">!</span>
&nbsp;
Now we<span style="color: #ff0000;">'re out of the header, into the body.  Grand!
&nbsp;
&nbsp;
&lt;SendRawEmailResponse xmlns=&quot;http://ses.amazonaws.com/doc/2010-12-01/&quot;&gt;
  &lt;SendRawEmailResult&gt;
    &lt;MessageId&gt;000001318bb51442-c2cfb780-0604-4363-925a-54a57015e567-000000&lt;/MessageId&gt;
  &lt;/SendRawEmailResult&gt;
  &lt;ResponseMetadata&gt;
    &lt;RequestId&gt;64e75a47-bd33-11e0-9d09-8f08f31615ad&lt;/RequestId&gt;
  &lt;/ResponseMetadata&gt;
&lt;/SendRawEmailResponse&gt;</span></pre></div></div>

<p>No errors, and I received the email below (extraneous SMTP headers added by Barracuda/Exchange removed):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">From: <span style="color: #000000; font-weight: bold;">&lt;</span>evan<span style="color: #000000; font-weight: bold;">@</span>example.com<span style="color: #000000; font-weight: bold;">&gt;</span>
To: <span style="color: #000000; font-weight: bold;">&lt;</span>evan<span style="color: #000000; font-weight: bold;">@</span>example.com<span style="color: #000000; font-weight: bold;">&gt;</span>
Subject: Email
X-Chicken: yummy
X-ASG-Orig-Subj: Email
X-Cats: yucky
X-Zombies: <span style="color: #c20cb9; font-weight: bold;">kill</span> them<span style="color: #000000; font-weight: bold;">!</span>
Date: Tue, <span style="color: #000000;">2</span> Aug <span style="color: #000000;">2011</span> <span style="color: #000000;">18</span>:<span style="color: #000000;">15</span>:<span style="color: #000000;">25</span> +0000
Message-ID: <span style="color: #000000; font-weight: bold;">&lt;</span>000001318bb51442-c2cfb780-0604-<span style="color: #000000;">4363</span>-925a-54a57015e567-000000<span style="color: #000000; font-weight: bold;">@</span>email.amazonses.com<span style="color: #000000; font-weight: bold;">&gt;</span>
Content-Type: text<span style="color: #000000; font-weight: bold;">/</span>plain
MIME-Version: <span style="color: #000000;">1.0</span>
&nbsp;
Now we<span style="color: #ff0000;">'re out of the header, into the body.  Grand!</span></pre></div></div>

<p>Illegal headers have been X-ified.  Hope this helps someone.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/08/02/amazon-ses-illegal-headers-with-ses-send-email-pl-followup/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>33 hours to restore a Postgres DB</title>
		<link>http://www.evanhoffman.com/evan/2011/07/26/33-hours/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=33-hours</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/26/33-hours/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 22:10:01 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[logger]]></category>
		<category><![CDATA[long]]></category>
		<category><![CDATA[pgrestore]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[syslog]]></category>
		<category><![CDATA[time]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1457</guid>
		<description><![CDATA[Restoring a huge DB takes a long time.]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/07/26/33-hours/&via=EvanHoffman&text=33 hours to restore a Postgres DB&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/07/26/33-hours/"></g:plusone></div><p>Having <a href="http://www.evanhoffman.com/evan/?p=1390">migrated our DB to a new machine</a>, I was left with a pretty good machine unused.  I decided to rebuild it and try out Postgres 9.0.<br />
<span id="more-1457"></span><br />
I downloaded and installed CentOS 6.0 x86_64, built Postgres 9.0.4 from SRPMS (makes me feel better building it myself), installed it and did <code>initdb</code>, dumped the primary DB to our NAS using <code>psql</code> 9.0 (<code>pg_dump [db] | gzip > /path/to/file.gz</code>) and began the restore.</p>
<p>Not much of a story but it took 33 hours to restore the DB, with the bulk of the time spent building indices.  When the restore was complete I did an <code>analyze verbose</code> which took another 2 hours, for a total of 35 hours, not counting the time it took to create the dump file &#8211; about 14 hours, but this was with the DB under heavy load, made heavier by the dump, so I don&#8217;t know how long it would really take.  I&#8217;m glad I didn&#8217;t have to do this to migrate, but I&#8217;m not relishing the idea of doing a real upgrade to 9.0 if it&#8217;s going to take this long.  For the restore I disabled autovacuum and set <code>fsync = off</code>.  It&#8217;s an ext4 filesystem on a 24-disk RAID 10 of 10krpm SAS drives.</p>
<p>DB size on disk after a clean restore was 1156 GB, as per <code>pg_database_size()</code>, versus 1237 GB on disk for the one that was migrated via bit-copy, so there&#8217;s a sizable chunk of crud accumulated in there.</p>
<p>Also, in doing this I discovered the <a href="http://linux.die.net/man/1/logger">logger</a> command.  One of the things that I&#8217;ve always found annoying about doing a pg restore is that the output is just a bunch of statements like this:</p>
<pre>
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
CREATE SCHEMA
ALTER SCHEMA
SET
CREATE TABLE
ALTER TABLE
CREATE FUNCTION
ALTER FUNCTION
</pre>
<p>This is just what&#8217;s returned from the SQL commands, but it&#8217;s not very informative, and most importantly it doesn&#8217;t show you the timestamp so you have no idea how long anything&#8217;s taking.  With <code>logger</code>, you can just pipe the output to it and it&#8217;ll be logged with syslog.  So my restore command looked like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">zcat</span> <span style="color: #000000; font-weight: bold;">/</span>nfs<span style="color: #000000; font-weight: bold;">/</span>db<span style="color: #000000; font-weight: bold;">/</span>pgdump-<span style="color: #000000;">90</span>.sql.gz <span style="color: #000000; font-weight: bold;">|</span> psql <span style="color: #660033;">-Upguser</span> db <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> ~<span style="color: #000000; font-weight: bold;">/</span>restore.20110723-<span style="color: #000000;">1916</span>.log <span style="color: #000000; font-weight: bold;">|</span> logger <span style="color: #660033;">-t</span> PGRESTORE</pre></div></div>

<p>This made it trivial to get the messages out of <code>/var/log/messages</code> with grep:</p>
<pre>
[root@link log]# grep PGRESTORE messages | head
Jul 24 03:36:43 link PGRESTORE: ALTER TABLE
Jul 24 03:36:43 link PGRESTORE: SET
Jul 24 03:36:44 link PGRESTORE: ALTER TABLE
Jul 24 03:36:44 link PGRESTORE: ALTER TABLE
Jul 24 03:38:45 link PGRESTORE: ALTER TABLE
Jul 24 03:39:13 link PGRESTORE: ALTER TABLE
Jul 24 03:39:13 link PGRESTORE: ALTER TABLE
Jul 24 03:39:13 link PGRESTORE: ALTER TABLE
Jul 24 03:39:13 link PGRESTORE: SET
Jul 24 03:39:13 link PGRESTORE: ALTER TABLE
</pre>
<p>In addition to having the timestamps it eliminates the accumulation of the random log files that accumulate like droppings from myriad one-off scripts.  I modified about 20 cron jobs to pipe their output to logger rather than junk files in /tmp or my homedir.  I can&#8217;t believe I never heard of logger before!  Hooray for logger!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/26/33-hours/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Benchmarking disk IO on ext3 vs ext4 vs xfs with fio</title>
		<link>http://www.evanhoffman.com/evan/2011/07/22/benchmarking-disk-io-on-ext3-vs-ext4-with-fio/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=benchmarking-disk-io-on-ext3-vs-ext4-with-fio</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/22/benchmarking-disk-io-on-ext3-vs-ext4-with-fio/#comments</comments>
		<pubDate>Fri, 22 Jul 2011 11:15:05 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[disk]]></category>
		<category><![CDATA[fio]]></category>
		<category><![CDATA[io]]></category>
		<category><![CDATA[iops]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[msa 70]]></category>
		<category><![CDATA[msa70]]></category>
		<category><![CDATA[p800]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[xfs]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1425</guid>
		<description><![CDATA[3 filesystems, 1 server.]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/07/22/benchmarking-disk-io-on-ext3-vs-ext4-with-fio/&via=EvanHoffman&text=Benchmarking disk IO on ext3 vs ext4 vs xfs with <code>fio</code>&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/07/22/benchmarking-disk-io-on-ext3-vs-ext4-with-fio/"></g:plusone></div><p>With the old database phased out, I figured this was a good time to benchmark IO on it before either repurposing it or mothballing it.  In <a href="http://www.evanhoffman.com/evan/?p=188">the past</a> I&#8217;ve used <code>dd</code> for elementary sequential read/write testing, but I recently found <a href="http://freshmeat.net/projects/fio/">fio</a> which is much more versatile.  Apparently developed by FusionIO, fio lets you control concurrency, blocksize and many other parameters and reports lots more data, most notably <a href="http://en.wikipedia.org/wiki/IOPS">IOPS</a>.<br />
<span id="more-1425"></span><br />
I created 4 fio config files, basically the same as the one below, for direct / buffered disk access and sequential / random writes.  All have 8k blocksize since that&#8217;s what Postgres uses by default.</p>
<pre>

[root@link ~]# cat random-write-test.fio
[random-write]
rw=randwrite
size=5G
direct=1
directory=/msa70/fio/data/
numjobs=5
group_reporting
name=random-write-direct
bs=8k
runtime=10
</pre>
<pre>
[root@link ~]# cat sequential-write-test-buf.fio
[sequential-write]
rw=write
size=5G
direct=0
directory=/msa70/fio/data/
numjobs=5
group_reporting
name=sequential-write-buffered
bs=8k
runtime=10
</pre>
<p>First I ran fio against a freshly created ext3 volume on our HP MSA70 with 24x 10kRPM SAS disks in RAID 10.  The mkfs command used was <code>mke2fs -j -m0 /dev/cciss/c0d0</code>.  The controller card is a <a href="http://h18000.www1.hp.com/products/servers/proliantstorage/arraycontrollers/smartarrayp800/index.html">HP P800</a>.  Here&#8217;s the output:</p>
<div id="wp-spoiler-1" class="wp-spoiler wpui-light">  <h3 class="wp-spoiler-title fade-true slide-true open-false">fio - ext3 full results</h3><div class="wp-spoiler-content">
<pre>
[root@link ~]# time fio random-write-test.fio random-write-test-buf.fio sequential-write-test.fio sequential-write-test-buf.fio
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
fio 1.57
Starting 20 processes
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
Jobs: 1 (f=1): [________________W___] [19.8% done] [0K/0K /s] [0 /0  iops] [eta 03m:14s]
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2447
  write: io=596856KB, bw=56946KB/s, iops=7118 , runt= 10481msec
    clat (usec): min=67 , max=944937 , avg=645.32, stdev=4647.69
     lat (usec): min=67 , max=944937 , avg=645.46, stdev=4647.69
    bw (KB/s) : min=  144, max=47152, per=22.71%, avg=12933.03, stdev=4985.93
  cpu          : usr=0.26%, sys=1.48%, ctx=74614, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/74607/0, short=0/0/0
     lat (usec): 100=12.22%, 250=80.24%, 500=6.59%, 750=0.20%, 1000=0.16%
     lat (msec): 2=0.07%, 4=0.01%, 10=0.10%, 20=0.05%, 50=0.08%
     lat (msec): 100=0.10%, 250=0.14%, 500=0.04%, 750=0.01%, 1000=0.01%
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2452
  write: io=6377.3MB, bw=472902KB/s, iops=59112 , runt= 13809msec
    clat (usec): min=8 , max=4490.8K, avg=77.54, stdev=3751.21
     lat (usec): min=8 , max=4490.8K, avg=77.66, stdev=3751.21
    bw (KB/s) : min=    7, max=438688, per=34.13%, avg=161414.56, stdev=63682.89
  cpu          : usr=2.27%, sys=24.01%, ctx=1596, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/816288/0, short=0/0/0
     lat (usec): 10=0.06%, 20=83.59%, 50=16.19%, 100=0.04%, 250=0.04%
     lat (usec): 500=0.03%, 750=0.01%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.03%, 50=0.01%
     lat (msec): 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
     lat (msec): 2000=0.01%, >=2000=0.01%
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2457
  write: io=2832.0KB, bw=286105 B/s, iops=34 , runt= 10136msec
    clat (usec): min=75 , max=1506.6K, avg=157500.69, stdev=96237.55
     lat (usec): min=75 , max=1506.6K, avg=157500.81, stdev=96237.54
    bw (KB/s) : min=    6, max=  444, per=19.58%, avg=54.61, stdev=13.65
  cpu          : usr=0.00%, sys=0.00%, ctx=572, majf=0, minf=140
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/354/0, short=0/0/0
     lat (usec): 100=4.80%, 250=33.05%, 500=0.56%
     lat (msec): 50=1.13%, 100=18.36%, 250=25.99%, 500=9.04%, 750=4.24%
     lat (msec): 1000=1.41%, 2000=1.41%
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2462
  write: io=255624KB, bw=19933KB/s, iops=2491 , runt= 12824msec
    clat (usec): min=7 , max=9411.7K, avg=1443.28, stdev=33091.95
     lat (usec): min=7 , max=9411.7K, avg=1443.38, stdev=33091.95
    bw (KB/s) : min=   31, max=43687, per=29.58%, avg=5896.30, stdev=2696.81
  cpu          : usr=0.05%, sys=0.89%, ctx=600, majf=0, minf=136
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/31953/0, short=0/0/0
     lat (usec): 10=13.51%, 20=77.52%, 50=8.68%, 100=0.07%, 250=0.08%
     lat (usec): 500=0.03%, 750=0.01%
     lat (msec): 4=0.01%, 10=0.01%, 20=0.02%, 50=0.01%, 250=0.01%
     lat (msec): 750=0.02%, 2000=0.01%, >=2000=0.03%

Run status group 0 (all jobs):
  WRITE: io=596856KB, aggrb=56946KB/s, minb=58313KB/s, maxb=58313KB/s, mint=10481msec, maxt=10481msec

Run status group 1 (all jobs):
  WRITE: io=6377.3MB, aggrb=472902KB/s, minb=484251KB/s, maxb=484251KB/s, mint=13809msec, maxt=13809msec

Run status group 2 (all jobs):
  WRITE: io=2832KB, aggrb=279KB/s, minb=286KB/s, maxb=286KB/s, mint=10136msec, maxt=10136msec

Run status group 3 (all jobs):
  WRITE: io=255624KB, aggrb=19933KB/s, minb=20411KB/s, maxb=20411KB/s, mint=12824msec, maxt=12824msec

Disk stats (read/write):
  cciss!c0d0: ios=798/24542244, merge=0/937067, ticks=15866/140262853, in_queue=140448875, util=89.71%

real    18m35.082s
user    0m4.328s
sys     5m16.479s
[root@link ~]#
</pre>
<p></div>  </div><!-- end div.wp-spoiler --><br />
That&#8217;s a lot of data; the most interesting numbers are these:</p>
<pre>
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2447
  write: io=596856KB, bw=56946KB/s, iops=7118 , runt= 10481msec
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2452
  write: io=6377.3MB, bw=472902KB/s, iops=59112 , runt= 13809msec
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2457
  write: io=2832.0KB, bw=286105 B/s, iops=34 , runt= 10136msec
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2462
  write: io=255624KB, bw=19933KB/s, iops=2491 , runt= 12824msec
</pre>
<p>I then reformatted the RAIDed LUN with ext4 with <code>mkfs.ext4 -m0 /dev/cciss/c0d0</code> and ran the same tests again:<br />
<div id="wp-spoiler-2" class="wp-spoiler wpui-light">  <h3 class="wp-spoiler-title fade-true slide-true open-false">fio - ext4 full results</h3><div class="wp-spoiler-content"></p>
<pre>
[root@link ~]# time fio random-write-test.fio random-write-test-buf.fio sequential-write-test.fio sequential-write-test-buf.fio
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
fio 1.57
Starting 20 processes
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
Jobs: 5 (f=5): [_______________WWWWW] [21.5% done] [0K/126.1M /s] [0 /15.9K iops] [eta 02m:30s]
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2379
  write: io=589392KB, bw=58933KB/s, iops=7366 , runt= 10001msec
    clat (usec): min=77 , max=2522.4K, avg=781.82, stdev=9768.99
     lat (usec): min=77 , max=2522.4K, avg=781.95, stdev=9768.99
    bw (KB/s) : min=  515, max=44176, per=22.05%, avg=12996.62, stdev=5332.75
  cpu          : usr=0.26%, sys=2.86%, ctx=73715, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/73674/0, short=0/0/0
     lat (usec): 100=2.54%, 250=92.13%, 500=4.76%, 750=0.14%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.07%, 20=0.04%, 50=0.07%
     lat (msec): 100=0.09%, 250=0.11%, 500=0.03%, 750=0.01%, 1000=0.01%
     lat (msec): 2000=0.01%, >=2000=0.01%
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2384
  write: io=6707.1MB, bw=670727KB/s, iops=83840 , runt= 10241msec
    clat (usec): min=7 , max=1582.5K, avg=57.04, stdev=1910.33
     lat (usec): min=7 , max=1582.5K, avg=57.15, stdev=1910.33
    bw (KB/s) : min=   30, max=518784, per=25.08%, avg=168240.26, stdev=84472.16
  cpu          : usr=2.51%, sys=25.56%, ctx=35766, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/858614/0, short=0/0/0
     lat (usec): 10=2.14%, 20=91.72%, 50=5.11%, 100=0.31%, 250=0.15%
     lat (usec): 500=0.19%, 750=0.15%, 1000=0.09%
     lat (msec): 2=0.08%, 4=0.03%, 10=0.01%, 20=0.01%, 50=0.01%
     lat (msec): 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
     lat (msec): 2000=0.01%
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2389
  write: io=839760KB, bw=83959KB/s, iops=10494 , runt= 10002msec
    clat (usec): min=70 , max=300244 , avg=473.09, stdev=3815.84
     lat (usec): min=71 , max=300244 , avg=473.22, stdev=3815.84
    bw (KB/s) : min= 8198, max=30528, per=20.27%, avg=17014.88, stdev=1677.78
  cpu          : usr=0.32%, sys=3.15%, ctx=104986, majf=0, minf=140
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/104970/0, short=0/0/0
     lat (usec): 100=73.60%, 250=26.18%, 500=0.01%, 750=0.01%
     lat (msec): 50=0.01%, 100=0.01%, 250=0.18%, 500=0.02%
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2394
  write: io=1730.7MB, bw=163683KB/s, iops=20460 , runt= 10827msec
    clat (usec): min=7 , max=7649.9K, avg=220.41, stdev=12535.19
     lat (usec): min=7 , max=7649.9K, avg=220.52, stdev=12535.19
    bw (KB/s) : min=   27, max=331055, per=35.92%, avg=58788.88, stdev=27863.44
  cpu          : usr=0.42%, sys=5.54%, ctx=4119, majf=0, minf=136
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/221525/0, short=0/0/0
     lat (usec): 10=50.94%, 20=47.34%, 50=1.45%, 100=0.18%, 250=0.05%
     lat (usec): 500=0.01%, 750=0.01%, 1000=0.01%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%
     lat (msec): 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
     lat (msec): 2000=0.01%, >=2000=0.01%

Run status group 0 (all jobs):
  WRITE: io=589392KB, aggrb=58933KB/s, minb=60347KB/s, maxb=60347KB/s, mint=10001msec, maxt=10001msec

Run status group 1 (all jobs):
  WRITE: io=6707.1MB, aggrb=670726KB/s, minb=686824KB/s, maxb=686824KB/s, mint=10241msec, maxt=10241msec

Run status group 2 (all jobs):
  WRITE: io=839760KB, aggrb=83959KB/s, minb=85974KB/s, maxb=85974KB/s, mint=10002msec, maxt=10002msec

Run status group 3 (all jobs):
  WRITE: io=1730.7MB, aggrb=163683KB/s, minb=167611KB/s, maxb=167611KB/s, mint=10827msec, maxt=10827msec

Disk stats (read/write):
  cciss!c0d0: ios=52/276341, merge=0/553601, ticks=224/1731709, in_queue=1735311, util=94.47%

real    0m42.218s
user    0m1.812s
sys     0m19.028s
[root@link ~]#
</pre>
<p></div>  </div><!-- end div.wp-spoiler --><br />
Summary numbers:</p>
<pre>
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2379
  write: io=589392KB, bw=58933KB/s, iops=7366 , runt= 10001msec
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2384
  write: io=6707.1MB, bw=670727KB/s, iops=83840 , runt= 10241msec
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2389
  write: io=839760KB, bw=83959KB/s, iops=10494 , runt= 10002msec
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2394
  write: io=1730.7MB, bw=163683KB/s, iops=20460 , runt= 10827msec
</pre>
<p>This is just one run of each test, so not very scientific, but it does look pretty clear that ext4 outperforms ext3 (I actually did run the test several times but didn&#8217;t collect the results, they were pretty consistent though).  What the test doesn&#8217;t show, but you can see from the <code>time</code> output is that each ext3 test took over 4 minutes to run while the ext4 tests each took about 10-12 seconds.  In the ext3 tests, each &#8220;file1: Laying out IO file(s) (1 file(s) / 5120MB)&#8221; line took nearly a minute; in the ext4 tests they were essentially instant.  </p>
<p>This is nothing groundbreaking, I was just playing around with fio and figured I&#8217;d post the results in case anyone else was curious.  I did notice some oddities though, like the fact that random buffered writes appear to be faster than even sequential buffered writes, on both ext3 and ext4 &#8211; on ext4, showing 670 MB/s random buffered writes and 83k IOPS.  That doesn&#8217;t seem to make much sense, but I&#8217;ll leave the tea-leaf reading to someone else.</p>
<p><ins datetime="2011-07-22T04:17:06+00:00">Addendum</ins>: I ran the test with XFS, just for fun.  Overall, it was significantly faster than ext3, but not as fast as ext4, though sequential buffered writes were much faster than either ext3 or ext4.</p>
<div id="wp-spoiler-3" class="wp-spoiler wpui-light">  <h3 class="wp-spoiler-title fade-true slide-true open-false">fio - xfs full results</h3><div class="wp-spoiler-content"></p>
<pre>
[root@link ~]# mkfs.xfs -f -b size=4k /dev/cciss/c0d0
meta-data=/dev/cciss/c0d0        isize=256    agcount=4, agsize=107506378 blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=430025510, imaxpct=5
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal log           bsize=4096   blocks=209973, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[root@link ~]# mount -v -t xfs /dev/cciss/c0d0 /msa70/
/dev/cciss/c0d0 on /msa70 type xfs (rw)
[root@link ~]# mkdir -p /msa70/fio/data
(reverse-i-search)`f': mkdir -p /msa70/^Co/data
[root@link ~]# time fio random-write-test.fio random-write-test-buf.fio sequential-write-test.fio sequential-write-test-buf.fio
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-direct: (g=0): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
random-write-buf: (g=1): rw=randwrite, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-direct: (g=2): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
...
sequential-write-buffered: (g=3): rw=write, bs=8K-8K/8K-8K, ioengine=sync, iodepth=1
fio 1.57
Starting 20 processes
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
random-write-buf: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-direct: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
sequential-write-buffered: Laying out IO file(s) (1 file(s) / 5120MB)
Jobs: 5 (f=5): [_______________WWWWW] [91.3% done] [0K/143.4M /s] [0 /17.1K iops] [eta 00m:26s]
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2662
  write: io=416920KB, bw=41688KB/s, iops=5210 , runt= 10001msec
    clat (usec): min=83 , max=1592.6K, avg=1013.62, stdev=10137.19
     lat (usec): min=83 , max=1592.6K, avg=1013.77, stdev=10137.19
    bw (KB/s) : min=    7, max=23184, per=22.46%, avg=9363.32, stdev=2852.49
  cpu          : usr=0.31%, sys=1.61%, ctx=106802, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/52115/0, short=0/0/0
     lat (usec): 100=0.06%, 250=4.55%, 500=87.85%, 750=4.23%, 1000=0.70%
     lat (msec): 2=2.01%, 4=0.13%, 10=0.24%, 20=0.07%, 50=0.01%
     lat (msec): 100=0.03%, 250=0.06%, 500=0.03%, 750=0.02%, 2000=0.02%
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2667
  write: io=6557.9MB, bw=27876KB/s, iops=3484 , runt=240892msec
    clat (usec): min=7 , max=237984K, avg=1631.10, stdev=257906.92
     lat (usec): min=7 , max=237984K, avg=1631.22, stdev=257906.92
    bw (KB/s) : min=    0, max=628832, per=1222.74%, avg=340851.04, stdev=70996.06
  cpu          : usr=0.13%, sys=1.33%, ctx=24945, majf=0, minf=134
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/839397/0, short=0/0/0
     lat (usec): 10=18.02%, 20=79.39%, 50=2.19%, 100=0.18%, 250=0.07%
     lat (usec): 500=0.03%, 750=0.01%, 1000=0.04%
     lat (msec): 2=0.02%, 4=0.01%, 10=0.02%, 20=0.01%, 50=0.01%
     lat (msec): 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 2000=0.01%
     lat (msec): >=2000=0.01%
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2677
  write: io=519056KB, bw=51895KB/s, iops=6486 , runt= 10002msec
    clat (usec): min=81 , max=242925 , avg=825.67, stdev=3980.13
     lat (usec): min=81 , max=242925 , avg=825.81, stdev=3980.13
    bw (KB/s) : min=   59, max=20029, per=19.03%, avg=9873.41, stdev=2128.50
  cpu          : usr=0.23%, sys=1.43%, ctx=129921, majf=0, minf=140
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/64882/0, short=0/0/0
     lat (usec): 100=60.60%, 250=38.63%, 500=0.01%
     lat (msec): 10=0.10%, 50=0.11%, 100=0.23%, 250=0.32%
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2682
  write: io=7688.1MB, bw=770776KB/s, iops=96347 , runt= 10215msec
    clat (usec): min=6 , max=1727.2K, avg=53.67, stdev=1633.96
     lat (usec): min=6 , max=1727.2K, avg=53.78, stdev=1633.96
    bw (KB/s) : min= 5340, max=704608, per=21.28%, avg=164049.10, stdev=87065.00
  cpu          : usr=2.15%, sys=19.54%, ctx=16284, majf=0, minf=136
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued r/w/d: total=0/984185/0, short=0/0/0
     lat (usec): 10=41.97%, 20=56.42%, 50=1.10%, 100=0.23%, 250=0.10%
     lat (usec): 500=0.05%, 750=0.02%, 1000=0.03%
     lat (msec): 2=0.01%, 4=0.01%, 10=0.02%, 20=0.01%, 50=0.01%
     lat (msec): 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 2000=0.01%

Run status group 0 (all jobs):
  WRITE: io=416920KB, aggrb=41687KB/s, minb=42688KB/s, maxb=42688KB/s, mint=10001msec, maxt=10001msec

Run status group 1 (all jobs):
  WRITE: io=6557.9MB, aggrb=27876KB/s, minb=28545KB/s, maxb=28545KB/s, mint=240892msec, maxt=240892msec

Run status group 2 (all jobs):
  WRITE: io=519056KB, aggrb=51895KB/s, minb=53140KB/s, maxb=53140KB/s, mint=10002msec, maxt=10002msec

Run status group 3 (all jobs):
  WRITE: io=7688.1MB, aggrb=770776KB/s, minb=789274KB/s, maxb=789274KB/s, mint=10215msec, maxt=10215msec

Disk stats (read/write):
  cciss!c0d0: ios=8/836060, merge=0/549215, ticks=11/36458428, in_queue=36468678, util=98.88%

real    4m31.948s
user    0m2.692s
sys     0m24.351s
[root@link ~]#
</pre>
<p></div>  </div><!-- end div.wp-spoiler -->
<p>XFS abridged:</p>
<pre>
random-write-direct: (groupid=0, jobs=5): err= 0: pid=2662
  write: io=416920KB, bw=41688KB/s, iops=5210 , runt= 10001msec
random-write-buf: (groupid=1, jobs=5): err= 0: pid=2667
  write: io=6557.9MB, bw=27876KB/s, iops=3484 , runt=240892msec
sequential-write-direct: (groupid=2, jobs=5): err= 0: pid=2677
  write: io=519056KB, bw=51895KB/s, iops=6486 , runt= 10002msec
sequential-write-buffered: (groupid=3, jobs=5): err= 0: pid=2682
  write: io=7688.1MB, bw=770776KB/s, iops=96347 , runt= 10215msec
</pre>
<p>IOPS graphed:</p>
<p><ins datetime="2011-07-28T20:08:02+00:00"><img src="https://spreadsheets.google.com/spreadsheet/oimg?key=0Arz9JIGL5KjodGplTjZIZGdnV1o3NHAwTER3ZmJEYnc&#038;oid=2&#038;zx=3w96k79xtmxm" /></p>
<p>Bandwidth: </p>
<p><img src="https://spreadsheets.google.com/spreadsheet/oimg?key=0Arz9JIGL5KjodGplTjZIZGdnV1o3NHAwTER3ZmJEYnc&#038;oid=4&#038;zx=fz9y6uzgniox" /><br />
</ins></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/22/benchmarking-disk-io-on-ext3-vs-ext4-with-fio/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>VMWare 5&#8242;s new licensing model.</title>
		<link>http://www.evanhoffman.com/evan/2011/07/17/vmware-5s-new-licensing-model/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=vmware-5s-new-licensing-model</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/17/vmware-5s-new-licensing-model/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 14:20:56 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[5]]></category>
		<category><![CDATA[licensing]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[money]]></category>
		<category><![CDATA[pricing]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[vmware 5]]></category>
		<category><![CDATA[vsphere]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1415</guid>
		<description><![CDATA[TweetAfter reading up on the new VMware licensing&#038;pricing model I understand the uproar. Limiting vRAM is a reasonable constraint, but 32GB per socket for Enterprise? 48 GB for &#8220;Enterprise Plus&#8221;? If you have a dual CPU server with 144 GB (easily configurable last year), with 4.1 you&#8217;d only need 2 enterprise licenses to use all [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/07/17/vmware-5s-new-licensing-model/&via=EvanHoffman&text=VMWare 5's new licensing model.&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/07/17/vmware-5s-new-licensing-model/"></g:plusone></div><p>After reading up on the new VMware licensing&#038;pricing model I understand the uproar. Limiting vRAM is a reasonable constraint, but 32GB per socket for Enterprise? 48 GB for &#8220;Enterprise Plus&#8221;? If you have a dual CPU server with 144 GB (easily configurable last year), with 4.1 you&#8217;d only need 2 enterprise licenses to use all 144 GB, since in 4.1 an &#8220;Enterprise&#8221; license covered 1 CPU (up to 6 cores) and up to 256 GB memory on the host.</p>
<p>But with 5.0 you&#8217;ll either have to buy 5 Enterprise licenses (160 GB) or 3 Enterprise Plus licenses (144 GB) just to use the full 144 GB. I guess VMware has done away with memory overcommit as a selling point? They used to tell us it was recommended to go up to 2:1 so we could safely put ~140 GB of VMs on a 72 GB machine &#8211; with the new model that&#8217;s completely gone.</p>
<p>To put it in monetary terms, on the machine with 144 GB ram from above, the cost for 4.1 would be $2875 * 2 = $5750. To stick with Enterprise it would be $2875 * 5 = $14,375, or $3495 * 3 = $10,485. A gigantic price jump. I haven&#8217;t read up on any features of vSphere 5, but I don&#8217;t think any feature can make up for at minimum nearly doubling the cost, with loss of a major selling point (memory overcommit). I mean, you can still overcommit as long as you&#8217;re willing to pay for the overcommitted memory.  Also, the above numbers are per-host, so if you&#8217;ve got a 5-host cluster you&#8217;re looking at a $25,000 price hike.</p>
<p>VMWare has long been one of my favorite products, but this is making me consider alternatives. Almost 100% of the feedback I&#8217;ve read about this change has been negative. Seems like a huge mistake on VMware&#8217;s part.</p>
<ul>
<li><a href="http://www.vmware.com/files/pdf/vsphere_pricing.pdf">VMware 5.0 pricing</a>
<li><a href="http://www.vmware.com/products/vsphere/pricing.html">VMware 4.1 pricing (as of 7/17/2011)</a>
<li><a href="http://thinkcloud.nl/2011/07/13/vmware-licensing-vram-entitlement-explained/">ThinkCloud: vRAM entitlement Explained</a>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/17/vmware-5s-new-licensing-model/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Migrating a PostgreSQL DB to a new machine without doing a dump &amp; restore</title>
		<link>http://www.evanhoffman.com/evan/2011/07/11/migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/11/migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 18:39:16 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[compellent]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[dba]]></category>
		<category><![CDATA[dl360]]></category>
		<category><![CDATA[dump]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[hp]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[msa]]></category>
		<category><![CDATA[msa70]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[restore]]></category>
		<category><![CDATA[rsync]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1390</guid>
		<description><![CDATA[rsync over NFS can be so fast.]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/07/11/migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore/&via=EvanHoffman&text=Migrating a PostgreSQL DB to a new machine without doing a dump & restore&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/07/11/migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore/"></g:plusone></div><p>Long ago, before I stepped into my role as de facto DBA in my current job, dump &#038; restore of our Postgres database (dumping the entire DB to a text file, formatting the data disk, and restoring the data) was a pretty regular event.  This was needed because we didn&#8217;t regularly vacuum the DB, which in turn was due to vacuums taking forever (which in the end ended up being due to crappy underlying hardware).  We started doing monthly global vacuums (they took so long that monthly was about all we could handle) and we discovered we no longer needed to do dump &#038; restores.  When we finally upgraded to Postgres 8.2, which introduced autovacuum, things got even better, since we didn&#8217;t have to manage vacuuming via cron jobs.<br />
<span id="more-1390"></span><br />
In the years between then and now our Postgres DB has ballooned to such a size that a D&#038;R isn&#8217;t something we could feasibly do in a scheduled maintenance window.  The last time I did one was when we bade farewell to the decrepit database in September, 2007.  At that point our database consumed 730 GB on disk.  Looking through my email archives, we began the dump at 6:30 PM on a Friday night and it completed at 3:48 AM Saturday.  The restore started around 9 AM and ran until around 1 PM (I assume it went so much faster than the dump due to the new DB being significantly better hardware-wise).  Building indices took until 9:27 PM Saturday.  We then ran a global &#8220;ANALYZE&#8221; to generate DB stats; the analyze ran from 10 PM until 1 AM Sunday.  We then had most of Sunday to process the backlog of data that accumulated since Friday afternoon when we took the database offline.</p>
<p>So, with a 730 GB DB, the entire procedure took 9 hours (dump) + 4 hours (restore) + 8 hours (index rebuild) + 3 hours (analyze), so about 24 hours.</p>
<p>However, as I said, in the years since then our database has grown as we house more and more data, currently at about 1220 GB.  It might have been possible to do the migration via dump &#038; restore in the scheduled window, but I wasn&#8217;t looking forward to it.  Instead, I decided to try a different option: copying the data files directly from the old server to the new one.  If this worked it would eliminate almost all the overhead and the move would be complete in however long it took to copy the data from one host to the other.</p>
<h3>Reasons</h3>
<p>We had a couple reasons for doing this upgrade.  Performance wasn&#8217;t really one of them though; we were pretty confident that the performance of the DB was as good as we were likely to get with platter disks, and our SAN doesn&#8217;t currently have SSDs.  The old DB has dual Xeon 5160 2-core CPUs @3.0ghz, 32 GB memory, and a RAID 5 OS volume.  The database resided on an <a href="http://h10010.www1.hp.com/wwpc/us/en/sm/WF05a/12169-304616-3930445-3930445-3930445-3355734.html">HP MSA70</a>, with 24x 10krpm 146 GB SAS drives (+1 hot spare) in RAID 10 for a 1.6 TB logical volume.  At the time I debated RAID 6 vs RAID 10 but in the end I opted for the performance of RAID 10 vs the capacity of RAID 6 and it worked out well.  </p>
<p>But one of the reasons we decided to upgrade was that the drives in the DB were starting to die and the warranty had expired on them, and each disk cost about $300 to replace.  That was a pretty big liability and I expected the disks to begin dying more frequently.</p>
<p>Another reason for upgrading was the benefits of having the data on the SAN, especially snapshotting.  We&#8217;d been doing daily backups for a while but doing a dump of the DB while it&#8217;s in use makes it take forever, causing degraded performance while it&#8217;s running.  Snapshot isn&#8217;t a perfect solution, but at least it&#8217;s an option.</p>
<p>Another reason for wanting to move the DB to the SAN was for DR purposes; if we setup SAN-SAN replication to another site, with the DB on the SAN, we get that backed up for free.</p>
<p>And probably the biggest reason, we were up to 1.25 TB used out of 1.6, over 80% full.  We&#8217;d probably be good for another few months, but for me 80% is pretty full.</p>
<h3>Prerequisites</h3>
<p>In order for this to work, the version of Postgres on both machines has to be of the same minor version.  In my case, the source DB (server A) was running 8.2.5 (the newest at the time the box was built), so I built 8.2.18 (<a href="http://yum.pgrpms.org/srpms/8.2/redhat/rhel-5Client-i386/postgresql-8.2.18-1PGDG.rhel5.src.rpm">source RPM</a>) on the target (server B).  Server B is pretty beefy: <a href="http://h10010.www1.hp.com/wwpc/us/en/sm/WF05a/15351-15351-3328412-241644-241475-4091408.html">HP DL360 G7</a> with dual <a href="http://ark.intel.com/Product.aspx?id=47921">Xeon X5660 6-core CPUs</a> @2.8 GHz, 96 GB PC3-10600 ECC mem, QLogic QLE-4062 iSCSI HBA connected to a 4TB volume on our Compellent SAN (tier 1, RAID 10 across 32x 15krpm FC disks).  Both machines of course need to be of the same architecture, in my case x86_64.  It might work across Intel/AMD, but I&#8217;m not sure about that; fortunately I didn&#8217;t have to worry about that.</p>
<h3>Moving the data</h3>
<p>When we did dump &#038; restores, we dumped directly to a commonly-mounted NAS, which worked well, since we wouldn&#8217;t start the restore until the dump was complete, and we didn&#8217;t want to consume disk on the target with a gigantic dump file (in addition to spinning the disks with reading the dumpfile while attempting to write to them; the contention causes everything to go much slower).  There wasn&#8217;t really any need to use a NAS as an intermediary in this case though, it would just double the amount of time needed to get the data from A to B.</p>
<p>I created an NFS export on B:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>pgsql             10.0.0.35<span style="color: #7a0874; font-weight: bold;">&#40;</span>rw,no_root_squash<span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>And mounted it on A with these options in /etc/fstab:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">10.0.0.36:<span style="color: #000000; font-weight: bold;">/</span>data<span style="color: #000000; font-weight: bold;">/</span>pgsql  <span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>gannon<span style="color: #000000; font-weight: bold;">/</span>nfs nfs     rw,<span style="color: #007800;">rsize</span>=<span style="color: #000000;">32768</span>,<span style="color: #007800;">wsize</span>=<span style="color: #000000;">32768</span>,<span style="color: #007800;">nfsvers</span>=<span style="color: #000000;">3</span>,noatime,udp        <span style="color: #000000;">0</span>     <span style="color: #000000;">0</span></pre></td></tr></table></div>

<p>I tried TCP vs UDP mounts and found UDP was faster.</p>
<p>I then copied the data over with my favorite Unix tool, rsync:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">time</span> rsync <span style="color: #660033;">-atp</span> <span style="color: #660033;">--delete</span> <span style="color: #660033;">--progress</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>pgsql<span style="color: #000000; font-weight: bold;">/</span>data <span style="color: #000000; font-weight: bold;">/</span>mnt<span style="color: #000000; font-weight: bold;">/</span>gannon<span style="color: #000000; font-weight: bold;">/</span>nfs<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>evan<span style="color: #000000; font-weight: bold;">/</span>rsync.log</pre></td></tr></table></div>

<h3>Dry run</h3>
<p>In January I did a dry run of the procedure.  I had tried copying data over without stopping postgres on A, so as not to cause a service interruption, but it didn&#8217;t work; data was changing too rapidly.  By the time the rsync completed, the files it had copied over earliest had already been modified again.  I ended up scheduling some downtime for a weekend and did the copy.  With the above NFS settings I was able to transfer data at around 50 MB/s over our gigabit switches, the whole thing took 3-4 hours.  When it came up, everything seemed to be fine.  I was pretty happy, because 3-4 hours is a whole lot better than 24+.</p>
<h3>Day of Reckoning</h3>
<p>I finally did the real migration this past weekend.  I started it at 8 PM and (after an rsync snafu) completed it around 4 AM.  The snafu was caused by my use of the &#8220;<code>--delay-updates</code>&#8221; flag, which I later learned copies modified files to a <code>/.~tmp~/</code> directory, and when all of them are copied, moves them into place in an attempt to make it a more &#8220;atomic&#8221; operation.  I didn&#8217;t realize this was what was happening, and I got a little freaked out when I saw the disk usage for the target growing 100 GB larger than the source.  I cancelled the rsync and ran it again, stupidly dropping the &#8211;delay-updates flag, which with the &#8211;delete flag caused it to delete all the stuff in .~tmp~ that it had already copied over.  It deleted like 300 GB of stuff before I freaked out and cancelled it again.  I cursed myself a few times, then manually moved the contents of .~tmp~ up to the parent to salvage what had already been transferred, and ran the rsync once again to move the remaining data.  So it probably would have been done much sooner had I not cancelled it and then deleted a bunch of my progress.</p>
<p>You may notice that the rsync flags above don&#8217;t include <code>-z</code>.  With huge binary files being transferred over a fast LAN I don&#8217;t think there&#8217;s much reason to use -z, in fact when I added -z the throughput plummeted.</p>
<p>After copying the data, I moved the virtual IP of the DB to the new machine, moved the cron jobs over, started postgres on B and everything worked.  I finished all of my cleanup around 6 AM Saturday, though like I said, I would have been done much sooner had I not deleted a bunch of my progress.  Even still, this is a lot better than the dump &#038; restore scenario, and has the added benefit of being reversible.  I&#8217;m planning to upgrade postgres on A to 8.2.18 and leave it as a standby server; if a problem arises with B, the data can be moved back relatively quickly.</p>
<h3>Conclusion</h3>
<p>Well, I don&#8217;t have any great insight to put here, but so far this has worked out.  My next DB project is upgrading from 8.2 to either 8.4 or the 9.x series, but that&#8217;s going to require a lot more planning since client drivers will likely need to be updated, and I&#8217;m not sure if queries might need to be altered.  </p>
<p>The end (I hope).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/11/migrating-a-postgresql-db-to-a-new-machine-without-doing-a-dump-restore/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remount all NFS mounts to another cluster IP</title>
		<link>http://www.evanhoffman.com/evan/2011/07/07/remount-all-nfs-mounts-to-another-cluster-ip/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=remount-all-nfs-mounts-to-another-cluster-ip</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/07/remount-all-nfs-mounts-to-another-cluster-ip/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 21:51:44 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[isilon]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[remount]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[xargs]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1387</guid>
		<description><![CDATA[Putting this here for safekeeping.]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/07/07/remount-all-nfs-mounts-to-another-cluster-ip/&via=EvanHoffman&text=Remount all NFS mounts to another cluster IP&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/07/07/remount-all-nfs-mounts-to-another-cluster-ip/"></g:plusone></div>
<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mount</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> 10.0.0.73 <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">cut</span> <span style="color: #660033;">-f3</span> -d\  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #c20cb9; font-weight: bold;">mount</span> <span style="color: #660033;">-o</span> remount,rw,<span style="color: #007800;">rsize</span>=<span style="color: #000000;">32768</span>,<span style="color: #007800;">wsize</span>=<span style="color: #000000;">32768</span>,<span style="color: #007800;">nfsvers</span>=<span style="color: #000000;">3</span>,<span style="color: #7a0874; font-weight: bold;">bg</span>,intr,tcp,<span style="color: #007800;">retrans</span>=<span style="color: #000000;">0</span>,<span style="color: #007800;">addr</span>=10.0.0.74</pre></td></tr></table></div>

<p>Not much to say.  This seems to work even when the disk is in use.  Using it with Isilon to remount off of a quiesced node.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/07/remount-all-nfs-mounts-to-another-cluster-ip/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Teaching myself node.js: Part 1</title>
		<link>http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=teaching-myself-node-js-part-1</link>
		<comments>http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 04:50:59 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[npm]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1323</guid>
		<description><![CDATA[In which I try to learn node.js by building a Quora-like site (since it seems everyone is building a blog).]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/&via=EvanHoffman&text=Teaching myself node.js: Part 1&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/"></g:plusone></div><p>I&#8217;ve been meaning for a while to learn node.js.  I read a couple of books and plenty of blog posts but in the end I find, as usual, I can only learn by doing.  I have most of the fundamentals to get started, I just need to have a project.  The typical tutorials I&#8217;ve found focus on creating a blog; I&#8217;m thinking of something more along the lines of a Quora question/answer site.  I&#8217;ll be trying to write this as I go, which will hopefully prod me into actually doing it this time.  (I have a tendency to bounce around different tenses and I expect this will be worse than usual &#8211; stuff will likely be written in past/present/future at various points).<br />
<span id="more-1323"></span><br />
Installing node is pretty easy, I just <a href="http://nodejs.org/dist/">downloaded the source</a> (I used 0.4.7), configured &#038; compiled it.  For MongoDB I use the <a href="http://www.mongodb.org/display/DOCS/CentOS+and+Fedora+Packages">10gen</a> CentOS/Fedora repository.  With node installed, I installed <a href="http://npmjs.org/">npm</a> to facilitate adding other packages.  I started mongod with
<pre>/etc/init.d/mongodb start</pre>
<p>With everything installed and mongod running I thought about the schema of my object.  One of the coolest things about MongoDB is the fact that it&#8217;s &#8220;schemaless&#8221; and you can basically put anything into the DB, so you just need to think about what your objects look like and you can basically shove them into Mongo in that exact format.  I&#8217;ve never been a fan of ORM stuff for SQL and the Mongo document-store type of DB seems like it eliminates the need for that almost entirely, which is great.  So here&#8217;s what I was thinking would be the central object in this q-a site:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;_id&quot;</span> <span style="color: #339933;">:</span> ObjectId<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;4defd2713fce2e9bc35d09f0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Bob&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;date&quot;</span> <span style="color: #339933;">:</span> ISODate<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2011-06-08T19:49:48.809Z&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;body&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Is it hot in here?&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;votes&quot;</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;answers&quot;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                <span style="color: #009900;">&#123;</span>
                        <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;evan&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;date&quot;</span> <span style="color: #339933;">:</span> ISODate<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2011-06-08T19:48:54.388Z&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;body&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;I think so.&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;votes&quot;</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span>
                <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                <span style="color: #009900;">&#123;</span>
                        <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Jim&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;date&quot;</span> <span style="color: #339933;">:</span> ISODate<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2011-06-08T19:51:04.714Z&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;body&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Could be.&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;votes&quot;</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span>
                <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
                <span style="color: #009900;">&#123;</span>
                        <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Aaron&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;date&quot;</span> <span style="color: #339933;">:</span> ISODate<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;2011-06-08T19:51:33.313Z&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;body&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;No&quot;</span><span style="color: #339933;">,</span>
                        <span style="color: #3366CC;">&quot;votes&quot;</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;tags&quot;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
                <span style="color: #3366CC;">&quot;question&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;silly&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;stupid&quot;</span><span style="color: #339933;">,</span>
                <span style="color: #3366CC;">&quot;microsoft&quot;</span>
        <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>So this is a &#8220;question&#8221; and it has an author, a date, an array of tags, a title, a vote count, a &#8220;body&#8221; (maybe a longer version of the question), and an array of &#8220;answers&#8221;.  Answers are embedded objects, each with an author, date, body, and votes.  This seems like a decent place to start.</p>
<p>The way the site would work is someone posts a question and other people answer it.  The answers would just be attached to the post in the &#8220;answers&#8221; array.  Other users can vote on answers and the answer with the most votes would be the &#8220;winner&#8221;.  Not exactly groundbreaking, but seems like it should be pretty easy to implement.</p>
<p>I used npm to install the following packages to aid in development:</p>
<pre>$ npm install express jade mongoskin underscore</pre>
<p>Express is a framework that handles request routing and jade is a templating framework.  I used <a href="http://jekjek1989.wordpress.com/2011/03/06/express-with-jade-on-node-js/">this quick walkthrough</a> to setup a basic express/jade app that works and demonstrates most of what I need to know to get this started.  Another good tutorial is <a href="http://dailyjs.com/2010/11/08/node-tutorial-2/">http://dailyjs.com/2010/11/08/node-tutorial-2/</a>.</p>
<p>After some mucking around I figured out how to use Express properly and it made things much easier.  I used mongoskin as the MongoDB library and jade for the template and managed to rig up something that responds to a &#8220;list&#8221; request at http://server:3000/questions by listing all the questions in the &#8220;questions&#8221; collection.  My code as of this point is available on github <a href="https://github.com/evandhoffman/Quaro/tree/f1ea545719c2284d3993f54592eb276563dc1c8d">here</a>.  The <a href="https://github.com/evandhoffman/Quaro/blob/f1ea545719c2284d3993f54592eb276563dc1c8d/views/list.jade">views/list.jade</a> has the template for the question list, and the code that calls the template is in <a href="https://github.com/evandhoffman/Quaro/blob/f1ea545719c2284d3993f54592eb276563dc1c8d/app.js#L47">app.js</a>.</p>
<p>When viewing in a web browser, it currently looks like this (YMMV based on what&#8217;s in your mongodb, of course):</p>
<div id="attachment_1335" class="wp-caption aligncenter" style="width: 656px"><a href="http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/fullscreen-capture-6142011-124430-am/" rel="attachment wp-att-1335"><img src="http://www.evanhoffman.com/evan/wp-content/uploads/2011/06/Fullscreen-capture-6142011-124430-AM.jpg" alt="nodeQuestionList.jpg" title="nodeQuestionList.jpg" width="646" height="609" class="size-full wp-image-1335" /></a><p class="wp-caption-text">nodeQuestionList.jpg</p></div>
<p>That&#8217;s enough for today.  So far I&#8217;m enjoying node.js now that I think I can finally wrap my head around the callback stuff.  Hopefully I can keep up the momentum.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/06/14/teaching-myself-node-js-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PostgreSQL query to determine the largest tables in the database</title>
		<link>http://www.evanhoffman.com/evan/2011/05/17/postgresql-query-to-determine-the-largest-tables-in-the-database/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=postgresql-query-to-determine-the-largest-tables-in-the-database</link>
		<comments>http://www.evanhoffman.com/evan/2011/05/17/postgresql-query-to-determine-the-largest-tables-in-the-database/#comments</comments>
		<pubDate>Tue, 17 May 2011 14:25:32 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[table size]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1283</guid>
		<description><![CDATA[A PostgreSQL query to see the largest tables on-disk in a given database and how large their indices are.]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/05/17/postgresql-query-to-determine-the-largest-tables-in-the-database/&via=EvanHoffman&text=PostgreSQL query to determine the largest tables in the database&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/05/17/postgresql-query-to-determine-the-largest-tables-in-the-database/"></g:plusone></div><p>This is just a handy query I use from time to time to see which tables are growing madly, and how much of the growth is index bloat.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>
schemaname<span style="color: #66cc66;">,</span>
tablename<span style="color: #66cc66;">,</span>
pg_size_pretty<span style="color: #66cc66;">&#40;</span>pg_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> size_p<span style="color: #66cc66;">,</span>
pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> siz<span style="color: #66cc66;">,</span>
pg_size_pretty<span style="color: #66cc66;">&#40;</span>pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> total_size_p<span style="color: #66cc66;">,</span>
pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> pg_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> index_size<span style="color: #66cc66;">,</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#40;</span>pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> pg_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">/</span><span style="color: #993333; font-weight: bold;">CASE</span> <span style="color: #993333; font-weight: bold;">WHEN</span> pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span> <span style="color: #993333; font-weight: bold;">THEN</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">ELSE</span> pg_total_relation_size<span style="color: #66cc66;">&#40;</span>schemaname <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'.'</span> <span style="color: #66cc66;">||</span> tablename<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">END</span> <span style="color: #66cc66;">||</span> <span style="color: #ff0000;">'%'</span> <span style="color: #993333; font-weight: bold;">AS</span> index_pct
<span style="color: #993333; font-weight: bold;">FROM</span> pg_tables
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> siz <span style="color: #993333; font-weight: bold;">DESC</span> <span style="color: #993333; font-weight: bold;">LIMIT</span> <span style="color: #cc66cc;">20</span>;</pre></td></tr></table></div>

<p>This returns schema, table, size on disk (in human-readable and byte format &#8211; for sorting), and total size on disk including indices, and the percentage of the total size that comprises the indexes.</p>
<p>Sample result from our <a href="http://www.igniterealtime.org/downloads/index.jsp">OpenFire</a> Jabber server:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"> schemaname <span style="color: #000000; font-weight: bold;">|</span>      tablename       <span style="color: #000000; font-weight: bold;">|</span>   size_p   <span style="color: #000000; font-weight: bold;">|</span>    siz    <span style="color: #000000; font-weight: bold;">|</span> total_size_p <span style="color: #000000; font-weight: bold;">|</span> index_size <span style="color: #000000; font-weight: bold;">|</span> index_pct 
------------+----------------------+------------+-----------+--------------+------------+-----------
 public     <span style="color: #000000; font-weight: bold;">|</span> ofconversation       <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">71</span> MB      <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">159236096</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">152</span> MB       <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">84623360</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">53</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofconparticipant     <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">38</span> MB      <span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000;">95395840</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">91</span> MB        <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">55394304</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">58</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofpresence           <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">10184</span> kB   <span style="color: #000000; font-weight: bold;">|</span>  <span style="color: #000000;">10452992</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">10208</span> kB     <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">24576</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofpubsubitem         <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">5336</span> kB    <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">7733248</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">7552</span> kB      <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">2269184</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">29</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofid                 <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">4008</span> kB    <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">4120576</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">4024</span> kB      <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">16384</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofpubsubsubscription <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">912</span> kB     <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">1458176</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1424</span> kB      <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">524288</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">35</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofpubsubaffiliation  <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">728</span> kB     <span style="color: #000000; font-weight: bold;">|</span>   <span style="color: #000000;">1196032</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">1168</span> kB      <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">450560</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">37</span><span style="color: #000000; font-weight: bold;">%</span>
 public     <span style="color: #000000; font-weight: bold;">|</span> ofoffline            <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">832</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">942080</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">920</span> kB       <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">90112</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">9</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_depend            <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">320</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">794624</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">776</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">466944</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">58</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_attribute         <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">384</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">761856</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">744</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">368640</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">48</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_proc              <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">376</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">753664</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">736</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">368640</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">48</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_rewrite           <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">72</span> kB      <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">270336</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">264</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">196608</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">72</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_description       <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">136</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">245760</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">240</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">106496</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">43</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_operator          <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">112</span> kB     <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">237568</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">232</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">122880</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">51</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_class             <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">88</span> kB      <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">212992</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">208</span> kB       <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">122880</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">57</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_type              <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">64</span> kB      <span style="color: #000000; font-weight: bold;">|</span>    <span style="color: #000000;">155648</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">152</span> kB       <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">90112</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">57</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_statistic         <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">72</span> kB      <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">98304</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">96</span> kB        <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">24576</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">25</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_amop              <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">24</span> kB      <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">90112</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">88</span> kB        <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">65536</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">72</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_conversion        <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">16</span> kB      <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">90112</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">88</span> kB        <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">73728</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">81</span><span style="color: #000000; font-weight: bold;">%</span>
 pg_catalog <span style="color: #000000; font-weight: bold;">|</span> pg_constraint        <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">8192</span> bytes <span style="color: #000000; font-weight: bold;">|</span>     <span style="color: #000000;">81920</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">80</span> kB        <span style="color: #000000; font-weight: bold;">|</span>      <span style="color: #000000;">73728</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000;">90</span><span style="color: #000000; font-weight: bold;">%</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">20</span> rows<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
Time: <span style="color: #000000;">8.917</span> ms</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/05/17/postgresql-query-to-determine-the-largest-tables-in-the-database/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript: The Good Parts</title>
		<link>http://www.evanhoffman.com/evan/2011/04/26/javascript-the-good-parts/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=javascript-the-good-parts</link>
		<comments>http://www.evanhoffman.com/evan/2011/04/26/javascript-the-good-parts/#comments</comments>
		<pubDate>Tue, 26 Apr 2011 21:20:21 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[book]]></category>
		<category><![CDATA[computers]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1197</guid>
		<description><![CDATA[TweetI just finished reading JavaScript: The Good Parts, one of the best programming books I&#8217;ve read. The ending is fantastic: We see a lot of feature-driven product design in which the cost of features is not properly accounted. Features can have a negative value to consumers because they make the products more difficult to understand [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/04/26/javascript-the-good-parts/&via=EvanHoffman&text=JavaScript: The Good Parts&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/04/26/javascript-the-good-parts/"></g:plusone></div><p>I just finished reading <a href="http://www.amazon.com/gp/product/0596517742/ref=as_li_ss_tl?ie=UTF8&#038;tag=evanhoffmasho-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399349&#038;creativeASIN=0596517742">JavaScript: The Good Parts</a>, one of the best programming books I&#8217;ve read.  The ending is fantastic:</p>
<blockquote><p>We see a lot of feature-driven product design in which the cost of features is not properly accounted. Features can have a negative value to consumers because they make the products more difficult to understand and use. We are finding that people like products that just work. It turns out that designs that just work are much harder to produce than designs that assemble long lists of features.</p>
<p>Features have a specification cost, a design cost, and a development cost. There is a testing cost and a reliability cost. The more features there are, the more likely one will develop problems or will interact badly with another. In software systems, there is a storage cost, which was becoming negligible, but in mobile applications is becoming significant again. There are ascending performance costs because Moore&#8217;s Law doesn&#8217;t apply to batteries.</p>
<p>Features have a documentation cost. Every feature adds pages to the manual, increasing training costs. Features that offer value to a minority of users impose a cost on all users. So, in designing products and programming languages, we want to get the core features—the good parts—right because that is where we create most of the value.</p>
<p>We all find the good parts in the products that we use. We value simplicity, and when simplicity isn&#8217;t offered to us, we make it ourselves. My microwave oven has tons of features, but the only ones I use are cook and the clock. And setting the clock is a struggle. We cope with the complexity of feature-driven design by finding and sticking with the good parts.</p>
<p>It would be nice if products and programming languages were designed to have only good parts.</p></blockquote>
<p><span id="more-1197"></span></p>
<p><iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=evanhoffmasho-20&#038;o=1&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=0596517742" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/04/26/javascript-the-good-parts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Renaming a single-label domain to a FQDN</title>
		<link>http://www.evanhoffman.com/evan/2011/04/07/renaming-a-single-label-domain-to-a-fqdn/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=renaming-a-single-label-domain-to-a-fqdn</link>
		<comments>http://www.evanhoffman.com/evan/2011/04/07/renaming-a-single-label-domain-to-a-fqdn/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 21:56:54 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[2003]]></category>
		<category><![CDATA[2008]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[ad]]></category>
		<category><![CDATA[dfs]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[exchange]]></category>
		<category><![CDATA[exchange 2010]]></category>
		<category><![CDATA[rename]]></category>
		<category><![CDATA[rendom]]></category>
		<category><![CDATA[single-label]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1144</guid>
		<description><![CDATA[TweetLong ago &#8212; eons, perhaps &#8212; before I had anything to do with the Windows environment here, someone created the AD domain in my company as a single-label domain (e.g. instead of &#8220;example.com&#8221; our domain is just &#8220;example&#8221;). Over the years this has led to lots of &#8220;fun&#8221; on the part of Windows admins who&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2011/04/07/renaming-a-single-label-domain-to-a-fqdn/&via=EvanHoffman&text=Renaming a single-label domain to a FQDN&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2011/04/07/renaming-a-single-label-domain-to-a-fqdn/"></g:plusone></div><p>Long ago &#8212; eons, perhaps &#8212; before I had anything to do with the Windows environment here, someone created the AD domain in my company as a single-label domain (e.g. instead of &#8220;example.com&#8221; our domain is just &#8220;example&#8221;).  Over the years this has led to lots of &#8220;fun&#8221; on the part of Windows admins who&#8217;ve worked here as the implications of this choice became more apparent.</p>
<p>Since I inherited this system about a year ago, I haven&#8217;t really bumped up against any problems stemming from the single-label domain issue&#8230; until now.  I recently attempted to add a new Windows 2008r2 file server to our DFS replication group/namespace.  This totally failed for some mysterious reason.  Well, I shouldn&#8217;t say &#8220;totally&#8221; failed, as I was able to add it to the DFS replication group, but unable to add it to the DFS namespace.  In my attempt to debug the namespace issue, I deleted the namespace and attempted to recreate it, but just kept getting this error: <b>The namespace cannot be queried.  The specified domain either does not exist or could not be contacted.</b>.  I couldn&#8217;t do anything with the namespace &#8211; even clicking on it in the DFS Management console brought up an error.  After some searching I found that this was likely due to having a single-label domain.  I wasn&#8217;t sure why the error was happening even on Windows 2003 machines though, maybe joining a 2008r2 box to the domain made some schema changes?  I tried a few suggestions like editing the hosts file but nothing seemed to resolve this.</p>
<p>Fortunately, we didn&#8217;t really need DFS namespaces and were able to just direct everybody to the fileserver via its DNS name, though as you can imagine this was clumsy.  However, since this has been a problem since time immemorial, I figured it was time to see if it was fixable.  After some quick searching, I found <a href="http://technet.microsoft.com/en-us/library/cc732097%28WS.10%29.aspx">RENDOM</a>.  However, after even more searching I discovered <a href="http://technet.microsoft.com/en-us/library/cc816848%28WS.10%29.aspx">this TechNet article</a> which says: </p>
<blockquote><p>The domain rename operation is not supported in Microsoft Exchange Server 2007 or Exchange Server 2010. DNS domain rename is supported in Exchange Server 2003. However, renaming of the NetBIOS domain name is not supported in any version of Exchange Server. Other non-Microsoft applications might also not support domain rename. </p></blockquote>
<p>Well.  We&#8217;re running Exchange 2010.  So now what?  I guess we&#8217;re going to have to create a second domain and migrate over to it.  We&#8217;d already discussed this as a likely way of implementing the rename anyway, since it didn&#8217;t seem like &#8220;RENDOM&#8221; had any rollback procedure &#8211; it either just works (hahaha) or semi-works and semi-fails, leaving a wake of destruction throughout AD.  Building a second domain seems like a lot of work, but at least we can move users over one at a time, and we get the side benefit of starting fresh, outgrowing the 5+ years of crud that&#8217;s accumulated in our AD.</p>
<p>Guess we&#8217;ll see what happens.  Neither option seems like much fun.  I guess the alternative is do nothing, but Microsoft clearly doesn&#8217;t think very highly of single-label domains, and anyone who asks about them gets looked at funny.  At least it gives us something to do!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/04/07/renaming-a-single-label-domain-to-a-fqdn/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>More fun parsing BIND query logs</title>
		<link>http://www.evanhoffman.com/evan/2010/12/13/more-fun-parsing-bind-query-logs/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=more-fun-parsing-bind-query-logs</link>
		<comments>http://www.evanhoffman.com/evan/2010/12/13/more-fun-parsing-bind-query-logs/#comments</comments>
		<pubDate>Mon, 13 Dec 2010 22:21:59 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[queries per second]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=978</guid>
		<description><![CDATA[Tweet&#8220;But wouldn&#8217;t it be cool if it also&#8230;&#8221; That phrase usually triggers a lot of wasted cycles in my brain, though it sometimes comes up with something neat. I added a super lame graph to the DNS QPS parser. Makes it really easy to see peaks &#038; troughs in usage: 2010-12-12 00:00 to 00:59 => [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2010/12/13/more-fun-parsing-bind-query-logs/&via=EvanHoffman&text=More fun parsing BIND query logs&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2010/12/13/more-fun-parsing-bind-query-logs/"></g:plusone></div><p>&#8220;But wouldn&#8217;t it be cool if it also&#8230;&#8221;  That phrase usually triggers a lot of wasted cycles in my brain, though it sometimes comes up with something neat.  I added a super lame graph to the DNS QPS parser.  Makes it really easy to see peaks &#038; troughs in usage:<br />
<span id="more-978"></span></p>
<pre>
2010-12-12 00:00 to 00:59 => 3237, rate 0.899 queries/sec	***********
2010-12-12 01:00 to 01:59 => 2709, rate 0.752 queries/sec	**********
2010-12-12 02:00 to 02:59 => 2473, rate 0.687 queries/sec	*********
2010-12-12 03:00 to 03:59 => 2171, rate 0.603 queries/sec	********
2010-12-12 04:00 to 04:59 => 2048, rate 0.569 queries/sec	*******
2010-12-12 05:00 to 05:59 => 1918, rate 0.533 queries/sec	*******
2010-12-12 06:00 to 06:59 => 2120, rate 0.589 queries/sec	********
2010-12-12 07:00 to 07:59 => 2477, rate 0.688 queries/sec	*********
2010-12-12 08:00 to 08:59 => 2994, rate 0.832 queries/sec	**********
2010-12-12 09:00 to 09:59 => 3704, rate 1.029 queries/sec	*************
2010-12-12 10:00 to 10:59 => 4297, rate 1.194 queries/sec	***************
2010-12-12 11:00 to 11:59 => 4744, rate 1.318 queries/sec	****************
2010-12-12 12:00 to 12:59 => 5106, rate 1.418 queries/sec	******************
2010-12-12 13:00 to 13:59 => 5311, rate 1.475 queries/sec	******************
2010-12-12 14:00 to 14:59 => 5083, rate 1.412 queries/sec	*****************
2010-12-12 15:00 to 15:59 => 4855, rate 1.349 queries/sec	*****************
2010-12-12 16:00 to 16:59 => 5179, rate 1.439 queries/sec	******************
2010-12-12 17:00 to 17:59 => 4959, rate 1.377 queries/sec	*****************
2010-12-12 18:00 to 18:59 => 4693, rate 1.304 queries/sec	****************
2010-12-12 19:00 to 19:59 => 4792, rate 1.331 queries/sec	****************
2010-12-12 20:00 to 20:59 => 4799, rate 1.333 queries/sec	****************
2010-12-12 21:00 to 21:59 => 5068, rate 1.408 queries/sec	*****************
2010-12-12 22:00 to 22:59 => 4672, rate 1.298 queries/sec	****************
2010-12-12 23:00 to 23:59 => 4514, rate 1.254 queries/sec	****************
2010-12-13 00:00 to 00:59 => 3917, rate 1.088 queries/sec	**************
2010-12-13 01:00 to 01:59 => 3458, rate 0.961 queries/sec	************
2010-12-13 02:00 to 02:59 => 2874, rate 0.798 queries/sec	**********
2010-12-13 03:00 to 03:59 => 2715, rate 0.754 queries/sec	**********
2010-12-13 04:00 to 04:59 => 2690, rate 0.747 queries/sec	*********
2010-12-13 05:00 to 05:59 => 2719, rate 0.755 queries/sec	**********
2010-12-13 06:00 to 06:59 => 2831, rate 0.786 queries/sec	**********
2010-12-13 07:00 to 07:59 => 3416, rate 0.949 queries/sec	************
2010-12-13 08:00 to 08:59 => 4962, rate 1.378 queries/sec	*****************
2010-12-13 09:00 to 09:59 => 6943, rate 1.929 queries/sec	************************
2010-12-13 10:00 to 10:59 => 8296, rate 2.304 queries/sec	****************************
2010-12-13 11:00 to 11:59 => 8938, rate 2.483 queries/sec	******************************
2010-12-13 12:00 to 12:59 => 8926, rate 2.479 queries/sec	******************************
2010-12-13 13:00 to 13:59 => 8950, rate 2.486 queries/sec	******************************
2010-12-13 14:00 to 14:59 => 2173, rate 0.604 queries/sec	********
</pre>
<p>You can see pretty quickly that 4-5 AM (Eastern) is the period of lowest activity, as you&#8217;d probably expect for a US-based US-centric site.  Modified perl script below.</p>
<p><script src="https://gist.github.com/994183.js?file=parsebind.pl"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2010/12/13/more-fun-parsing-bind-query-logs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl script to calculate DNS queries per second in BIND (named)</title>
		<link>http://www.evanhoffman.com/evan/2010/12/07/perl-script-to-calculate-dns-queries-per-second-in-bind-named/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=perl-script-to-calculate-dns-queries-per-second-in-bind-named</link>
		<comments>http://www.evanhoffman.com/evan/2010/12/07/perl-script-to-calculate-dns-queries-per-second-in-bind-named/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 22:53:43 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[analyzer]]></category>
		<category><![CDATA[bind]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[name server]]></category>
		<category><![CDATA[named]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[queries per second]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[rndc]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=951</guid>
		<description><![CDATA[TweetI&#8217;m pricing out DNS providers and was asked what our current queries-per-second currently are. Sadly I had no idea. After lots of Googling I decided there was really no good way to get this information so I decided to parse the logfile myself. First, I turned on logging with timestamp in named.conf: logging { ... [...]]]></description>
			<content:encoded><![CDATA[<div style="vertical-align: top; float: right; margin-left: 10px;"><a href="http://twitter.com/share?url=http://www.evanhoffman.com/evan/2010/12/07/perl-script-to-calculate-dns-queries-per-second-in-bind-named/&via=EvanHoffman&text=Perl script to calculate DNS queries per second in BIND (named)&related=EvanHoffman:&lang=en&count=horizontal" class="twitter-share-button">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="plus-one-wrap"><g:plusone size="small" href="http://www.evanhoffman.com/evan/2010/12/07/perl-script-to-calculate-dns-queries-per-second-in-bind-named/"></g:plusone></div><p>I&#8217;m pricing out DNS providers and was asked what our current queries-per-second currently are.  Sadly I had no idea.  After lots of Googling I decided there was really no good way to get this information so I decided to parse the logfile myself.<br />
<span id="more-951"></span><br />
First, I turned on logging with timestamp in named.conf:</p>
<pre>
logging
{
...
        # Query logging 2010-12-07
        channel query-log {
                file "data/queries.log" versions 3 size 10m;
                print-time yes;
        };
        category queries { query-log; };
};
options
{
...
        # Query logging 2010-12-07
        querylog yes;

};
</pre>
<p>Then I restarted named and had to figure out how to parse the file.  My first guess was Perl and it didn&#8217;t disappoint.  Here&#8217;s the hideous mess of code:</p>
<p>parsebind.pl</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#use Date::Parse;</span>
<span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">ParseDate</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line_num</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$first_line</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$date</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%query_counter</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@abbr</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">&lt;&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">chomp</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#my ($date, $time, $ip, $hostname, $in, $type, $crap) = $line  =~ m/^([\d]{2}-[\w]{3}-[\d]{4}) ([\d]{2}:[\d]{2}:[\d]{2}\.[\d]{3}) client ([\d\.]+)#[\d]*: [\w]+: ([\w\d\.]+) ([\w]+) ([\w]+) ([.]*)/;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$line</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">m/^([\d]{2}-[\w]{3}-[\d]{4}) ([\d]{2}:[\d]{2}:[\d]{2}\.[\d]{3}) client ([\d\.]+)#[\d]*: [\w]+: ([\w\d\.]+) ([\w]+) ([\w]+) ([.]*)/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$date</span> <span style="color: #339933;">=</span> parsedate<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$1 $2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">#		print &quot;$1 $2 =&gt; $date\n&quot;;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$date</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$first_line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$line_num</span><span style="color: #339933;">;</span>
			<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;First line:<span style="color: #000099; font-weight: bold;">\t</span>$line_num<span style="color: #000099; font-weight: bold;">\t</span>date<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sec</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$min</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mon</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$year</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$wday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$yday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$isdst</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$year</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1900</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$mon</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$year</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'-'</span> <span style="color: #339933;">.</span> <span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mon</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'-'</span> <span style="color: #339933;">.</span> <span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mday</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span> <span style="color: #ff0000;">' '</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">':00 to '</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">':59'</span> <span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">++;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #0000ff;">$line_num</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Last line:<span style="color: #000099; font-weight: bold;">\t</span>$line_num<span style="color: #000099; font-weight: bold;">\t</span>date<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$elapsed</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$date</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$oldest_record</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$net_records</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$line_num</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$first_line</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$rate</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$net_records</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000ff;">$elapsed</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Rate for $elapsed seconds: &quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%0.2f'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$rate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot; per second<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">sort</span> <span style="color: #000066;">keys</span> <span style="color: #0000ff;">%query_counter</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$rate</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #cc66cc;">3600</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;$key =&gt; $query_counter{$key}, rate &quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%0.3f'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$rate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot; queries/sec<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And the beautiful output:</p>
<pre>
[root@ns3 ~]# perl ~evan/parsebind.pl /var/named/chroot/var/named/data/queries.log
First line:	308	date	Tue Dec  7 17:56:02 2010
Last line:	41289	date	Tue Dec  7 22:44:01 2010
Rate for 17279 seconds: 2.37 per second

2010-12-07 17:00 to 17:59 => 533, rate 0.148 queries/sec
2010-12-07 18:00 to 18:59 => 9185, rate 2.551 queries/sec
2010-12-07 19:00 to 19:59 => 8618, rate 2.394 queries/sec
2010-12-07 20:00 to 20:59 => 8075, rate 2.243 queries/sec
2010-12-07 21:00 to 21:59 => 8762, rate 2.434 queries/sec
2010-12-07 22:00 to 22:59 => 5808, rate 1.613 queries/sec
HASH(0x112382a0) => , rate 0.000 queries/sec
[root@ns3 ~]#
</pre>
<p>Not pretty but good enough to get a sense of QPS.  Hope it helps someone.</p>
<p><strong>Edit</strong>: It occurred to me that you may have more than one domain on a single bind server, and you may want the stats for a single one (rather than all aggregated together, which the above script does).  The below version includes the second-level domain in the hash key for the final report:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
&nbsp;
<span style="color: #666666; font-style: italic;">#use Date::Parse;</span>
<span style="color: #000000; font-weight: bold;">use</span> Time<span style="color: #339933;">::</span><span style="color: #006600;">ParseDate</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line_num</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$first_line</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$date</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">%query_counter</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">@abbr</span> <span style="color: #339933;">=</span> <span style="color: #000066;">qw</span><span style="color: #009900;">&#40;</span> Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">&lt;&gt;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066;">chomp</span><span style="color: #339933;">;</span>
	<span style="color: #0000ff;">$line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$_</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">#my ($date, $time, $ip, $hostname, $in, $type, $crap) = $line  =~ m/^([\d]{2}-[\w]{3}-[\d]{4}) ([\d]{2}:[\d]{2}:[\d]{2}\.[\d]{3}) client ([\d\.]+)#[\d]*: [\w]+: ([\w\d\.]+) ([\w]+) ([\w]+) ([.]*)/;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$line</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">m/^([\d]{2}-[\w]{3}-[\d]{4}) ([\d]{2}:[\d]{2}:[\d]{2}\.[\d]{3}) client ([\d\.]+)#[\d]*: [\w]+: ([\w\d\.]+) ([\w]+) ([\w]+) ([.]*)/</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #0000ff;">$date</span> <span style="color: #339933;">=</span> parsedate<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;$1 $2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$domain</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$4</span> <span style="color: #339933;">=~</span> <span style="color: #009966; font-style: italic;">m/([\w\d\-]+\.[\w]+)$/</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$domain</span> <span style="color: #339933;">=</span> <span style="color: #000066;">lc</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$domain</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">#		print &quot;$1 $2 =&gt; $date\n&quot;;</span>
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$oldest_record</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$date</span><span style="color: #339933;">;</span>
			<span style="color: #0000ff;">$first_line</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$line_num</span><span style="color: #339933;">;</span>
			<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;First line:<span style="color: #000099; font-weight: bold;">\t</span>$line_num<span style="color: #000099; font-weight: bold;">\t</span>date<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$sec</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$min</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mon</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$year</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$wday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$yday</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$isdst</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$year</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1900</span><span style="color: #339933;">;</span>
		<span style="color: #0000ff;">$mon</span> <span style="color: #339933;">+=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$domain</span> <span style="color: #339933;">.</span><span style="color: #ff0000;">' '</span><span style="color: #339933;">.</span><span style="color: #0000ff;">$year</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'-'</span> <span style="color: #339933;">.</span> <span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mon</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'-'</span> <span style="color: #339933;">.</span> <span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$mday</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span> <span style="color: #ff0000;">' '</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">':00 to '</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%02d'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$hour</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">':59'</span> <span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">++;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #0000ff;">$line_num</span><span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Last line:<span style="color: #000099; font-weight: bold;">\t</span>$line_num<span style="color: #000099; font-weight: bold;">\t</span>date<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">localtime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$date</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$elapsed</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$date</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$oldest_record</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$net_records</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$line_num</span> <span style="color: #339933;">-</span> <span style="color: #0000ff;">$first_line</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$rate</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$net_records</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #0000ff;">$elapsed</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;Rate for $elapsed seconds: &quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%0.2f'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$rate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot; per second<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$key</span> <span style="color: #009900;">&#40;</span><span style="color: #000066;">sort</span> <span style="color: #000066;">keys</span> <span style="color: #0000ff;">%query_counter</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #0000ff;">$rate</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$query_counter</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$key</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #cc66cc;">3600</span><span style="color: #339933;">;</span>
	<span style="color: #000066;">print</span> <span style="color: #ff0000;">&quot;$key =&gt; $query_counter{$key}, rate &quot;</span><span style="color: #339933;">.</span><span style="color: #000066;">sprintf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'%0.3f'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">$rate</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #ff0000;">&quot; queries/sec<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000066;">exit</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>I suppose this doesn&#8217;t account for PTR (reverse DNS) lookups, but oh well.</p>
<p><b>Edit</b>: I added some lame ASCII graphing functionality to the script, check it out <a href="http://www.evanhoffman.com/evan/?p=978">in this post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2010/12/07/perl-script-to-calculate-dns-queries-per-second-in-bind-named/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

