<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>Planet PostgreSQL</title><link>http://planet.postgresql.org</link><description>Planet PostgreSQL</description><lastBuildDate>Sun, 12 Feb 2012 06:30:51 GMT</lastBuildDate><generator>Planet PostgreSQL</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Mark Wong: PDXPUG: February meeting</title><link>http://pdxpug.wordpress.com/2012/02/10/pdxpug-february-meeting/</link><description>&lt;p&gt;&lt;strong&gt;When:&lt;/strong&gt; 7-9pm Thu Feb 16, 2012&lt;br /&gt;
&lt;strong&gt;Where:&lt;/strong&gt; Iovation&lt;br /&gt;
&lt;strong&gt;Who:&lt;/strong&gt; John Melesky&lt;br /&gt;
&lt;strong&gt;What:&lt;/strong&gt; Locks&amp;#8230; etc.&lt;/p&gt;
&lt;p&gt;High-traffic systems have to deal with locks. That&amp;#8217;s just the way it is. But that&amp;#8217;s okay! Locks invisibly help manage concurrency! Properly structured transactions will never run into deadlocks with each other! Right?&lt;/p&gt;
&lt;p&gt;Well, sometimes locks are very visible, and sometimes you end up with deadlocks that don&amp;#8217;t make sense. I&amp;#8217;m going to talk through a couple of row-locking problems i&amp;#8217;ve run into, and explain how and why that should end up changing PostgreSQL&amp;#8217;s SQL syntax.&lt;/p&gt;
&lt;p&gt;John&amp;#8217;s been poking computers since he was old enough to type, which was long enough ago that he debated whether to make a &amp;#8220;POKEing&amp;#8221; joke. He&amp;#8217;s a Software Engineer at Janrain, working with the reporting and analytics infrastructure.&lt;/p&gt;
&lt;p&gt;Our meeting will be held at Iovation, on the 32nd floor of the US Bancorp Tower at 111 SW 5th (5th &amp;amp; Oak).  It&amp;#8217;s right on the Green &amp;amp; Yellow Max lines.  Underground bike parking is available in the parking garage;  outdoors all around the block in the usual spots.  No bikes in the office, sorry!&lt;/p&gt;
&lt;p&gt;Building security will close access to the floor at 7:30.&lt;/p&gt;
&lt;p&gt;After-meeting beer location TBD.  See you there!&lt;/p&gt;
&lt;br /&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pdxpug.wordpress.com/66/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pdxpug.wordpress.com/66/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pdxpug.wordpress.com&amp;blog=30930172&amp;post=66&amp;subd=pdxpug&amp;ref=&amp;feed=1" width="1" height="1" /&gt;</description><guid isPermaLink="false">http://pdxpug.wordpress.com/?p=66</guid><pubDate>Fri, 10 Feb 2012 22:05:29 GMT</pubDate></item><item><title>Jim Smith: Announcing the Arizona Postgres Users Group</title><link>http://www.postgresmigrations.com/blog/post/3336006</link><description>As mentioned in an earlier post, we're announcing the start of a PUG for Arizona.&amp;nbsp; The first meeting will be Thursday, March 29, from 5 to 7 at Bull's facility in Northwest Phoenix.&amp;nbsp; Refreshments will be provided.&lt;br /&gt;
&lt;br /&gt;
You can join and get onto the mailing list and RSVP for the first meeting at &lt;a href="https://www.bigtent.com/groups/azpug"&gt;https://www.bigtent.com/groups/azpug&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
We look forward to meeting other PostgreSQL lovers and to help grow the PostgreSQL community in our part of the world.&amp;nbsp; Please feel free to pass the above link to anyone that's interested.</description><guid isPermaLink="true">http://www.postgresmigrations.com/blog/post/3336006</guid><pubDate>Thu, 09 Feb 2012 23:10:30 GMT</pubDate></item><item><title>Bruce Momjian: Virtualizing Postgres</title><link>http://momjian.us/main/blogs/pgblog/2012.html#February_9_2012</link><description>&lt;p&gt;Postgres is an ideal database to run in a virtual environment or public/private cloud &amp;mdash; one reason is that Postgres relies
heavily on the operating system, rather than using features like raw devices.  Second, its license is obviously very flexible for virtual
deployments.
&lt;/p&gt;
&lt;p&gt;I am often asked about running Postgres in virtual environments, and I usually answer that it runs just fine --- and it does.  However, I
am starting to realize that I am not answering the more complex questions of which visualization technology to choose, and what is the
performance and reliability impact of virtualization.
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://momjian.us/main/blogs/pgblog/2012.html#February_9_2012"&gt;Continue Reading &amp;raquo;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://momjian.us/main/blogs/pgblog/2012.html#February_9_2012</guid><pubDate>Thu, 09 Feb 2012 18:00:01 GMT</pubDate></item><item><title>Chris Travers: Further Response to Robert Young</title><link>http://ledgersmbdev.blogspot.com/2012/02/further-response-to-robert-young.html</link><description>Robert Young has &lt;a href="http://drcoddwasright.blogspot.com/2012/02/camel-passes-through-eye-of-needle.html"&gt;responded&lt;/a&gt; to my previous post and clarified his position.&amp;nbsp; However, he is still incorrect in his assessment.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&amp;nbsp; The issue is lost cycles as one moves down to a single thread. It's more about the number of clients that can be supported "simultaneously". At one time I was also enamoured of thread count to execute queries in parallel; not so much now. For reporting generally, and BI/DW specifically, sure. But for OLTP, where my interest lies, not so much. There, client count is what matters. Clients run relatively discrete transactions on few rows; parallelism isn't much help for that sort of client. Yes, to some extent I've changed my mind.&lt;/blockquote&gt;I think this makes the mistake of assuming that single threaded multiple process models cannot utilize hyperthreading architectures to increase computational efficiency. &lt;br /&gt;&lt;br /&gt;The first thing to note is that how a CPU cycles are utilized is primarily the job of the scheduler which is a part of any multitasking kernel, and different operating systems utilize very different process and thread models.&amp;nbsp; These cannot be merely reduced to their hardware equivalents.&amp;nbsp; If they were we would see process vs thread performance to be largely equivalent in Windows and Linux, but in fact while Windows is very thread-friendly and process-unfriendly, though my understanding is that applications on Windows running under SUA experience better multiprocess performance than under the Win32 subsystem.&lt;br /&gt;&lt;br /&gt;On Linux and UNIX there is very little difference between a pthread and a process except for memory isolation.&amp;nbsp; Individual processes can be scheduled on logical cores supporting hyperthreading, for example.&amp;nbsp; The overhead for supporting multiple processes is low.&lt;br /&gt;&lt;br /&gt;On the other hand, on Windows, threads are cheap and processes are expensive.&amp;nbsp; This is one reason why I typically recommend that high-concurrency &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt; instances are not run on Windows.&amp;nbsp; My understanding is that SUA addresses this issue but I can't find solid comparisons at the moment and I don't know of a PostgreSQL port to that platform.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Think of the issue this way: if it were true that scaling down threads to one per processor/core yielded a scale up in performance equivalently (only one of two threads yields twice the performance on that last thread), then the question gets more difficult. But threads and cores don't scale that way. Such reverse scaling could only happen if the core's frequency increased as the inverse of threads active. That just doesn't happen, you get a bin or two; that nasty frequency brick wall is the reason vendors have turned to multi-core and threads in the first place. &lt;/blockquote&gt;I am not sure I buy that.&amp;nbsp; Linux, for example, is quite happy to schedule different processes on different logical cores, thus meaning that two processes can share a hyperthreading core in the same way two threads can.&amp;nbsp; Again, that behavior is specific to a combination of a CPU, OS and scheduler.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Unless you've been building database applications from before 1995 (or thereabouts), which is to say only webbie thingees, the efficiency and user friendliness of *nix/RDBMS/RS-232/terminal is a foreign concept; just as it still is for mainframe COBOL coders writing to 3270 terminals, same semantics (I'll grant that javascript is more capable than 3270 edit language, and Wikipedia does it again, with this write up). In the web age, AJAX was the first widely known (and possibly absolute first) attempt to get back to that future, then there is Comet. Now, we have WebSocket, discussed in earlier posts.&lt;/blockquote&gt;&lt;br /&gt;I don't see what this has to do with anything.&amp;nbsp; I personally find the user friendliness of an RDBMS and *nix to be very important.&amp;nbsp; I also primarily build accounting apps, and I will tell you that doing so often over the web is not very performance-friendly for reasons that I am more than happy to discuss in another post (it's one reason why long-run I want to move away from requiring that everything goes through a web interface).&amp;nbsp;&amp;nbsp; But basically, transactional handling is somewhat crippled when tied to a stateless network protocol like HTTP, meaning all transactions must be atomic to within a single http request, and where we would normally not do that, we have to invent ways to get around that limitation.&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;The Achilles heel of those *nix/RDBMS/RS-232/VT-X00 applications was the limit on the number of clients that could be accommodated since the client patch remained while the user kept a session. The emerging hardware/infrastructure that I'm discussing may/should remove that restriction. This also means that developers must heed the mantra, "the user doesn't determine transaction scope". With HTTP (un)connectedness, that isn't much of an issue.&lt;/blockquote&gt;&lt;br /&gt;This is the wrong way to look at it. &amp;nbsp; HTTP unconnectedness actually in many cases makes the problem worse rather than better if you have to preserve db state across HTTP requests (which&lt;a href="http://www.ledgersmb.org/"&gt; LedgerSMB&lt;/a&gt; btw does in some cases).&amp;nbsp; It's one thing to have 15 connections updating payments in a db with 10 million transactions and relying on advisory locks.&amp;nbsp; It's a very different thing to have 15 users hitting&amp;nbsp; a db with 10 million transactions and having to store in the db which transactions they are temporarily holding for payment.&amp;nbsp; now suddenly you go from 3 sec queries to 45 sec queries, and I would expect that we could support at least 10x the number of concurrent users in a large db if it wasn't for this unconnectedness.&amp;nbsp; Now you are dealing with a large amount of I/O contention and row-locking (because we have to make sure we get the right info so invoices aren't double-paid), and while it works, it isn't pretty, nor does it perform particularly well.&lt;br /&gt;&lt;br /&gt;This being said, the DB is usually even less of an issue in these cases than the web server.....&lt;br /&gt;&lt;br /&gt;Moreover, web apps, particularly those that run public sites, can experience traffic spikes that can easily exceed the number of connections a db can be expected to gracefully handle.&amp;nbsp; So in both cases: simple web site apps like blogs accessible to the public, and complex web-based business apps, rdbms-backed web apps are worse performance-wise than thick clients.&lt;br /&gt;&lt;br /&gt;But the overall point remains the same:&amp;nbsp; scheduling of processes and threads is the OS's job, not the CPU's.&amp;nbsp; Wasted cycles in scheduling&amp;nbsp; are the OS's problem, not the CPU's.&amp;nbsp; If an OS can't schedule processes as efficiently as it schedules threads, that's the OS's constraint, and it is only the app's problem if you are writing with an OS in mind and your OS doesn't behave the way you would like it to.&amp;nbsp; Windows, in particular, is heavily oriented towards threads.&amp;nbsp; It isn't clear that most *nix platforms see the same benefit, as witnessed by&amp;nbsp;&lt;a href="http://docs.oracle.com/cd/E11882_01/server.112/e25789/process.htm#i16977"&gt;Oracle's architecture&lt;/a&gt; which assumes one process per connection.&lt;br /&gt;&lt;br /&gt;Also a note on DB2's connection multiplexing.&amp;nbsp; It isn't clear that this actually requires multiple threads to do.&amp;nbsp; The fact is you can only receive a string of data over a connection.&amp;nbsp; This has to be parsed and handled.&amp;nbsp; It's not at all clear that this needs threads when it is clear that regardless of how you do it, it needs a queue.&lt;br /&gt;&lt;br /&gt;BTW, PostgreSQL parallel performance is getting a LOT of attention in the move from 9.1 to 9.2.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3346090548501966296-5388637259321123062?l=ledgersmbdev.blogspot.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="false">tag:blogger.com,1999:blog-3346090548501966296.post-5388637259321123062</guid><pubDate>Thu, 09 Feb 2012 01:47:46 GMT</pubDate></item><item><title>Robert Haas: My Patches Are Breeding</title><link>http://rhaas.blogspot.com/2012/02/my-patches-are-breeding.html</link><description>One of the great things about being a long-term contributor to an open source project like PostgreSQL is that you get to see other people take the stuff you've done and use it as a stepping stone to bigger and better things. One of my early PostgreSQL hacking projects was &lt;a href="http://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=d4382c4ae7ea1e272f4fee388aac8ff99421471a"&gt;a patch to extend the syntax of EXPLAIN&lt;/a&gt;. Prior to 9.0, the grammar looked &lt;a href="http://www.postgresql.org/docs/8.4/static/sql-explain.html"&gt;like this&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;EXPLAIN [ ANALYZE ] [ VERBOSE ] statement&lt;/pre&gt;&lt;br /&gt;Now, there's nothing particularly wrong with that grammar from a usability perspective, but it turns out to be pretty terrible for extensibility.  Let's suppose we want to add a new EXPLAIN option that does something new and different - say, omit the costing information from the output. Then we have to change the grammar to something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;EXPLAIN [ ANALYZE ] [ VERBOSE ] [ NOCOSTS ] statement&lt;/pre&gt;&lt;br /&gt;There are a couple of problems with this. One is that, as the number of options increases, it gets hard to remember the order in which they must be specified.  You might think that it would be easy enough to recode the grammar to look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;EXPLAIN [ ANALYZE | VERBOSE | NOCOSTS ]... statement&lt;/pre&gt;&lt;br /&gt;...and it might be, but it's surprisingly easy, when using bison, to create situations that bison finds ambiguous, even though a human being might not.  Another problem is that NOCOSTS has to become what's called a keyword, which has a very small but nonzero distributed cost across our entire grammar.  Rightly or wrongly, a number of patches that proposed to enhance EXPLAIN in various ways got shot down because of these issues.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://rhaas.blogspot.com/2012/02/my-patches-are-breeding.html#more"&gt;Read more »&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/20038672-6386329063044399715?l=rhaas.blogspot.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="false">tag:blogger.com,1999:blog-20038672.post-6386329063044399715</guid><pubDate>Wed, 08 Feb 2012 19:28:42 GMT</pubDate></item><item><title>Selena Deckelmann: Catching up with pgsql-hackers: CRCs, checkpoint performance, SKIP LOCKED ROWS, dry-run pg_archivecleanup</title><link>http://www.chesnok.com/daily/2012/02/07/catching-up-with-pgsql-hackers-crcs-checkpoint-performance-skip-locked-rows-dry-run-pg_archivecleanup/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=catching-up-with-pgsql-hackers-crcs-checkpoint-performance-skip-locked-rows-dry-run-pg_archivecleanup</link><description>&lt;div id="tweetbutton3686" class="tw_button"&gt;&lt;a href="http://twitter.com/share?url=http%3A%2F%2Fwww.chesnok.com%2Fdaily%2F2012%2F02%2F07%2Fcatching-up-with-pgsql-hackers-crcs-checkpoint-performance-skip-locked-rows-dry-run-pg_archivecleanup%2F&amp;text=Catching%20up%20with%20pgsql-hackers%3A%20CRCs%2C%20checkpoint%20performance%2C%20SKIP%20LOCKED%20ROWS%2C%20dry-run%20pg_archivecleanup&amp;related=selenamarie:Catching%20up%20with%20pgsql-hackers&amp;lang=en&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.chesnok.com%2Fdaily%2F2012%2F02%2F07%2Fcatching-up-with-pgsql-hackers-crcs-checkpoint-performance-skip-locked-rows-dry-run-pg_archivecleanup%2F" class="twitter-share-button"&gt;Tweet&lt;/a&gt;&lt;/div&gt;&lt;p&gt;I&amp;#8217;ve been sick for a few days, so I settled in with a nice cup of tea and started in on the tremendous backlog I&amp;#8217;ve got on pgsql-hackers. I put patch status at the end of each paragraph. &lt;/p&gt;
&lt;p&gt;The first thread I read was a patch for &lt;a href="http://archives.postgresql.org/message-id/CA+U5nMJzQyxcObkpNAf1SYTX-gO_Mom3O9JXHnGpxRo1kXJ7ww@mail.gmail.com"&gt;implementing 16-bit CRCs for all buffer pages&lt;/a&gt;. This is the most recent patch in a multi-year effort around CRCs. There are many small and large problems with implementing this (performance, hint bits and cramped page header space for starters). If you read the whole thread, you&amp;#8217;ll see some interesting compromises, and the role that pg_upgrade now plays in the stewardship of page format changes.  Patch is still under review.&lt;/p&gt;
&lt;p&gt;That lead me over to performance &lt;a href="http://archives.postgresql.org/pgsql-hackers/2012-01/msg00943.php"&gt;testing results&lt;/a&gt; from what was titled as a double-write buffer patch from VMWare. The author of these patches doesn&amp;#8217;t respond to comments in-line like everyone else on -hackers does, so it makes his responses pretty difficult to keep track of. Still WIP.&lt;/p&gt;
&lt;p&gt;And, related a &lt;a href="http://archives.postgresql.org/pgsql-hackers/2012-01/msg00883.php"&gt;checkpoint performance tuning treatise from Greg Smith&lt;/a&gt;. This started from a patch to add a parameter that allows adding pause time before a checkpoint. He points out that to tune this usefully, you need to know what the number of files a checkpoint typically syncs. (and &lt;a href="http://archives.postgresql.org/message-id/4F13C38D.2080905@2ndQuadrant.com"&gt;has a related patch that publishes this information&lt;/a&gt;). Patches are still under review. &lt;/p&gt;
&lt;p&gt;There&amp;#8217;s another discussion about &lt;a href="http://archives.postgresql.org/message-id/CADLWmXUUjmrPU-+9ss7BCATxM-hr6__9mB6Wv7ry3-r+KXGgBw@mail.gmail.com"&gt;SKIP LOCKED ROWS and a patch&lt;/a&gt;, apparently a commercial database feature. Early WIP.&lt;/p&gt;
&lt;p&gt;In usability land, there was &lt;a href="http://archives.postgresql.org/message-id/4EE4C393.4060302@2ndQuadrant.it"&gt;an addition of a &amp;#8220;dry-run&amp;#8221; feature to pg_archivecleanup&lt;/a&gt;. This one&amp;#8217;s committed!&lt;/p&gt;
&lt;p&gt;This all makes me so excited for the 9.2 release this year. Also, great to see a bunch of new folks submitting patches.&lt;/p&gt;</description><guid isPermaLink="false">http://www.chesnok.com/daily/?p=3686</guid><pubDate>Tue, 07 Feb 2012 16:25:04 GMT</pubDate></item><item><title>Chris Travers: Robert Young is Wrong about Threads and PostgreSQL</title><link>http://ledgersmbdev.blogspot.com/2012/02/robert-young-is-wrong-about-threads-and.html</link><description>Robert Young has claimed, not&amp;nbsp;&lt;a href="http://drcoddwasright.blogspot.com/2012/01/dont-thread-on-me.html"&gt;once&lt;/a&gt; but &lt;a href="http://drcoddwasright.blogspot.com/2012/02/damn-you-damocles.html"&gt;twice&lt;/a&gt;, that a multi-threaded engine is necessary for database performance to be good enough.&amp;nbsp; I am going to explain here why he is wrong.&lt;br /&gt;&lt;br /&gt;Mr Young's argument more or less goes something like this:&amp;nbsp; threads are more efficient, processor-power-wise to spin up than processes, and therefore if you insist on a single-threaded multi-process model, you can't have sufficient performance to make your database system relevant.&lt;br /&gt;&lt;br /&gt;There are several important problems with this thinking.&amp;nbsp; The first is that for it to be significant, the thread vs process overhead, plus related IPC, etc. must be a significant portion of actual CPU load.&amp;nbsp; If this is not the case, the difference largely gets lost in the noise.&amp;nbsp; In my experience in looking at databases, I have yet to identify one case where this is the case.&amp;nbsp; Instead things like network connection/teardown, command parsing, and, well, actual work dwarf process/thread startup cycles by several orders of magnitude.&amp;nbsp; This means that the actual startup processing overhead is likely insignificant in the overall scheme of things,&lt;br /&gt;&lt;br /&gt;Of course actually starting up a process or thread is not all there is to the picture.&amp;nbsp; There's communication between processes or threads to take into account.&amp;nbsp; There is also the added complexity of locking shared resources in a threaded vs process model.&amp;nbsp; And there are of course the costs that come with a lack of process isolation on the other side.&amp;nbsp; These all have to be weighed against eachother, and it is not clear who the winner is.&amp;nbsp; In fact even these costs will dwarf the startup costs by a significant margin.&lt;br /&gt;&lt;br /&gt;Rather the reason why many RDBMS's have gone to a multi-threaded model is that it is one way, perhaps even an elegant way, to support intraquery parallelism.&amp;nbsp; In other words if you can spin up a few more threads in your process, those threads can be conducting scans on different partitions in different table spaces, and thus overall increasing the resource utilization of a given query.&amp;nbsp; This is an important feature and it is currently lacking on PostgreSQL.&amp;nbsp; Postgres-XC however is a project that offers such a solution based on a multi-server, distributed model.&amp;nbsp; It is perhaps not quite ready for prime time but is getting there. &lt;br /&gt;&lt;br /&gt;But while a multi-threaded engine would make this sort of parallelism easier to implement, it isn't clear to me that either it is necessary or that the cost in complexity would be worth it compared to multi-process and even multi-server models.&amp;nbsp; Threaded systems are far harder to troubleshoot, far less transparent, and far more brittle than process-oriented systems.&lt;br /&gt;&lt;br /&gt;Note that each approach has strong points and weak points.&amp;nbsp; Declaring a specific architecture as a clear winner forgets that these differences exist.&amp;nbsp; Ideally eventually PostgreSQL would support multi-server and multi-process methods of intraquery parallelism.&amp;nbsp; I am not convinced that we need to support a multi-threaded method in addition.&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3346090548501966296-8279578337979786657?l=ledgersmbdev.blogspot.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="false">tag:blogger.com,1999:blog-3346090548501966296.post-8279578337979786657</guid><pubDate>Tue, 07 Feb 2012 05:54:18 GMT</pubDate></item><item><title>Steve Singer: 10 years of PostgreSQL replication</title><link>http://scanningpages.wordpress.com/2012/02/06/10-years-of-postgresql-replication/</link><description>&lt;p&gt;February 6&amp;#8242;th 2012 marks the 10 year anniversary of the open source &lt;a href="http://archives.postgresql.org/pgsql-patches/2002-02/msg00004.php" target="_blank"&gt;release&lt;/a&gt; of the DBMirror replication system.  DBMirror was not the first PostgreSQL replication solution to be released but it was the first one I was involved with.&lt;/p&gt;
&lt;p&gt;In the summer of 2001 I was working for &lt;a href="http://www.navtech.aero" target="_blank"&gt;Navtech System Support&lt;/a&gt;, an aviation software company.  We were using PostgreSQL 6.x to store data for one of our applications. We needed to have an up to date copy of the database available on servers at a remote site.  We also needed a standby database server in case our primary server failed.&lt;br /&gt;
&lt;span id="more-477"&gt;&lt;/span&gt;&lt;br /&gt;
PostgreSQL didn&amp;#8217;t have any built in replication but it did have triggers. My colleagues at Navtech and myself figured that if we wrote a trigger that captured a record of all changes made to a database table we would then know what changes needed to be made on a replica to keep it up to date with the master.&lt;/p&gt;
&lt;p&gt;I wrote the initial version of DBMirror over a few weeks during the summer of 2001 targetting PostgreSQL 7.1.  I no longer have a copy of the original version but I think it only stored the primary key of each row and referenced the original table while replicating.  In the September/October time-frame I spent a few more weeks reworked DBMirror into the form we released it in.  This version stored the entire contents of a modified row.  This is was the first version that saw production use.&lt;/p&gt;
&lt;p&gt;In February of 2002 the management team at Navetch was kind enough to allow us too open-source DBMirror.  DBMirror was included with the PostgreSQL source code as contrib/dbmirror where it remained as a contrib module until 2007. No one tracks how many users any particular PostgreSQL replication solution has (or had) but based on mailing list traffic DBMirror was far more popular than contrib/rserv, or any of the other options available until Slony become more mature almost 4 years later.&lt;/p&gt;
&lt;p&gt;DBMirror was not particularly efficient, it stored each column of a replicated table in its own row of the pendingData table, the replication daemon was written in perl and the query to approximate the commit order taxed the database server.  The cleanup script also created a lot of work for vacuum.&lt;/p&gt;
&lt;p&gt;The biggest strength DBMirror had going for it was that it was simple to setup and it was flexible.  People could install DBMirror and replicate their database after reading a three page README file.  The replication daemon was written in perl and was easy to understand.  Many people customized dbmirror.pl to perform site specific tasks like renaming tables or excluding rows that matched a particular regex.&lt;/p&gt;
&lt;p&gt;I haven&amp;#8217;t modified the dbmirror code in years and I would be surprised if there were many dbmirror installations still running.  I am truly grateful that I was given the opportunity to develop and release DBMirror.  I continue to be involved with PostgreSQL replication as a Slony developer. I also assist with built in replication where by skills and time allow.&lt;/p&gt;
&lt;p&gt;In the past 10 years PostgreSQL replication has come a long way from the few thousand lines of C and perl code that made up dbmirror.  I look forward to the advances in replication we will see in the next 10 years.&lt;/p&gt;
&lt;p&gt;It has been years since I have heard from the other people at Navtech who were involved in the development, testing and deployment of DBMirror.  If any of them are reading this they should send me a note.&lt;/p&gt;
&lt;br /&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/scanningpages.wordpress.com/477/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/scanningpages.wordpress.com/477/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scanningpages.wordpress.com&amp;blog=13081650&amp;post=477&amp;subd=scanningpages&amp;ref=&amp;feed=1" width="1" height="1" /&gt;</description><guid isPermaLink="false">http://scanningpages.wordpress.com/?p=477</guid><pubDate>Mon, 06 Feb 2012 12:26:18 GMT</pubDate></item><item><title>Joe Abbate: Automated Database Augmentation</title><link>http://pyrseas.wordpress.com/2012/02/05/automated-database-augmentation/</link><description>&lt;p&gt;Suppose you have a PostgreSQL database like the &lt;a href="http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/dbsamples/pagila/pagila-schema.sql?rev=1.8&amp;content-type=text/x-cvsweb-markup"&gt;Pagila sample&lt;/a&gt; with 14 tables, each with a &lt;tt&gt;last_update&lt;/tt&gt; timestamp column to record the date and time each row was modified, and it is now a requirement to capture which user effected each change. Or perhaps you have several tables without such audit trail columns and need to add them quickly. Or maybe you have decided to denormalize your design by adding a calculated column, e.g., extended price = unit price times quantity ordered, or a derived column, e.g., carrying the customer name in the invoice table.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://classroom209.blogspot.com/2011/01/vocab-for-fire-stormf.html"&gt;&lt;img class="alignright" title="Drudgery" src="http://4.bp.blogspot.com/_knNIUa4PX-s/TSSSaT20CJI/AAAAAAAABLc/gem_AOMgrz0/s1600/Drudgery.jpg" alt="" width="288" height="230" /&gt;&lt;/a&gt;If you have some experience as a DBA, the word &amp;#8220;&lt;a href="http://en.wiktionary.org/wiki/drudgery"&gt;drudgery&lt;/a&gt;&amp;#8221; may have come to mind at the prospect of implementing the above features. It&amp;#8217;s possible that, after a while, you&amp;#8217;ve developed an approach for dealing with some of them but still wish there&amp;#8217;d be &lt;em&gt;some way&lt;/em&gt; to automate these thankless tasks.&lt;/p&gt;
&lt;p&gt;You may have looked at the Andromeda project&amp;#8217;s &amp;#8220;&lt;a href="http://www.andromeda-project.org/automations.html"&gt;automations&lt;/a&gt;&amp;#8221; which provide some of these capabilities. However, in order to take advantage of the automations, you&amp;#8217;ll first have to manually describe your database in a YAML format (and you&amp;#8217;ll have to install Apache and PHP). Or you could have tried to use the follow-on project, &lt;a href="http://code.google.com/p/triangulum-db/wiki/UsingTriangulum"&gt;Triangulum&lt;/a&gt;, but essentially you&amp;#8217;d still have to create a YAML schema (no need for Apache, but you still need PHP).&lt;/p&gt;
&lt;p&gt;Some relief is forthcoming. As a result of discussions resulting from my &lt;a title="Business Logic in the Database" href="http://pyrseas.wordpress.com/2012/01/02/business-logic-in-the-database/"&gt;Business Logic in the Database&lt;/a&gt; post, I have been collaborating with Roger Hunwicks on a potential solution to these common DBA needs. The new Pyrseas tool is tentatively named &lt;tt&gt;dbextend&lt;/tt&gt;&lt;sup&gt;1&lt;/sup&gt; and its initial documentation is available in the &lt;a href="https://github.com/jmafc/Pyrseas/blob/extender/docs/dbextend.rst"&gt;Pyrseas extender branch&lt;/a&gt;. This is how I envision &lt;tt&gt;dbextend&lt;/tt&gt; being used.&lt;/p&gt;
&lt;p&gt;Consider the opening example. The DBA would create a simple YAML file such as the (abbreviated) one below, listing the tables and the needed features:&lt;/p&gt;
&lt;pre&gt;schema public:
  table actor:
    audit_columns: default
  table category:
    audit_columns: default
