<?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; linux</title>
	<atom:link href="http://www.evanhoffman.com/evan/tag/linux/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>Fedora Core 15 &amp; Gnome 3</title>
		<link>http://www.evanhoffman.com/evan/2011/09/23/fedora-core-15-gnome-3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fedora-core-15-gnome-3</link>
		<comments>http://www.evanhoffman.com/evan/2011/09/23/fedora-core-15-gnome-3/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 14:27:22 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[autostart]]></category>
		<category><![CDATA[chkconfig]]></category>
		<category><![CDATA[fc12]]></category>
		<category><![CDATA[fc15]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[preupgrade]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[service]]></category>
		<category><![CDATA[smb]]></category>
		<category><![CDATA[systemctl]]></category>
		<category><![CDATA[systemd]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1618</guid>
		<description><![CDATA[Shrinking partitions, installing/upgrading to FC15, and systemd/chkconfig.]]></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/23/fedora-core-15-gnome-3/&via=EvanHoffman&text=Fedora Core 15 & Gnome 3&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/23/fedora-core-15-gnome-3/"></g:plusone></div><p>Over a year ago, the hard drive in my primary desktop at home bricked itself and rather than going through the hassle of reinstalling Win7 on the new disk, I decided to go with FC12. I&#8217;ve been pretty happy with it in general, since I&#8217;ve always been partial to Red Hat and use CentOS primarily at work.<br />
<span id="more-1618"></span><br />
Last week I got the great idea to upgrade to FC14. In hindsight I can&#8217;t even recall what led me to try this, but it didn&#8217;t end well. I tried the &#8220;preupgrade&#8221; procedure, which appeared to do the entire upgrade from FC12 to FC14 in place. I left it overnight, and when I looked at it the next day it looked like it was done. I was in FC14 and everything looked ok. But then I tried syncing my photos over NFS and discovered nfs wasn&#8217;t running on my desktop. When I tried starting it, it failed. After some trial and error, I used the Google and found that <a href="http://forums.fedoraforum.org/showthread.php?t=264182">this is just what happens when upgrading to FC14</a> due to changes between FC12 and FC14, namely the introduction of <a href="http://fedoraproject.org/wiki/Systemd">systemd</a>.</p>
<p>In all the threads I read, the &#8220;solution&#8221; was a clean install of Fedora. I tried doing this without formatting my / (root) partition, since that had 500 gigs of my stuff on it, but it kept failing. What I ended up doing was downloading <a href="http://partedmagic.com/doku.php?id=start">partedmagic</a>, which is a totally awesome partitioning tool.  If you&#8217;re familiar with Partition Magic, this is similar but Linux-based and free.  I burned the iso to disc, booted to it, and shrunk my / partition from 900 GB to 850 GB, and created a new 50 GB partition at the end of my disk without losing any of my data:</p>
<div id="attachment_1619" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.evanhoffman.com/evan/2011/09/23/fedora-core-15-gnome-3/parted-20110923/" rel="attachment wp-att-1619"><img class="size-medium wp-image-1619" title="FC15 Partitions" src="http://www.evanhoffman.com/evan/wp-content/uploads/2011/09/parted-20110923-300x195.png" alt="FC15 Partitions" width="300" height="195" /></a><p class="wp-caption-text">FC15 Partitions</p></div>
<p>Once this was done, which took surprisingly little time, I did a net install of FC15. I opted for a net install rather than downloading the ISO because I feel that with FiOS it&#8217;s actually faster than reading a DVD, and avoids having to run &#8220;yum update&#8221; afterwards.</p>
<p>So, I ended up with FC15 clean-installed to the new &#8220;/&#8221; partition. I moved everything around so the old partition is mounted at /docs and has all my stuff in it. I&#8217;d heard that FC15 was causing an uproar but until I logged into Gnome 3 myself I didn&#8217;t really understand the fuss. It&#8217;s going to take some getting used to, but after adding the <a href="http://code.google.com/p/tint2/">tint2</a> taskbar it&#8217;s not too awful.</p>
<p>But back to systemd. In FC15 I wanted to ensure Samba started at boot, since that&#8217;s how I share docs between my VMs and host. Chkconfig is still there, but based on my problems with NFS and systemd on FC14 I decided to look into it a bit and see if there&#8217;s a &#8220;new&#8221; way to enable stuff at startup. <a href="http://fedoraproject.org/wiki/Systemd#How_do_I_start.2Fstop_or_enable.2Fdisable_services.3F">There is!</a></p>
<p>Instead of:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># chkconfig smb on</span></pre></div></div>

<p>The command is:</p>

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

<p>Of course, when I did this it apparently fell back to using chkconfig for smb:</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>evan-fedora ~<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #666666; font-style: italic;"># systemctl enable smb.service</span>
smb.service is not a native service, redirecting to <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>chkconfig.
Executing <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>chkconfig smb on</pre></div></div>

<p>It does say in the <a href="http://fedoraproject.org/wiki/Systemd#Does_chkconfig_command_work_with_systemd.3F">Fedora wiki</a> that systemd respects chkconfig and vice versa, so I guess this post is kind of pointless and I should have just linked to the wiki. But, whatever.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/09/23/fedora-core-15-gnome-3/feed/</wfw:commentRss>
		<slash:comments>1</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>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>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>MongoDB logrotate script</title>
		<link>http://www.evanhoffman.com/evan/2011/07/21/mongodb-logrotate-script/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mongodb-logrotate-script</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/21/mongodb-logrotate-script/#comments</comments>
		<pubDate>Thu, 21 Jul 2011 14:10:26 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[logrotate]]></category>
		<category><![CDATA[logrotate.conf]]></category>
		<category><![CDATA[logrotate.d]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongod]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1421</guid>
		<description><![CDATA[Daily mongodb log rotation via <code>logrotate</code>.]]></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/21/mongodb-logrotate-script/&via=EvanHoffman&text=MongoDB logrotate script&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/21/mongodb-logrotate-script/"></g:plusone></div><p>MongoDB has log rotation functionality <a href="http://www.mongodb.org/display/DOCS/Logging#Logging-Fromthemongoshell">built in</a>, but since I run CentOS I like to have everything managed through <code>logrotate</code>.  The 10gen RPM I installed doesn&#8217;t have a logrotate script, so I wrote one.  Create file <code>/etc/logrotate.d/mongod</code>:</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
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>mongo<span style="color: #000000; font-weight: bold;">/</span>mongod.log <span style="color: #7a0874; font-weight: bold;">&#123;</span>
        daily
        rotate <span style="color: #000000;">30</span>
        compress
        dateext
