<?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>Open Query blog</title>
	<atom:link href="http://openquery.com/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://openquery.com/blog</link>
	<description>About MySQL, Drizzle, MariaDB and more!</description>
	<lastBuildDate>Thu, 02 Sep 2010 07:06:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Open Query turns 3!</title>
		<link>http://openquery.com/blog/open-query-turns-3</link>
		<comments>http://openquery.com/blog/open-query-turns-3#comments</comments>
		<pubDate>Thu, 02 Sep 2010 06:58:52 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mysql mariadb]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1385</guid>
		<description><![CDATA[Open Query is now three years old! We initially started with consulting and training services, and extended this with our proactive subscriptions that also offers system administration and monitoring. So how is it going? Pretty well. We&#8217;ve been profitable from the start, without funding (beyond a few hundred $ startup costs paid by Arjen) or [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://openquery.com" target="_blank">Open Query</a> is now three years old! We initially started with consulting and training services, and extended this with our proactive subscriptions that also offers system administration and monitoring.</p>
<p>So how is it going? Pretty well. We&#8217;ve been profitable from the start, without funding (beyond a few hundred $ startup costs paid by Arjen) or any credit &#8211; by choice. Our objective has never been to grow ridiculously in terms of revenue or number of customers, we simply charge reasonable prices for real service. Right now we have dozens of clients on an ongoing basis, a neat trickle of new clients, and Open Query sustains the livelyhood and lifestyle of a number of people.</p>
<p>For me (Arjen), the three year mark is particularly interesting, since most startups do not make it past their first two years. With our different approach to doing business, we&#8217;ve seen our fair share of skepticism. Not that we mind, if anything it&#8217;s encouragement <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /><br />
If you&#8217;d like to learn more about our business principles, see the <a href="http://upstarta.biz/Main/Principles" target="_blank">Upstarta</a> site.</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/open-query-turns-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Report from Barcamp Johor Bahru</title>
		<link>http://openquery.com/blog/report-barcamp-johor-bahru</link>
		<comments>http://openquery.com/blog/report-barcamp-johor-bahru#comments</comments>
		<pubDate>Mon, 30 Aug 2010 04:27:05 +0000</pubDate>
		<dc:creator>walter</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[barcamp]]></category>
		<category><![CDATA[malaysia]]></category>
		<category><![CDATA[report]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1381</guid>
		<description><![CDATA[This weekend, I decided to attend BarcampJB pretty last minute. Lucky for me, barcamps are made for chaotics like me, so it was no problem at all. I found some friends that live here in Kuala Lumpur who I drove down to JB with (JB is around a 5 hour drive from KL, we did [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend, I decided to attend <a href="http://barcamp.org/BarCampJB">BarcampJB</a> pretty last minute. Lucky for me, barcamps are made for chaotics like me, so it was no problem at all. I found some friends that live here in Kuala Lumpur who I drove down to JB with (JB is around a 5 hour drive from KL, we did it in 3.5 <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>The camp was very interesting. Because JB is on the border with Singapore, there&#8217;s a good crossover between Malaysian and Singaporean techies.</p>
<p>I decided to go all out and give three talks on Saturday: First up was the <a href="http://mysql-mmm.org">MMM</a> talk I&#8217;ve given at a few conferences before. All went well, and later on in the day some people approached me for more in-depth questions. It still seems that people have this idea in their head that they somehow need MySQL Cluster when there is more then one machine involved. When I explain them that that is very rarely the case and they can achieve what they want with MMM as well, they are often happy to hear that.</p>
<p>My next talk was more of a personal development one. People keep asking me here where I am from. When I explain to them that I&#8217;ve been location independent for the last 3 years, they are usually very eager to find out how I pull that off. I decided to summarise my experiences and put them in a talk. This talk was very well attended and I loved giving it. Most of the attendants were young techies, they are usually in a perfect position to do something very similar to what I&#8217;m doing.</p>
<p>The last talk was a lightning talk on <a href="http://www.zabbix.com">Zabbix</a>, the Open Source monitoring system we use at Open Query. Quick, and dirty, but effective.</p>
<p>Other interesting talks I attended were on <a href="http://breeze.standardchartered.com/online-internet-banking-service.html">breeze, an online banking application</a> made for Standard Chartered bank that looks very slick and usable (If anyone from my bank is reading this: get with the program and fix our banking application to enter the 21st century please <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ).</p>
<p>Conary and <a href="http://www.foresightlinux.org/five-reasons-to-use-foresight-linux/">Foresight Linux</a> were interesting as well. Conary (the package management system in Foresight Linux) is not quite mature yet, but definitely a very interesting technology. I was interested to hear about it and hope to see it become more mainstream in the future.</p>
<p>Daniel Cerventus gave a good lightning talk on what not to do as a startup. The main message was to just do it, and not wait for grant money or VC&#8217;s. Some solid tips as well, one of them being to run your potential name through <a href="http://www.namechk.com/">Namechk</a>, a handy potential username checker for many services.</p>
<p>There was obviously also a lot of networking and we went for a foot massage at the end of the day. Funny fact: I was the only one to stay awake through the massage (Even though I am narcoleptic), while two of my  friends (who I won&#8217;t name here <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ) snored all the way through it <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>All in all another succesful tech event in Malaysia. Definitely one of the many reasons I love living here!</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/report-barcamp-johor-bahru/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Query on Twitter/Identi.ca</title>
		<link>http://openquery.com/blog/open-query-twitteridentica</link>
		<comments>http://openquery.com/blog/open-query-twitteridentica#comments</comments>
		<pubDate>Fri, 27 Aug 2010 03:47:27 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[feed]]></category>
		<category><![CDATA[follow]]></category>
		<category><![CDATA[identica]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Open Query]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1377</guid>
		<description><![CDATA[Open Query now has its own @openquery account on Twitter and Identi.ca so you can conveniently follow us there for announcements and tips &#8211; and also ask us questions! All OQ engineers can post/reply. The OQ site front page also tracks this feed. Previously I was posting from my personal @arjenlentz account with #openquery hashtag, [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://openquery.com" target="_blank">Open Query</a> now has its own @openquery account on <a href="http://twitter.com/openquery" target="_blank">Twitter</a> and <a href="http://identi.ca/openquery" target="_blank">Identi.ca</a> so you can conveniently follow us there for announcements and tips &#8211; and also ask us questions! All OQ engineers can post/reply. The OQ site front page also tracks this feed.</p>
<p>Previously I was posting from my personal <a href="http://twitter.com/arjenlentz" target="_blank">@arjenlentz</a> account with #openquery hashtag, but that&#8217;s obviously less practical.</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/open-query-twitteridentica/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Challenge: identify this pattern in datadir</title>
		<link>http://openquery.com/blog/challenge-identify-this-pattern-in-datadir</link>
		<comments>http://openquery.com/blog/challenge-identify-this-pattern-in-datadir#comments</comments>
		<pubDate>Mon, 02 Aug 2010 02:07:14 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Good practice / Bad practice]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[datadir]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[symbolic link]]></category>
		<category><![CDATA[symlink]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1373</guid>
		<description><![CDATA[You take a look at someone&#8217;s MySQL (or MariaDB) data directory, and see mysql foo bar -&#62; foo What&#8217;s the issue? Identify pattern. What does it mean?  Consequences. Is there any way it can be safe and useful/usable? Describe. Good luck!]]></description>
			<content:encoded><![CDATA[<p>You take a look at someone&#8217;s MySQL (or MariaDB) data directory, and see</p>
<blockquote><p>mysql<br />
foo<br />
bar -&gt; foo</p></blockquote>
<ol>
<li>What&#8217;s the issue? Identify pattern.</li>
<li>What does it mean?  Consequences.</li>
<li>Is there any way it can be safe and useful/usable? Describe.</li>
</ol>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/challenge-identify-this-pattern-in-datadir/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>6to4: Easing the IPv6 transition</title>
		<link>http://openquery.com/blog/6to4-easing-ipv6-transition</link>
		<comments>http://openquery.com/blog/6to4-easing-ipv6-transition#comments</comments>
		<pubDate>Tue, 29 Jun 2010 00:48:11 +0000</pubDate>
		<dc:creator>Monkee</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[6to4]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[ipv4]]></category>
		<category><![CDATA[ipv6]]></category>
		<category><![CDATA[ipv6calc]]></category>
		<category><![CDATA[ipv6tables]]></category>
		<category><![CDATA[Linode]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1289</guid>
		<description><![CDATA[With the exhaustion of IPv4 address space looming sometime in 2012; probably earlier rather than later, it makes sense to ease on into IPv6 land.  Without straying into tunnel broking and endpoint shenanigans 6to4 is a method of wrapping up IPv6 inside of IPv4. 6to4 performs three functions: Allocates an IPv6 address block to any [...]]]></description>
			<content:encoded><![CDATA[<p>With the exhaustion of IPv4 address space looming sometime in 2012; probably earlier rather than later, it makes sense to ease on into IPv6 land.  Without straying into tunnel broking and endpoint shenanigans 6to4 is a method of wrapping up IPv6 inside of IPv4.</p>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;">6to4 performs three functions:</p>
<ol style="line-height: 1.5em; margin-top: 0.3em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 3.2em; list-style-image: none; padding: 0px;">
<li>Allocates an IPv6 address block to any host/network that has a global IPv4 address.</li>
<li>Wraps up IPv6 packets inside IPv4 packets for transmission over IPv4 using <a title="6in4" href="http://en.wikipedia.org/wiki/6in4">6in4</a> (traffic is sent over IPv4 inside IPv4 packets whose IP headers have the IP protocol number  set to 41; <em>IPv6-in-IPv4</em>. ) <a title="6to4" href="http://en.wikipedia.org/wiki/6to4">6to4</a> makes use of IP protocol 41 too, but instead of static endpoints, the endpoint IPv4 address is sourced from IPv6 addresses within the IPv6 packet header.</li>
<li>Routes traffic between 6to4 and &#8220;native&#8221; IPv6 networks.</li>
</ol>
<p>As such its pretty easy to implement, especially on our good friend Debian (and its better looking cousin Ubuntu).</p>
<p>I am going to step through setting up a Debian host at Linode.</p>
<h3>Step 1 Check your Kernel</h3>
<p>Now, the first caveat is that you must be running a 2.6.20+ kernel (At the time of writing the latest linode kernel for Debian was : 2.6 Paravirt (2.6.34-x86_64-linode)). The default &#8216;Etch&#8217; release kernel (2.6.18) supports IPv6 but woefully implements IPv6 stateful connection tracking, which is just not good enough for a decent firewall. If you have a look under your Linode Configuration Profile you can see what Kernel you are running, and change it to one that is supported; obviously a reboot would be in order if you change it. The linode kernels have IPV6 support compiled in.</p>
<p>But here is the quick way to check whether IPV6 is compiled in, if the following fails IPv6 is either not compiled in or the module has not been loaded:</p>
<table style="font-family: 'Times New Roman'; line-height: normal; font-size: small;" border="0" width="100%" bgcolor="#E0E0E0">
<tbody>
<tr>
<td><span style="color: #000000;"></p>
<pre> $ cat /proc/net/if_inet6
00000000000000000000000000000001 01 80 10 80       lo
fe80000000000000fcfd4afffecff19f 02 40 20 80     eth0</pre>
<p></span></td>
</tr>
</tbody>
</table>
<h3>WARNING UBUNTU Pre 10.04LTS !!!</h3>
<p>Modprobe is kind of janky and will stop your interfaces coming up if you follow this guide to the letter. You will need to do this first:</p>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;">As root/sudo divert the old modprobe, this means that any subsequent upgrade won&#8217;t blow away your script</p>
<pre style="color: black; background-color: #f9f9f9; line-height: 1.1em; padding: 1em; border: 1px dashed #2f6fab;">dpkg-divert --add --rename --divert /sbin/modprobe.real /sbin/modprobe</pre>
<p style="margin-top: 0.4em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; line-height: 1.5em;">Create a replacement /sbin/modprobe script:</p>
<pre style="color: black; background-color: #f9f9f9; line-height: 1.1em; padding: 1em; border: 1px dashed #2f6fab;">#!/bin/bash
/sbin/modprobe.real "$@"
ret=$?

if [ "$1" == "-Q" ] ; then
        exit 0
fi

exit $ret</pre>
<h3>Step 2 Calculate your new IPv6 address</h3>
<p>Any IPv6 address that begins with the 2002::/16 prefix is known as a 6to4 address, as opposed to a native IPv6 address which does not use that prefix. The Internet Assigned Numbers Authority (IANA: www.iana.org) has set aside this address space just for 6to4. IPv6 addresses are assigned based upon your IPv4 address; for instance, 74.207.254.16 would become 2002:4acf:fe10::/48</p>
<p>We need some tools to help us calculate our IPV6 address, luckily there is a package for this</p>
<pre style="padding-left: 30px;">$ sudo apt-get install ipv6calc</pre>
<p>Now its a matter of plugging in your IPv4 address into ipv6calc to determine your reserved IPv6 address range.</p>
<pre style="padding-left: 30px;">$ ipv6calc -q --action conv6to4 --in ipv4 74.207.254.16 --out ipv6</pre>
<p>and voila your IPv6 address range appears:</p>
<pre style="padding-left: 30px;">2002:4acf:fe10:: (/48)</pre>
<p>You get given an address range with a prefix length of 48 bits, which leaves room for a 16-bit subnet field and a 64 bit host address within the subnet.</p>
<h3>Step 3 Update your interface configuration</h3>
<p>You now need to edit your network configuration file /etc/network/interfaces file</p>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">auto tun6to4</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">iface tun6to4 inet6 v4tunnel</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">address 2002:4acf:fe10::1</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">netmask 16</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">gateway ::192.88.99.1</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">endpoint any</div>
<div style="position: absolute; left: -10000px; top: 390px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">local 74.207.254.16 #fits address</div>
<pre style="padding-left: 30px;">auto tun6to4 # make sure this interface comes up on boot</pre>
<pre style="padding-left: 60px;"> iface tun6to4 inet6 v4tunnel</pre>
<pre style="padding-left: 60px;"> address 2002:4acf:fe10::1 #first host in this address range</pre>
<pre style="padding-left: 60px;"> netmask 16</pre>
<pre style="padding-left: 60px;"> gateway ::192.88.99.1 #special anycast address for 6to4 (2002:c058:6301::)</pre>
<pre style="padding-left: 60px;"> endpoint any</pre>
<pre style="padding-left: 60px;"> local 74.207.254.16</pre>
<pre style="padding-left: 60px;"> mtu 1472 #The MTU is therefore the normal Ethernet MTU (1500) minus the headers used on the tunnel.</pre>
<pre style="padding-left: 60px;"> ttl 255</pre>
<p style="padding-left: 30px;">Restart your interfaces (not recommended):</p>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace; padding-left: 60px;">$sudo /etc/init.d/networking restart</pre>
<p style="padding-left: 30px;">If you want to be a little  but more careful and not wipe out all networking  if something goes wrong (eg you are using Ubuntu or IPv6 is not available), you could just bring up the new interface:</p>
<pre>        $sudo ifup tun6to4</pre>
<h3>Step 4 Update IPv6 Firewall script/rules</h3>
<p>Now it&#8217;s fairly important (read as critical) to firewall IPv6 stuff as it is with IPv4. Here is a small sample of a firewall that will at the very least not leave you hanging in the breeze. Needless to say you can add your own rules and make this as complex as you need.</p>
<pre style="padding-left: 30px;"># Initialize all the chains by removing all the rules</pre>
<pre style="padding-left: 30px;">iptables --flush</pre>
<pre style="padding-left: 30px;">iptables -t nat --flush</pre>
<pre style="padding-left: 30px;">iptables -t mangle --flush</pre>
<pre style="padding-left: 30px;">ip6tables --flush</pre>
<pre style="padding-left: 30px;">ip6tables -t mangle --flush</pre>
<pre style="padding-left: 30px;"># The loopback interface should accept all traffic</pre>
<pre style="padding-left: 30px;">iptables -A INPUT  -i lo -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -o lo -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -i lo -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -o lo -j ACCEPT</pre>
<pre style="padding-left: 30px;">#Allow IPV6 packets to come over the tunnel</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p ipv6 -i eth0 -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -p ipv6 -o eth0 -j ACCEPT</pre>
<pre style="padding-left: 30px;"># Allow outbound DNS queries from the FW and the replies too</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -p udp -o eth0 --dport 53 --sport 1024:65535 -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p udp -i eth0 --sport 53 --dport 1024:65535  -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -p udp -o tun6to4 --dport 53 --sport 1024:65535 -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -p udp -i tun6to4 --sport 53 --dport 1024:65535  -j ACCEPT</pre>
<pre style="padding-left: 30px;"># Accept and reply to ICMP ping</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT</pre>
<pre style="padding-left: 30px;"># IMPORTANT!!!! Allow all icmpv6 because they make IPV6 work</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -p icmpv6 -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -p icmpv6 -j ACCEPT</pre>
<pre style="padding-left: 30px;"># Allow previously established connections</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -o tun6to4 -m state --state ESTABLISHED,RELATED -j ACCEPT</pre>
<pre style="padding-left: 30px;"># Allow port 80 (www) and 51515 (SSH) connections to the firewall</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p tcp -i eth0 --dport 51515 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p tcp -i eth0 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -p tcp -i eth0 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -p tcp -i tun6to4 --dport 51515 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -p tcp -i tun6to4 --dport 443 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -p tcp -i tun6to4 --dport 80 --sport 1024:65535 -m state --state NEW -j ACCEPT</pre>
<pre style="padding-left: 30px;"># Allow port 80 (www) and 443 (https) connections from the firewall</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -j ACCEPT -m state --state NEW,ESTABLISHED,RELATED -o eth0 -p tcp -m multiport --dport 51515,80,443 -m multiport --sport 1024:65535</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -j ACCEPT -m state --state NEW,ESTABLISHED,RELATED -o tun6to4 -p tcp -m multiport --dport 51515,80,443 -m multiport  --sport 1024:65535</pre>
<pre style="padding-left: 30px;"># Allow previously established connections</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED -i eth0 -p tcp</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -j ACCEPT -m state --state ESTABLISHED,RELATED -i tun6to4 -p tcp</pre>
<pre style="padding-left: 30px;"># The policy should be to drop it</pre>
<pre style="padding-left: 30px;">iptables -A INPUT -j DROP</pre>
<pre style="padding-left: 30px;">iptables -A OUTPUT -j DROP</pre>
<pre style="padding-left: 30px;">iptables -A FORWARD -j DROP</pre>
<pre style="padding-left: 30px;">ip6tables -A INPUT -j DROP</pre>
<pre style="padding-left: 30px;">ip6tables -A OUTPUT -j DROP</pre>
<pre style="padding-left: 30px;">ip6tables -A FORWARD -j DROP</pre>
<p>I usually create a directory called /etc/iptables  (owner root:root  / permissions 750) and drop  firewall up and down scripts in there.</p>
<p>Then it is  a simple matter of adding the following scripts to the bottom of your eth0 interface definition stanza in /etc/network/interfaces to invoke them on boot or whenever:</p>
<div style="position: absolute; left: -10000px; top: 927px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden; padding-left: 30px;">pre-up /etc/iptables/firewall_up.sh</div>
<div style="position: absolute; left: -10000px; top: 927px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden; padding-left: 30px;">post-down /etc/iptables/firewall_down.sh</div>
<pre style="padding-left: 30px;">pre-up /etc/iptables/firewall_up.sh</pre>
<pre style="padding-left: 30px;">post-down /etc/iptables/firewall_down.sh</pre>
<p><strong>IMPORTANT: Just a quick note don&#8217;t block icmpv6 because it is the glue that holds IPv6 together.</strong></p>
<h3>Step 5 Setup Forward DNS</h3>
<p>I am not going to over explain this one because everyone has an opinion on how to setup DNS but in essence you need to add a line like this to your zone file. There are plenty of articles outlining this stuff.</p>
<p style="padding-left: 30px;"><span style="font-family: 'Times New Roman'; line-height: normal; font-size: small;"> </span></p>
<pre style="padding-left: 30px;">hyosine			AAAA	2002:4acf:fe10::1</pre>
<h3>Step 6 Setup Reverse DNS</h3>
<p>You now need to setup  reverse DNS for your address, so using our example of 2002:4acf:fe10 you will have to configure the zone of &#8221;0.0.0.0.0.1.e.f.f.c.a.4.2.0.0.2.ip6.arpa&#8221; in your name servers.  The zone should have PTR records for your hosts just like an in-addr.arpa zone for IPv4, but with hex digits of the IPv6 address backwards, separated by dots. Using our example, the 6to4 host will have a ::1 suffix, so a reverse DNS record looks like:</p>
<p>1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.e.f.f.c.a.4.2.0.0.2.ip6.arpa.<span style="white-space: pre;"> </span>PTR<span style="white-space: pre;"> </span>hyosine.openquery.com.</p>
<p>You will need to register this zone and its servers with the 6to4 reverse zone authority. eg <a href="https://6to4.nro.net/">https://6to4.nro.net/</a></p>
<h3>Step 7  Test</h3>
<p>The ping6 utility is probably best to test whether your host is now working. It&#8217;s probably best to try the IPv6 address first:</p>
<pre style="padding-left: 30px;"><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;"><span style="line-height: 18px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;">
$ ping6 2002:4acf:fe10::1 </span></span></span></span></pre>
<pre style="padding-left: 30px;"><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;"><span style="line-height: 18px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> PING 2002:4acf:fe10::1(2002:4acf:fe10::1) 56 data bytes </span></span></span></span></pre>
<pre style="padding-left: 30px;"><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;"><span style="line-height: 18px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> 64 bytes from 2002:4acf:fe10::1: icmp_seq=1 ttl=60 time=1.59 ms </span></span></span></span></pre>
<pre style="padding-left: 30px;"><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; font-size: small;"><span style="line-height: 18px; white-space: pre;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> 64 bytes from 2002:4acf:fe10::1: icmp_seq=2 ttl=60 time=1.42 ms </span></span></span></span></pre>
<div style="position: absolute; left: -10000px; top: 321px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0<span style="white-space: pre;"> </span>PTR<span style="white-space: pre;"> </span>6to4.example.com.</div>
<div style="position: absolute; left: -10000px; top: 321px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">With that record inside the above zone, the full record would be</div>
<p>Now you can try with the DNS name you just setup.</p>
<div style="position: absolute; left: -10000px; top: 321px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.c.2.0.8.a.0.c.2.0.0.2.ip6.arpa.<span style="white-space: pre;"> </span>PTR<span style="white-space: pre;"> </span>6to4.example.com.</div>
<div style="position: absolute; left: -10000px; top: 3060px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">$ ping6 hyosine.cloudcaster.com</div>
<div style="position: absolute; left: -10000px; top: 3060px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">PING hyosine.cloudcaster.com(2002:4acf:fe10::1) 56 data bytes</div>
<div style="position: absolute; left: -10000px; top: 3060px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">64 bytes from 2002:4acf:fe10::1: icmp_seq=1 ttl=60 time=1.41 ms</div>
<div style="position: absolute; left: -10000px; top: 3060px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">64 bytes from 2002:4acf:fe10::1: icmp_seq=2 ttl=60 time=1.34 ms</div>
<p style="padding-left: 30px;">$ ping6 hyosine.openquery.com</p>
<p style="padding-left: 30px;">PING hyosine.openquery.com(2002:4acf:fe10::1) 56 data bytes</p>
<p style="padding-left: 30px;">64 bytes from 2002:4acf:fe10::1: icmp_seq=1 ttl=60 time=1.41 ms</p>
<p style="padding-left: 30px;">64 bytes from 2002:4acf:fe10::1: icmp_seq=2 ttl=60 time=1.34 ms</p>
<div style="position: absolute; left: -10000px; top: 321px; width: 1px; height: 1px; overflow-x: hidden; overflow-y: hidden;">Lastly, you need to register this zone and its servers with the 6to4 reverse zone authority. Note that when you visit that site, you&#8217;ll get an SSL certificate warning. This is normal. You need to visit this site using IPv6 from the actual 6to4 zone you&#8217;re trying to register. Follow the form to set up the nameservers for the zone and that&#8217;s it!</div>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> </span></span><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> </span></span></span></span><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> </span></span></span></span></span></span><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: small;"><span style="line-height: 19px; white-space: normal;"> </span></span></span></span></span></span></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/6to4-easing-ipv6-transition/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast paging in the real world</title>
		<link>http://openquery.com/blog/fast-paging-real-world</link>
		<comments>http://openquery.com/blog/fast-paging-real-world#comments</comments>
		<pubDate>Mon, 31 May 2010 03:36:55 +0000</pubDate>
		<dc:creator>cafuego</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[COUNT]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[SQL_CALC_FOUND_ROWS]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1271</guid>
		<description><![CDATA[This blag was originally posted at http://cafuego.net/2010/05/26/fast-paging-real-world Some time ago I attended the &#8220;Optimisation by Design&#8221; course from Open Query¹. In it, Arjen teaches how writing better queries and schemas can make your database access much faster (and more reliable). One such way of optimising things is by adding appropriate query hints or flags. These hints [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: right;"><em>This blag was originally posted at <a href="http://cafuego.net/2010/05/26/fast-paging-real-world">http://cafuego.net/2010/05/26/fast-paging-real-world</a></em></p>
<p>Some time ago I attended the &#8220;Optimisation by Design&#8221; course from Open Query¹. In it, Arjen teaches how writing better queries and schemas can make your database access much faster (and more reliable). One such way of optimising things is by adding appropriate query hints or flags. These hints are magic strings that control how a server executes a query or how it returns results.</p>
<p>An example of such a hint is <em>SQL_CALC_FOUND_ROWS</em>. You use it in a select query with a <em>LIMIT</em> clause. It instructs the server to select a limited numbers of rows, but also to calculate the total number of rows that would have been returned without the limit clause in place. That total number of rows is stored in a session variable, which can be retrieved via <em>SELECT FOUND_ROWS(); </em> That simply reads the variable and clears it on the server, it doesn&#8217;t actually have to look at any table or index data, so it&#8217;s very fast.</p>
<p>This is useful when queries are used to generate pages of data where a user can click a specific page number or click previous/next page. In this case you need the total number of rows to determine how many pages you need to generate links for.</p>
<p>The traditional way is to first run a <em>SELECT COUNT(*)</em> query and then select the rows you want, with <em>LIMIT</em>. If you don&#8217;t use a <em>WHERE</em> clause in your query, this can be pretty fast on MyISAM, as it has a magic variable that contains the number of rows in a table. On InnoDB however, which is <a href="http://cafuego.net/2009/10/10/mysql-yoursql">my storage engine of choice</a>, there is no such variable and consequently it&#8217;s not pretty fast.</p>
<h3></h3>
<h3>Paging Drupal</h3>
<p>At DrupalConSF earlier this year I&#8217;d floated the idea of making Drupal 7 use SQL_CALC_FOUND_ROWS in its pager queries. These are queries generated specifically to display paginated lists of content and the API to do this is pretty straightforward. To do it I needed to add query hint support to the MySQL driver. When it turned out that PostgreSQL and Oracle also support query hints though, the aim became adding hint support for all database drivers.</p>
<p>That&#8217;s now done, though only the patch only implements hints on the pager under MySQL at the moment.</p>
<p>One issue keeps cropping up though, a <a href="http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/">blog by Alexey Kovyrin in 2007</a> that states <em>SELECT COUNT(*)</em> is faster than using <em>SQL_CALC_FOUND_ROWS</em>. It&#8217;s all very well to not have a patch accepted if that statement is correct, but in my experience that is in fact not the case. In my experience the stats are in fact the other way around, SQL_CALC_FOUND_ROWS is nearly always faster than <em>SELECT COUNT(*)</em>.</p>
<p>To back up my claims I thought I should run some benchmarks.</p>
<p>I picked the Drupal pager query that lists content (nodes) on the content administration page. It selects node IDs from the node table with a WHERE clause which filters by the content language. Or, in plain SQL, what currently happens is:</p>
<pre>SELECT COUNT(*) FROM node WHERE language = 'und';
SELECT nid FROM node WHERE language = 'und' LIMIT 0,50;</pre>
<p>and what I&#8217;d like to happen is:</p>
<pre>SELECT SQL_CALC_FOUND_ROWS nid FROM node WHERE language = 'und' LIMIT 0,50;
SELECT FOUND_ROWS();</pre>
<h3></h3>
<h3>Methodology</h3>
<p>I ran two sets of tests. One on a node table with 5,000 rows and one with 200,000 rows. For each of these table sizes I ran a pager with 10, 20, 50, 100 and 200 loops, each time increasing the offset by 50; effectively paging through the table. I ran all these using both MyISAM and InnoDB as the storage engine for the node table and I ran them on two machines. One was my desktop, a dual core Athlon X2 5600 with 4Gb of RAM and the other is a single core Xen virtual machine with 512Mb of RAM.</p>
<p>I was hoping to also run tests with 10,000,000 rows, but the virtual machine did not complete any of the queries. So I ran these on my desktop machine only. Again for 10, 20, 50, 100 and 200 queries per run. First with an offset of 50, then with an offset of 10,000. I restarted the MySQL server between each run. To discount query cache advantages, I ran all tests with the query cache disabled. The script I used is attached at the bottom of this post. The calculated times <strong>do</strong> include the latency of client/server communication, though all tests ran via the local socket connection.</p>
<p>My desktop runs an <a href="http://ourdelta.org/">OurDelta</a> mysql .5.0.87 (the -d10-ourdelta-sail66) to be exact. The virtual machine runs 5.0.87 (-d10-ourdelta65).  Before you complain that not running a vanilla MySQL invalidates the results, I run these because I am able to tweak InnoDB a bit more, so the I/O write load on the virtual machine is somewhat reduced compared to the vanilla MySQL.</p>
<h3></h3>
<h3>Results</h3>
<p><a href="http://cafuego.net/sites/cafuego.net/files/Graphs.png"><img src="http://cafuego.net/sites/cafuego.net/files/small-count-graphs.png" border="0" alt="Query time graphs - NEW is faster than OLD and InnoDB is not slower than MyISAM" hspace="12" vspace="4" width="600" height="275" /></a></p>
<p>The graphs show that using <em>SQL_CALC_FOUND_ROWS</em> is virtually always faster than running two queries that each need to look at actual data. Even when using MyISAM. As the database gets bigger, the speed advantage of <em>SQL_CALC_FOUND_ROWS</em> increases. At the 10,000,000 row mark, it&#8217;s consistently about twice as fast.</p>
<p>Also interesting is that InnoDB seems significantly slower than MyISAM on the shorter runs. I say <em>seems</em>, because (especially with the 10,000,000 row table) the delay is caused by InnoDB first loading the table from disk into its buffer pool. In the spreadsheet you can see the first query takes up to 40 seconds, whilst subsequent ones are much faster. The MyISAM data is still in the OS file cache, so it doesn&#8217;t have that delay on the first query. Because I use <em>innodb_flush_method=O_DIRECT</em>, the InnoDB data is not kept in the OS file cache.</p>
<h3></h3>
<h3>Conclusion</h3>
<p>So, it&#8217;s official. COUNT(*) is dead, long live SQL_CALC_FOUND_ROWS!  :-)</p>
<p>I&#8217;ve attached my raw results as a Gnumeric document, so feel free to peruse them. The test script I&#8217;ve used is also attached, so you can re-run the benchmark on your own systems if you wish.</p>
<h3></h3>
<h3>Conclusion Addendum</h3>
<p>As pointed out in the Drupal <a href="http://drupal.org/node/778050">pager issue</a> that caused me to run these tests, the query I&#8217;m benchmarking uses the language column, which is not indexed and the test also doesn&#8217;t allow the server to cache the COUNT(*) query. I&#8217;ve rerun the tests with 10 million rows after adding an index and I no longer get a signification speed difference between the two ways of getting the total number of rows.</p>
<p>So I suppose that at least SQL_CALC_FOUND_ROWS will cause your non-indexed pager queries to suck a lot less than they might otherwise and it won&#8217;t hurt if they <em>are</em> properly indexed <img src='http://openquery.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>¹ I now work for Open Query as a consultant.</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/fast-paging-real-world/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Unqualified COUNT(*) speed PBXT vs InnoDB</title>
		<link>http://openquery.com/blog/unqualified-count-speed-pbxt-vs-innodb</link>
		<comments>http://openquery.com/blog/unqualified-count-speed-pbxt-vs-innodb#comments</comments>
		<pubDate>Thu, 27 May 2010 04:54:47 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Good practice / Bad practice]]></category>
		<category><![CDATA[COUNT]]></category>
		<category><![CDATA[index scan]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[MyISAM]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pbxt]]></category>
		<category><![CDATA[reporting]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1261</guid>
		<description><![CDATA[So this is about a SELECT COUNT(*) FROM tblname without a WHERE clause. MyISAM has an optimisation for that since it maintains a rowcount for each table. InnoDB and PBXT can&#8217;t do that (at least not easily) because of their multi-versioned nature&#8230; different transactions may see a different number of rows for the table table! [...]]]></description>
			<content:encoded><![CDATA[<p>So this is about a <strong>SELECT COUNT(*) FROM tblname</strong> without a <strong>WHERE</strong> clause. MyISAM has an optimisation for that since it maintains a rowcount for each table. InnoDB and PBXT can&#8217;t do that (at least not easily) because of their multi-versioned nature&#8230; different transactions may <em>see</em> a different number of rows for the table table!</p>
<p>So, it&#8217;s kinda known but nevertheless often ignored that this operation on InnoDB is costly in terms of time; what InnoDB has to do to figure out the exact number of rows is scan the primary key and just tally. Of course it&#8217;s faster if it doesn&#8217;t have to read a lot of the blocks from disk (i.e. smaller dataset or a large enough buffer pool).</p>
<p>I was curious about PBXT&#8217;s performance on this, and behold it appears to be quite a bit faster! For a table with 50 million rows, PBXT took about 20 minutes whereas the same table in InnoDB took 30 minutes. Interesting!</p>
<p>From those numbers [addendum: yes I do realise there's something else wrong on that server to take that long, but it'd be slow regardless] you can tell that doing the query at all is not an efficient thing to do, and definitely not something a frontend web page should be doing. Usually you just need a ballpark figure so running the query in a cron job and putting the value into memcached (or just an include file) will work well in such cases.</p>
<p>If you do use a WHERE clause, all engines (including MyISAM) are in the same boat&#8230; they  might be able to use an index to filter on the conditions &#8211; but the  bigger the table, the more work it is for the engine. PBXT being faster than InnoDB for this task makes it potentially interesting for reporting purposes as well, where otherwise you might consider using MyISAM &#8211; we generally recommend using a separate reporting slave with particular settings anyway (fewer connections but larger session-specific buffers), but it&#8217;s good to have extra choices for the task.</p>
<p>(In case you didn&#8217;t know, it&#8217;s ok for a slave to use a different engine from a master &#8211; so you can really make use of that ability for specialised tasks such as reporting.)</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/unqualified-count-speed-pbxt-vs-innodb/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PBXT early impressions in production use</title>
		<link>http://openquery.com/blog/pbxt-early-impressions-production</link>
		<comments>http://openquery.com/blog/pbxt-early-impressions-production#comments</comments>
		<pubDate>Thu, 27 May 2010 02:03:19 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Software and tools]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pbxt]]></category>
		<category><![CDATA[storage engine]]></category>
		<category><![CDATA[XA]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1257</guid>
		<description><![CDATA[With Paul McCullagh&#8217;s PBXT storage engine getting integrated into MariaDB 5.1, it&#8217;s never been easier to it out. So we have, on a slave off one of our own production systems which gets lots of inserts from our Zabbix monitoring system. That&#8217;s possibly an ideal usage profile, since PBXT is a log based engine (simplistically [...]]]></description>
			<content:encoded><![CDATA[<p>With Paul McCullagh&#8217;s <a href="http://primebase.org" target="_blank">PBXT</a> storage engine getting integrated into <a href="http://askmonty.org" target="_blank">MariaDB 5.1</a>, it&#8217;s never been easier to it out. So we have, on a slave off one of our own production systems which gets lots of inserts from our Zabbix monitoring system.</p>
<p>That&#8217;s possibly an ideal usage profile, since PBXT is a log based engine (simplistically stated, it indexes its transaction logs, rather than rewriting data from log into index and indexing that) so it should require less disk I/O than say InnoDB. And that means it should be particularly suited to for instance logging, which have lots of inserts on a sustained basis. Note that for short insert burst you may not see a difference with InnoDB because of caching, but sustain it and then you can notice.</p>
<p>Because PBXT has such different/distinct architecture there&#8217;s a lot of learning involved. Together with Paul and help from Roland Bouman we also created a stored procedure that can calculate the optimal average row size for PBXT, and even ALTER TABLE statements you can paste to convert tables. The AVG_ROW_LENGTH option is quite critical with PBXT, if set too big (or if you let PBXT guess and it gets it wrong) it&#8217;ll eat heaps more diskspace as well as being much slower, and if too small it&#8217;ll be slower also; this, it needs to be in the right ballpark. For existing datasets it can be calculated, so that&#8217;s what we&#8217;ve worked on. The procs will be published shortly, and Paul will also put them in with the rest of the PBXT files.</p>
<p>Another important aspect for PBXT is having sufficient cache memory allocated, otherwise operations can take much much longer. While the exact &#8220;cause&#8221; is different, one would notice similar performance aspects when using InnoDB on larger datasets and buffers that are too small for the purpose.</p>
<p>So, while using or converting some tables to PBXT takes a bit of consideration, effort and learning, it appears to be dealing with the real world very well so far &#8211; and that&#8217;s a testament to Paul&#8217;s experience. Paul is also very responsive to questions. As we gain more experience, it is our intent to try PBXT for some of our clients that have operational needs that might be a particularly good fit for PBXT.</p>
<p>I should also mention that it is possible to have a consistent  transaction between PBXT, InnoDB and the binary log, because of the  2-phase commit (XA) infrastructure. This means that you should even be  able to do a mysqldump with &#8211;single-transaction if you have both PBXT  and InnoDB tables, and acquire a consistent snapshot!</p>
<p>More experiences and details to come.</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/pbxt-early-impressions-production/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Today&#8217;s up-time requirements</title>
		<link>http://openquery.com/blog/todays-uptime-requirements</link>
		<comments>http://openquery.com/blog/todays-uptime-requirements#comments</comments>
		<pubDate>Mon, 24 May 2010 03:43:51 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[emergency]]></category>
		<category><![CDATA[mariadb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[outage]]></category>
		<category><![CDATA[resilience]]></category>
		<category><![CDATA[SLA]]></category>
		<category><![CDATA[support]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1253</guid>
		<description><![CDATA[When asking about up-time requirements set down in SLAs (Service Level Agreements) with our clients&#8217; clients, we&#8217;d hear anything ranging from hours to the familiar five nines, but these days also simply 100% and otherwise penalties apply. From my perspective, there&#8217;s not much difference between five nines and 100%, 99.999% uptime over a year amounts [...]]]></description>
			<content:encoded><![CDATA[<p>When asking about up-time requirements set down in SLAs (Service Level Agreements) with our clients&#8217; clients, we&#8217;d hear anything ranging from hours to the familiar five nines, but these days also simply 100% and otherwise penalties apply. From my perspective, there&#8217;s not much difference between five nines and 100%, 99.999% uptime over a year amounts to a maximum of little over 5 minutes outage. In many cases, this includes scheduled outages!</p>
<p>So, we can just not have any outages, scheduled or otherwise. Emergency support is not going to help here, because however fast and good they are, you&#8217;re already in serious penalty time or well on your way to not having a business any more. Most will respond within say 30 minutes but then need up to a few hours to resolve the issue. That won&#8217;t help you, really, will it? And in any case, how are you going to do your maintenance? The answer is, you need to architect things differently.</p>
<p>I do appreciate the issue of transitioning from the corporate tradition of outsourcing the liability along with emergency support, e.g. someone to call and if need be sue&#8230; it takes time both in business processes as well as in actual architecture to make things resilient. But really, if those are the SLAs you agree on with your clients, that&#8217;s what has to be done.</p>
<p>Anyway, aiming for resilience (expecting things to break but building infra so that it can cope with it) rather than purchasing many-9s is I think a better focus. This because making an individual component even more reliable becomes prohibitively expensive, whereas having more servers is relatively cheap. That&#8217;s simple economics.</p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/todays-uptime-requirements/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Long tails on licensing questions</title>
		<link>http://openquery.com/blog/long-tails-licensing-questions</link>
		<comments>http://openquery.com/blog/long-tails-licensing-questions#comments</comments>
		<pubDate>Mon, 17 May 2010 00:26:51 +0000</pubDate>
		<dc:creator>arjen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[gpl]]></category>
		<category><![CDATA[licensing]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://openquery.com/blog/?p=1245</guid>
		<description><![CDATA[In my time at MySQL AB in the Community Relations possition (2004-2006) I wrote several articles on MySQL&#8217;s licensing for the MySQL web site. The core reason for having to explain anything was (and still is) the dual licensing of MySQL, in particular the client library. I left MySQL AB years ago, but people still [...]]]></description>
			<content:encoded><![CDATA[<p>In my time at MySQL AB in the Community Relations possition (2004-2006) I wrote several articles on MySQL&#8217;s licensing for the MySQL web site. The core reason for having to explain anything was (and still is) the dual licensing of MySQL, in particular the client library. I left MySQL AB years ago, but people still ask me licensing questions. Below is an excerpt from one such question, and my response.</p>
<p><span style="color: #0000bb;">&gt;  Hi, Found a post on the mysql website from  Arjen Lentz to do with the whole</span><br />
<span style="color: #0000bb;">&gt;  mysql licensing question.</span><br />
<span style="color: #0000bb;">&gt;  Do you know if the issue with, php scripts  (that use a mysql database) issued</span><br />
<span style="color: #0000bb;">&gt;  under a proprietary license require you to  have a commercial license for</span><br />
<span style="color: #0000bb;">&gt;  mysql, or will the issues be covered for the  GPL version through the fact</span><br />
<span style="color: #0000bb;">&gt;  that the scripts run via php which in-turn  connects to the GPL mysql server</span><br />
<span style="color: #0000bb;">&gt;  for which the FOSS exception applies.</span></p>
<p><em><span style="color: #000000;"> Note: I am not a lawyer; this is not legal  advice.</span></em></p>
<p><span style="color: #000000;"> The issue might be a bit fuzzy since you are  actually dependent on MySQL server, whether or not you are &#8220;linking&#8221;. So  the linkage could be there anyway (there&#8217;s no consensus on this interpretation of &#8220;linking&#8221;, it is however the viewpoint of some &#8211; hence the fuzzyness).</span></p>
<p><span style="color: #000000;"> My recommendation to you would be to not fuss  with any nasty licensing for the PHP code you create for clients. While  this provides the client with more freedom, you are the expert and thus  the first choice for any support and future development. Providing  clients with freedom tends to bind them more to you, while restrictions  tend to make them look around for alternatives.</span></p>
<p><span style="color: #000000;"> Your clients are in whatever business they&#8217;re in,  which is probably not PHP code development; it&#8217;s not in their interest  to go spend time on that or undermining you, unless you were to provide  bad service.</span></p>
<p><span style="color: #000000;"> If you approach your software in this way with  your clients, you can generally GPL it and do equal or better business  while not having to worry about nettly licensing questions. You don&#8217;t  want to base your business on a legal argument, as you just don&#8217;t want  the question to get raised to begin with&#8230; it&#8217;d be costly and  distracting (if not destructive).</span></p>
]]></content:encoded>
			<wfw:commentRss>http://openquery.com/blog/long-tails-licensing-questions/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->