...
  table store:
    audit_columns: default&lt;/pre&gt;
&lt;p&gt;The DBA would then use this file, say &lt;tt&gt;audext.yaml&lt;/tt&gt;, as input to dbextend, e.g.,&lt;/p&gt;
&lt;pre&gt;dbextend pagiladb audext.yaml&lt;/pre&gt;
&lt;p&gt;dbextend reads the PostgreSQL catalogs (using code shared with &lt;a href="http://pyrseas.readthedocs.org/en/latest/dbtoyaml.html"&gt;dbtoyaml&lt;/a&gt; and &lt;a href="http://pyrseas.readthedocs.org/en/latest/yamltodb.html"&gt;yamltodb&lt;/a&gt;), building its internal representation. It also reads the YAML extensions file and builds a parallel (albeit much smaller) structure. Thirdly, it reads extension configuration information, e.g., a definition of what columns need to be added for &amp;#8220;&lt;tt&gt;audit_columns: default&lt;/tt&gt;&amp;#8220;, for example, modified_timestamp and modified_by_user, what trigger(s) to add, and what function(s) to be created.&lt;/p&gt;
&lt;p&gt;The output of dbextend is a YAML schema file, just like the one output by dbtoyaml, which can be piped directly to yamltodb to generate SQL to implement the desired features.&lt;/p&gt;
&lt;p&gt;In case you&amp;#8217;re wondering, dbextend —like other Pyrseas tools— will require Python, psycopg2 and pyyaml.&lt;/p&gt;
&lt;p&gt;What features would &lt;em&gt;you&lt;/em&gt; like to see automated? What are &lt;em&gt;your&lt;/em&gt; suggested best practices for automating these common needs?&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Picture credit: Thanks to Mr. O&amp;#8217;Brien, a fourth-grade teacher in Minnesota.&lt;/p&gt;
&lt;p&gt;&lt;sup&gt;1&lt;/sup&gt; We&amp;#8217;re still receptive to some other suitable name.&lt;/p&gt;
&lt;br /&gt;Filed under: &lt;a href="http://pyrseas.wordpress.com/category/database-tools/"&gt;Database tools&lt;/a&gt;, &lt;a href="http://pyrseas.wordpress.com/category/postgresql-2/"&gt;PostgreSQL&lt;/a&gt;, &lt;a href="http://pyrseas.wordpress.com/category/python/"&gt;Python&lt;/a&gt;  &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pyrseas.wordpress.com/1476/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pyrseas.wordpress.com/1476/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pyrseas.wordpress.com&amp;blog=19437126&amp;post=1476&amp;subd=pyrseas&amp;ref=&amp;feed=1" width="1" height="1" /&gt;</description><guid isPermaLink="true">http://pyrseas.wordpress.com/?p=1476</guid><pubDate>Mon, 06 Feb 2012 03:38:49 GMT</pubDate></item><item><title>Andrew Dunstan: JSON for PG 9.2 ... and now for 9.1!</title><link>http://people.planetpostgresql.org/andrew/index.php?/archives/255-JSON-for-PG-9.2-...-and-now-for-9.1!.html</link><description>Robert Haas committed his bare bones JSON type five days ago, and three days later I committed my array_to_json and row_to_json constructors, so this is now definitely a go for 9.2. Kudos to Robert for persisting with this - I had just about given up on us getting it done for this release.&lt;br /&gt;
&lt;br /&gt;
As an added bonus for those of you who are a bit impatient to use this stuff, I have back ported this to 9.1 as an extension. You can get the code from my &lt;a href="https://bitbucket.org/adunstan/json_91"&gt;bitbucket repository&lt;/a&gt;, and when I have polished it a bit more I will publish it on &lt;a href="http://pgxn.org/"&gt;PGXN&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
PLEASE NOTE: this should work fine if you dump and restore the database when moving to 9.2 - just suppress the extension creation. But it won't work with binary upgrade.</description><guid isPermaLink="false">http://people.planetpostgresql.org/andrew/index.php?/archives/255-guid.html</guid><pubDate>Sun, 05 Feb 2012 18:24:42 GMT</pubDate></item><item><title>Leo Hsu and Regina Obe: Back from DDOS Attack</title><link>http://www.postgresonline.com/journal/archives/242-Back-from-DDOS-Attack.html</link><description>&lt;p&gt;As many may have noticed, PostgresOnline.com has been down for the past week or so and probably is still not reachable from many parts of the world since our DNS server was also taken down as a result of a Denial of Service (DDOS) attack instigated by an Activision &lt;a href="http://www.callofduty.com/" target="_blank"&gt;Call of Duty Game exploit&lt;/a&gt;  that turned thousands of Call of Duty game servers into Zombies launching an attack on us.&lt;/p&gt;