&nbsp;
    missingok
    notifempty
    sharedscripts
    postrotate
        <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #660033;">-SIGUSR1</span> <span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">cat</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>mongo<span style="color: #000000; font-weight: bold;">/</span>mongod.lock <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span> <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #c20cb9; font-weight: bold;">true</span>
    endscript
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></td></tr></table></div>

<p><code>logrotate</code> runs at 4 AM daily by default (via the script in <code>/etc/cron.daily/logrotate</code>).  The file above rotates the mongod.log file daily, retaining 30 days of files, appending the date to each one after rotation (rather than the &#8220;.1&#8243; or &#8220;.2&#8243; suffix) and then gzipping it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/21/mongodb-logrotate-script/feed/</wfw:commentRss>
		<slash:comments>0</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>Using WAL archiving &amp; Compellent snapshots for PostgreSQL backups</title>
		<link>http://www.evanhoffman.com/evan/2011/07/13/using-wal-archiving-compellent-snapshots-for-postgresql-backups/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-wal-archiving-compellent-snapshots-for-postgresql-backups</link>
		<comments>http://www.evanhoffman.com/evan/2011/07/13/using-wal-archiving-compellent-snapshots-for-postgresql-backups/#comments</comments>
		<pubDate>Wed, 13 Jul 2011 17:46:40 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[archive_command]]></category>
		<category><![CDATA[archiving]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[CompCU.jar]]></category>
		<category><![CDATA[compellent]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[pg_dump]]></category>
		<category><![CDATA[pg_start_backup]]></category>
		<category><![CDATA[pitr]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[replay]]></category>
		<category><![CDATA[san]]></category>
		<category><![CDATA[snapshot]]></category>
		<category><![CDATA[wal]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1401</guid>
		<description><![CDATA[Changing my Postgres DB backup strategy from nightly <code>pg_dump</code>s to WAL archiving with SAN snapshots.]]></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/13/using-wal-archiving-compellent-snapshots-for-postgresql-backups/&via=EvanHoffman&text=Using WAL archiving & Compellent snapshots for PostgreSQL backups&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/13/using-wal-archiving-compellent-snapshots-for-postgresql-backups/"></g:plusone></div><p>I seem to have what may be an irrational dislike for differential backups in general.  No matter what system I&#8217;m backing up, I feel far more confident in doing complete backups than differential ones.  The significant exception to this is rsync, but even rsync does &#8220;full&#8221; backups of the files that have changed.  Even so, I usually add the <code>-W</code> flag to rsync so it moves the entire file if it&#8217;s been modified.  I guess I just like knowing there&#8217;s a single file that contains the entire database rather than having to restore a huge file and then replay a bunch of differential files in sequence.<br />
<span id="more-1401"></span><br />
This has worked for a long time, even with our PostgreSQL DB, which I&#8217;ve been backing up with good ol&#8217; <code>pg_dump</code>, but it&#8217;s gotten to the point that the DB backup takes over 12 hours now, during which performance is seriously degraded.  With the <a href="http://www.evanhoffman.com/evan/?p=1390">recent migration</a> to the new server, overall performance seems significantly better overall, but performance during the nightly pg_dump is much worse.  Rather than trying to troubleshoot it, I think it&#8217;s time I bit the bullet and move to <a href="http://www.postgresql.org/docs/8.2/interactive/continuous-archiving.html">WAL archiving</a> to enable differential backups, and stop doing a full backup every night.</p>
<p>The PostgreSQL docs are pretty great at explaining how to do this.  Basically:</p>
<ol>
<li>Configure WAL archiving to copy the WAL files to another server as soon as they&#8217;re complete.</li>
<li>Issue the <code>pg_start_backup()</code> command.</li>
<li>Perform a filesystem-level backup of the DB (usually <code>/var/lib/pgsql</code> on RedHat/CentOS distros).</li>
<li>Issue the <code>pg_stop_backup()</code> command.</li>
</ol>
<p>That&#8217;s basically it.  The backup from step 2 plus the archived WAL files will allow you to recover to any point in time after issuing the pg_stop_backup() command.  So if you complete your backup at 2 AM on Sunday and your DB crashes on Wednesday at 6 PM, you can restore to any point between 2 AM Sunday and whatever your most recently archived WAL file is (presumably within a few minutes of the crash at 6 PM Wednesday).  If you decided you wanted to restore to 12:01 AM on Wednesday, you can do that using the <a href="http://www.postgresql.org/docs/8.2/interactive/continuous-archiving.html#RECOVERY-TARGET-TIME"><code>recovery_target_time</code> setting</a>.  My aversion to differential backups aside, this is pretty awesome.  </p>
<p>As I said, the Postgres docs do a good job of covering this procedure completely.  The only thing I have to add is how I did this using a SAN-level snapshot as my &#8220;filesystem backup.&#8221;  I&#8217;d never done any scripting with Compellent before and it turned out to be pretty easy.  From the <a href="https://kc.compellent.com/">Knowledge Center</a>, under <b>Software</b> download the latest version of <b>Command Utility</b> (I downloaded 5.4.1).  The utility itself is just a JAR, you&#8217;ll need Java installed to run it.  </p>
<p>I considered doing a real filesystem backup of the DB (love that rsync) but the problem was that the DB is currently 1.2 TB and gobbling that much space on the NAS wasn&#8217;t very appealing.  Compellent replays (snapshots) are just deltas, and I can easily store a week worth of backups for much less than (7 * 1.2 = ) 8.4 TB.</p>
<p>I wrote a crappy bash script to do everything, included below:</p>
<p><script src="https://gist.github.com/1079026.js"> </script></p>
<p>I retain the WAL files for 8 days and the snapshots for 7 days, but I may adjust this since the WAL files themselves consume a lot of space &#8211; about 30-40 GB per day.  Though this is still less than the gzipped pg_dump I had been doing, which was about 85 GB per day.</p>
<p>I&#8217;ve cronned the script to run at 2 AM and so far it appears to work.  Compellent replays are created almost instantly, so the backup script completed in about 10 seconds, which includes 6 seconds of <code>sleep</code>, which probably aren&#8217;t necessary.  Considering that the pg_dump method took 12+ hours to complete, 10 seconds is immeasurably better.  Well, I guess it <i>is</i> measurable, you just need to divide 12 hours by 10 seconds.  </p>
<p>I&#8217;m pretty happy with this so far.  The improved performance far outweighs any irrational philosophical objection I may have had to differential backups.  Buuuut I&#8217;m still going to do pg_dumps on Saturdays.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/07/13/using-wal-archiving-compellent-snapshots-for-postgresql-backups/feed/</wfw:commentRss>
		<slash:comments>0</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>Calculating SHA-1 sums in Java</title>
		<link>http://www.evanhoffman.com/evan/2011/05/25/calculating-sha-1-sums-in-java/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=calculating-sha-1-sums-in-java</link>
		<comments>http://www.evanhoffman.com/evan/2011/05/25/calculating-sha-1-sums-in-java/#comments</comments>
		<pubDate>Wed, 25 May 2011 22:19:27 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[byte array]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[hex string]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sha-1]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1299</guid>
		<description><![CDATA[Java code for calculating SHA-1 sums from arbitrary InputStreams, files, or Strings and printing them as strings.]]></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/25/calculating-sha-1-sums-in-java/&via=EvanHoffman&text=Calculating SHA-1 sums in Java&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/25/calculating-sha-1-sums-in-java/"></g:plusone></div><p>Java has functionality for calculating SHA-1 and MD5 checksums but not for displaying them as the 40-char hex strings I&#8217;m used to.  I want to update my photo reorganizer so it doesn&#8217;t create duplicate files so I figured this would be a handy thing to write.  I wrote one for MD5 a while ago (the only code you really need to write is the <a href="https://github.com/evandhoffman/Java-SHA-1-Hasher/blob/0e7fc9f3013a20eeecc30b523d1400c0ad5db41d/src/com/evanhoffman/messagedigest/SHA1.java#L31">byte-array-to-hex-string converter</a>) but I guess I lost it.  Anyway, here it is.</p>
