<?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>2ndQuadrant &#187; Greg&#8217;s PlanetPostgreSQL</title>
	<atom:link href="http://blog.2ndquadrant.com/gregs-planetpostgresql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.2ndquadrant.com</link>
	<description>PostgreSQL expertise from specialists with a source code level understanding of RDBMS</description>
	<lastBuildDate>Mon, 17 Jun 2013 08:00:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Intel SSDs:  Lifetime and the 320 vs. 710 Series</title>
		<link>http://blog.2ndquadrant.com/intel_ssds_lifetime_and_the_32/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=intel_ssds_lifetime_and_the_32</link>
		<comments>http://blog.2ndquadrant.com/intel_ssds_lifetime_and_the_32/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 22:03:25 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[United States News]]></category>
		<category><![CDATA[postgresql ssd]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=88</guid>
		<description><![CDATA[This week I&#8217;ve been digging deep into PostgreSQL storage hardware again. &#160;Since I&#8217;m giving a conference talk...]]></description>
			<content:encoded><![CDATA[<div>This week I&#8217;ve been digging deep into PostgreSQL storage hardware again. &nbsp;Since I&#8217;m giving a conference talk on database storage in <a href="http://pgday.austinpug.org/talks/">Austin</a> and in the <a href="http://pgday.bwpug.org/">DC area</a> next week, it seems like a good time for me to actually know the material. &nbsp;One of the most common questions here is &#8220;what&#8217;s the cheapest SSD I can put my database on?&#8221;, with the implied hope &#8220;&#8230;without <a href="http://wiki.postgresql.org/wiki/Reliable_Writes">losing it all the time</a>&#8220;.  Last year the first inexpensive answer to that appeared on the market, and I suggested people <a href="http://blog.2ndquadrant.com/en/2011/04/intel-ssd-now-off-the-sherr-sh.html">take a look</a> at Intel&#8217;s 320 series drives. &nbsp;With 217 days of runtime on my first 320 drive here, and Intel&#8217;s 3rd generation storage line filled out with the more enterprise oriented 710 Series now, it&#8217;s worth reviewing how that turned out.</div>
<div></div>
<div>It wasn&#8217;t long after the 320 series drives were introduced that people started reporting a firmware problem with the drive, where it did things like report a capacity of 8MB after a restart along with &#8220;BAD_CTX 0000013x&#8221; errors. &nbsp;A <a href="http://communities.intel.com/thread/24205?tstart=20">firmware update to fix that</a> was released. &nbsp;There&#8217;s still some claims of <a href="http://communities.intel.com/thread/24339?tstart=0">continued problems</a> floating around. &nbsp;You have to expect some percentage of any product are going to be bad, and the later production of this drive (after the big bug was fixed) don&#8217;t seem above the usual risk level in hard drives to me. &nbsp;With the warranty here <a href="http://newsroom.intel.com/community/intel_newsroom/blog/2011/05/19/chip-shot-new-5-year-limited-warranty-on-intel-ssd-320">extended to 5 years</a> (unless you&#8217;re using it at &#8216;enterprise usage levels&#8217;), I think that Intel would be getting killed if the reliability on these was as bad as some people claim.</div>
<div></div>
<div>The reason behind the usage level caveat is the main thing worth talking about here. &nbsp;The <a href="http://www.intel.com/support/ssdc/hpssd/sb/CS-032510.htm">long version of the warranty</a> suggests &#8220;The media wear-out indicator reports a normalized value of 100 (when the <span class="caps">SSD </span>is brand new out of the factory) and declines to a minimum value of 1. When the value reads 1, this indicates that the <span class="caps">SSD </span>is reaching the wear-out limit&#8221;. &nbsp;Here&#8217;s what my first 320 looks like so far:</div>
<pre><code>
[root@toy ~]# smartctl -a /dev/sdc
=== START OF INFORMATION SECTION ===
Device Model:     INTEL SSDSA2CW120G3
...
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
3 Spin_Up_Time            0x0020   100   100   000    Old_age   Offline      -       0
4 Start_Stop_Count        0x0030   100   100   000    Old_age   Offline      -       0
5 Reallocated_Sector_Ct   0x0032   100   100   000    Old_age   Always       -       0
9 Power_On_Hours          0x0032   100   100   000    Old_age   Always       -       5225
12 Power_Cycle_Count       0x0032   100   100   000    Old_age   Always       -       58
170 Unknown_Attribute       0x0033   100   100   010    Pre-fail  Always       -       0
171 Unknown_Attribute       0x0032   100   100   000    Old_age   Always       -       0
172 Unknown_Attribute       0x0032   100   100   000    Old_age   Always       -       0
184 End-to-End_Error        0x0033   100   100   090    Pre-fail  Always       -       0
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       34
225 Load_Cycle_Count        0x0032   100   100   000    Old_age   Always       -       201389
226 Load-in_Time            0x0032   100   100   000    Old_age   Always       -       2687040
227 Torq-amp_Count          0x0032   100   100   000    Old_age   Always       -       0
228 Power-off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       314526
232 Available_Reservd_Space 0x0033   100   100   010    Pre-fail  Always       -       0
233 Media_Wearout_Indicator 0x0032   099   099   000    Old_age   Always       -       0
241 Total_LBAs_Written      0x0032   100   100   000    Old_age   Always       -       201389
242 Total_LBAs_Read         0x0032   100   100   000    Old_age   Always       -       133021
</code></pre>
<p>Not all of these attributes are labeled correctly, and some are &#8220;Unknown&#8221;; all the gory details are in the <a href="http://www.intel.com/content/www/us/en/solid-state-drives/ssd-320-specification.html">product specifications</a>.  You can see the Media Wearout above; here&#8217;s the raw values for other interesting ones, formatted so they&#8217;re more blog-friendly:</p>
<pre><code>
ID# ATTRIBUTE_NAME          RAW_VALUE
9 Power_On_Hours          5225
12 Power_Cycle_Count       58
192 Power-Off_Retract_Count 34
225 Load_Cycle_Count        201389
241 Total_LBAs_Written      201389
242 Total_LBAs_Read         133021
</code></pre>
<p>192 (hex C0) is &#8220;Power-Off Retract Count&#8221;. &nbsp;That&#8217;s how many unsafe shutdowns the drive has been through, which are the situations where the battery backed cache in the drive has been triggered. &nbsp;With 34 of them here, you can see I&#8217;ve tried to get this drive to die that way.
<div></div>
<div>The first interesting wear figure is 225 (hex code E1) which Intel&#8217;s documentation describes as &#8220;Host Writes&#8221;. &nbsp;The units for that are 32MB. &nbsp;If you look carefully, you&#8217;ll see that&#8217;s the same value given in 241 &#8220;Total <span class="caps">LBA</span>s Written&#8221;. &nbsp;That suggests the <span class="caps">LBA </span>unit for the drive is also 32MB, which I <a href="http://archives.postgresql.org/pgsql-performance/2011-07/msg00194.php"> double-checked</a> last year. &nbsp;At 32MB each, my write value of 201389 means I&#8217;ve written 6.15TB to this drive.</div>
<div></div>
<div>Now, computing the true lifetime of an <span class="caps">SSD </span>depends on a couple of magic values, like the &#8220;write amplification&#8221; of your workload. &nbsp;That suggests how often your workload forces small bits of data out to flash, using up some of the <span class="caps">NAND </span>cell lifetime faster than it might otherwise last. &nbsp;These numbers are really hard to estimate. &nbsp;The most realistic way is figure this out is to run a workload simulation after resetting the drive&#8217;s internal counters, then see just how much you burned through. &nbsp;The process is walked through with an example at <a href="http://www.anandtech.com/show/5518/a-look-at-enterprise-performance-of-intel-ssds/6">&#8220;Measuring How Long Your Intel <span class="caps">SSD</span> Will Last&#8221;</a>, and it&#8217;s not too hard to translate that example (which uses Intel&#8217;s <span class="caps">SSD</span> Toolbox software) into a set of of smartctl commands if you&#8217;re on Linux&#8211;the article even uses smartctl for the counter reset part.</div>
<div></div>
<div>The official documentation is this is Intel&#8217;s <a href="http://www.intel.com/content/www/us/en/solid-state-drives/ssd-320-enterprise-server-storage-application-specification-addendum.html">Enterprise Server addendum</a>, and here we finally find some hard numbers about the expected life of these drives. &nbsp;My 120GB drive is said to have a &#8220;write endurance&#8221; of 15TB. &nbsp;A pessimistic look at my sample drive here would check total writes and say that, having written over 6TB, I&#8217;ve gone through 40% of the drive lifetime. &nbsp;But write endurance doesn&#8217;t work that way; the firmware is constantly doing tricks to extend the life of the drive. &nbsp;Intel&#8217;s official number they sometimes tie the warranty to, the Media Wearout, is showing 99% left! &nbsp;If that&#8217;s true&#8211;I&#8217;ve only used 1% of the drive&#8217;s lifespan&#8211;then I might manage 600TB of writes before this one really dies on me.</div>
<div></div>
<div>So what&#8217;s the story with the true Enterprise lifetime 710 Series drives? &nbsp;Those almost the same drives as the 320 series ones, with three significant changes. &nbsp;First, they&#8217;re said to use higher quality flash, probably with the same sort of &#8220;put the best tested chips first in the expensive models&#8221; approach Intel is said to use on their <span class="caps">CPU </span>production&#8211;what&#8217;s sometimes called binning. &nbsp;Second, the drives are overprovisioned with a lot more unused flash compared to the 320 series models, and unused flash really helps extend longevity. &nbsp;Finally, they don&#8217;t claim the capabilities to be quite as good. &nbsp;Random write <span class="caps">IOPS </span>numbers on the 710 series drives are lower; my 120GB 320 series drive is specified at 14K write <span class="caps">IOPS, </span>while the 100GB 710 series only aims for 2700.  The drive doesn&#8217;t claim to support lots of tiny writes and still last for years, which means it&#8217;s aimed at a different set of write amplification expectations. &nbsp;Similarly, the 710 series drives don&#8217;t refresh the stored cells in the same way. &nbsp;The downside there is that 710 models are only specified to retain their data for 3 months. &nbsp;That&#8217;s probably fine for data center use, but that wouldn&#8217;t be very acceptable to the more consumer oriented market the 320 series is sold to.</div>
<div></div>
<div>The end result of that, and how the 710 compares to the 320 series drives, is nicely summarized in the &#8220;Write Endurance&#8221; table in the <a href="http://www.tomshardware.com/reviews/ssd-710-enterprise-x25-e,3038-2.html">Tom&#8217;s Hardware Review</a>. &nbsp;Instead of the 15TB endurance number my 320 drive specifies, the similar 100GB 710 series model aims for 500TB. &nbsp;That&#8217;s just over 30X as long. &nbsp;In the real world, there may not be that big of a difference, as shown by the projected 600TB figure I&#8217;m seeing out of my 320 drive so far. &nbsp;But Intel&#8217;s aiming at conservative engineering lifetimes on the specification sheets, and by that measure the storage cells 710 <strong>will</strong> last longer; the 320 models only <strong>may</strong> last longer. &nbsp;And an expected lifetime 30X as long is something some people are surely willing to pay the 710&#8242;s price premium for.</div>
<div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/intel_ssds_lifetime_and_the_32/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the PostgreSQL System Columns</title>
		<link>http://blog.2ndquadrant.com/using_the_postgresql_system_co/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using_the_postgresql_system_co</link>
		<comments>http://blog.2ndquadrant.com/using_the_postgresql_system_co/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 21:53:43 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=87</guid>
		<description><![CDATA[There are a few parts of the PostgreSQL internals that poke out usefully if you look in...]]></description>
			<content:encoded><![CDATA[<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
A:link { so-language: zxx }
CODE.cjk { font-family: "DejaVu Sans", monospace }
--></style>
<p>There are a few parts of the PostgreSQL internals that poke out usefully if you look in the right place for them.&nbsp; One useful set to know about are the <a href="http://www.postgresql.org/docs/current/static/ddl-system-columns.html">System Columns</a>, which you can explicitly request but don&#8217;t see by default.&nbsp; For example:</p>
<blockquote><p>psql -x -c &#8220;SELECT oid,* FROM pg_class LIMIT 1&#8243;</p></blockquote>
<p>There is no column named oid in the pg_class table, but it&#8217;s there if you ask for it.&nbsp; The oid used to be relied on more heavily in PostgreSQL as a way to identify rows.&nbsp; That&#8217;s not true for regular tables anymore, and you really don&#8217;t want to start doing that for your own tables.&nbsp; OIDs are mainly useful now when joining parts of the <a href="http://www.postgresql.org/docs/current/static/catalogs.html">System Catalog</a> together.&nbsp; A good example is the <a href="http://wiki.postgresql.org/wiki/Disk_Usage">Disk Usage</a> query.&nbsp; If you want to find the namespace a table is in, you need to know you can ask for its OID.&nbsp; It&#8217;s possible to get some of this data out of more portable views like information_schema.tables.&nbsp; But many of the useful things in this area are PostgreSQL specific.&nbsp; Sometimes I see people starting with the information_schema views and joining against other tables using its text name fields, such as the listed table_name.&nbsp; That approach has several edge cases that don&#8217;t work out correctly; not handling <a href="http://www.postgresql.org/docs/current/static/storage-toast.html">TOAST</a> columns is a common example.&nbsp; That makes them more prone to breaking on you later, probably after your system has gone into production, than an OID based join.</p>
<p>There is also a tableoid system column.&nbsp; As described in the documentation, its main use case is identifying which partition a row come from.&nbsp; That&#8217;s not a great thing to be driving application logic from, but it can be useful for monitoring or troubleshooting purposes.&nbsp; For example, if you SELECT rows from the parent table in a partitioning inheritance scheme, it&#8217;s normally expected that no rows will actually be stored there.&nbsp; Checking the tableoid is one way to confirm that.&nbsp; You might confirm that your INSERT/UPDATE trigger is moving rows to the right place using tableoid as well.&nbsp; It&#8217;s possible to do that for each individual partition section, but running a query against the parent will make sure you hit every row in the table.</p>
<p>Another internal column related to uniquely identifying rows is the ctid.&nbsp; The ctid is a direct pointer to the physical block (using PostgreSQL&#8217;s 8K page size) and position of a row.&nbsp; ctids are a pair of numbers, and the first row will be (0,1).&nbsp; While this is the fastest way to find a row more than once in the same transaction block, these numbers are not stable in the long term.&nbsp; Any UPDATE and some maintenance operations will change them.&nbsp; One thing you can use these for is finding duplicate data in a table.&nbsp; Let&#8217;s say you&#8217;re trying to add a unique constraint, but one row in the table is duplicated 3 times, which blocks the unique index from being created.&nbsp; When rows are identical in every column, you can&#8217;t write any simple SELECT statement to uniquely identify them.&nbsp; That means deleting all of them but one copy requires some annoying and fragile SQL code, combining DELETE with LIMIT and/or OFFSET&#8211;which is always scary.&nbsp; If you use the ctid instead, the implementation will be PostgreSQL specific, but it will also be faster and cleaner.&nbsp; See <a href="http://www.postgresonline.com/journal/archives/22-Deleting-Duplicate-Records-in-a-Table.html">Deleting Duplicate Records in a Table</a> for an example of how that can be done.</p>
<p>The other system columns all relate to transaction visibility:&nbsp; xmin, cmin, xmax, cmax.&nbsp; When you delete a row in PostgreSQL, it isn&#8217;t eliminated from disk immediately.&nbsp; It&#8217;s possible that some other query that&#8217;s executing at the same time will still need to see that row, and the <a href="http://www.postgresql.org/docs/current/static/transaction-iso.html">transaction isolation</a> in PostgreSQL worries about such things.&nbsp; If you ever want to learn how that isolation works, the way the <a href="http://www.postgresql.org/docs/current/static/mvcc.html">Multiversion Concurrency Control</a> (MVCC) implementation is handled, you can watch parts of it happen.&nbsp; Just open transactions in two different sessions, UPDATE/DELETE in one of them, and then look at those rows in the other.&nbsp; You can still see them in the session where they weren&#8217;t touched, but they&#8217;ll be marked to expire in the future via their xmax being set.&nbsp; To really pull that all together, you also need to know about some of the <a href="http://www.postgresql.org/docs/current/static/functions-info.html">System Information Functions</a>.&nbsp; <i>txid_current()</i> is the most useful for this sort of learning experience, it provides a reference point for the always increasing system transaction ID.&nbsp; You can find a more detailed exploration of using these functions and system columns in Bruce&#8217;s <a href="http://momjian.us/main/presentations/internals.html">MVCC Unmasked</a> talk.&nbsp; The &#8220;Routine Maintenance&#8221; chapter of <a href="https://www.packtpub.com/postgresql-90-high-performance/book">my book</a> also shows examples how how MVCC works through the perspective of the system columns.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/using_the_postgresql_system_co/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Global trends in deploying PostgreSQL</title>
		<link>http://blog.2ndquadrant.com/global_trends_in_deploying_pos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=global_trends_in_deploying_pos</link>
		<comments>http://blog.2ndquadrant.com/global_trends_in_deploying_pos/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 18:08:39 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=80</guid>
		<description><![CDATA[This year&#8217;s conference lineup led me all over the world, a giant rectangle triangle going from the...]]></description>
			<content:encoded><![CDATA[<p>This year&#8217;s conference lineup led me all over the world, a giant rectangle triangle going from the west coast of the US, north to Canada, east to the UK and Amsterdam, then ending south in Brazil.&nbsp; I&#8217;ve now locked myself in to focus on the 3rd CommitFest for PostgreSQL 9.2, which began a few days ago.&nbsp; Check out the 2011-11 section of the <a href="https://commitfest.postgresql.org/">CommitFest tracker</a> to see what changes have been submitted, we&#8217;re always looking for new volunteer <a href="http://wiki.postgresql.org/wiki/Reviewing_a_Patch">patch reviewers</a>.</p>
<p>Talking to people deploying PostgreSQL in several countries during a short span of time has given me some interesting perspective on where the project is at.&nbsp; I follow a lot of adoption trends in the US, and some of those I assume are quirks in how business is done in this country.&nbsp; But when I hear the same sort of feedback from people in all four of the countries I&#8217;ve been to this year, too, it&#8217;s clear this is a larger issue.</p>
<p>The first thing I&#8217;m seeing a surprising amount of is satisfaction with the feature set in PostgreSQL.&nbsp; A few years ago, conversations about what you could and couldn&#8217;t do with PostgreSQL usually stalled on one of a few common requests.&nbsp; There&#8217;s a good survey of <a href="http://postgresql.uservoice.com/forums/21853-general">PostgreSQL feature feedback</a> at User Voice.&nbsp; 13 important features originally on that list have been closed already, with Index Only scans as the next expected to fall in the upcoming 9.2.&nbsp; PostgreSQL now includes regular and synchronous replication as of 9.1.&nbsp; pg_upgrade has been getting an increasing amount of testing that proves it works for many in-place upgrade scenarios.&nbsp; Extensions are dramatically easier to use now.</p>
<p>It seems the total feature set has crossed the threshold where PostgreSQL is good enough for a whole lot more deployment situations than it used to be.&nbsp; What I&#8217;m hearing from people all over the world now is that the basic feature set and performance of PostgreSQL isn&#8217;t failing the &#8220;checkbox test&#8221; so often anymore, where business people require certain things before they&#8217;ll even consider a database.&nbsp; There are some major wants that are some distance off, such as materialized views and better OLAP support (cube/rollup/etc.)&nbsp; And using partitioning for bigger data sets is harder than people would like.&nbsp; But these are all things that are only needed for larger deployments, and some workarounds exist if you&#8217;re willing to work at them.</p>
<p>If the feature set isn&#8217;t holding back as many deployments now, what is?&nbsp; Well, the next thing I&#8217;ve been hearing everywhere is on that survey list too:&nbsp; better administration and monitoring tools.&nbsp; You really need a whole open-source stack to monitor PostgreSQL right now, from OS+database trending to query log analysis.&nbsp; It&#8217;s fine for these tools to live outside the database core, but some changes are clearly needed to make such tools easier to write.&nbsp; For example, the one built-in tool that allows query monitoring is pg_stat_statements, and the limitations preventing it from being useful to most people are so obvious we&#8217;ve gotten <a href="https://commitfest.postgresql.org/action/patch_view?id=681">two</a> <a href="https://commitfest.postgresql.org/action/patch_view?id=693">submissions</a> to improve it in the last month.</p>
<p>There are a few projects that aim at the monitoring/administration problem.&nbsp; EnterpriseDB&#8217;s PostgreSQL Enterprise Manager, Cybertec&#8217;s pgwatch, OmniTI&#8217;s Reconnoiter, the suite of smaller tools from End Point, and even the text UI of pg_statsinfo all hit the edges of this problem.&nbsp; What I hear when I have my advocacy hat on is that the community needs a major open-source project bigger than any of these to make database monitoring easier.&nbsp; That&#8217;s now one of the major distinguishing features the commercial competition has.&nbsp; Getting enough of the people developing in this area all pointing in the same direction and working together is a big challenge though.</p>
<p>On a related note, now that the underlying features are there, it seem making replication easier to monitor and setup is a major issue too.&nbsp; There are so many choices in replication technologies available for PostgreSQL it&#8217;s easy for new people to get overwhelmed by them all.&nbsp; And the documentation guides around this area are still filled with a lot of complications that aren&#8217;t even really necessary to get started at this point.&nbsp; It&#8217;s easy for newcomers get dragged into details like how old style archiving works as a precusor to setting up even basic replication, despite that they&#8217;re using the easier features in the current PostgreSQL instead.&nbsp; This area still has some work in the core database happening in 9.2, and it will be important for the community to create replication guides that include current information covering both 9.1 and that release.&nbsp; What I&#8217;m hear from every country I visit now is &#8220;I need material to help me compete against the idea of using Oracle RAC&#8221;.</p>
<p>The last of the global trends that have really jumped out at me is how companies everywhere are reinventing the development process around database applications.&nbsp; In some places, mostly bigger companies and government installations in particular, the expected staff &#8220;stack&#8221; is business as usual; it hasn&#8217;t changed in a long time.&nbsp; New applications go from Developer to DBA to systems administrator.&nbsp; Management ideas like DevOps are catching on to improvement interface between these roles, but not really upset its basic structure.&nbsp; Everywhere I go now, I&#8217;m seeing everything but the developer role being squeezed out.&nbsp; ORM-driven development is eliminating the DBA&#8217;s role in database design.&nbsp; Managed application hosting platforms are wiping out the systems administrator role.&nbsp; Startups with an idea for a web application go right from developer to deployment, and happily this is increasingly happening with a PostgreSQL backend in the database role.&nbsp; There isn&#8217;t even the perception that DBA-like help might be needed until the application grows quite a bit.&nbsp; I&#8217;m seeing the need for better database specific optimization skills than a typical developer has being deferred until the application has tens of gigabytes of data to sling around.</p>
<p>Being able to deploy small PostgreSQL installs and grow them to a reasonable size without specialized DBA knowledge is a great thing as far as I&#8217;m concerned.&nbsp; The exact advances in things like ORMs that have allowed reaching this point across the world are a topic that deserves its own long discussion.&nbsp; I&#8217;m going to cut this off here and return to that later.&nbsp; In this country, there&#8217;s some concrete work around the 9.2 release that needs to get done this month.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/global_trends_in_deploying_pos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apple&#8217;s Lossless Audio Codec and Software Patents</title>
		<link>http://blog.2ndquadrant.com/apples_lossless_audio_codec_an/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=apples_lossless_audio_codec_an</link>
		<comments>http://blog.2ndquadrant.com/apples_lossless_audio_codec_an/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 13:07:45 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql apple patents]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=76</guid>
		<description><![CDATA[Today my mailbox was crowded with some Apple news. The source code to the Apple Lossless Audio...]]></description>
			<content:encoded><![CDATA[<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
A:link { so-language: zxx }
-->
</style>
<p style="margin-bottom: 0in">Today my mailbox was crowded with some<br />
Apple news.  The source code to the Apple Lossless Audio Codec, encoders and decoders, was <a href="http://alac.macosforge.org/">released to<br />
the world</a>.  A few open-source projects such as FFmpeg and FAAC has<br />
already had support for the resulting .m4a file; this gives them an<br />
official release to validate against.  As a well documented audio<br />
snob, I&#8217;m known to be a fan of lossless audio, with a few hundred CDs<br />
here ripped into FLAC.  Unfortunately, this source code drop doesn&#8217;t<br />
change anything for me, and that&#8217;s all because of software patents.<br />
Right now I consider such patents to be the greatest risk to software<br />
I work on like PostgreSQL, so I spent some time looking into just<br />
what Apple has done here, as a data point on that topic.</p>
<p style="margin-bottom: 0in">If your baseline is MP3 files, Apple<br />
Lossless appears to be a step forward as far as licensing goes.  All<br />
MP3 playback requires a patent license, while playback of Apple&#8217;s<br />
format does not&#8211;only the encoding side need be licensed.  That&#8217;s<br />
not my baseline though.  FLAC has specifically avoided using any<br />
known patented technology, so it&#8217;s the clear winner in being clean of<br />
patent issues.</p>
<p style="margin-bottom: 0in">You can&#8217;t even read the just released source code without being shown the door that leads to Apple&#8217;s patents.&nbsp; <a href="http://alac.macosforge.org/trac/browser/trunk/codec/ALACEncoder.cpp">ALACEncoder.cpp</a> pushes you that way when you read it, saying &#8220;The<br />
relevance of the ALAC coefficients is explained in detail in patent<br />
documents.&#8221;  So you can&#8217;t fully understand what this code does<br />
unless you dip into the patent description.  That&#8217;s a big sign of<br />
trouble.&nbsp; I&#8217;m not sure exactly which patent they are referring to; it may be <a href="http://www.freepatentsonline.com/y2008/0027709.html">Determining scale factor values in encoding audio data with AAC</a>.
</p>
<p style="margin-bottom: 0in">I&#8217;m not sure because I don&#8217;t read patent descriptions if I<br />
can avoid it, due to how&nbsp;<a href="http://en.wikipedia.org/wiki/Treble_damages">damages are tripled</a> with willful infringement.  That rule puts<br />
open-source developers in a weird place.  The act of researching<br />
which patents your free implementation might infringe on can have a<br />
wildly negative return on investment.  If it&#8217;s impossible to<br />
implement the idea without infringing in the patents you find, which<br />
can easily be the case given the ridiculously low bar for grating<br />
such patents, if a lawsuit does happen you&#8217;d be better off not<br />
knowing about that risk when it starts.  On the PostgreSQL mailing<br />
lists, mentioning how a patented implementation of something works is<br />
one of the few things that will get you a warning and potentially<br />
blocked from the lists.  Knowingly implementing a patented idea can<br />
be a very expensive mistake for the project to make.</p>
<p style="margin-bottom: 0in">Now, you can claim this problem has<br />
gone away for this bit of software due to how Apple has released this<br />
code under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 license</a>.  If you build something using the Apple Lossless<br />
code, and you distribute the result under the Apache 2.0 license, you<br />
get the protection of its Grant of Patent License.  You&#8217;ll only lose<br />
it if you sue someone in a way that involves this code+patent<br />
combination.  That doesn&#8217;t necessarily protect manufacturers of<br />
hardware who want to include this capability, as they may not want to<br />
license the result that way.  I don&#8217;t really care about them though.<br />
People who want to take advantage of open-source code but not<br />
contribute back to can worry about their own legal issues, they&#8217;re<br />
not my concern.</p>
<p style="margin-bottom: 0in">My real issue with using this format is<br />
that it implicitly approves of business practices around software<br />
patents I find hostile to my own work, and that leads me back to the<br />
patent-less FLAC again.  Apple used to more often be the victim of<br />
valid and frivolous patent claims, but increasingly they&#8217;ve become<br />
the originator of them instead.  In mid 2006, Apple was sued over<br />
patent issues by Creative Technology; they settled paying Creative<br />
$100M dollars.  Since then, patent issues have increasingly been part<br />
of their <a href="http://en.wikipedia.org/wiki/Apple_Inc._litigation#Patent_infringement">well exercised legal arm</a>.</p>
<p style="margin-bottom: 0in">Starting last year, Apple has seriously<br />
turned around in how it handles patents&#8211;it&#8217;s now aggressively<br />
enforcing its patents rather than just being sued for violations.  Steve<br />
Jobs issued a warning shot about that, saying &#8220;competitors should<br />
create their own original technology, not steal ours&#8221;.<br />
Considering it had only been four years before then that Apple was<br />
sued&#8211;and paid out in a big way&#8211;for stealing other people&#8217;s<br />
patented ideas, that came off as rather hypocritical to me.
</p>
<p style="margin-bottom: 0in">The company has done well staying ahead<br />
of its competitors by production innovation, rather than court<br />
fights.  iPod competitors failed to gain traction because their<br />
products weren&#8217;t as good, not because they couldn&#8217;t steal the design.<br />
Apple&#8217;s iPad should have the same property; the knock-offs are not<br />
selling because they&#8217;re not as good.  The only real threat to their<br />
product line right now are how Android phones are displacing the<br />
iPhone.  Dumping so much money into offensive lawsuits is burning up<br />
money that could be used for real product advances there instead.<br />
It&#8217;s a shame they&#8217;ve resorted to this tactic.</p>
<p style="margin-bottom: 0in">At this point, a cautious person would<br />
avoid using technology encumbered by Apple&#8217;s patents, as they clearly<br />
have the means and intent to sue for violations.  And someone who<br />
values open source projects should avoid patented approaches even<br />
when they are freely licensed.  Whether or not individuals using<br />
Apple Lossless is particular are exposed to problems here is missing<br />
the big picture.</p>
<p style="margin-bottom: 0in">As an advocate for free software, I<br />
reflexively pick the less patent encumbered approach to any problem,<br />
using that as the tie breaker for decisions that are otherwise even.<br />
Encoding into and helping popularize Apple Lossless may be legal now.<br />
But I&#8217;ll keep encoding into FLAC, copying the result onto my Sansa<br />
Fuse player, and avoiding their entire music ecosystem.  Software<br />
patents are too dangerous to implicitly endorse them if it can be<br />
avoided, and here they easily can.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/apples_lossless_audio_codec_an/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sync rep scaling</title>
		<link>http://blog.2ndquadrant.com/sync_rep_scaling/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sync_rep_scaling</link>
		<comments>http://blog.2ndquadrant.com/sync_rep_scaling/#comments</comments>
		<pubDate>Wed, 26 Oct 2011 17:31:04 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql replication]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=75</guid>
		<description><![CDATA[﻿I&#8217;m almost done with this year&#8217;s crazy conference season schedule, just Brazil&#8217;s PG.BR next week left.&#160; All...]]></description>
			<content:encoded><![CDATA[<p>﻿I&#8217;m almost done with this year&#8217;s crazy conference season schedule, just Brazil&#8217;s <a href="http://pgbr.postgresql.org.br/">PG.BR</a> next week left.&nbsp; All of my recent presentations are now available at our <a href="http://www.2ndquadrant.com/en/talks/">talks page</a>.&nbsp; You&#8217;ll also find many of the talks from our CHAR(11) conference this summer there for the first time.&nbsp; Those were unavailable for a while due to an unfortunately timed web site change.</p>
<p>I like to do some original research for my talks, and this year that included a look into <a href="http://www.2ndquadrant.com/static/2quad/media/pdfs/talks/SyncRepDurability.pdf">Synchronous Replication and Durability Tuning</a> in PostgreSQL 9.1, specifically the performance side.&nbsp; At last week&#8217;s PG.EU I gave an updated version of this talk (with Simon Riggs), including a bit more info than I had available during the Postgres Open presentation on the same topic.<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.2ndquadrant.com/en/clients-3.html" onclick="window.open('http://blog.2ndquadrant.com/en/clients-3.html','popup','width=640,height=480,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.2ndquadrant.com/en/clients-3-thumb-320x240.png" alt="clients-3.png" class="mt-image-none" style="" height="240" width="320" /></a></span><br />The good news/bad news performance results are nicely summarized by the &#8220;Group commit magic&#8221; graph on slide 17.&nbsp; There I was replicating across the Atlantic Ocean, crossing from my home here in Baltimore over to the conference site in Amsterdam.&nbsp; When doing synchronous replication, the speed of light determines how fast any single client can commit.&nbsp; You can only reach about 50% of that round trip time given current (and expected future) technology here.&nbsp; The efficiency rate of the fiber-optic cables used is not perfect, and tasks like routing add some overhead too.<br />
<br />&nbsp;<br />With that sort of distance, the round trip time is at least 100 milliseconds.&nbsp; What this means is that no one client can commit more than 10 times per second.&nbsp; This shows just how difficult sync rep is to run well, the maximum rate drops fast if you expect to leave your local data center to commit.&nbsp; Light turns out to be really slow compared with what many people expect.<br />
<br />&nbsp;<br />The great thing I proved in that slide is that the efficiency when multiple clients are committing at the same time scales almost linearly.&nbsp; If you want 1000 transactions/second over this sort of distance, you can get that&#8211;but you&#8217;ll need just over 125 clients going at once to do it.&nbsp; Each one of those clients will be seeing 10 commits/second and 100 millisecond latencies (and higher for a small percentage, peak latency in the test was closer to 600ms).&nbsp; But each commit reply will be acknowledging a pile of clients at once, just by sending a small packet with an updated &#8220;committed up to this point&#8221; response.<br />
<br />&nbsp;<br />When the speed of light turns out to be your bottleneck, there&#8217;s not much you can do about that attacking directly.&nbsp; Some people who want to reach higher rates might architect their systems with many smaller clients, as I&#8217;ve shown in this example.&nbsp; I was able to reach my goal of 2000 INSERT commits/second here, but it took 275 clients to get there.<br />
<br />&nbsp;<br />The other great thing about how PostgreSQL implements sync rep is that it&#8217;s controlled per transaction.&nbsp; Once you see how expensive the commits are, if that&#8217;s too high for some of your data, you can always tweak that for higher performance just by disabling sync rep for some transactions.&nbsp; Having such fine-grained control over synchronous commits is a unique feature to PostgreSQL, allowing something like a Quality of Service suggestion to the database.&nbsp; The PostgreSQL code as of 9.1 really has an unprecedented range of trade-offs here.&nbsp; You can go for faster but not very durable at all (with unlogged tables), locally durable but not guaranteed to a remote data center at a medium speed, all the way up to fully synchronous and very expensive to commit.&nbsp; It&#8217;s possible to argue that other database choices are better at one end of this range.&nbsp; You might use MongoDB for higher speeds at the low durability range, and Oracle for their better tested sync rep capabilities (I saw better tested simply because the PostgreSQL 9.1 code is very new relative to Oracle&#8217;s implementation).</p>
<p>PostgreSQL started in the middle here, and with 9.1 it&#8217;s expanded nicely toward both ends of the spectrum at once.&nbsp; It&#8217;s now providing options for higher and lower durability at the same time, in one database, and with the speed/durability trade-off adjustable for every transaction.&nbsp; Building one size fits all software is really hard, and the new features in 9.1 nicely push out capabilities here for several popular use cases, all at the same time, and only when you want to pay for them.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/sync_rep_scaling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Limitations removed in PostgreSQL 9.1</title>
		<link>http://blog.2ndquadrant.com/limitations_removed_in_postgre/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=limitations_removed_in_postgre</link>
		<comments>http://blog.2ndquadrant.com/limitations_removed_in_postgre/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 13:58:50 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql 9.1]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=65</guid>
		<description><![CDATA[The release of PostgreSQL 9.1 lining up with this week&#8217;s Postgres Open conference has resulted in my...]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0in;">The release of <a href="http://www.postgresql.org/docs/9.1/static/release-9-1.html">PostgreSQL 9.1</a> lining up with this week&#8217;s <a href="http://www.postgresopen.org/">Postgres Open</a> conference has resulted in my getting asked the same question by several people now: &#8220;how long should I wait before deploying 9.1?&#8221; It&#8217;s an interesting question that highlights some of the benefits and hazards of the PostgreSQL release schedule, and one I have a very strong opinion on: you should consider 9.1 for new projects instead of 9.0 starting right now.</p>
<p style="margin-bottom: 0in;">Read on and I&#8217;ll detail why I feel that way.</p>
<p style="margin-bottom: 0in;">Most changes to a software project are sorted into two main groups: bug fixes and features. PostgreSQL is very good about backporting bug fixes to all supported versions of the program, when practical to do so. But feature changes aren&#8217;t done in older releases. Stability is highly prioritized in the stable versions&#8211;sometimes to the point where some very annoying things that could be fixed aren&#8217;t.</p>
<p style="margin-bottom: 0in;">The last release, PostgreSQL 9.0, started its life as version 8.5. When it became obvious several big, disruptive features were going to be included, the version number was bumped in part to make people a little more wary of the release. The bug count over the last year hasn&#8217;t been too terrible, but there have been plenty of serious bugs. April&#8217;s <a href="http://www.postgresql.org/docs/9.0/static/release-9-0-4.html">9.0.4</a> corrected both a nasty data loss bug (for users of pg_upgrade) and a case where new database crash recovery code could introduce a problem even when not using the feature it was modified to support.</p>
<p style="margin-bottom: 0in;">There is a third category of changes here though: removing limitations. Sometimes the new &#8220;feature&#8221; added by a new version is that a part of the database code is made to support new cases, because they didn&#8217;t do everything people really wanted . These are considered new features and not backported, even though it&#8217;s often the case that people are running into the limitation on older versions.</p>
<p style="margin-bottom: 0in;">While all the genuine new features are great, too, what makes 9.1 a really compelling upgrade from my perspective is how many of these limitations are blown away by it.</p>
<p style="margin-bottom: 0in;">Here&#8217;s my short list of limitations removed that I&#8217;ve run into on multiple installations of 9.0 and earlier versions now:</p>
<ul>
<li>Queries using MIN or MAX against a partitioned table can now use an index to return that value. This is a showstopper for sites that run into it, one that normally doesn&#8217;t show up until after you&#8217;ve got a large amount of data into PostgreSQL; then it hits you by surprise. The most common way I&#8217;ve run into this are sites that monitor the last time/entry inserted into some busy table. <em>SELECT now() &#8211; max(timestampfield) FROM t</em> is a good way to tell how long it&#8217;s  been since the last record was inserted into your database, to set an alarm if that grows too big. On a busy site that means something has probably broken and stopped importing records. But if you use this approach, and you switch to partitioned tables&#8230;you&#8217;re toast. Until 9.1, you had to rewrite the query to fix this. And in some places, application changes like that take a huge amount of QA work to do. Now it just works.</li>
<li>Replication lag time can easily be monitored using pg_stat_replication. All of our 9.0 deployments integrate our repmgr tool in order to provide this capability. In 9.1, you get that part in the core server.  (We&#8217;re adding some new stuff to repmgr to keep it relevant&#8211;it&#8217;s always going to be where between release features we&#8217;re working on can incubate at)</li>
<li>Systems using Hot Standby to run long reports against standby systems can now set a large value for <em>max_standby_archive_delay</em> and <em>max_standby_streaming_delay</em>. Changing the mechanics of these two parameters was one of the very last code changes in 9.0 before its feature code freeze. And subsequent testing missed the fact that the maximum value you can set these two only allows 35 minutes of delay until it was too late to fix in 9.0.</li>
<li>Long reports on the standby can use the new <em>hot_standby_feedback</em> mechanism to keep the data they are looking at from being removed from the master. This is really the right way to handle running most longer reports on the standby. This limitation was recognized before 9.0 shipped, with one fix proposed and a prototype built. It just wasn&#8217;t possible to get the code into 9.0 before its feature freeze.</li>
<li>There is a maximum <em>replication_time </em>setting. It&#8217;s far too easy to have connections to a system that isn&#8217;t working get stuck in TCP/IP retries for several minutes in 9.0.</li>
<li>Checkpoints on busy servers are much less likely to get stuck when the background writer&#8217;s internal fsync aborb queue fills. The worst case of this problem can cause your checkpoints for a long time&#8211;I&#8217;ve seen what should have been a 5<br />
minute checkpoint take six hours now. And even mild cases you might not normally notice can slow your system down.</li>
</ul>
<p style="margin-bottom: 0in;">When I talk with people who are looking into a 9.0 upgrade from an earlier version, it&#8217;s often so that they can take advantage of all the benefits Hot Standby allows: read scaling by adding standby servers, reporting servers, live monitoring of the standby. If you do this on 9.0, you are likely to run into one of these limitations. And as more sites grow their PostgreSQL installations, and new sites are converting increasingly big databases over to it, I&#8217;m seeing a lot more of them run into either the partitioning MIN/MAX issue for the checkpoint one.</p>
<p style="margin-bottom: 0in;">Normally, people don&#8217;t like to consider the latest version of a database program because of the perception that it&#8217;s more likely to have bugs than an older one. Well, in this case, the dynamic is a little different. If you deploy PostgreSQL 9.0, and you run into one of the bugs described above, there is little you can do about them other than upgrading to the newer version.</p>
<p style="margin-bottom: 0in;">Some workarounds exist, and plugging holes like that between version releases is part of why consultants and support companies have something to sell anyway when the software is free.</p>
<p style="margin-bottom: 0in;">If you deploy 9.1 instead, you will not run into these problems. The question you should be asking is not whether there are any unknown bugs to be scared of in 9.1; there surely are. Given the sort of code changes that happened, I expect there to be a steady stream of bug reports against the new features introduced. But there weren&#8217;t that many things changed that will impact users who don&#8217;t use those features.</p>
<p style="margin-bottom: 0in;">But if you deploy on 9.0, the odds are decent you will run into one of these known limitations of that version. Which would you rather have: the <em>possibility</em> of running into a bug, or the <em>certainty</em> you will run into a known limitation?</p>
<p style="margin-bottom: 0in;">Many people choose wrong and cling to older versions longer than they should, only to waste a lot of resources fighting known limitations and bugs that are already fixed in the newer release. You don&#8217;t want to be one of those people, and now that 9.1 has shipped you should seriously consider deploying it instead of 9.0.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/limitations_removed_in_postgre/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Making a VACUUM suck&#8230;wait, is going faster more or less here?</title>
		<link>http://blog.2ndquadrant.com/making_a_vacuum_suckwait_is_go/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=making_a_vacuum_suckwait_is_go</link>
		<comments>http://blog.2ndquadrant.com/making_a_vacuum_suckwait_is_go/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 06:55:49 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql vacuum]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=61</guid>
		<description><![CDATA[One downside to having a specialty you&#8217;re know for is that the people with the hardest problems...]]></description>
			<content:encoded><![CDATA[<p><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><br />
<title></title><br />
<meta name="GENERATOR" content="OpenOffice.org 3.0  (Linux)"></p>
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
A:link { so-language: zxx }
-->
</style>
<p style="margin-bottom: 0in;">One downside to having a specialty<br />
you&#8217;re know for is that the people with the hardest problems in that<br />
area tend to find you.  For me this is good in that it keeps me<br />
working, but it can easily turn out bad if the difficult is not<br />
distinguished from the impossible correctly.  As someone who&#8217;s done a<br />
lot of work on tuning PostgreSQL for heavy write volumes, the<br />
workloads I see are skewed closer than I&#8217;d like them to be some days<br />
to the impossible side.  One of the areas that&#8217;s really snuck up on<br />
me recently is just how hard it is to tune autovacuum for a database<br />
that&#8217;s constantly written to.</p>
<p style="margin-bottom: 0in;">The way PostgreSQL&#8217;s transaction<br />
visibility system works, every database page you write will be<br />
written at least one more time, to freeze its transactions ids.  And<br />
you may get yet another write on top of that, to reclaim free space<br />
on deleted items.  <a href="http://wiki.postgresql.org/wiki/Hint_Bits">Hint bits</a><br />
are another nuisance.  And that&#8217;s just the average case; pages can be<br />
overwritten many times if the deletion happens in chunks.
</p>
<p style="margin-bottom: 0in;">The big problem happens if you build a<br />
system that can just barely keep up the incoming write volume at its<br />
beginning.  That system will then be crushed by its workload once the<br />
overhead of this background maintenance kicks in.  Here&#8217;s how it will<br />
happen:  early performance tests say the server meets specifications.<br />
It survives initial rollout.  But after a few months go by, the<br />
archive of data gets bigger, and next thing you know autovacuum needs<br />
to run 25 hours a day to keep up.  (Hint:  this doesn&#8217;t work.  That<br />
consulting advice, you get for free, as in beer.  Which you&#8217;ll likely<br />
end up drinking more of once this happens.)</p>
<p style="margin-bottom: 0in;">What doesn&#8217;t help matters is how arcane<br />
the parameters for tuning autovacuum are.  Yesterday I submitted <a href="http://archives.postgresql.org/message-id/4E4C2CE1.5000801@2ndQuadrant.com">a<br />
patch</a>&nbsp;<a href="http://archives.postgresql.org/message-id/4E4C2CE1.5000801@2ndQuadrant.com"></a>to add the first readout to help with this problem I&#8217;ve been able to<br />
put together.  Developed with my new co-worker Noah Misch, the patch<br />
itself is pretty simple.  It takes the information autovacuum makes<br />
it decisions about and exposes it, in real-time, via the process&#8217;s<br />
command line.  Similarly to how you can track progress of things like<br />
the archiver this way, sampling this data turns out to be very useful<br />
for predicting how long things are going to take to run.  There&#8217;s<br />
also a report in the log file at the end.  It looks like this:</p>
<p style="margin-bottom: 0in;">
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><br />
<title></title><br />
<meta name="GENERATOR" content="OpenOffice.org 3.0  (Linux)"></p>
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</style>
</p>
<p style="margin-bottom: 0in;">
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><br />
<title></title><br />
<meta name="GENERATOR" content="OpenOffice.org 3.0  (Linux)"></p>
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</style>
</p>
<p style="margin-bottom: 0.2in;"><tt>LOG: automatic vacuum of table<br />
"pgbench.public.pgbench_accounts": index scans: 1 </tt>
</p>
<pre>    pages: 0 removed, 819673 remain
tuples: 19999999 removed, 30000022 remain
buffer usage: 809537 hits, 749340 misses, 686660 dirtied
system usage: CPU 5.70s/19.73u sec elapsed 2211.60 sec
</pre>
<p style="margin-bottom: 0in;">The &#8220;buffer usage&#8221; line is the new<br />
one here.  This is units of buffer pages, which are the 8192 byte<br />
chunks of memory.  So seeing 686660 of them dirtied means this<br />
autovacuum wrote 8192 * 686660 bytes=5364MB in 2212 seconds.  That<br />
makes for an average write rate of 2.43MB/s.  If you&#8217;ve every tried<br />
to tweak autovacuum before, you&#8217;ll know that guessing the rate at<br />
which it&#8217;s going to write to disk is the hard part.  This doesn&#8217;t<br />
solve that problem completely, but it does let you trivially figure<br />
out something that is enormously useful:  how fast things are writing<br />
given the current parameter set.  And even that used to be really<br />
painful to figure out.
</p>
<p style="margin-bottom: 0in;">The patch is really small and could<br />
easily be applied with minimal risk to a production server.  I expect<br />
it to be the next thing I end up <a href="http://blog.2ndquadrant.com/en/2011/06/backporting-and-checkpoint-tro.html">backporting</a> heavily onto troublesome customer systems.  Next time I&#8217;ll write a<br />
bit more about how the information gathered by this patch has given<br />
me new insight into vacuum tuning, some observations that can help<br />
you even if you&#8217;re not running a server with it installed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/making_a_vacuum_suckwait_is_go/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Day of the Dead Software</title>
		<link>http://blog.2ndquadrant.com/day_of_the_dead_software/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=day_of_the_dead_software</link>
		<comments>http://blog.2ndquadrant.com/day_of_the_dead_software/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 05:16:25 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[United States News]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=60</guid>
		<description><![CDATA[Procrastination can be a virtue, when it saves you from having to do ultimately doomed work altogether.&#160;...]]></description>
			<content:encoded><![CDATA[<p>Procrastination can be a virtue, when it saves you from having to do ultimately doomed work altogether.&nbsp; I like writing about topics like <a href="http://blog.2ndquadrant.com/en/2011/05/a-lazy-ride-on-the-disk-sortin.html">lazy disk writing</a> because I personally identify with them.&nbsp; But sometimes putting things off ends up costing you, and it can kill you too.&nbsp; We&#8217;re now reaching that point with the fall PostgreSQL conferences.&nbsp; The costing you part that is.<br /><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://blog.2ndquadrant.com/en/2011/08/13/day-dead-skull.html" onclick="window.open('http://blog.2ndquadrant.com/en/2011/08/13/day-dead-skull.html','popup','width=375,height=500,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blog.2ndquadrant.com/en/2011/08/13/day-dead-skull-thumb-200x266.jpg" alt="day-dead-skull.jpg" class="mt-image-right" style="margin: 0pt 0pt 20px 20px; float: right;" width="200" height="266" /></a></span><br />If you haven&#8217;t booked a hotel yet for <a href="http://www.postgresopen.org/2011/home/">Postgres Open</a>, during mid September in Chicago&#8230;starting on Monday the conference rate is gone.&nbsp; You already missed early bird registration, but if you <a href="http://www.postgresopen.org/2011/blog/2011/08/04/schedule-announced-and-little-discount-code-loyal-/">poke around</a>, you might find some discounts still available.&nbsp; Like several of the conferences this fall, there are some great bargains to be had in both the sessions and the training classes at this conference.&nbsp; Compared with the typical commercial database conference and training, this stuff is quite cheap.&nbsp; Even if you ignore me, wait until the last minute, and have to pay full price.</p>
<p><a href="https://www.postgresqlconference.org/">#PGWest</a> is at the end of September in San Jose.&nbsp; That you still have some time left for; schedule isn&#8217;t up yet.</p>
<p><a href="http://omniti.com/surge/2011">Surge</a> is in Baltimore that same week&#8230;early bird is gone for that already too, but you might still get the <a href="http://omniti.com/surge/2011/hotelandtravel">hotel discount</a>.&nbsp; Maybe; get on that already if you want to go.&nbsp; Surge is near where I live, yet it&#8217;s the only conference I&#8217;m mentioning here I can&#8217;t make it to.&nbsp; It just wouldn&#8217;t be right for me to have an conference that&#8217;s easy to attend I guess, I need to do my talks completely frantic after various degrees of airport mayhem.&nbsp; Baltimore is also famous for being a place people go to die.&nbsp; We have a <a href="http://www.eapoe.org/balt/poehse.htm">Poe house and museum</a>, most notable because it was here old Edgar passed away at mysteriously.&nbsp; This tradition continues to current day television, with TV shows like &#8220;Homicide:&nbsp; Life in the Streets&#8221; and &#8220;The Wire&#8221; all being set here.&nbsp; The area where Surge is being held at?&nbsp; Nice part of town; you&#8217;ll have to wander away from there if you want the true Baltimore experience.</p>
<p>Speaking of places filled with mayhem, the <a href="http://2011.pgconf.eu/">PostgreSQL Conference Europe</a> this year is in Amsterdam.&nbsp; You still have nearly a month left to get the early rates for that conference, but who knows what will happen to travel prices by then.&nbsp; This would be a good one to book early too.</p>
<p>The last of my conference visits this year is <a href="http://pgbr.postgresql.org.br/">PGBR</a>, held in early November in São Paulo, Brazil.&nbsp; I&#8217;m excited to be seeing a whole new group of people at this conference, while making my first visit to South America.&nbsp; I was also excited to see the conference is the day after Brazil&#8217;s Dia de Finados, <a href="http://en.wikipedia.org/wiki/Day_of_the_Dead">&#8220;Day of the Dead&#8221;</a>.&nbsp; In addition to reminding me of Baltimore and being an awesome <a href="http://en.wikipedia.org/wiki/Day_of_the_Dead_%281985_film%29">horror movie</a>, this gives me a chance while I&#8217;m there to celebrate the memory of things I managed to procrastinate working on until they were dead, nicely avoiding them.&nbsp; I intend to pay my tribute to Sun and Solaris this year, which are of course dead now that Oracle has ruined them.&nbsp; MySQL is still flopping around, but the migrations off it are accelerating under its new malevolent overlords; not dead yet, but getting there.&nbsp; I know they&#8217;re not as into the whole skull mask thing in Brazil like they are for this holiday in Mexico, but I&#8217;m going to keep a hopeful eye out for one that reminds me of Larry Ellison.&nbsp; Trying to kill off Oracle is one thing I never procrastinate.
<div><i>Day of the Dead Mask photo from <a href="http://laughingsquid.com/">Scott Beale / Laughing Squid</a></i></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/day_of_the_dead_software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Progress, SQL, and SQL Progress</title>
		<link>http://blog.2ndquadrant.com/progress_sql_and_sql_progress/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=progress_sql_and_sql_progress</link>
		<comments>http://blog.2ndquadrant.com/progress_sql_and_sql_progress/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 19:33:02 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql progress sql]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=59</guid>
		<description><![CDATA[My work the last few years with PostgreSQL is actually my second career as a database person...]]></description>
			<content:encoded><![CDATA[<p><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><br />
<title></title><br />
<meta name="GENERATOR" content="OpenOffice.org 3.0  (Linux)"></p>
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
-->
</style>
<p style="margin-bottom: 0in;">My work the last few years with<br />
PostgreSQL is actually my second career as a database person mainly<br />
focused on performance tuning.  My first was in the mid to early<br />
90&#8242;s, working with the Progress 4GL.  If you want to see just how<br />
similar that time and learning arc was to what I&#8217;m doing recently,<br />
check out my &#8220;Progress Performance FAQ&#8221; on my <a href="http://www.westnet.com/%7Egsmith/content/progress.html">Progress Page</a>.<br />
Anyone who&#8217;s looked at my PostgreSQL performance book should see the<br />
many similarities.  Wanting to know enough to duplicate everything<br />
covered in that 47 page document, but in a PostgreSQL content, was<br />
basically how I got started in this second database community for me;<br />
had that game plan from day one.
</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">The similarities go so deep I can&#8217;t<br />
help but laugh when I look at them again.  Progress users gather on<br />
a mailing list named <a href="http://www.peg.com/">PEG</a> to discuss everything about the product (my<br />
PostgreSQL tool <a href="https://github.com/gregs1104/peg/">peg</a> was named with<br />
a nod toward that, retroactive acronym style).  I settled into <a href="http://archives.postgresql.org/pgsql-performance/">pgsql-performance</a><br />
in exactly the same way I used to spend time on PEG.  We had a Tom, a<br />
Bruce, and a Peter as part of the core group of regular posters on<br />
the list.  No Joshes, but Progress expert Geoff Crawford and<br />
PostgreSQL&#8217;s Josh Berkus are so similar they each could play the<br />
other in a movie (checking up on Geoff, I&#8217;m unsurprised to find that just like Josh he&#8217;s <a href="http://it.toolbox.com/people/gcrawford/">active at Toolbox for IT</a>).  I was of course the second Greg then too, often<br />
confused with the other one who had been there much longer than me.<br />
We the users sort of puttered around some of the time, but<br />
periodically we got input from Gus Bjorklund, the main database<br />
engine designer at Progress and a seriously deep technical guy.  If I<br />
showed you some e-mail I exchanged with Gus in 1995 about details of<br />
the database&#8217;s &#8220;after image writer&#8221;, they&#8217;d be barely<br />
distinguishable from some messages I exchanged with Tom Lane on the<br />
PostgreSQL &#8220;background writer&#8221; in 2007.
</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">And there&#8217;s another big similarity on<br />
the technology side:  in 1995 when I was deepest into this work,<br />
Progress didn&#8217;t use SQL, just like early Postgres.  It used a 4th<br />
Generation Language (4GL) that was much more procedural in feel.  So<br />
instead of:
</p>
<p style="margin-bottom: 0in;">
<blockquote><p style="margin-bottom: 0in;">SELECT * FROM customer;
</p>
</blockquote>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">In the Progress 4/GL (now called<br />
&#8216;OpenEdge Advanced Business Language&#8217;) you&#8217;d do:
</p>
<p style="margin-bottom: 0in;">
<blockquote><p style="margin-bottom: 0in;">FOR EACH customer NO-LOCK:
</p>
<p style="margin-bottom: 0in;">  DISPLAY customer.
</p>
<p style="margin-bottom: 0in;">END.
</p>
</blockquote>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">As a traditional programmer coming to<br />
databases just to pull stuff out of them for later processing, I was<br />
perfectly happy with this model.  And I started out my work with<br />
PostgreSQL ambivilant about needing to improve my SQL skills to<br />
change that.  Like a lot of non-database oriented developers, I wrote<br />
my share of procedural code that could have been wedged into a<br />
complicated query instead, rather than get too fancy with the query<br />
language.  But you don&#8217;t scale into the terabyte range of data sets<br />
that way, and the last few years have compelled me to really come to<br />
grips with with addressing problems in a way that turns into<br />
efficient SQL.
</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">It was just today that I realized that<br />
mental transformation has really completed now:  I&#8217;m now just as<br />
likely to think in SQL terms as I am procedural ones.  I have some<br />
data to analyze that&#8217;s sitting in some CSV files.  I imported them<br />
into a spreadsheet; that made some types of analysis easier.  I write<br />
a little Python script to loop over them and compute some things;<br />
that got me some of what I needed.  But as I stared at this grid of<br />
data for a bit, in my head the data I wanted to extract kept<br />
decomposing into SQL.  This part, SUM() and AVG() over a GROUP BY().<br />
Running total, SQL window function.  And these two parts that fit<br />
together&#8230;there&#8217;s not a natural foreign key there, but I can derive<br />
one that will work to join them together.
</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">The idea I was about to start heading<br />
toward&#8211;writing a Python program to compute the statistics<br />
needed&#8211;seems like a ridiculous one now that I consider the<br />
alternative.  There&#8217;s a lot of &#8220;buzz&#8221; lately against using<br />
SQL for things.  But when you come across the sort of problem SQL and<br />
SQL-oriented database are good as solving, and you understand how to<br />
use SQL well enough to leverage it, you&#8217;d be crazy to solve them any<br />
other way.
</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/progress_sql_and_sql_progress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pushing all-in with PostgreSQL and Texas Hold&#8217;Em</title>
		<link>http://blog.2ndquadrant.com/pushing_allin_with_postgresql/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pushing_allin_with_postgresql</link>
		<comments>http://blog.2ndquadrant.com/pushing_allin_with_postgresql/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 05:59:02 +0000</pubDate>
		<dc:creator>greg.smith</dc:creator>
				<category><![CDATA[Greg's PlanetPostgreSQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[postgresql performance poker]]></category>

		<guid isPermaLink="false">http://blog.2ndquadrant.com/?p=58</guid>
		<description><![CDATA[Just before I started working with PostgreSQL as my main occupation, there was a period in my...]]></description>
			<content:encoded><![CDATA[<p><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><br />
<title></title><br />
<meta name="GENERATOR" content="OpenOffice.org 3.0  (Linux)"></p>
<style type="text/css">
<!--
@page { margin: 0.79in }
P { margin-bottom: 0.08in }
A:link { so-language: zxx }
-->
</style>
<p style="margin-bottom: 0in;">Just before I started working with<br />
PostgreSQL as my main occupation, there was a period in my life where<br />
I was a degenerate gambler.  Manipulating people just to pull a few<br />
dollars out the transaction, giant cons designed to fleece the marks, everybody involved was dirty.  But then I decided to take a break<br />
from trading stocks, and instead explore the comparatively clean and<br />
honest world of Texas Hold&#8217;Em Poker for a bit.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">A question today about <a href="http://postgresql.1045698.n5.nabble.com/Building-an-home-computer-for-best-Poker-Tracker-performance-tp4597798p4597798.html">optimizing<br />
hardware for a poker hand database</a> on one of the PostgreSQL lists got<br />
me digging out my old play record&#8211;which is in a PostgreSQL database.<br />
How the Poker industry ended up adopting PostgreSQL as its standard<br />
database of choice for high-performance analyzing of hands and play<br />
is kind of an interesting story.  The great article <a href="http://www.codingthewheel.com/archives/stranger-than-fiction-story-online-poker-tracker-postgresql">Stranger than Fiction: The Story<br />
of PokerTracker, Online Poker, and PostgreSQL</a> covers a lot of the background here.  I thought it would be fun to<br />
revisit my own time in that land, and show just how that actually all<br />
works at the database query level.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">In April of this year the FBI did a<br />
massive crackdown that has almost killed on-line poker in this<br />
country, at least in its original form.  I still have $35 that&#8217;s<br />
stuck in an account I can neither play with nor withdraw from after,<br />
perhaps my final &#8220;sin tax&#8221; on that era.  But in the heady days<br />
circa 2006, where seemingly everyone had a not quite legal Hold&#8217;Em<br />
account they&#8217;d play from, I went through a poker apprenticeship that<br />
included around 60,000 hands worth of play.</p>
<p style="margin-bottom: 0in;"></p>
<p style="margin-bottom: 0in;">The first six months were frustrating and I slowly lost most of the money in my account.&nbsp; But before wiping out I staged a comeback, won my losses back, and kept going up from there.&nbsp; By the end of my serious playing time, &#8220;greg1104&#8243;<br />
was the terror of the no-limit penny tables at Ultimate Bet, a tight<br />
playing grinder who&#8217;d wait hours for just the right moment to turn<br />
hyper aggressive.  On a good night I&#8217;d wipe out a half dozen players<br />
in a row by forcing them all-in to chase their speculative hands.  If<br />
you have a small &#8220;edge&#8221;&#8211;you&#8217;re slightly more likely to win a<br />
hand than your opponent&#8211;and a large enough bankroll to support some<br />
unfair losses (players call them &#8220;bad beats&#8221;), eventually the<br />
worse player will end up broke.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">To understand why this becomes a<br />
database overflowing with info eventually, you need to know a bit about on-line poker.  You<br />
sit at a table that typically holds 6 to 10 people.  Hands worth<br />
playing are rare enough (some players will only intentionally ante to play a<br />
hand less than 20% of the time) that any decent player will play at<br />
least 2 or 3 of them at once on-line.  The speed of a table is<br />
measured in hands/hour, with a relatively fast typically going from<br />
50 to 100.  So even a journeyman player will have a hand possibility<br />
pass in front of them every 30 seconds; you have to make a quick<br />
decision about which to play and which to avoid.  It doesn&#8217;t take<br />
long until you have thousands of hands of history to use to make that<br />
decision.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">As a database and math oriented guy, I<br />
quickly turned learning proper play into a query problem.  What hands<br />
did I play well?  Which did I botch?  And, statistically, what types<br />
of players did I play well against?  Around this same period,<br />
software aimed specifically at this problem started appearing.  Each<br />
hand of Hold&#8217;Em you played could be exported into a &#8220;Hand History&#8221;<br />
file that detailed exactly what happened.  Import those into a<br />
database, analyze information about each player, and you could put<br />
numbers on things you only had a gut feel for&#8211;and sometimes learn,<br />
the hard way, that your gut feel was wrong.  PokerTracker was the<br />
software of choice, and it moved from Access to PostgreSQL around the<br />
same time I was playing regularly.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">I don&#8217;t have all my hand histories, but<br />
I saved enough of them (and kept moving them forward into new<br />
versions of PostgreSQL/PokerTracker) to have a clear record of my<br />
play during a period after I&#8217;d gotten good at the game.  Here&#8217;s the<br />
high level view of that play history, as a query against a<br />
PokerTracker database:</p>
<p style="margin-bottom: 0in;">
</p>
<blockquote><p style="margin-bottom: 0in;">SELECT count(*),sum(amt_won) FROM<br />
player p
</p>
<p style="margin-bottom: 0in;">JOIN holdem_hand_player_statistics s<br />
USING (id_player)
</p>
<p style="margin-bottom: 0in;">WHERE p.player_name=&#8217;greg1104&#8242;;
</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">count,sum
</p>
<p style="margin-bottom: 0in;">33687,68.99
</p>
</blockquote>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">So 33K hands winning $68.99.  Not<br />
exactly World Series of Poker, but clearly I was a winning player.<br />
If I racked up 33K hands worth of history data in this fairly brief period, you<br />
can imagine how many a really serious player would have.  The person<br />
asking about this today had 5M of them to query.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">This is an example of the a first-level<br />
statistic you&#8217;d want about the other players at your table.  You<br />
should react one way to a raise from a player with a winning track<br />
record over a long period, and a very different one from the guy<br />
who&#8217;s been bleeding money the whole time he&#8217;s been playing.  The<br />
total is one thing; what percentage of the time did I win?</p>
<p style="margin-bottom: 0in;">
</p>
<blockquote><p style="margin-bottom: 0in;">SELECT<br />
flg_won_hand,count(*),sum(amt_won)
</p>
<p style="margin-bottom: 0in;">FROM player p
</p>
<p style="margin-bottom: 0in;">JOIN holdem_hand_player_statistics s<br />
USING (id_player)
</p>
<p style="margin-bottom: 0in;">WHERE p.player_name=&#8217;greg1104&#8242;
</p>
<p style="margin-bottom: 0in;">GROUP BY flg_won_hand;
</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">flg_won_hand,count,sum
</p>
<p style="margin-bottom: 0in;">f,30432,-1547.84
</p>
<p style="margin-bottom: 0in;">t,3255,1616.83
</p>
</blockquote>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Typically I was playing at 10 player<br />
tables, so winning around 10% of the time would be normal.  And<br />
that&#8217;s the case here.  You can imagine how having these sort of<br />
statistics on every player&#8211;and a much more complicated set, like the<br />
percentage of time a player paid money to see the &#8220;flop&#8221; and play<br />
a hand&#8211;accumulated over time as you played would be a huge<br />
advantag.</p>
<p style="margin-bottom: 0in;"></p>
<p style="margin-bottom: 0in;">What happens at a table is that good players quickly recognize<br />
the other sharks who&#8217;ve come to snack, and you respectfully play<br />
against them while at the same time gobbling down each new &#8220;fish&#8221;<br />
(that&#8217;s their nickname) who appears.  If you&#8217;re running<br />
PokerTracker with its heads-up display, the easiest type of player to<br />
take money from gets a little icon over their head showing a picture<br />
of a fish.&nbsp; There they are, labeled for you whether or not you were even paying attention to them, all based on some database driven statistics.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Not only does having stats on the other<br />
players help, having your own lets you tune your play around your<br />
personal strengths and weaknesses.  In a Hold&#8217;Em hand, the two cards<br />
you&#8217;re dealt before each hand begins are your &#8220;hole cards&#8221;.  If<br />
you&#8217;re any good, you should make a lot of your money when your hole<br />
cards are the known set where your odds are good to win.  That was certainly the<br />
case for me:</p>
<p style="margin-bottom: 0in;">
</p>
<blockquote><p style="margin-bottom: 0in;">SELECT hole_cards,count(*),sum(amt_won)
</p>
<p style="margin-bottom: 0in;">FROM player p
</p>
<p style="margin-bottom: 0in;">JOIN holdem_hand_player_statistics s<br />
USING (id_player)
</p>
<p style="margin-bottom: 0in;">JOIN lookup_hole_cards USING<br />
(id_holecard)
</p>
<p style="margin-bottom: 0in;">WHERE p.player_name=&#8217;greg1104&#8242;
</p>
<p style="margin-bottom: 0in;">GROUP BY hole_cards
</p>
<p style="margin-bottom: 0in;">ORDER by sum(amt_won)
</p>
<p style="margin-bottom: 0in;">LIMIT 10;
</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">hole_cards,count,sum
</p>
<p style="margin-bottom: 0in;">AA,139,51.16
</p>
<p style="margin-bottom: 0in;">55,142,25.71
</p>
<p style="margin-bottom: 0in;">AKs,95,21.44
</p>
<p style="margin-bottom: 0in;">QQ,148,20.49
</p>
<p style="margin-bottom: 0in;">AKo,313,16.82
</p>
<p style="margin-bottom: 0in;">KK,153,14.82
</p>
<p style="margin-bottom: 0in;">TT,159,13.45
</p>
<p style="margin-bottom: 0in;">JJ,166,12.95
</p>
<p style="margin-bottom: 0in;">A8s,112,11.60
</p>
<p style="margin-bottom: 0in;">T9o,343,11.10
</p>
<p style="margin-bottom: 0in;">
</p>
</blockquote>
<p style="margin-bottom: 0in;">All the usual suspects:&nbsp; AA, KK, QQ, AKs (suited, meaning they have the same suit, so likely to form a flush), AKo (off-suit), JJ, TT.&nbsp; One of my specialties was playing<br />
pocket pairs that turned into trio after the &#8220;flop&#8221; of 3 initial<br />
cards aggressively, particularly against players who didn&#8217;t raise<br />
quite enough to keep me out of the hand.  This is how I ended up<br />
winning so much with the slightly odd &#8220;55&#8243; combination.&nbsp; I was<br />
quite good at spotting when someone else had AA, KK, or QQ before the<br />
flop from their betting pattern.&nbsp; If they raised enough that I spotted them, but not so much it wasn&#8217;t worth my trouble, I&#8217;ll call and see what happened.&nbsp; If I got a matching third 5 on the flop (around 10% of the time it happens), I&#8217;d act like I was<br />
bluffing to steal the hand, get them committed and betting aggressively at me, and then raise to all-in.&nbsp; If they called, the hand was usually mine.&nbsp; You have to fine-tune that strategy based on how aggressive the other player is, and I&#8217;d be doing it with a stack of heads-up data showing various numeric measurements of that aspect of their play.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">If I reverse the order here to see my<br />
worst hands, that&#8217;s where you can find even more valuable<br />
information:</p>
<p style="margin-bottom: 0in;">
</p>
<blockquote><p style="margin-bottom: 0in;">A4o,296,-13.83
</p>
<p style="margin-bottom: 0in;">QTo,300,-12.27
</p>
<p style="margin-bottom: 0in;">54o,294,-10.31
</p>
<p style="margin-bottom: 0in;">Q9s,113,-7.13
</p>
<p style="margin-bottom: 0in;">43o,294,-6.82
</p>
<p style="margin-bottom: 0in;">66,157,-6.52
</p>
<p style="margin-bottom: 0in;">J3o,294,-6.49
</p>
<p style="margin-bottom: 0in;">42s,114,-6.32
</p>
<p style="margin-bottom: 0in;">KJo,300,-6.02
</p>
<p style="margin-bottom: 0in;">A7o,348,-5.40</p>
</blockquote>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">Apparently I got tripped up at least<br />
once using the same technique on &#8220;pocket sixes&#8221; that made me so<br />
much money on the &#8220;55&#8243; combination; that&#8217;s just poker.  But the<br />
fact that I lost so often with QT, Q9, and KJ suggests my play around<br />
handling those good but not great cards wasn&#8217;t quite right.  And the<br />
fact that I lost quite a bit, relatively, on 54 and 43 off-suit tells<br />
me I was overvaluing the possibility of a low-end straight<br />
considerably.  This is very different fine-tuning from when I first started<br />
playing, where I&#8217;d lose lots of money even playing strong cards.  You<br />
only have to lose a flush to a full house so many times before you<br />
start considering that possibility for a second when you decide how<br />
to bet.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">By the time I gave up on playing online<br />
poker, I was just starting to get to where I had my own custom<br />
queries to run.  A &#8220;win % adjusted aggression factor&#8221; was the one<br />
I was working on at the end, basically separating out people who were<br />
aggressive betters all the time from those who only did that when<br />
they actually had a hand&#8211;what I did.  With a few million hands of<br />
data to research against, like the person asking on the list today has, fine tuning the statistics you collect and<br />
want to overlay (in real-time, updating after each hand) on top of<br />
the table heads-up display turns into a pretty difficult query<br />
processing challenge.  Given that the lack of an early Windows<br />
version of PostgreSQL is often cited as one reason it didn&#8217;t get<br />
better adoption, it&#8217;s kind of amusing to see it&#8217;s the database that<br />
completely owns this space&#8211;which, like PokerTracker itself and all the gaming client software&#8211;is a<br />
Windows only one.</p>
<p style="margin-bottom: 0in;">
</p>
<p style="margin-bottom: 0in;">When I was playing Texas Hold&#8217;Em, I<br />
never thought I&#8217;d be offering advice on database tuning suggestions<br />
as a way to improve play.  But that really is where we&#8217;re at now.<br />
It&#8217;s a shame there&#8217;s no good place for me to play on-line legally in the US<br />
anymore, because it forces to fold the cards I&#8217;ve scribbled notes on outlining a book I&#8217;d name &#8220;High-Speed<br />
Poker with PostgreSQL 9&#8243;.  If that ever gets sorted out, and I find<br />
myself with time to play again and a legal on-line venue to do it at<br />
here, you can bet I&#8217;m all-in on that idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.2ndquadrant.com/pushing_allin_with_postgresql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