&lt;p&gt;We have a small confession to make.  One of the businesses we co-own is an e-Commerce site that sells condoms.  You never know how people will react when you say that in mixed company so we only mention it in closer company. Some people are glad we are in a business protecting against venereal diseases or unwanted pregnancies and some feel strongly we are violating a mother nature creed of conduct.  WowCondoms was the site that was under attack on a UDP port and we are not sure if it was a malicious intent or not since the root instigator has not been found yet.  The attack was higher up from our servers so it knocked our ISP who in turn blamed us for their outage. We never saw the traffic.&lt;/p&gt;

&lt;p&gt;The tragic thing is that it can happen to any site and does all the time. It really hit home when it happened to us.&lt;/p&gt;
&lt;p&gt;Details of our fight are described here: &lt;a href="http://wowcondoms.com/Condom_Blog/83/Call_of_Duty_DDOS_Exploit" target="_blank"&gt;WowCondoms plugs hole in Activision's Call of Duty Game Servers&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://www.postgresonline.com/journal/archives/242-guid.html</guid><pubDate>Sun, 05 Feb 2012 15:43:02 GMT</pubDate></item><item><title>Chris Travers: LedgerSMB talk at FOSDEM</title><link>http://ledgersmbdev.blogspot.com/2012/02/ledgersmb-talk-at-fosdem.html</link><description>&lt;span&gt;Hi,&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I just arrived at FOSDEM - Brussels. Due to last minute arrangements, my talk about LedgerSMB isn't in the schedule. So, here's the announcement:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There will be a LedgerSMB talk in the Perl devroom (AW1.121)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;between 12.25 and 12.45&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The talk is on the fosdem site:&amp;nbsp;&lt;a href="http://fosdem.org/2012/schedule/event/ledgersmb_perl" target="_blank"&gt;http://fosdem.org/2012/schedule/event/ledgersmb_perl&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With kind regards,&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Erik.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/3346090548501966296-2503007040587536117?l=ledgersmbdev.blogspot.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="false">tag:blogger.com,1999:blog-3346090548501966296.post-2503007040587536117</guid><pubDate>Sun, 05 Feb 2012 10:54:01 GMT</pubDate></item><item><title>Hubert 'depesz' Lubaczewski: Waiting for 9.2 – pg_basebackup from slave</title><link>http://www.depesz.com/index.php/2012/02/03/waiting-for-9-2-pg_basebackup-from-slave/</link><description>On 25th of January, Simon Riggs committed patch: Allow pg_basebackup FROM standby node WITH safety checking. Base backup follows recommended PROCEDURE, plus goes TO great lengths TO ensure that partial page writes are avoided. &amp;#160; Jun Ishizuka AND Fujii Masao, WITH minor modifications In PostgreSQL 9.1 we got pg_basebackup &amp;#8211; it is a tool to [...]</description><guid isPermaLink="false">http://www.depesz.com/?p=2399</guid><pubDate>Fri, 03 Feb 2012 14:08:48 GMT</pubDate></item><item><title>Jared Watkins: What I Do – Broadsoft CDR Files to Radius Accounting Records</title><link>http://jaredwatkins.com/wordpress/2012/02/what-i-do-broadsoft-cdr-files-to-radius-accounting-records/</link><description>&lt;div class="dd_post_share dd_post_share_right"&gt;&lt;div class="dd_buttons"&gt;&lt;div class="dd_button_v"&gt;&lt;div class="dd-linkedin-ajax-load dd-linkedin-675"&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="dd_button_v"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As part of a larger project I needed to generate real time radius records from the CDR accounting files of several cluster pairs of Broadsoft application servers. So I wrote a perl script to do just that. It maps the CDR fields to radius attribs and encodes the accounting packet using the &lt;a href="http://search.cpan.org/~luismunoz/Net-Radius-2.103/Radius/Packet.pm"&gt;Net::Radius::Packet&lt;/a&gt; CPAN module.  In my case I&amp;#8217;m using the &lt;a href="http://www.open.com.au/radiator/"&gt;Radiator radius server&lt;/a&gt;  from &lt;a href="http://www.open.com.au/"&gt;OSC Software&lt;/a&gt; on the other end with lots of custom &amp;#8216;hook code&amp;#8217; to clean up and store the call data coming off our network into a &lt;a href="http://www.postgresql.org/"&gt;Postgresql&lt;/a&gt; database.  This is my first time doing any development with radius.. but I&amp;#8217;ve been running this script on several servers for a few weeks now and it appears to be quite stable.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get it on the &lt;a href="http://jaredwatkins.com/wordpress/my-projects/file2radius/"&gt;Project Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com --&gt;</description><guid isPermaLink="false">http://jaredwatkins.com/wordpress/?p=675</guid><pubDate>Fri, 03 Feb 2012 03:40:17 GMT</pubDate></item><item><title>Bruce Momjian: Let's See work_mem</title><link>http://momjian.us/main/blogs/pgblog/2012.html#February_2_2012</link><description>&lt;p&gt;Having shown memory allocation (and deallocation) in my previous &lt;a class="txt2html" href="http://momjian.us/main/blogs/pgblog/2012.html#February_1_2012"&gt;blog
post&lt;/a&gt;, I would like to show
&lt;a class="txt2html" href="http://www.postgresql.org/docs/9.1/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY"&gt;&lt;em&gt;work_mem&lt;/em&gt;&lt;/a&gt; in action.
&lt;/p&gt;
&lt;p&gt;First, I ran the following database session using a &lt;a class="txt2html" href="http://momjian.us/main/blogs/pgblog/2012.html#January_20_2012"&gt;~6k RPM drive&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://momjian.us/main/blogs/pgblog/2012.html#February_2_2012"&gt;Continue Reading &amp;raquo;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://momjian.us/main/blogs/pgblog/2012.html#February_2_2012</guid><pubDate>Thu, 02 Feb 2012 15:45:01 GMT</pubDate></item><item><title>Hubert 'depesz' Lubaczewski: Waiting for 9.2 – Trigger Depth</title><link>http://www.depesz.com/index.php/2012/02/01/waiting-for-9-2-trigger-depth/</link><description>On 25th of January, Alvaro Herrera committed patch: ADD pg_trigger_depth&amp;#40;&amp;#41; FUNCTION &amp;#160; This reports the depth level OF triggers currently IN execution, OR zero IF NOT called FROM inside a TRIGGER. &amp;#160; No catversion bump IN this patch, but you have TO initdb IF you want access TO the NEW FUNCTION. &amp;#160; Author: Kevin Grittner [...]</description><guid isPermaLink="false">http://www.depesz.com/?p=2396</guid><pubDate>Wed, 01 Feb 2012 17:36:50 GMT</pubDate></item><item><title>Jim Smith: Why aren't more people/companies using PostgreSQL?</title><link>http://www.postgresmigrations.com/blog/post/3323648</link><description>&lt;p&gt;Why aren't more people/companies using PostgreSQL? Why aren't they moving from proprietary databases to PostgreSQL?&amp;nbsp;&lt;br /&gt;
Possible answers: I haven't heard of PostgreSQL. I don't think PostgreSQL will meet my needs. I don't know how to get away from my database vendor.&lt;br /&gt;
I'd like to hear some of the reasons for not considering PostgreSQL when creating or migrating a database.&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;</description><guid isPermaLink="true">http://www.postgresmigrations.com/blog/post/3323648</guid><pubDate>Wed, 01 Feb 2012 16:58:55 GMT</pubDate></item><item><title>Bruce Momjian: Postgres Memory Surprises</title><link>http://momjian.us/main/blogs/pgblog/2012.html#February_1_2012</link><description>&lt;p&gt;In my previous &lt;a class="txt2html" href="http://momjian.us/main/blogs/pgblog/2012.html#January_30_2012"&gt;blog entry&lt;/a&gt;, I analyzed how various
tools (&lt;em&gt;ps&lt;/em&gt; and &lt;em&gt;smem&lt;/em&gt;) report memory usage.  In summary:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;ps&lt;/em&gt; columns &lt;em&gt;TRS&lt;/em&gt;, &lt;em&gt;DRS&lt;/em&gt;, and &lt;em&gt;VSZ&lt;/em&gt; report virtual address space allocated, not actual RAM allocated.
  &lt;/li&gt;&lt;li&gt;&lt;em&gt;smem&lt;/em&gt;'s &lt;em&gt;USS&lt;/em&gt; reports a process's private (unshared) memory allocated.
  &lt;/li&gt;&lt;li&gt;&lt;em&gt;smem&lt;/em&gt;'s &lt;em&gt;PSS&lt;/em&gt; is a sum of process's private memory allocated and a proportional amount of shared memory (both System V shared
memory, like Postgres's shared_buffers, and shared libraries).
  &lt;/li&gt;&lt;li&gt;&lt;em&gt;RSS&lt;/em&gt; shows actual RAM allocated, private and shared.
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;With these issues understood, let's look at a running Postgres cluster:
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://momjian.us/main/blogs/pgblog/2012.html#February_1_2012"&gt;Continue Reading &amp;raquo;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://momjian.us/main/blogs/pgblog/2012.html#February_1_2012</guid><pubDate>Wed, 01 Feb 2012 15:15:01 GMT</pubDate></item><item><title>Hubert 'depesz' Lubaczewski: Waiting for 9.2 – ALTER IF EXISTS</title><link>http://www.depesz.com/index.php/2012/02/01/waiting-for-9-2-alter-if-exists/</link><description>On 23th of January, Simon Riggs committed patch: ALTER &amp;#60;thing&amp;#62; &amp;#91;IF EXISTS&amp;#93; ... allows silent DDL IF required, e.g. ALTER FOREIGN TABLE IF EXISTS foo RENAME TO bar &amp;#160; Pavel Stehule This adds important capability &amp;#8211; change object of it exists, and not raise exception if it doesn&amp;#8217;t. Conditional DDL was always big point on [...]</description><guid isPermaLink="false">http://www.depesz.com/?p=2393</guid><pubDate>Wed, 01 Feb 2012 13:14:11 GMT</pubDate></item><item><title>Pavel Golub: Factorial using CTE in PostgreSQL</title><link>http://pgolub.wordpress.com/2012/02/01/factorial-using-cte-in-postgresql/</link><description>&lt;p&gt;Not so long ago &lt;a href="http://pgolub.wordpress.com/2010/06/20/fibonacci-rides-again/"&gt;I used&lt;/a&gt; Common Table Expressions for &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Fibonacci Numbers&lt;/a&gt; calculation.&lt;/p&gt;
&lt;p&gt;Today I had a conversation with one client about SQL in general and about PosgreSQL dialect in particular. We talked about SQL&amp;#8217;s &lt;a href="http://en.wikipedia.org/wiki/Turing_completeness"&gt;Turing completeness&lt;/a&gt; also. Well my opponent is sure that SQL (Postgres dialect either) is not Turing Complete. But I know for sure that if SQL supports CTE it is Turing Complete. Well, I&amp;#8217;m sure about it because some time ago at &lt;a href="http://www.oscon.com/oscon2009"&gt;Oscon 2009&lt;/a&gt; David Fetter said so. And my confidence in this man is boundless.  &lt;img src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /&gt;&lt;br /&gt;
&lt;img alt="" src="http://habrastorage.org/storage2/8e8/001/13c/8e800113cf3071f21c26c0de1aff577c.png" title="Result set" class="alignright" width="106" height="287" /&gt;&lt;br /&gt;
Anyway, my client proposed to implement Factorial calculation on a pure SQL. I choose Postgres dialect. He agreed. &lt;/p&gt;
&lt;p&gt;That was his first mistake! He didn&amp;#8217;t know that Postgres has built in &lt;a href="http://www.postgresql.org/docs/9.1/static/functions-math.html"&gt;&amp;#8220;!&amp;#8221; and &amp;#8220;!!&amp;#8221; operators&lt;/a&gt; for this purpose. &lt;img src="http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /&gt; &lt;/p&gt;
&lt;p&gt;But to be more convincing, I have wrote this code:&lt;/p&gt;
&lt;table border="0" cellspacing="0" cellpadding="5"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;
WITH RECURSIVE fact(i, f) AS (
    VALUES (2, 1)
UNION ALL
    SELECT i + 1, i * f FROM fact
)
SELECT f FROM fact LIMIT 10;
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;Filed under: &lt;a href="http://pgolub.wordpress.com/category/postgresql/coding/"&gt;Coding&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/category/postgresql/"&gt;PostgreSQL&lt;/a&gt; Tagged: &lt;a href="http://pgolub.wordpress.com/tag/cte/"&gt;CTE&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/tag/factorial/"&gt;factorial&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/tag/oscon/"&gt;oscon&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/tag/postgresql/"&gt;PostgreSQL&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/tag/sql/"&gt;SQL&lt;/a&gt;, &lt;a href="http://pgolub.wordpress.com/tag/trick/"&gt;trick&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/pgolub.wordpress.com/1730/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/pgolub.wordpress.com/1730/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=pgolub.wordpress.com&amp;blog=5816673&amp;post=1730&amp;subd=pgolub&amp;ref=&amp;feed=1" width="1" height="1" /&gt;</description><guid isPermaLink="false">http://pgolub.wordpress.com/?p=1730</guid><pubDate>Wed, 01 Feb 2012 09:42:26 GMT</pubDate></item><item><title>Damien Clochard: Write a Foreign Data Wrapper in 15 minutes (Part 1/2)</title><link>http://blog.taadeem.net/index.php?post/2012/01/31/Write-a-Foreign-Data-Wrapper-in-15-minutes-Part-1/2</link><description>&lt;p&gt;Among the &lt;a href="http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.1"&gt;long list of new features of PostgreSQL 9.1&lt;/a&gt; the new SQL/MED implementation is probably of the most underrated. &lt;a href="http://en.wikipedia.org/wiki/SQL/MED"&gt;SQL/MED&lt;/a&gt; is an extension of the SQL standard defines foreign data wrappers (FDW) that allow you to reach data located outside of your database, with regular SQL request (MED stands for Management of External Data). In a nutshell, &lt;a href="http://rhaas.blogspot.com/2011/01/why-sqlmed-is-cool.html"&gt;SQL/MED is cool&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;As far as i know, PostgreSQL and DB2 are the only major RDBMS providing an implementation of this standard. The beauty with  PostgreSQL is that you can write your own data wrappers to connect your database to any storage you want ; other RDBMS, NoSQL storages, web services,  whatever system that holds data and can deliver it.&lt;/p&gt;



&lt;p&gt;Basically to &lt;a href="http://www.postgresql.org/docs/9.1/static/fdwhandler.html"&gt;Write a Foreign Data Wrapper&lt;/a&gt; you need to code &lt;a href="http://www.postgresql.org/docs/9.1/static/fdw-callbacks.html"&gt;six callback routines in C&lt;/a&gt; to explain how to plan and execute queries toward your new source of data.&lt;/p&gt;


&lt;p&gt;PostgreSQL 9.1 has been released a few month ago, but there's already a bunch of FDW available (even though most of them are still beta). At the time, I'm writing this we already have &lt;a href="http://wiki.postgresql.org/wiki/Foreign_data_wrappers more than 15 wrappers" title="http://wiki.postgresql.org/wiki/Foreign_data_wrappers more than 15 wrappers"&gt;http://wiki.postgresql.org/wiki/For...&lt;/a&gt;, so you can connect your PostgreSQL server to ; &lt;a href="http://pgfoundry.org/projects/oracle-fdw/"&gt;Oracle&lt;/a&gt;, &lt;a href="http://github.com/dpage/mysql_fdw"&gt;MySQL&lt;/a&gt;, &lt;a href="http://multicorn.org/foreign-data-wrappers/#sqlite-foreign-data-wrapper"&gt;SQLlite&lt;/a&gt;, &lt;a href="https://github.com/ZhengYang/odbc_fdw"&gt;anything providing an ODBC driver&lt;/a&gt;, &lt;a href="https://github.com/guedes/ldap_fdw"&gt;LDAP&lt;/a&gt;, &lt;a href="https://github.com/ZhengYang/couchdb_fdw"&gt;couchdb&lt;/a&gt;, &lt;a href="https://github.com/dpage/redis_fdw"&gt;redis&lt;/a&gt;, &lt;a href="https://github.com/umitanuki/s3_fdw"&gt;Amazon S3 storage&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/9.1/static/file-fdw.html"&gt;CSV files&lt;/a&gt;, &lt;a href="https://github.com/umitanuki/twitter_fdw"&gt;Twitter&lt;/a&gt;, &lt;a href="https://github.com/Kozea/Multicorn/blob/master/python/multicorn/googlefdw.py"&gt;Google Search&lt;/a&gt;, &lt;a href="https://github.com/cyga/www_fdw/"&gt;HTML pages&lt;/a&gt;, &lt;a href="http://multicorn.org/foreign-data-wrappers/#rss-foreign-data-wrapper"&gt;RSS feeds&lt;/a&gt;, ....&lt;/p&gt;


&lt;p&gt;For an almost complete list, check out the PostgreSQL wiki ;
&lt;a href="http://wiki.postgresql.org/wiki/Foreign_data_wrappers" title="http://wiki.postgresql.org/wiki/Foreign_data_wrappers"&gt;http://wiki.postgresql.org/wiki/For...&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;And of course these wrappers are packaged as extension and most of them are available on PGXN and quite easy to install :
&lt;a href="http://pgxn.org/tag/fdw/" title="http://pgxn.org/tag/fdw/"&gt;http://pgxn.org/tag/fdw/&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;But there's more ! Among these FDW there's one called &lt;a href="http://multicorn.org/"&gt;Multicorn&lt;/a&gt;. This particular extension that allow you to write FDW in Python. A wrapper over another wrapper. Basically this means you don't have to know C to write your own FDW and you can use high-level libraries from the Python world.&lt;/p&gt;


&lt;p&gt;Ok let's take a simple example. I'd like to query data contained in a web calendar like Google Calendar. Those data are available in ical files, with a specific format called iCalendar. So want i need to do is explain PostgreSQL how to reach and parse the files.&lt;/p&gt;


&lt;p&gt;With Python and Multicorn, this is done with 20 lines of code : see  &lt;a href="https://github.com/daamien/Multicorn/blob/80e2ac7650d0a125b1eebb77c03cc77489cd134d/python/multicorn/icalfdw.py"&gt;icalfdw.py&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;And that's it.&lt;/p&gt;


&lt;p&gt;Of course this is a basic implementation. We can do better with some optimizations and a few log handling. It's also important to keep in mind that  foreign data wrappers have strong limitations... I'll talk about all that and other things in my next blog post.&lt;/p&gt;


&lt;p&gt;In the meantime, if you're in Brussels this week-end for &lt;a href="http://fosdem.org/2012/"&gt;FOSDEM&lt;/a&gt; you can come to the &lt;a href="http://fosdem.org/2012/schedule/track/postgresql_devroom"&gt;PostgreSQL Devroom&lt;/a&gt;, I'll make a presentation of Multicorn along with its creator.&lt;/p&gt;</description><guid isPermaLink="false">urn:md5:970ce34186e9712836787ee46c13c121</guid><pubDate>Tue, 31 Jan 2012 22:49:00 GMT</pubDate></item><item><title>Greg Smith: Using the PostgreSQL System Columns</title><link>http://blog.2ndquadrant.com/en/2012/01/using-the-postgresql-system-co.html</link><description>&lt;!--
		@page { margin: 0.79in }
		P { margin-bottom: 0.08in }
		A:link { so-language: zxx }
		CODE.cjk { font-family: "DejaVu Sans", monospace }
	--&gt;There are a few parts of the PostgreSQL internals that poke out usefully if you look in the right place for them.&amp;nbsp; One useful set to know about are the &lt;a href="http://www.postgresql.org/docs/current/static/ddl-system-columns.html"&gt;System Columns&lt;/a&gt;, which you can explicitly request but don't see by default.&amp;nbsp; For example:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;psql -x -c "SELECT oid,* FROM pg_class LIMIT 1"&lt;br /&gt;&lt;/blockquote&gt;There is no column named oid in the pg_class table, but it's there if you ask for it.&amp;nbsp; The oid used to be relied on more heavily in PostgreSQL as a way to identify rows.&amp;nbsp; That's not true for regular tables anymore, and you really don't want to start doing that for your own tables.&amp;nbsp; OIDs are mainly useful now when joining parts of the &lt;a href="http://www.postgresql.org/docs/current/static/catalogs.html"&gt;System Catalog&lt;/a&gt; together.&amp;nbsp; A good example is the &lt;a href="http://wiki.postgresql.org/wiki/Disk_Usage"&gt;Disk Usage&lt;/a&gt; query.&amp;nbsp; If you want to find the namespace a table is in, you need to know you can ask for its OID.&amp;nbsp; It's possible to get some of this data out of more portable views like information_schema.tables.&amp;nbsp; But many of the useful things in this area are PostgreSQL specific.&amp;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.&amp;nbsp; That approach has several edge cases that don't work out correctly; not handling &lt;a href="http://www.postgresql.org/docs/current/static/storage-toast.html"&gt;TOAST&lt;/a&gt; columns is a common example.&amp;nbsp; That makes them more prone to breaking on you later, probably after your system has gone into production, than an OID based join.&lt;br /&gt;&lt;br /&gt;There is also a tableoid system column.&amp;nbsp; As described in the documentation, its main use case is identifying which partition a row come from.&amp;nbsp; That's not a great thing to be driving application logic from, but it can be useful for monitoring or troubleshooting purposes.&amp;nbsp; For example, if you SELECT rows from the parent table in a partitioning inheritance scheme, it's normally expected that no rows will actually be stored there.&amp;nbsp; Checking the tableoid is one way to confirm that.&amp;nbsp; You might confirm that your INSERT/UPDATE trigger is moving rows to the right place using tableoid as well.&amp;nbsp; It'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.&lt;br /&gt;&lt;br /&gt;Another internal column related to uniquely identifying rows is the ctid.&amp;nbsp; The ctid is a direct pointer to the physical block (using PostgreSQL's 8K page size) and position of a row.&amp;nbsp; ctids are a pair of numbers, and the first row will be (0,1).&amp;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.&amp;nbsp; Any UPDATE and some maintenance operations will change them.&amp;nbsp; One thing you can use these for is finding duplicate data in a table.&amp;nbsp; Let's say you'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.&amp;nbsp; When rows are identical in every column, you can't write any simple SELECT statement to uniquely identify them.&amp;nbsp; That means deleting all of them but one copy requires some annoying and fragile SQL code, combining DELETE with LIMIT and/or OFFSET--which is always scary.&amp;nbsp; If you use the ctid instead, the implementation will be PostgreSQL specific, but it will also be faster and cleaner.&amp;nbsp; See &lt;a href="http://www.postgresonline.com/journal/archives/22-Deleting-Duplicate-Records-in-a-Table.html"&gt;Deleting Duplicate Records in a Table&lt;/a&gt; for an example of how that can be done.&lt;br /&gt;&lt;br /&gt;The other system columns all relate to transaction visibility:&amp;nbsp; xmin, cmin, xmax, cmax.&amp;nbsp; When you delete a row in PostgreSQL, it isn't eliminated from disk immediately.&amp;nbsp; It's possible that some other query that's executing at the same time will still need to see that row, and the &lt;a href="http://www.postgresql.org/docs/current/static/transaction-iso.html"&gt;transaction isolation&lt;/a&gt; in PostgreSQL worries about such things.&amp;nbsp; If you ever want to learn how that isolation works, the way the &lt;a href="http://www.postgresql.org/docs/current/static/mvcc.html"&gt;Multiversion Concurrency Control&lt;/a&gt; (MVCC) implementation is handled, you can watch parts of it happen.&amp;nbsp; Just open transactions in two different sessions, UPDATE/DELETE in one of them, and then look at those rows in the other.&amp;nbsp; You can still see them in the session where they weren't touched, but they'll be marked to expire in the future via their xmax being set.&amp;nbsp; To really pull that all together, you also need to know about some of the &lt;a href="http://www.postgresql.org/docs/current/static/functions-info.html"&gt;System Information Functions&lt;/a&gt;.&amp;nbsp; &lt;i&gt;txid_current()&lt;/i&gt; is the most useful for this sort of learning experience, it provides a reference point for the always increasing system transaction ID.&amp;nbsp; You can find a more detailed exploration of using these functions and system columns in Bruce's &lt;a href="http://momjian.us/main/presentations/internals.html"&gt;MVCC Unmasked&lt;/a&gt; talk.&amp;nbsp; The "Routine Maintenance" chapter of &lt;a href="https://www.packtpub.com/postgresql-90-high-performance/book"&gt;my book&lt;/a&gt; also shows examples how how MVCC works through the perspective of the system columns.&lt;br /&gt;</description><guid isPermaLink="true">tag:blog.2ndquadrant.com,2012:/en//3.191</guid><pubDate>Tue, 31 Jan 2012 22:02:06 GMT</pubDate></item><item><title>Hubert 'depesz' Lubaczewski: Change in anonmymization of plans on explain.depesz.com</title><link>http://www.depesz.com/index.php/2012/01/31/change-in-anonmymization-of-plans-on-explain-depesz-com/</link><description>As you perhaps know, explain.depesz.com has anonymization feature. Couple of days ago Filip contacted me and sent a patch that stopped anonymization of typecasts. I thought about the patch, and what it achieves, changed it&amp;#8217;s internals, but kept the effect. And today, it got released. Normal plan looks like this. But you might want to [...]</description><guid isPermaLink="false">http://www.depesz.com/?p=2382</guid><pubDate>Tue, 31 Jan 2012 12:10:56 GMT</pubDate></item><item><title>Greg Sabino Mullane: Protecting and auditing your secure PostgreSQL data</title><link>http://blog.endpoint.com/2012/01/protecting-auditing-postgresql-data.html</link><description>&lt;a href="http://4.bp.blogspot.com/-1R42QgfZvFs/TycvCoG8BtI/AAAAAAAAAPU/xJIL640LkBk/s1600/EIB.png"&gt;&lt;img src="http://4.bp.blogspot.com/-1R42QgfZvFs/TycvCoG8BtI/AAAAAAAAAPU/xJIL640LkBk/s320/EIB.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5703579175260784338" /&gt;&lt;/a&gt;span{font-family:sans-serif;}span.p{color:red;}span.d{color:gray;}span.c{color:green;font-family:monospace;}span.o{font-family:monospace;color:#0022cc;}span.oo{font-family:monospace;font-weight:bolder;}&lt;p&gt;PostgreSQL functions can be written in &lt;a href="http://www.postgresql.org/docs/9.1/static/xplang.html"&gt;many languages&lt;/a&gt;. These languages fall into two categories, 'trusted' and 'untrusted'. Trusted languages cannot do things "outside of the database", such as writing to local files, opening sockets, sending email, connecting to other systems, etc. Two such languages are &lt;a href="http://www.postgresql.org/docs/9.1/static/plpgsql.html"&gt;PL/pgSQL&lt;/a&gt; and and &lt;a href="http://www.postgresql.org/docs/9.1/static/plperl.html"&gt;PL/Perl&lt;/a&gt;. For "untrusted" languages, such as PL/PerlU, all bets are off, and they have no limitations placed on what they can do. Untrusted languages can be very powerful, and sometimes dangerous.&lt;/p&gt;&lt;p&gt;One of the reasons untrusted languages can be considered dangerous is that they can cause side effects outside of the normal transactional flow that cannot be rolled back. If your function writes to local disk, and the transaction then rolls back, the changes on disk are still there. Working around this is extremely difficult, as there is no way to detect when a transaction has rolled back at the level where you could, for example, undo your local disk changes.&lt;/p&gt;&lt;p&gt;However, there are times when this effect can be very useful. For example, in a &lt;a href="http://postgresql.1045698.n5.nabble.com/Logging-access-to-data-in-database-table-td5430079.html"&gt; recent thread&lt;/a&gt; on the PostgreSQL "general" mailing list (aka pgsql-general), somebody asked for a way to audit SELECT queries into a logging table that would survive someone doing a ROLLBACK. In other words, if you had a function named weapon_details() and wanted to have that function log all requests to it by inserting to a table, a user could simply run the query, read the data, and then rollback to thwart the auditing:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