<p><ins datetime="2011-05-26T14:24:13+00:00">Edit:</ins> Rather than paste a huge useless block of code here, I put it on github: <a href="https://github.com/evandhoffman/Java-SHA-1-Hasher">https://github.com/evandhoffman/Java-SHA-1-Hasher</a>.</p>
<p>Output appears to match that of the command-line utility:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>evan<span style="color: #000000; font-weight: bold;">@</span>EvanMBP bin<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ java <span style="color: #660033;">-jar</span> SHA1.jar ~<span style="color: #000000; font-weight: bold;">/</span>text.txt 
3bbed58697cc1775e8fadcf1324e26d4d092e7c2        <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>evan<span style="color: #000000; font-weight: bold;">/</span>text.txt
<span style="color: #7a0874; font-weight: bold;">&#91;</span>evan<span style="color: #000000; font-weight: bold;">@</span>EvanMBP bin<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ shasum ~<span style="color: #000000; font-weight: bold;">/</span>text.txt 
3bbed58697cc1775e8fadcf1324e26d4d092e7c2  <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>evan<span style="color: #000000; font-weight: bold;">/</span>text.txt</pre></div></div>

<p>It&#8217;s not as fast as shasum (as I expected) but that may partially be due to reading data in 1k chunks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/05/25/calculating-sha-1-sums-in-java/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>Amazon SES &#8211; &#8220;Illegal Header&#8221; errors</title>
		<link>http://www.evanhoffman.com/evan/2011/05/16/amazon-ses-illegal-header-errors/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=amazon-ses-illegal-header-errors</link>
		<comments>http://www.evanhoffman.com/evan/2011/05/16/amazon-ses-illegal-header-errors/#comments</comments>
		<pubDate>Mon, 16 May 2011 16:37:49 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[auto-submitted]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[illegal header]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[organization]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[precedence]]></category>
		<category><![CDATA[ses]]></category>
		<category><![CDATA[ses-send-email.pl]]></category>
		<category><![CDATA[smtp]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1270</guid>
		<description><![CDATA[My thoughts on the "illegal header" error some people are encountering when relaying mail through postfix/SES.  Plus some perl code that should help fix it.]]></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/16/amazon-ses-illegal-header-errors/&via=EvanHoffman&text=Amazon SES - "Illegal Header" errors&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/16/amazon-ses-illegal-header-errors/"></g:plusone></div><p><ins datetime="2011-08-02T21:31:58+00:00">Update 8/2/2011:</ins> please see <a href="http://www.evanhoffman.com/evan/?p=1486"> the followup post</a> for a possible workaround.</p>
<p>A few people have inquired about the &#8220;Illegal header&#8221; error when attempting to relay email through SES.  <a href="http://www.evanhoffman.com/evan/2011/04/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/#comment-675">&#8220;Oncle Tom&#8221;</a> pointed to <a href="https://forums.aws.amazon.com/thread.jspa?threadID=59098">a thread</a> on Amazon&#8217;s forums about a similar problem which led to a list of headers Amazon will accept.  The list is below; if you need to add headers outside this list, you can do so using &#8220;X-Headers.&#8221;</p>
<p>Some people have posted sample code in the thread with modifications to ses-send-email.pl to replace &#8220;illegal&#8221; headers read from STDIN with an equivalent X-Header.  I wrote something generic that takes the list of <b>legal</b> headers and replaces anything not on that list with its X-Header equivalent.  <B>Disclaimer:</B> I haven&#8217;t tested it, but it seems like this type of solution would be more adaptable since you don&#8217;t have to keep fixing it every time a new application attempts to send email with a new header.  I haven&#8217;t worked this into ses-send-email.pl (since I&#8217;m not having any problems, I don&#8217;t want to touch it <img src='http://www.evanhoffman.com/evan/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) but I fed in an email header and the output looked correct.</p>
<p><script src="https://gist.github.com/1068310.js"> </script></p>
<p>Input email:</p>
<pre>
MIME-Version: 1.0
Received: by 10.142.136.15 with HTTP; Mon, 16 May 2011 09:32:44 -0700 (PDT)
Date: Mon, 16 May 2011 12:32:44 -0400
Delivered-To: evandhoffman@gmail.com
Message-ID: <BANLkTimTOHR03Ln8CRmBxXQAhtHR9otzUQ@mail.gmail.com>
Subject: Hi friend.
From: "Evan D. Hoffman" <evandhoffman@gmail.com>
To: "Evan D. Hoffman (Personal)" <evandhoffman@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Email Test.
</pre>
<p>Output email:</p>
<pre>
[evan@EvanMBP ~]$ perl replace-headers.pl test-email.txt
MIME-Version: 1.0
Received: by 10.142.136.15 with HTTP; Mon, 16 May 2011 09:32:44 -0700 (PDT)
Date: Mon, 16 May 2011 12:32:44 -0400
X-Delivered-To: evandhoffman@gmail.com
X-Message-ID: <BANLkTimTOHR03Ln8CRmBxXQAhtHR9otzUQ@mail.gmail.com>
Subject: Hi friend.
From: "Evan D. Hoffman" <evandhoffman@gmail.com>
To: "Evan D. Hoffman (Personal)" <evandhoffman@gmail.com>
Content-Type: text/plain; charset=ISO-8859-1

Email Test.
</pre>
<p>Hope this helps someone.</p>
<p>Here&#8217;s the legal header list, from <a href="http://docs.amazonwebservices.com/ses/2010-12-01/DeveloperGuide/index.html?AppendixHeaders.html">http://docs.amazonwebservices.com/ses/2010-12-01/DeveloperGuide/index.html?AppendixHeaders.html</a></p>
<ul>
<li>
<p class="simpara">Accept-Language</p>
</li>
<li>
<p class="simpara">Bcc</p>
</li>
<li>
<p class="simpara">Cc</p>
</li>
<li>
<p class="simpara">Comments</p>
</li>
<li>
<p class="simpara">Content-Type</p>
</li>
<li>
<p class="simpara">Content-Transfer-Encoding</p>
</li>
<li>
<p class="simpara">Content-ID</p>
</li>
<li>
<p class="simpara">Content-Description</p>
</li>
<li>
<p class="simpara">Content-Disposition</p>
</li>
<li>
<p class="simpara">Content-Language</p>
</li>
<li>
<p class="simpara">Date</p>
</li>
<li>
<p class="simpara">DKIM-Signature</p>
</li>
<li>
<p class="simpara">DomainKey-Signature</p>
</li>
<li>
<p class="simpara">From</p>
</li>
<li>
<p class="simpara">In-Reply-To</p>
</li>
<li>
<p class="simpara">Keywords</p>
</li>
<li>
<p class="simpara">List-Archive</p>
</li>
<li>
<p class="simpara">List-Help</p>
</li>
<li>
<p class="simpara">List-Id</p>
</li>
<li>
<p class="simpara">List-Owner</p>
</li>
<li>
<p class="simpara">List-Post</p>
</li>
<li>
<p class="simpara">List-Subscribe</p>
</li>
<li>
<p class="simpara">List-Unsubscribe</p>
</li>
<li>
<p class="simpara">Message-Id</p>
</li>
<li>
<p class="simpara">MIME-Version</p>
</li>
<li>
<p class="simpara">Received</p>
</li>
<li>
<p class="simpara">References</p>
</li>
<li>
<p class="simpara">Reply-To</p>
</li>
<li>
<p class="simpara">Return-Path</p>
</li>
<li>
<p class="simpara">Sender</p>
</li>
<li>
<p class="simpara">Subject</p>
</li>
<li>
<p class="simpara">Thread-Index</p>
</li>
<li>
<p class="simpara">Thread-Topic</p>
</li>
<li>
<p class="simpara">To</p>
</li>
<li>
<p class="simpara">User-Agent</p>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/05/16/amazon-ses-illegal-header-errors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Integrating Amazon Simple Email Service with postfix for SMTP smarthost relaying.</title>
		<link>http://www.evanhoffman.com/evan/2011/04/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying</link>
		<comments>http://www.evanhoffman.com/evan/2011/04/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 16:23:47 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[credentials]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Missing final '@domain']]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[postfix]]></category>
		<category><![CDATA[relay]]></category>
		<category><![CDATA[sendmail]]></category>
		<category><![CDATA[ses]]></category>
		<category><![CDATA[ses-get-stats.pl]]></category>
		<category><![CDATA[ses-send-email.pl]]></category>
		<category><![CDATA[smtp]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1220</guid>
		<description><![CDATA[How I configured an EC2 instance to relay mail through Amazon's SES, and some of the bumps I encountered along the way.]]></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/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/&via=EvanHoffman&text=Integrating Amazon Simple Email Service with postfix for SMTP smarthost relaying.&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/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/"></g:plusone></div><p>So, we&#8217;ve outgrown the 500 outbound messages/day limit imposed by Google Apps&#8217;s Standard tier.  A wise friend suggested <a href="http://sendgrid.com/">SendGrid</a>, but I figured it was worth looking into what options Amazon provides.  I found <a href="http://aws.amazon.com/ses/faqs/">SES</a> and am in the process of setting it up.  Hopefully I can set it up as a drop-in replacement, obviating the need for code changes to use it.  SES is attractive for us because:</p>
<blockquote><p>Free Tier<br />
If you are an Amazon EC2 user, you can get started with Amazon SES for free. You can send 2,000 messages for free each day when you call Amazon SES from an Amazon EC2 instance directly or through AWS Elastic Beanstalk. Many applications are able to operate entirely within this free tier limit.</p>
<p>Note: Data transfer fees still apply. For new AWS customers eligible for the AWS free usage tier, you receive 15 GB of data transfer in and 15 GB of data transfer out aggregated across all AWS services, which should cover your Amazon SES data transfer costs. In addition, all AWS customers receive 1GB of free data transfer per month. </p></blockquote>
<p>Free to try? Sounds good.</p>
<p>After signing up, the first thing I did was <a href="https://aws.amazon.com/code/Amazon-SES/8945574369528337">download the Perl scripts</a>.  Create a credentials file with your AWS access key ID and Secret Key (credentials can be found <a href="https://aws-portal.amazon.com/gp/aws/developer/account/index.html">here</a> when logged in).  The credentials file (aws-credentials) should look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">AWSAccessKeyId</span>=022QF06E7MXBSH9DHM02
<span style="color: #007800;">AWSSecretKey</span>=kWcrlUX5JEDGM<span style="color: #000000; font-weight: bold;">/</span>LtmEENI<span style="color: #000000; font-weight: bold;">/</span>aVmYvHNif5zB+d9+ct</pre></div></div>

<p>Make sure to <tt>chmod 0600 aws-credentials</tt>.  To ensure it&#8217;s working, run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-s</span></pre></div></div>

<p>If it doesn&#8217;t return anything it should be working correctly.</p>
<p>Next, you need to add at least one verified email address:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>ses-verify-email-address.pl <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">--verbose</span> <span style="color: #660033;">-v</span> support<span style="color: #000000; font-weight: bold;">@</span>example.com</pre></div></div>

<p>Amazon will send a verification message to support@example.com with a link you need to click to verify the address.  Once you click, it&#8217;s verified.  It&#8217;s important to note that <b>initially your account will only be able to send email to verified addresses</b>.  According to <a href="https://forums.aws.amazon.com/thread.jspa?messageID=224245">this thread</a>, you need to <a href="http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/index.html?InitialSetup.Customer.html">submit a production access request</a> to send to unverified To: addresses.  I did this and got my &#8220;approval&#8221; email about 30 minutes later.</p>
<p>To send a test email:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<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;">-s</span> <span style="color: #ff0000;">&quot;Test from SES&quot;</span> <span style="color: #660033;">-f</span> support<span style="color: #000000; font-weight: bold;">@</span>example.com evan<span style="color: #000000; font-weight: bold;">@</span>example.com
This is a <span style="color: #7a0874; font-weight: bold;">test</span> message from SES.</pre></div></div>

<p>(Press ctrl-D to send.)</p>
<p>The next step is integrating the script with sendmail/postfix.  The first thing I did was move my scripts to /opt/ (out of /root/) and attempt to run them with absolute pathnames (rather than ./ses-send-email.pl) and I got perl @INC errors:</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>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #c20cb9; font-weight: bold;">mv</span> amazon-email<span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-s</span>
-bash: <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl: No such <span style="color: #c20cb9; font-weight: bold;">file</span> or directory
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-s</span>
Can<span style="color: #ff0000;">'t locate SES.pm in @INC (@INC contains: /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/site_perl/5.8.8 /usr/lib/perl5/site_perl/5.8.7 /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl/5.8.5 /usr/lib/perl5/site_perl /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.7/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.6/x86_64-linux-thread-multi /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi /usr/lib/perl5/vendor_perl/5.8.8 /usr/lib/perl5/vendor_perl/5.8.7 /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl/5.8.5 /usr/lib/perl5/vendor_perl /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi /usr/lib/perl5/5.8.8 .) at /opt/amazon-email/ses-get-stats.pl line 23.
BEGIN failed--compilation aborted at /opt/amazon-email/ses-get-stats.pl line 23.</span></pre></div></div>

<p>The problem is that SES.pm isn&#8217;t in perl&#8217;s include path.  To solve this, I tried adding the directory to the PERL5LIB environment var:</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>web2 amazon-email<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #007800;">PERL5LIB</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 amazon-email<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$PERL5LIB</span>
<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 amazon-email<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #7a0874; font-weight: bold;">cd</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #7a0874; font-weight: bold;">export</span> PERL5LIB
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> aws-credentials <span style="color: #660033;">-s</span>
Cannot open credentials <span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #000000; font-weight: bold;">&lt;</span>aws-credentials<span style="color: #000000; font-weight: bold;">&gt;</span>. at <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">//</span>SES.pm line <span style="color: #000000;">54</span>.
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$ <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>aws-credentials <span style="color: #660033;">-s</span>
Timestamp               DeliveryAttempts        Rejects Bounces Complaints      
<span style="color: #000000;">2011</span>-04-27T20:<span style="color: #000000;">27</span>:00Z    <span style="color: #000000;">1</span>                       <span style="color: #000000;">0</span>       <span style="color: #000000;">0</span>       <span style="color: #000000;">0</span>               
<span style="color: #7a0874; font-weight: bold;">&#91;</span>root<span style="color: #000000; font-weight: bold;">@</span>web2 ~<span style="color: #7a0874; font-weight: bold;">&#93;</span>$</pre></div></div>

<p>This worked for setting all users&#8217; PERL5LIB &#8230; but didn&#8217;t allow postfix to send the message.  After a couple more attempts at doing this &#8220;the right way,&#8221; I just ended up dropping a symlink to SES.pm in <tt>/usr/lib/perl5/site_perl</tt> and the @INC error went away.</p>
<p>After following Amazon&#8217;s instructions for editing main.cf and master.cf, I still was unable to send mail through Postfix, even though I could send directly through the perl scripts.  I kept getting this error:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Apr <span style="color: #000000;">28</span> <span style="color: #000000;">11</span>:<span style="color: #000000;">26</span>:<span style="color: #000000;">32</span> web2 postfix<span style="color: #000000; font-weight: bold;">/</span>pipe<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27226</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>: A2AD33C9A6: <span style="color: #007800;">to</span>=<span style="color: #000000; font-weight: bold;">&lt;</span>user<span style="color: #000000; font-weight: bold;">@</span>domain.com<span style="color: #000000; font-weight: bold;">&gt;</span>, <span style="color: #007800;">relay</span>=aws-email, <span style="color: #007800;">delay</span>=<span style="color: #000000;">0.35</span>, <span style="color: #007800;">delays</span>=<span style="color: #000000;">0.01</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">0.34</span>, <span style="color: #007800;">dsn</span>=5.3.0, <span style="color: #007800;">status</span>=bounced <span style="color: #7a0874; font-weight: bold;">&#40;</span>Command died with status <span style="color: #000000;">1</span>: <span style="color: #ff0000;">&quot;/opt/amazon-email/ses-send-email.pl&quot;</span>. Command output: Missing final <span style="color: #ff0000;">'@domain'</span> <span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Google led me to <a href="http://www.bashbang.com/geek/aws-ses-mta/">this blog post</a> which led me to <a href="http://benjisimon.blogspot.com/2011/02/gotcha-of-day-ec2-postfix-amazon-simple.html">this other blog post</a> which illuminated the problem: apparently the Postfix pipe macro ${sender} uses the user@hostname of the mail sender.  Since the hostname of an EC2 machine is usually something crazy like dom11-22-33-44.internal, this is not likely a validated sending email address.  So the solution proposed by Ben Simon was to create a regex to map user@internal to user@realdomain.com and have postfix map everything.  This didn&#8217;t work for me or the bashbang.com guys, who changed it to map from user@internal to validuser@realdomain.com.  I found that you can eliminate the need for the mapping entirely by changing the master.cf entry to this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">  <span style="color: #007800;">flags</span>=R <span style="color: #007800;">user</span>=mailuser <span style="color: #007800;">argv</span>=<span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>ses-send-email.pl <span style="color: #660033;">-r</span> <span style="color: #660033;">-k</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>aws-credentials <span style="color: #660033;">-e</span> https:<span style="color: #000000; font-weight: bold;">//</span>email.us-east-<span style="color: #000000;">1</span>.amazonaws.com <span style="color: #660033;">-f</span> support<span style="color: #000000; font-weight: bold;">@</span>example.com <span style="color: #800000;">${recipient}</span></pre></div></div>

<p>The only difference between the above line and Amazon&#8217;s suggestion is that this replaces &#8220;-f ${sender}&#8221; with &#8220;support@example.com&#8221; which is a validated email address.</p>
<p>After this I was able to relay email successfully through SES.  Whew!</p>
<p><ins datetime="2011-05-26T16:32:24+00:00">Update 5/26/2011</ins>: We&#8217;ve been relaying through SES without issues for a few weeks now.  I recently ran ses-get-stats.pl to see how many messages we&#8217;re actually sending and it&#8217;s a lot lower than expected.  I&#8217;m still glad we moved to SES though, since it has no hard cap like Google Apps does:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>ses-get-stats.pl <span style="color: #660033;">-k</span> <span style="color: #000000; font-weight: bold;">/</span>opt<span style="color: #000000; font-weight: bold;">/</span>amazon-email<span style="color: #000000; font-weight: bold;">/</span>aws-credentials <span style="color: #660033;">-q</span>
SentLast24Hours Max24HourSend   MaxSendRate     
<span style="color: #000000;">317</span>             <span style="color: #000000;">10000</span>           <span style="color: #000000;">5</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/04/28/integrating-amazon-simple-email-service-with-postfix-for-smarthost-relaying/feed/</wfw:commentRss>
		<slash:comments>8</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>Going back to FiOS</title>
		<link>http://www.evanhoffman.com/evan/2011/04/24/going-back-to-fios/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=going-back-to-fios</link>
		<comments>http://www.evanhoffman.com/evan/2011/04/24/going-back-to-fios/#comments</comments>
		<pubDate>Sun, 24 Apr 2011 05:40:05 +0000</pubDate>
		<dc:creator>Evan Hoffman</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cable]]></category>
		<category><![CDATA[cablevision]]></category>
		<category><![CDATA[cablevision vs fios]]></category>
		<category><![CDATA[dig]]></category>
		<category><![CDATA[dns]]></category>
		<category><![CDATA[dvr]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[fios]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[long island]]></category>
		<category><![CDATA[money]]></category>
		<category><![CDATA[movies.netflix.com]]></category>
		<category><![CDATA[netflix]]></category>
		<category><![CDATA[ool]]></category>
		<category><![CDATA[optimum]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://www.evanhoffman.com/evan/?p=1192</guid>
		<description><![CDATA[TweetI&#8217;m not sure why these guys operate this way &#8211; they&#8217;re more than happy to lose me as a customer and then throw huge discounts at me to get me back. If they&#8217;d just give me a good price I&#8217;d love not to have to go through this rigmarole. But after being with Cablevision for [...]]]></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/24/going-back-to-fios/&via=EvanHoffman&text=Going back to FiOS&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/24/going-back-to-fios/"></g:plusone></div><p>I&#8217;m not sure why these guys operate this way &#8211; they&#8217;re more than happy to lose me as a customer and then throw huge discounts at me to get me back.  If they&#8217;d just give me a good price I&#8217;d love not to have to go through this rigmarole.  But after being with Cablevision for 2 months I checked Verizon&#8217;s pricing and it beat my current deal with Cablevision.</p>
<p>FiOS digital voice with number ported for free; 25/25 Mbps internet; HMDVR free &#8220;forever&#8221; plus a second HD STB, Showtime, Movie Channel and Flix.  Since I already had the battery thing installed last time I had FiOS they gave me a fair discount.  Basically the whole package for $87/month + tax, price locked for 2 years, no contract.  Not as great of a deal as I&#8217;d had with FiOS originally, but it&#8217;s pretty good, and FiOS&#8217;s service is definitely better than Cablevision&#8217;s.  I&#8217;ve heard Cablevision was rolling out their &#8220;DVR plus&#8221; service with all programs recorded &#8220;in the cloud&#8221; rather than on the actual box, but it&#8217;s been two months and I haven&#8217;t heard of it coming to Long Island.  So basically 2 years later Cablevision&#8217;s service is exactly the same while Verizon has iPhone apps to control the DVR and use the phone as a remote, plus DVR that&#8217;s much faster and just generally better service.</p>
<p>On a side note, I noticed tonight I was having problems trying to stream Netflix to my Wii.  I tried loading netflix.com on my laptop and that also didn&#8217;t work, it said &#8220;couldn&#8217;t find server movies.netflix.com.&#8221;  I tested this via dig on my linux box and sure enough, movies.netflix.com isn&#8217;t resolving against the default Cablevision nameserver (167.206.3.206) &#8211; getting a SERVFAIL:</p>
<pre>[evan@lunix ~]$ dig movies.netflix.com

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> movies.netflix.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 17569
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;movies.netflix.com.            IN      A

;; ANSWER SECTION:
movies.netflix.com.     232     IN      CNAME   merchweb-frontend-1502974957.us-east-1.elb.amazonaws.com.

;; Query time: 2129 msec
;; SERVER: 167.206.3.206#53(167.206.3.206)
;; WHEN: Sun Apr 24 01:23:58 2011
;; MSG SIZE  rcvd: 103
</pre>
<p>I tried the same query against Google's nameserver (8.8.8.8) and it resolves correctly:</p>
<pre>
[evan@lunix ~]$ dig movies.netflix.com @8.8.8.8

; <<>> DiG 9.3.6-P1-RedHat-9.3.6-4.P1.el5_5.3 <<>> movies.netflix.com @8.8.8.8
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43718
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;movies.netflix.com.            IN      A

;; ANSWER SECTION:
movies.netflix.com.     300     IN      CNAME   merchweb-frontend-1502974957.us-east-1.elb.amazonaws.com.
merchweb-frontend-1502974957.us-east-1.elb.amazonaws.com. 39 IN A 174.129.220.6

;; Query time: 34 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Sun Apr 24 01:37:26 2011
;; MSG SIZE  rcvd: 119
</pre>
<p>I set my router to resolve against 8.8.8.8 rather than whatever Cablevision provides and now it works.  I'm not sure if this is related to <a href="http://news.google.com/news/more?pz=1&#038;cf=all&#038;cf=all&#038;ncl=dXGaFnLxwIuhH4M6TS8iFF_fwl7SM">the big EC2 disaster</a> of the past few days but it looks more like Cablevision's fault than Amazon's or Netflix's.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.evanhoffman.com/evan/2011/04/24/going-back-to-fios/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