BEGIN;

SELECT weapon_details('BFG 9000'); -- also inserts to an audit table

ROLLBACK;                          -- inserts to the audit table are now gone!
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Certainly there are other ways to track who is using this query, the most obvious being by enabling full Postgres logging (by setting log_statement = 'all' in your postgresql.conf file.) However, extracting that information from logs is no fun, so let's find a way to make that INSERT stick, even if the surrounding function was rolled back.&lt;/p&gt;&lt;p&gt;Stepping back for one second, we can see there are actually two problems here: restricting access to the data, and logging that access somewhere. The ultimate access restriction is to simply force everyone to go through your custom interface. However, in this example, we will assume that someone has &lt;a href="http://www.postgresql.org/docs/9.1/static/app-psql.html"&gt;psql&lt;/a&gt; access and needs to be able to run ad hoc SQL queries, as well as be able to BEGIN, ROLLBACK, COMMIT, etc.&lt;/p&gt;&lt;p&gt;Let's assume we have a table with some Very Important Data inside of it. Further, let's establish that regular users can only see some of that data, and that we need to know who asked for what data, and when. For this example, we will create a normal user named Alice:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE USER alice;
&lt;span class="d"&gt;CREATE ROLE&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We need a way to tell which rows are suitable for people like Alice to view. We will set up a quick classification scheme using the nifty &lt;a href="http://www.postgresql.org/docs/9.1/static/datatype-enum.html"&gt;ENUM feature&lt;/a&gt; of PostgreSQL:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE TYPE classification AS ENUM (
 'unclassified',
 'restricted',
 'confidential',
 'secret',
 'top secret'
);
&lt;span class="d"&gt;CREATE TYPE&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Next, as a superuser, we create the table containing sensitive information, and populate it:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE TABLE weapon (
  id              SERIAL          PRIMARY KEY,
  name            TEXT            NOT NULL,
  cost            TEXT            NOT NULL,
  security_level  CLASSIFICATION  NOT NULL,
  description     TEXT            NOT NULL DEFAULT 'a fine weapon'
);
&lt;span class="d"&gt;NOTICE:  CREATE TABLE will create implicit sequence "weapon_id_seq" for serial column "weapon.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "weapon_pkey" for table "weapon"
CREATE TABLE&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;INSERT INTO weapon (name,cost,security_level) VALUES
 ('Crowbar',  10,  'unclassified'),
 ('M9',  200,  'restricted'),
 ('M16A2',  300,  'restricted'),
 ('M4A1',  400,  'restricted'),
 ('FGM-148 Javelin',  700,  'confidential'),
 ('Pulse Rifle',  50000,  'secret'),
 ('Zero Point Energy Field Manipulator',  'unknown',  'top secret');
&lt;span class="d"&gt;INSERT 0 7&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;We don't want anyone but ourselves to be able to access this table, so for safety, we make some explicit revocations. We'll examine the permissions before and after we do this:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\dp weapon
&lt;span class="c"&gt;                           Access privileges
 Schema |  Name  | Type  | Access privileges | Column access privileges 
--------+--------+-------+-------------------+--------------------------
 public | weapon | table |                   | &lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;REVOKE ALL ON TABLE weapon FROM public;
&lt;span class="d"&gt;REVOKE&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\dp weapon
&lt;span class="c"&gt;
                               Access privileges
 Schema |  Name  | Type  |     Access privileges     | Column access privileges 
--------+--------+-------+---------------------------+--------------------------
 public | weapon | table | postgres=arwdDxt/postgres | &lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;As you can see, what the REVOKE really does is remove the implicit "no permission" and grant explicit permissions to only the postgres user to view or modify the table. Let's confirm that Alice cannot do anything with that table:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\c postgres alice
&lt;span class="c"&gt;You are now connected to database "postgres" as user "alice".&lt;/span&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;postgres=&gt; SELECT * FROM weapon;
&lt;span class="c"&gt;ERROR:  permission denied for relation weapon&lt;/span&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;postgres=&gt; UPDATE weapon SET id = id;
&lt;span class="c"&gt;ERROR:  permission denied for relation weapon&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Alice does need to have access to parts of this table, so we will create a "wrapper function" that will query the table for us and return some results. By declaring this function as SECURITY DEFINER, it will run as if the person who created the function invoked it  - in this case, the postgres user. For this example, we'll be letting Alice see the "cost and description" of exactly one item at a time. Further, we are not going to let her (or anyone else using this function) view certain items. Only those items classified as "confidential" or lower can be viewed (i.e. "confidential", "restricted", or "unclassified"). Here's the first version of our function:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE LANGUAGE plperlu;
&lt;span class="d"&gt;CREATE LANGUAGE&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE OR REPLACE FUNCTION weapon_details(TEXT)
RETURNS TABLE (name TEXT, cost TEXT, description TEXT)
LANGUAGE plperlu
SECURITY DEFINER
AS $bc$

use strict;
use warnings;

## The item they are looking for
my $name = shift;
## We will be nice and ignore the case and any whitespace
$name =~ s{^\s*(\S+)\s*$}{lc $1}e;

## What is the maximum security_level that people who are 
## calling this function can view?
my $seclevel = 'confidential';

## Query the table and pull back the matching row
## We need to differentiate between "not found" and "not allowed",
## by comparing a passed-in level to the security_level for that row.
my $SQL = q{
SELECT name,cost,description,
  CASE WHEN security_level &lt;= $1 THEN 1 ELSE 0 END AS allowed
FROM weapon
WHERE LOWER(name) = $2};

## Run the query, pull back the first row, as well as the allowed column value
my $sth = spi_prepare($SQL, 'CLASSIFICATION', 'TEXT');
my $rv = spi_exec_prepared($sth, $seclevel, $name);
my $row = $rv-&gt;{rows}[0];
my $allowed = delete $row-&gt;{allowed};

## Did we find anything? If not, simply return undef
if (! $rv-&gt;{processed}) {
   return undef;
}

## Throw an exception if we are not allowed to view this row
if (! $allowed) {
   die qq{Sorry, you are not allowed to view information on that weapon!\n};
}

## Return the requested data
return_next($row);

$bc$;
&lt;span class="d"&gt;CREATE FUNCTION&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The above should be fairly self-explanatory. We are using PL/Perl's &lt;a href="http://www.postgresql.org/docs/9.1/static/plperl-builtins.html"&gt;built-in database access functions&lt;/a&gt;, such as spi_prepare, to do the actual querying. Let's confirm that this works as it should for Alice:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\c postgres alice
&lt;span class="c"&gt;You are now connected to database "postgres" as user "alice".&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('crowbar');
&lt;span class="c"&gt;  name   | cost |  description  
---------+------+---------------
 Crowbar | 10   | a fine weapon&lt;/span&gt;
&lt;span class="d"&gt;(1 row)&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('anvil');
&lt;span class="c"&gt; name | cost | description 
------+------+-------------&lt;/span&gt;
&lt;span class="d"&gt;(0 rows)&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('pulse rifle');
&lt;span class="c"&gt;ERROR:  Sorry, you are not allowed to view information on that weapon!
CONTEXT:  PL/Perl function "weapon_details"&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Now that we have solved the restricted access problem, let's move on the auditing. We will create a simple table to hold information about who accessed what and when:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE TABLE data_audit (
  tablename TEXT         NOT NULL,
  arguments TEXT             NULL,
  results   INTEGER          NULL,
  status    TEXT         NOT NULL  DEFAULT 'normal',
  username  TEXT         NOT NULL  DEFAULT session_user,
  txntime   TIMESTAMPTZ  NOT NULL  DEFAULT now(),
  realtime  TIMESTAMPTZ  NOT NULL  DEFAULT clock_timestamp()
);
&lt;span class="d"&gt;CREATE TABLE&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The 'tablename' column simply records which table they are getting data from. The 'arguments' is a free-form field describing what they were looking for. The 'results' column shows how many matching rows were found. The 'status' column will be used primarily to log unusual requests, such as the case where Alice looks for a forbidden item. The 'username' column records the name of the user doing the searching. Because we are using functions with SECURITY DEFINER set, this needs to be session_user, not current_user, as the latter will switch to 'postgres' within the function, and we want to log the real caller (e.g. 'alice'). The final two columns tell us then the current transaction started, and the exact time when an entry was made inside of this table. As a first attempt, we'll have our function do some simple inserts to this new data_audit table:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE OR REPLACE FUNCTION weapon_details(TEXT)
RETURNS TABLE (name TEXT, cost TEXT, description TEXT)
LANGUAGE plperlu
SECURITY DEFINER
AS $bc$

use strict;
use warnings;

## The item they are looking for
my $name = shift;
## We will be nice and ignore the case and any whitespace
$name =~ s{^\s*(\S+)\s*$}{lc $1}e;

## What is the maximum security_level that people who are 
## calling this function can view?
my $seclevel = 'confidential';

## Query the table and pull back the matching row
## We need to differentiate between "not found" and "not allowed",
## by comparing a passed-in level to the security_level for that row.
my $SQL = q{
SELECT name,cost,description,
  CASE WHEN security_level &lt;= $1 THEN 1 ELSE 0 END AS allowed
FROM weapon
WHERE LOWER(name) = $2};

## Run the query, pull back the first row, as well as the allowed column value
my $sth = spi_prepare($SQL, 'CLASSIFICATION', 'TEXT');
my $rv = spi_exec_prepared($sth, $seclevel, $name);
my $row = $rv-&gt;{rows}[0];
my $allowed = delete $row-&gt;{allowed};

&lt;span class="oo"&gt;
## Log this request
$SQL = 'INSERT INTO data_audit(tablename,arguments,results,status)
  VALUES ($1,$2,$3,$4)';
my $status = $rv-&gt;{rows}[0] ? $allowed ? 'normal' : 'forbidden' : 'na';
$sth = spi_prepare($SQL, 'TEXT', 'TEXT', 'INTEGER', 'TEXT');
spi_exec_prepared($sth, 'weapon', $name, $rv-&gt;{processed}, $status);
&lt;/span&gt;

## Did we find anything? If not, simply return undef
if (! $rv-&gt;{processed}) {
   return undef;
}

## Throw an exception if we are not allowed to view this row
if (! $allowed) {
   die qq{Sorry, you are not allowed to view information on that weapon!\n};
}

## Return the requested data
return_next($row);

$bc$;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;However, this fails the case pointed out in the original poster's email about viewing the data within a transaction that is then rolled back. It also fails to work at all when a forbidden item is requested, as that insert is rolled back by the die() call:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\c postgres alice
&lt;span class="c"&gt;You are now connected to database "postgres" as user "alice".&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('crowbar');
&lt;span class="c"&gt;  name   | cost |  description  
---------+------+---------------
 Crowbar | 10   | a fine weapon
(1 row)&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('pulse rifle');
&lt;span class="c"&gt;ERROR:  Sorry, you are not allowed to view information on that weapon!
CONTEXT:  PL/Perl function "weapon_details"&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;BEGIN;
&lt;span class="d"&gt;BEGIN&lt;/span&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM weapon_details('m9');
&lt;span class="c"&gt; name | cost |  description  
------+------+---------------
 M9   | 200  | a fine weapon&lt;/span&gt;
&lt;span class="d"&gt;(1 row)&lt;/span&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;ROLLBACK;
&lt;span class="d"&gt;ROLLBACK&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\c postgres postgres
&lt;span class="c"&gt;You are now connected to database "postgres" as user "postgres".&lt;/span&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;SELECT * FROM data_audit \x \g
&lt;span class="d"&gt;Expanded display is on.&lt;/span&gt;
&lt;span class="c"&gt;-[ RECORD 1 ]----------------------------
tablename | weapon
arguments | crowbar
results   | 1
status    | normal
username  | alice
txntime   | 2012-01-30 17:37:39.497491-05
realtime  | 2012-01-30 17:37:39.545891-05&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;How do we get around this? We need a way to commit something that will survive the surrounding transaction's rollback. The closest thing Postgres has to such a thing at the moment is to connect back to the database with a new and entirely separate connection. Two such popular ways to do so are with &lt;a href="http://www.postgresql.org/docs/9.1/static/dblink.html"&gt;the dblink program&lt;/a&gt; and &lt;a href="http://www.postgresql.org/docs/9.1/static/plperl.html"&gt;the PL/PerlU language&lt;/a&gt;. Obviously, we are going to focus on the latter, but all of this could be done with dblink as well. Here are the additional steps to connect back to the database, do the insert, and then leave again:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE OR REPLACE FUNCTION weapon_details(TEXT)
RETURNS TABLE (name TEXT, cost TEXT, description TEXT)
LANGUAGE plperlu
SECURITY DEFINER
&lt;span class="oo"&gt;VOLATILE&lt;/span&gt;
AS $bc$

use strict;
use warnings;
&lt;span class="oo"&gt;use DBI;&lt;/span&gt;

## The item they are looking for
my $name = shift;
## We will be nice and ignore the case and any whitespace
$name =~ s{^\s*(\S+)\s*$}{lc $1}e;

## What is the maximum security_level that people who are 
## calling this function can view?
my $seclevel = 'confidential';

## Query the table and pull back the matching row
## We need to differentiate between "not found" and "not allowed",
## by comparing a passed-in level to the security_level for that row.
my $SQL = q{
SELECT name,cost,description,
  CASE WHEN security_level &lt;= $1 THEN 1 ELSE 0 END AS allowed
FROM weapon
WHERE LOWER(name) = $2};

## Run the query, pull back the first row, as well as the allowed column value
my $sth = spi_prepare($SQL, 'CLASSIFICATION', 'TEXT');
my $rv = spi_exec_prepared($sth, $seclevel, $name);
my $row = $rv-&gt;{rows}[0];
my $allowed = defined $row ? delete $row-&gt;{allowed} : 1;

## Log this request
&lt;span class="oo"&gt;$SQL = 'INSERT INTO data_audit(username,tablename,arguments,results,status)
  VALUES (?,?,?,?,?)';
my $status = $rv-&gt;{rows}[0] ? $allowed ? 'normal' : 'forbidden' : 'na';
my $dbh = DBI-&gt;connect('dbi:Pg:service=auditor', '', '',
  {AutoCommit=&gt;0, RaiseError=&gt;1, PrintError=&gt;0});
$sth = $dbh-&gt;prepare($SQL);
my $user = spi_exec_query('SELECT session_user')-&gt;{rows}[0]{session_user};
$sth-&gt;execute($user, 'weapon', $name, $rv-&gt;{processed}, $status);
$dbh-&gt;commit();&lt;/span&gt;

## Did we find anything? If not, simply return undef
if (! $rv-&gt;{processed}) {
   return undef;
}

## Throw an exception if we are not allowed to view this row
if (! $allowed) {
   die qq{Sorry, you are not allowed to view information on that weapon!\n};
}

## Return the requested data
return_next($row);

$bc$;
&lt;span class="d"&gt;CREATE FUNCTION&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Note that because we are making external changes, we marked the function as VOLATILE, which ensures that it will always be run every time it is called, and not cached in any form. We are also using &lt;a href="http://www.postgresql.org/docs/9.1/static/libpq-pgservice.html"&gt;a Postgres service file&lt;/a&gt; with the 'db:Pg:service=auditor'. This means that the connection information (username, password, database) is contained in an external file. This is not only tidier than hard-coding those values into this function, but safer as well, as the function itself can be viewed by Alice. Finally, note that we are passing the 'username' directly into the function this time, as we have a brand new connection which is no longer linked to the 'alice' user, so we have to derive it ourselves from "SELECT session_user" and then pass it along.&lt;/p&gt;&lt;p&gt;Once this new function is in place, and we re-run the same queries as we did before, we see three entries in our audit table:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;\c postgres postgres
&lt;span class="c"&gt;You are now connected to database "postgres" as user "postgres".
&lt;span class="d"&gt;Expanded display is on.&lt;/span&gt;
-[ RECORD 1 ]----------------------------
tablename | weapon
arguments | crowbar
results   | 1
status    | normal
username  | alice
txntime   | 2012-01-30 17:56:01.544557-05
realtime  | 2012-01-30 17:56:01.54569-05
-[ RECORD 2 ]----------------------------
tablename | weapon
arguments | pulse rifle
results   | 1
status    | forbidden
username  | alice
txntime   | 2012-01-30 17:56:01.559532-05
realtime  | 2012-01-30 17:56:01.561225-05
-[ RECORD 3 ]----------------------------
tablename | weapon
arguments | m9
results   | 1
status    | normal
username  | alice
txntime   | 2012-01-30 17:56:01.573335-05
realtime  | 2012-01-30 17:56:01.574989-05&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So that's the basic premise of how to solve the auditing problem. For an actual production script, you would probably want to cache the database connection by sticking things inside of the special &lt;a href="http://www.postgresql.org/docs/9.1/static/plperl-global.html"&gt;%_SHARED hash available to PL/Perl and Pl/PerlU&lt;/a&gt;. Note that each user gets their own version of that hash, so Alice will not be able to create a function and have access to the same %_SHARED hash that the postgres user has access to. It's probably a good idea to simply not let users like Alice use the language at all. Indeed, that's the default when we do the CREATE LANGUAGE call as above:&lt;/p&gt;&lt;pre&gt;&lt;span class="o"&gt;
&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt; \c postgres alice
&lt;span class="c"&gt;You are now connected to database "postgres" as user "alice".&lt;/span&gt;

&lt;span class="p"&gt;postgres=&gt; &lt;/span&gt;CREATE FUNCTION showplatform()
RETURNS TEXT
LANGUAGE plperlu
AS $bc$
  return $^O;
$bc$;
&lt;span class="c"&gt;ERROR:  permission denied for language plperlu&lt;/span&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Further refinements to the actual script might include refactoring the logging bits to a separate function, writing some of the auditing data to a file on the local disk, recording the actual results returned to the user, and sending the data to another Postgres server entirely. For that matter, as we are using DBI, you could send it to other place entirely - such as a MySQL, Oracle, or DB2 database!&lt;/p&gt;&lt;p&gt;Another place for improvement would be associating each user with a security_level classification, such that any user could run the function and only see things at or below their level, rather than hard-coding the level as "confidential" as we have done here. Another nice refinement might be to always return undef (no matches) for items marked "top secret", to prevent the very existence of a top secret weapon from being deduced. :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7997313029981170997-7734681975994677033?l=blog.endpoint.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="true">tag:blogger.com,1999:blog-7997313029981170997.post-7734681975994677033</guid><pubDate>Tue, 31 Jan 2012 03:55:59 GMT</pubDate></item><item><title>Bruce Momjian: Revisiting Memory Reporting</title><link>http://momjian.us/main/blogs/pgblog/2012.html#January_30_2012</link><description>&lt;p&gt;Memory is very important to databases &amp;mdash; much more so than for typical applications
(&lt;a class="txt2html" href="http://momjian.us/main/presentations/overview.html#hw_selection"&gt;presentation&lt;/a&gt;).  Unfortunately, because memory allocation is so
complex, it is often hard to figure out how physical RAM is being used.  There are several reasons for the complexity:
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Virtual Memory:&lt;/strong&gt; CPUs in virtual memory mode don't access RAM directly, but rather through
&lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Page_table"&gt;page tables&lt;/a&gt;.
  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Segmentation:&lt;/strong&gt; Memory is allocated in specific &lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Segmentation_%28memory%29"&gt;segments&lt;/a&gt;:
&lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Text_segment"&gt;text(code)&lt;/a&gt;, &lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Data_segment"&gt;data&lt;/a&gt;, and stack.
  &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Sharing:&lt;/strong&gt;  physical RAM is often shared by multiple processes, either in read-only mode (program instructions), shared mode (read/write
of share memory), or &lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Copy-on-write"&gt;copy-on-write&lt;/a&gt; (create a new copy on write; used by
&lt;a class="txt2html" href="http://en.wikipedia.org/wiki/Fork_%28operating_system%29"&gt;fork&lt;/a&gt;).
&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Robert Haas's excellent &lt;a class="txt2html" href="http://rhaas.blogspot.com/2012/01/linux-memory-reporting.html"&gt;blog post&lt;/a&gt; highlighted much uncertainty about
how to analyze memory usage for specific processes, especially Postgres.  I commented on his blog, as did others, and now have a much
clearer idea of how to study memory usage.  A &lt;a class="txt2html" href="http://utcc.utoronto.ca/~cks/space/blog/linux/LinuxMemoryStats"&gt;blog post&lt;/a&gt; by Chris
Siebenmann directly addresses some of my and Robert's questions, and suggests &lt;a class="txt2html" href="http://www.selenic.com/smem/"&gt;smem&lt;/a&gt; as a way to analyze
memory, especially the sharing of memory.  It was interesting to learn that smem was designed specifically to address the problems Robert
outlined (&lt;a class="txt2html" href="http://lwn.net/Articles/230975/"&gt;2007&lt;/a&gt;, &lt;a class="txt2html" href="http://lwn.net/Articles/329458/"&gt;2009&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://momjian.us/main/blogs/pgblog/2012.html#January_30_2012"&gt;Continue Reading &amp;raquo;&lt;/a&gt;&lt;/p&gt;</description><guid isPermaLink="false">http://momjian.us/main/blogs/pgblog/2012.html#January_30_2012</guid><pubDate>Mon, 30 Jan 2012 21:45:01 GMT</pubDate></item><item><title>David Wheeler: &lt;p&gt;SQL Change Management Sans Duplication</title><link>http://feedproxy.google.com/~r/justatheory/pgsum/~3/TloDXCSP52M/sql-change-management-sans-redundancy.html</link><description>&lt;p&gt;In the &lt;a href="http://justatheory.com/computers/databases/vcs-sql-change-management.html"&gt;previous episode&lt;/a&gt; in this series, I had one issue with regard to SQL change management that I wanted to resolve: duplication of code between deploy and revert scripts sucks. Worse still is the duplication of code to change just one line of a procedure. Here&amp;rsquo;s how I propose to eliminate the dupes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://justatheory.com/computers/databases/sql-change-management-sans-redundancy.html"&gt;Read More »&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/justatheory/pgsum/~4/TloDXCSP52M" height="1" width="1" /&gt;</description><guid isPermaLink="true">tag:justatheory.com,2012:/computers/databases/sql-change-management-sans-redundancy</guid><pubDate>Mon, 30 Jan 2012 16:00:00 GMT</pubDate></item><item><title>Satoshi Nagayasu: PostgreSQL Conference 2012 on February 24 in Japan</title><link>http://pgsnaga.blogspot.com/2012/01/postgresql-conference-2012-on-february.html</link><description>Japan PostgreSQL Users Group will be having an annual 1day technical conference, PostgreSQL Conference 2012, on February 24 in Tokyo. There will be two keynote sessions and 13 sessions on PostgreSQL. (The photo was taken by @koyhoge at PostgreSQL Conference 2011)

- PostgreSQL Conference 2012 - NPO法人 日本PostgreSQLユーザ http://www.postgresql.jp/events/pgcon2012/ (Google translated)

The opening</description><guid isPermaLink="true">tag:blogger.com,1999:blog-12493181.post-7480472843747503062</guid><pubDate>Mon, 30 Jan 2012 00:54:14 GMT</pubDate></item><item><title>Josh Berkus: pgCon CfP and other events</title><link>http://it.toolbox.com/blogs/database-soup/pgcon-cfp-and-other-events-50214?rss=1</link><description>The dates for pgCon have been set and this year we have a bunch of exciting new events to make pgCon even more worth attending.  First, though, I wanted to remind everyone that the Call for Presentations ends Wednesday, so please make some talk submissions!</description><guid isPermaLink="false">http://rss.ittoolbox.com/rss/50214@http://it.toolbox.com/blogs/database-soup</guid><pubDate>Sun, 29 Jan 2012 16:27:11 GMT</pubDate></item><item><title>Peter Geoghegan: Power consumption in Postgres 9.2</title><link>http://pgeoghegan.blogspot.com/2012/01/power-consumption-in-postgres-92.html</link><description>&lt;div&gt;&lt;b id="internal-source-marker_0.7957186095882207"&gt;&lt;span&gt;&lt;span&gt;One of the issues of major concern to CPU vendors is optimising the power consumption of their devices. In a world where increasingly, computing resources are purchased in terms of fairly abstract units of work, and where, when selecting the location of a major data-centre, the local price of a kilowatt hour is likely to be weighed just as heavily as the wholesale price of bandwidth, this is quite understandable. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Globally, data centres consumed between 1.1 and 1.5 percent of electricity in 2010 (Source: &lt;a href="http://www.analyticspress.com/datacenters.html"&gt;Koomey&lt;/a&gt;). The economic and ecological importance of minimizing that number is fairly obvious.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;The broad trend towards increasing amounts of computing being performed within large data centres, with consolidated infrastructure, sold as a service rather than a product is undeniable. Of course, the term “cloud computing” is often applied to this phenomenon. That’s a term that I try to avoid, as it’s fairly ambiguous. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;&lt;span&gt;There has been considerable effort to reduce wake-ups when idle in software in general, including everything from web browsers to word processors, which is related to the increasing importance of mobile and embedded platforms. However, this effort is most pronounced among developers of software that is expected to be deployed in virtualised environment on many servers, as wake-ups prevent CPUs from entering various idle states that allow them to save electricity, and when these wakeups are multiplied by thousands of VM instances, they add up very quickly.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;As part of 4CaaSt, a research project funded by the European Commission's Seventh Framework programme, that brings together members of industry and academia with the collective goal of producing an innovative &lt;/span&gt;&lt;span&gt;platform-as-as-service&lt;/span&gt;&lt;span&gt; offering, I spent time reducing the idle wake-ups per second in PostgreSQL. Postgres services firm 2ndQuadrant, where I work as a database architect, has had the development of several PostgreSQL features sponsored by 4CaaSt in furtherance of that goal, of which this is only one.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Historically, PostgreSQL has been weak in this particular area. With a standard Postgres server, with no special configuration, I have measured the wake-ups when idle at 11.5 per second, using &lt;a href="http://www.lesswatts.org/projects/powertop/"&gt;Intel’s powertop utility&lt;/a&gt;, as of the current 9.1 release. This was thought to be unacceptably high, for 4CaaSt, other solutions that leverage virtualisation extensively, and for embedded systems too.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;CPUs have a number of methods of reducing power consumption. These are specified by the ACPI standard (which covers discoverability, configuration and power-management), which in case you hadn't heard, is an open specification that makes minimal assumptions about the architecture or platform in use, and was written to help authors of operating system kernels.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;Briefly, ACPI describes the following states (I’ve avoided mentioning other states that have more to do with thin&lt;/span&gt;&lt;span&gt;gs like managing laptop hibernation):&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;b&gt;&lt;span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/ul&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;Performance states &lt;/span&gt;P0&lt;span&gt; through to &lt;/span&gt;PN&lt;span&gt; (i.e. the exact number of states is implementation-defined). Dynamic CPU frequency scaling states. This might be better known under marketing names for specific implementations, like “Intel SpeedStep technology”. Ever notice how the frequency reported for your CPU under /proc/cpuinfo varies from one moment to the next on Linux? This is why! This state tends to be a bit sticky, in that it might take a few seconds to observe changes in frequency, as it is increased to meet demand. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;&lt;b&gt;&lt;span&gt; &lt;/span&gt;&lt;/b&gt;&lt;/ul&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;&lt;span&gt;Processor states &lt;/span&gt;&lt;span&gt;C0&lt;/span&gt;&lt;span&gt; through to &lt;/span&gt;&lt;span&gt;C3&lt;/span&gt;&lt;span&gt;. Processors will change this state very quickly, and we basically want to keep this as high as possible, as higher values are associated with using less power.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;b&gt;&lt;span&gt; &lt;ul&gt;&lt;li&gt;&lt;span&gt;C0 is the operating state.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;C1, or the halt state, is a state where the processor is not executing instructions, but can return to an executing state essentially instantaneously.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;C2, or the Stop-Clock state, is a state where the processor maintains all software-visible state, but may take longer to wake up. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;C3, or the sleep state, is a state where the processor does not need to maintain &amp;nbsp;cache coherency, but does maintain some other state. There can even be graduations of how deep a sleep this state represents, depending on the implementation - the Intel Core i5 chip in my laptop has a C4 state, for example.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;/b&gt;&lt;/ul&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;Postgres has a multi-process architecture, which includes at a minimum a number of “auxiliary processes”: processes that perform a single, well defined task across the installation. There is also a process associated with each connection, and autovacuum daemon. Out-of-the-box, you’ll see just the following processes, once the PostgreSQL server becomes idle:&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Postmaster&lt;/span&gt;&lt;span&gt;. A “clearing-house process”, that manages all other processes, and is minimally exposed to installation-wide failures, so that it has a good chance of recovering the server in the event of an unanticipated failure. To simulate this, you can kill another auxiliary process, and watch as the postmaster starts it again.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Background writer&lt;/span&gt;&lt;span&gt;. A process that is charged with writing out “dirty”, or unwritten buffers, in the hope of preventing individual connection backends from ever having to.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;WAL Writer&lt;/span&gt;&lt;span&gt;. A process that writes out WAL, log files that describe changes made to data in PostgreSQL databases. This is part of a whole subsystem through which the server efficiently maintains its crash-safety/durability guarantees. &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Autovacuum launcher&lt;/span&gt;&lt;span&gt;. This process notices if there is a need to vacuum dead rows, which are an artifact of the Postgres MVCC implementation. It launches autovacuum worker processes as needed, to perform this garbage collection.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Statistics collector&lt;/span&gt;&lt;span&gt;. This process collects statistics on tables, that influence the planner’s subsequent choice of plans, as the distribution and volume of data in tables can radically alter what the optimal plan is for most queries.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Checkpointer (new to 9.2)&lt;/span&gt;&lt;span&gt;. This process is responsible for managing checkpoints - smoothed writing of all data to disk, so that WAL files that describe those changes in sequence before a certain point can finally be truncated.&amp;nbsp;This used to be an additional responsibility of the background writer.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt; &lt;span&gt;The reason that all these wake-ups had to occur within each auxiliary process was because they needed to check if the Postmaster was still alive very regularly, or if they had work assigned to them. If they took too long to notice that the Postmaster was dead (a major failure that neccessitates all processes immediately exiting), they would take too long to detach from shared memory, which would prevent the DBA from starting a new instance, as Postgres will refuse to start when it notices this to avoid data corruption.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;The solution was to amend the latch, a low-level facility to wait-sleep on an event that was already used for synchronous replication, to also monitor Postmaster death. This infrastructure was committed first. I then proceeded to write patches for each auxiliary process, most recently the Background writer, which was particularly tricky, though accounted for most of the wake-ups when idle among auxiliary processes - usually 5 per second.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;Some considerable progress has been made. Additional variability has been added to the number of wake-ups per second, but if you monitor the wake-ups per second using powertop at a sufficiently high granularity, it stabilises at:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;3.8% ( 35.0) &amp;nbsp;&amp;nbsp;SignalSender&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;3.0% ( 27.2) &amp;nbsp;&amp;nbsp;[kernel scheduler] Load balancing tick&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;2.8% ( 25.6) &amp;nbsp;&amp;nbsp;kworker/0:0&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;0.8% ( &amp;nbsp;7.6) &amp;nbsp;&amp;nbsp;postgres&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;0.6% ( &amp;nbsp;5.7) &amp;nbsp;&amp;nbsp;[TLB shootdowns] &amp;lt;kernel IPI&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &amp;nbsp;&amp;nbsp;0.6% ( &amp;nbsp;5.6) &amp;nbsp;&amp;nbsp;[kernel core] hrtimer_start (tick_sched_ti&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;To give you some notion of how this relates to CPU states, this is an account of the time my laptop’s CPU spends in each of the states at one moment in time, according to powertop:&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Cn &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Avg residency &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;P-states (frequencies)&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C0 (cpu running) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;( 1.5%) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Turbo Mode &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3.0%&lt;/span&gt;&lt;br /&gt;&lt;span&gt;polling &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.0ms ( 0.0%) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2.00 Ghz &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.1%&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C1 mwait &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.0ms ( 1.3%) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.80 Ghz &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.1%&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C2 mwait &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.5ms ( 1.8%) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1200 Mhz &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.2%&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C3 mwait &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.4ms ( 0.4%) &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;800 Mhz &amp;nbsp;&amp;nbsp;&amp;nbsp;96.7%&lt;/span&gt;&lt;br /&gt;&lt;span&gt;C4 mwait &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7.9ms (95.0%)&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;br /&gt;&lt;b&gt;&lt;span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span&gt;There is still some more work to do though. Simon Riggs and I submitted a patch to add group commit to PostgreSQL, which is being reviewed in the ongoing commitfest. This feature is anticipated to be very valuable to workloads that are bound by their commit rate, and a number of benchmarks that have been performed are very promising. That patch included support for allowing the WAL Writer to sleep. However, the exact details of group commit’s implementation have yet to be agreed upon, and it is not yet completely clear how effectively we will be able to reduce the WAL writer's idle wake-ups. However, I am hopeful that we will be able to eliminate them entirely, bringing the total number down to 2.6 per second for an idle Postgres 9.2 installation with standard settings. The WAL writer, much like the background writer, accounts for a relatively large 5 wake-ups per second (assuming default settings), and is similarly a bit tricky to adjust in this way.&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;I’d previously measured the idle wake-ups per second for my distro’s mysqld at 2.2 (mysql-server version 5.1.56, Fedora 14), though when I check now, with mysql-server 5.5.19 on Fedora 16, that’s way up at consistently over 20 wake-ups per second. I’m not sure why that might be, but I welcome input as to what a fair, objective comparison would look like. I have made every effort to be fair here, and I'd speculate that this may have something to do with the storage engine in use in each case.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/7609611625311126307-1854108391899089194?l=pgeoghegan.blogspot.com" alt="" /&gt;&lt;/div&gt;</description><guid isPermaLink="true">tag:blogger.com,1999:blog-7609611625311126307.post-1854108391899089194</guid><pubDate>Sun, 29 Jan 2012 00:10:15 GMT</pubDate></item><item><title>Andrew Dunstan: Microsoft C extension building</title><link>http://people.planetpostgresql.org/andrew/index.php?/archives/254-Microsoft-C-extension-building.html</link><description>Someone asked on IRC how to build an external module using Microsoft C. I have done a lot of building core Postgres with various versions of Microsoft C, and written or committed substantial parts of the build system we use for it, but sadly I don't know the answer, and couldn't find one anywhere in our docs or on the wiki. Maybe there isn't a simple answer. If so, it's long since time we should remedy that. Unix people tend to look down on Windows, but in fact some of the largest deployments of Postgres anywhere are on Windows. It should not be beyond our wits to support this better.</description><guid isPermaLink="false">http://people.planetpostgresql.org/andrew/index.php?/archives/254-guid.html</guid><pubDate>Sat, 28 Jan 2012 14:18:57 GMT</pubDate></item></channel></rss>
