<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Advogato blog for cbbrowne</title>
    <link>http://www.advogato.org/person/cbbrowne/</link>
    <description>Advogato blog for cbbrowne</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Fri, 10 Feb 2012 18:53:45 GMT</pubDate>
    <item>
      <pubDate>Tue, 11 Oct 2011 20:08:14 GMT</pubDate>
      <title>Subversion &#x201C;deprecation&#x201D;</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=27</link>
      <guid>http://linuxdatabases.info/blog/?p=111</guid>
      <description>&lt;p&gt;I was a bit tickled by the characterization I saw today in the new &lt;a href="http://subversion.apache.org/docs/release-notes/1.7.html" &gt;Subversion&lt;/a&gt; release, describing the deprecation of version 1.5: &lt;/p&gt;
&lt;pre&gt;The Subversion 1.5.x line is no longer supported. This doesn't mean
that your 1.5 installation is doomed; if it works well and is all you
need, that's fine. "No longer supported" just means we've stopped
accepting bug reports against 1.5.x versions, and will not make any
more 1.5.x bugfix releases.
&lt;/pre&gt;
&lt;p&gt; They aren&#x2019;t telling us &lt;i&gt;the world will end&lt;/i&gt; for anyone using version 1.5, just that &lt;i&gt;they don&#x2019;t intend to provide support anymore.&lt;/i&gt; &lt;/p&gt;
&lt;p&gt; Which seems like a fine thing.  Version 1.5 is 3 years old, and, when they seem to be releasing about a version per year (1.0 in 2004, 1.7 in 2011), 3 years of backwards support doesn&#x2019;t seem dramatically insufficient.  Particularly if, when support goes away, you&#x2019;re not inherently &lt;i&gt;doomed&lt;/i&gt;! &lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 12 Sep 2011 18:06:24 GMT</pubDate>
      <title>PostgreSQL 9.1 now available</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=26</link>
      <guid>http://linuxdatabases.info/blog/?p=108</guid>
      <description>&lt;p&gt;Making for some reasonably &lt;i&gt;good&lt;/i&gt; news on 9/11, the next version of PostgreSQL, version 9.1, &lt;a href="http://www.postgresql.org/about/news.1349" &gt;has been released.&lt;/a&gt; &lt;/p&gt;
&lt;p&gt; Major enhancements include: &lt;/p&gt;
&lt;dl&gt;&lt;dt&gt;Synchronous replication&lt;/dt&gt;
&lt;dd&gt;continuing the enhancements to built-in WAL-based replication &lt;/dd&gt;
&lt;dt&gt;Per-column collations&lt;/dt&gt;
&lt;dd&gt;to support linguistically-correct sorting down to the column level &lt;/dd&gt;
&lt;dt&gt;Unlogged tables&lt;/dt&gt;
&lt;dd&gt;improving performance for the handling of ephemeral data (&lt;i&gt;e.g.&lt;/i&gt; &#x2013; such as caches) &lt;/dd&gt;
&lt;dt&gt;K-Nearest-Neighbor Indexing&lt;/dt&gt;
&lt;dd&gt;indexing on distances for geographical and text-search queries &lt;/dd&gt;
&lt;dt&gt;Serialized Snapshot Isolation&lt;/dt&gt;
&lt;dd&gt;implementing &#x201C;true serializability&#x201D; &lt;/dd&gt;
&lt;dt&gt;Writable Common Table Expressions&lt;/dt&gt;
&lt;dd&gt;recursive and similar queries can now update data &lt;/dd&gt;
&lt;dt&gt;Security Enhanced Postgres&lt;/dt&gt;
&lt;dd&gt;Similar to SE-Linux, providing       Mandatory Access Controls for higher grade security &lt;/dd&gt;
&lt;dt&gt;Foreign Data Wrappers&lt;/dt&gt;
&lt;dd&gt;attach to other databases and data sources &lt;/dd&gt;
&lt;dt&gt;Extensions&lt;/dt&gt;
&lt;dd&gt;managing deployment of additional database features &lt;/dd&gt;
&lt;/dl&gt;&lt;p&gt; Many of these continue the trend of &lt;i&gt;continuing to enhance&lt;/i&gt; features added in earlier versions (&lt;i&gt;e.g.&lt;/i&gt; &#x2013; synchronous replication, KNN, Writable CTEs) &lt;/p&gt;
&lt;p&gt; Some introduce new kinds of functionality (&lt;i&gt;e.g.&lt;/i&gt; &#x2013; SE-Postgres, FDW, Extensions), where new seeds are sown, that we may expect to flower into further new features in future versions. &lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Wed, 15 Jun 2011 22:08:35 GMT</pubDate>
      <title>Music Playing</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=25</link>
      <guid>http://linuxdatabases.info/blog/?p=107</guid>
      <description>&lt;p&gt;My latest &#x201C;musical experiment&#x201D; is with &lt;a href="http://www.clementine-player.org/" &gt;Clementine&lt;/a&gt;, which was recently added to Debian. &lt;/p&gt;
&lt;p&gt; I should note things that I have used in the past, and some areas of past pain: &lt;/p&gt;
&lt;dl&gt;&lt;dt&gt;XMMS&lt;/dt&gt;
&lt;dd&gt;Which has often been nice enough, but which has grown long in the tooth. &lt;/dd&gt;
&lt;dt&gt;XMMS2&lt;/dt&gt;
&lt;dd&gt;Which takes the desirable step of being a client/server            system which admits the availability of a bunch of            backends.  I have, when using it, tended to prefer the            shell backend. &lt;/dd&gt;
&lt;dt&gt;Amarok&lt;/dt&gt;
&lt;dd&gt;An &#x201C;all singing, all dancing&#x201D; option&#x2026;
&lt;ul&gt;&lt;li&gt;It uses KDE, which I&#x2019;m historically not terribly keen on &lt;/li&gt;
&lt;li&gt;It has libraries that are evidently clever enough to pull music off my iPod Touch as long as it&#x2019;s plugged into a USB dock &lt;/li&gt;
&lt;li&gt;It has the &#x201C;KDE integration&#x201D; that seems to want to have widgets     integrating into some &#x201C;KDE-compliant&#x201D; window manager.  I&#x2019;m running     &lt;a href="http://www.nongnu.org/stumpwm/StumpWM" &gt;StumpWM&lt;/a&gt;, which is decidedly not a &lt;i&gt;KDE thing&lt;/i&gt;, so controlling     Amarok always seems like a bit of a crapshoot&#x2026; &lt;/li&gt;
&lt;li&gt;I have played a bit with the &#x201C;playlist&#x201D; functionality; it hasn&#x2019;t     yet agreed with me&#x2026; &lt;/li&gt;
&lt;/ul&gt;&lt;/dd&gt;
&lt;/dl&gt;&lt;p&gt; At any rate, I saw Clementine listed as &#x201C;new in Debian,&#x201D; so thought I&#x2019;d take a peek.  I&#x2019;m liking what I see thus far: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Onscreen widgets for all the sorts of things that need to be   controlled, including
&lt;ul&gt;&lt;li&gt;Managing music library, so as to add things &lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Like Amarok, it can see my iPod whenever it&#x2019;s plugged in, and can   play that music through the computer &lt;/li&gt;
&lt;li&gt;It easily grabbed album covers (I&#x2019;m not sure what service it&#x2019;s using) for most of my music &lt;/li&gt;
&lt;li&gt;Onscreen controls seem pretty reasonable, though I kind of wish the   volume control was larger, as that&#x2019;s something one wants most   frequently to fiddle with. &lt;/li&gt;
&lt;li&gt;There&#x2019;s a cool visualization widget (think &#x201C;equalizer&#x201D;) &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt; Seems pretty likable thus far&#x2026; &lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>What&#x2019;s Up Lately With Slony?</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=24</link>
      <guid>http://linuxdatabases.info/blog/?p=102</guid>
      <description>&lt;div id="outline-container-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;What&amp;#8217;s up Lately? &lt;span class="timestamp-wrapper"&gt; &lt;span class="timestamp"&gt;2011-04-12 Tue&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;div id="text-1" class="outline-text-2"&gt;&lt;/div&gt;
&lt;div id="outline-container-1_1" class="outline-3"&gt;
&lt;h3 id="sec-1_1"&gt;Git Changeover&lt;/h3&gt;
&lt;div id="text-1_1" class="outline-text-3"&gt;
&lt;p&gt;In July 2010, we switched over to use Git, which has been working out quite fine so far. The official repository is at &lt;a href="http://git.postgresql.org/gitweb?p=slony1-engine.git" &gt;git.postgresql.org&lt;/a&gt;; note that some developers are publishing their repositories publicly at GitHub:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; &lt;a href="https://github.com/cbbrowne/slony1-engine" &gt;Christopher Browne&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/ssinger/slony1-engine" &gt;Steve Singer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://github.com/wieck/slony1-engine" &gt;Jan Wieck&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find details at those &amp;#8220;private&amp;#8221; repositories of branches that the developers have opened to work on various bug fixes and features.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-1_2" class="outline-3"&gt;
&lt;h3 id="sec-1_2"&gt;The next big version&lt;/h3&gt;
&lt;div id="text-1_2" class="outline-text-3"&gt;
&lt;p&gt;We have been working on what seems most likely to be called the &amp;#8220;2.1 release.&amp;#8221;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; There are quite a lot of fixes and enhancements already in place. We have been quite faithful about integrating release notes in as changes are made, so &lt;a href="http://git.postgresql.org/gitweb?p=slony1-engine.git;a=blob_plain;f=RELEASE;hb=refs/heads/master" &gt;Master RELEASE notes&lt;/a&gt; should be quite accurate in representing what has changed.  Some highlights include:
&lt;ul&gt;
&lt;li&gt; Changes to queries against &lt;code&gt;sl_log_*&lt;/code&gt; tables improve performance when undergoing large backlog&lt;/li&gt;
&lt;li&gt; Slonik now supports commands to bulk-add tables and sequences&lt;/li&gt;
&lt;li&gt; Integration of &lt;a href="https://github.com/clustertest/clustertest-framework" &gt;clustertest framework&lt;/a&gt; that does rather more sophisticated tests, obsolescing previous &amp;#8220;ducttape&amp;#8221; and shell script tests.&lt;/li&gt;
&lt;li&gt; Cleanup of a bunch of things
&lt;ul&gt;
&lt;li&gt; Use named parameters in all functions.&lt;/li&gt;
&lt;li&gt; Dropped SNMP support that doesn&amp;#8217;t seem to run anymore, and which was never part of any regression tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; It is unlikely that it will get dubbed &amp;#8220;version 3,&amp;#8221; as there aren&amp;#8217;t the sorts of deep changes that would warrant such.
&lt;ul&gt;
&lt;li&gt; The database schema has not materially changed in any way that would warrant re-initializing clusters, as was the case between version 1.2 and 2.0.&lt;/li&gt;
&lt;li&gt; The changes generally aren&amp;#8217;t really huge, with the exceptions of a couple features that aren&amp;#8217;t quite ready yet (which deserves its own separate discussion)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="outline-container-1_2_1" class="outline-4"&gt;
&lt;h4 id="sec-1_2_1"&gt;Still Outstanding&lt;/h4&gt;
&lt;div id="text-1_2_1" class="outline-text-4"&gt;
&lt;p&gt;There are two features being worked on, which we hoped would be ready around the time of PGCon 2011:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Implicit WAIT FOR EVENT&lt;/dt&gt;
&lt;dd&gt; This feature causes most Slonik commands to wait for whatever event responses should be received before they may be considered properly finished. For instance &lt;code&gt;SUBSCRIBE SET&lt;/code&gt; would wait until the subscription has been completed before proceeding. &lt;/dd&gt;
&lt;dt&gt;Multinode FAIL OVER&lt;/dt&gt;
&lt;dd&gt; For clusters where there are multiple origins for different sets, this allows reshaping the entire cluster properly, which has historically been rather more troublesome than people usually were able to recognize. &lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Unfortunately, neither of these are &lt;em&gt;quite&lt;/em&gt; ready yet.  It is conceivable that the automatic waiting may be &lt;em&gt;mostly&lt;/em&gt; ready, but complications and interruptions have gotten in the way of completion of multinode failover.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-1_3" class="outline-3"&gt;
&lt;h3 id="sec-1_3"&gt;When will 2.1 be ready?&lt;/h3&gt;
&lt;div id="text-1_3" class="outline-text-3"&gt;
&lt;p&gt;Three possibilities seem to present themselves:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Release what we&amp;#8217;ve got as 2.1, let the outstanding items arrive in a future version.Unfortunately, this would seem to dictate that we support a &amp;#8220;version 2.1&amp;#8243; for an extended period of time, complete with the trouble and effort of backpatching.  It&amp;#8217;s not very attractive.&lt;/li&gt;
&lt;li&gt; Draw in &lt;code&gt;Implicit WAIT FOR EVENT&lt;/code&gt;, which would make for a substantially more featureful 2.1, and let &lt;code&gt;multinode FAIL       OVER&lt;/code&gt; come along later.We had been &lt;em&gt;hoping&lt;/em&gt; that there would be common functionality between these two features, so had imagined it a bad idea to do one without the other.  But perhaps that&amp;#8217;s wrong, and &lt;code&gt;Implicit WAIT FOR EVENT&lt;/code&gt; doesn&amp;#8217;t &lt;em&gt;need&lt;/em&gt; multinode failover to be meaningful.  That does seem like it may be true.
&lt;p&gt;There is still the same issue as with 1. above, that this would mean having an extra version of Slony to support, which isn&amp;#8217;t something anyone is too keen on.&lt;/li&gt;
&lt;li&gt; Wait until it&amp;#8217;s all ready.This gets rid of the version proliferation problem, but means that it&amp;#8217;s going to be a while (several months, perhaps quite a few) before users may benefit from &lt;em&gt;any&lt;/em&gt; of these enhancements.
&lt;p&gt;Development of the failover facility seems like it will be bottlenecked for a while on Jan, so this suggests that it may be timely to solicit features that Steve and I might work on concurrently in the interim.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-1_4" class="outline-3"&gt;
&lt;h3 id="sec-1_4"&gt;So, what might still go into 2.1?&lt;/h3&gt;
&lt;div id="text-1_4" class="outline-text-3"&gt;
&lt;ul&gt;
&lt;li&gt; We periodically get bug reports from people about this and that, and minor things will certainly get drawn in, particularly if they represent incorrect behaviour.&lt;/li&gt;
&lt;li&gt; &lt;a href="http://www.slony.info/bugzilla/show_bug.cgi?id=173" &gt;ABORT script&lt;/a&gt;I plan to send a note out soon describing my thoughts thus far.&lt;/li&gt;
&lt;li&gt; &lt;a href="http://www.slony.info/bugzilla/show_bug.cgi?id=176" &gt;Cluster Analysis Tooling&lt;/a&gt;I think it would be pretty neat to connect to a Slony cluster, pull out some data, and generate some web pages and GraphViz diagrams to characterize the status and health of the cluster.&lt;/li&gt;
&lt;li&gt; There was evidently discussion at PGEast about trying to get the &lt;a href="http://git.postgresql.org/gitweb?p=slony1-engine.git;a=tree;f=tools/altperl;h=2625f405fb36319c8db4b05df66ca626f911dbc6;hb=HEAD" &gt;altperl scripts&lt;/a&gt; improved/cleaned up.My personal opinion (cbbrowne) is that they&amp;#8217;re not quite general enough, and that making them so would be more trouble than it&amp;#8217;s worth, so my &amp;#8220;vote&amp;#8221; would be to deprecate them.
&lt;p&gt;But that is certainly not the only opinion out there &amp;#8211; there are apparently others that regularly use them.&lt;/p&gt;
&lt;p&gt;While I&amp;#8217;m not keen on putting effort into them, if there is some consensus on what to do, I&amp;#8217;d go along with it.  That might include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Adding scripts to address slonik features that have not thus far been included in &lt;code&gt;altperl&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Integrating tests into the set of tests run using the clustertest framework, so that we have some verification that this stuff works properly.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Insert Your Pet Feature Here?&lt;/em&gt;Maybe there&amp;#8217;s some low hanging fruit that we&amp;#8217;re not aware of that&amp;#8217;s worth poking at.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>Fast COUNT(*) in PostgreSQL</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=23</link>
      <guid>http://linuxdatabases.info/blog/?p=99</guid>
      <description>&lt;p&gt;One of the &lt;a href="http://wiki.postgresql.org/wiki/FAQ#Why_is_.22SELECT_count.28.2A.29_FROM_bigtable.3B.22_slow.3F" &gt;frequently-asked questions&lt;/a&gt; about PostgreSQL is &amp;#8220;why is SELECT COUNT(*) FROM some_table doing a slow sequential scan?&amp;#8221;&lt;/p&gt;
&lt;p&gt;This has been asked repeatedly on mailing lists everywhere, and the common answer in the FAQ provides a fine explanation which I shall not repeat.  There is some elaboration on &lt;a href="http://wiki.postgresql.org/wiki/Slow_Counting" &gt;slow counting&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Regrettably, the proposed alternative solutions aren&amp;#8217;t always quite so fine.  The one that is most typically pointed out is this one, &lt;a href="http://www.varlena.com/GeneralBits/49.php" &gt;Tracking the row count&lt;/a&gt;&lt;/p&gt;
&lt;div id="outline-container-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;How Tracking the row count works&lt;/h2&gt;
&lt;div id="text-1" class="outline-text-2"&gt;
&lt;p&gt;The idea is fine, at least at first blush:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set up a table that captures row counts&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="src src-SQL"&gt;CREATE TABLE rowcounts (
  table_name text not null primary key,
  total_rows bigint);&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Initialize row counts for the desired tables&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="src src-SQL"&gt;DELETE FROM rowcounts WHERE table_name = 'my_table';
INSERT INTO ROWCOUNTS (table_name, total_rows) SELECT 'my_table', count(*) from my_table;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Establish trigger function on my_table which has the following logic&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="src src-SQL"&gt;if tg_op = 'INSERT' then
   update rowcounts set total_rows = total_rows + 1
     where table_name = 'my_table';
elsif tg_op = 'DELETE' then
   update rowcounts set total_rows = total_rows - 1
     where table_name = 'my_table';
end if;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;If you want to know the size of my_table, then query&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="src src-SQL"&gt;SELECT total_rows FROM rowcounts WHERE table_name = 'my_table';&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;The problem with this approach&lt;/h2&gt;
&lt;div id="text-2" class="outline-text-2"&gt;
&lt;p&gt;On the face of it, it looks fine, but regrettably, it doesn&amp;#8217;t work out happily under conditions of concurrency.  If there are multiple connections trying to INSERT or DELETE on &lt;code&gt;my_table&lt;/code&gt;, concurrently, then all require an exclusive lock on the tuple in &lt;code&gt;rowcounts&lt;/code&gt; for &lt;code&gt;my_table&lt;/code&gt;, and there is a risk (heading towards unity) of:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt; Deadlock, if different connections access data in incompatible orderings&lt;/li&gt;
&lt;li&gt; Lock contention, leading to delays&lt;/li&gt;
&lt;li&gt; If some of the connections are running in SERIALIZABLE mode, rollbacks due to inability to serialize this update&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, there is risk of delay, or, rather worse, that this counting process causes otherwise perfectly legitimate transactions to &lt;em&gt;fail&lt;/em&gt;.  Eek!&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3" class="outline-2"&gt;
&lt;h2 id="sec-3"&gt;A non-locking solution&lt;/h2&gt;
&lt;div id="text-3" class="outline-text-2"&gt;
&lt;p&gt;I suggest a different approach, which eliminates the locking problem, in that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; The triggers are set up to only ever INSERT into the &lt;code&gt;rowcounts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt; An asynchronous process does summarization, to shorten &lt;code&gt;rowcounts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt; I&amp;#8217;d be inclined to use a stored function to query &lt;code&gt;rowcounts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_1" class="outline-3"&gt;
&lt;h3 id="sec-3_1"&gt;Table definition&lt;/h3&gt;
&lt;div id="text-3_1" class="outline-text-3"&gt;
&lt;pre class="src src-SQL"&gt;CREATE TABLE rowcounts (
    table_name text not null,
    total_rows bigint,
    id serial primary key);
create index rc_by_table on rowcounts(table_name);&lt;/pre&gt;
&lt;p&gt;I add the &lt;code&gt;id&lt;/code&gt; column for the sake of &lt;em&gt;nit-picking normalization&lt;/em&gt;, so that anyone that demands a primary key gets what they demand. I&amp;#8217;d not be hugely uncomfortable with leaving it off.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_2" class="outline-3"&gt;
&lt;h3 id="sec-3_2"&gt;Trigger strategy&lt;/h3&gt;
&lt;div id="text-3_2" class="outline-text-3"&gt;
&lt;p&gt;The triggers have the following form:&lt;/p&gt;
&lt;pre class="src src-SQL"&gt;if tg_op = 'INSERT' then
   insert into rowcounts(table_name,total_rows) values ('my_table',1);
elsif tg_op = 'DELETE' then
   insert into rowcounts(table_name,total_rows) values ('my_table',-1);
end if;&lt;/pre&gt;
&lt;p&gt;Note that since the triggers only ever INSERT into rowcounts, they no longer interact with one another in a way that would lead to locks or deadlocks.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_3" class="outline-3"&gt;
&lt;h3 id="sec-3_3"&gt;Function to return row count&lt;/h3&gt;
&lt;div id="text-3_3" class="outline-text-3"&gt;
&lt;pre class="src src-SQL"&gt;create or replace function row_count(i_table text) returns integer as $$
begin
   return sum(total_rows) from rowcounts where table_name = i_table;
end
$ language plpgsql;&lt;/pre&gt;
&lt;p&gt;It would be tempting to have this function itself do a &amp;#8220;shortening&amp;#8221; of the table, but, that would reintroduce into the application the locking that we were wanting to avoid.  So &lt;code&gt;DELETE/UPDATE&lt;/code&gt; are still deferred.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_4" class="outline-3"&gt;
&lt;h3 id="sec-3_4"&gt;Function to clean up row counts table&lt;/h3&gt;
&lt;div id="text-3_4" class="outline-text-3"&gt;
&lt;p&gt;This function needs to be run once in a while to summarize the table contents.&lt;/p&gt;
&lt;pre class="src src-SQL"&gt;create or replace function rowcount_cleanse() returns integer as $$
define
   prec record;
begin
   for prec in select table_name, sum(total_rows) as sum, count(*) as count from rowcounts group by table_name loop
       if count &amp;gt; 1 then
          delete from rowcounts where table_name = prec.table_name;
          insert into rowcounts (table_name, total_rows) values (prec.table_name, prec.total_rows);
       end if;
   end loop;
   return 0;
end
$ language plpgsql;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_5" class="outline-3"&gt;
&lt;h3 id="sec-3_5"&gt;Initializing rowcounts for a table that is already populated&lt;/h3&gt;
&lt;div id="text-3_5" class="outline-text-3"&gt;
&lt;p&gt;Nothing has yet been mentioned that would cause an initial entry to go into rowcounts for an already-populated table.&lt;/p&gt;
&lt;pre class="src src-SQL"&gt;create or replace function rowcount_new_table(i_table text) returns integer as $$
declare
   query text;
begin
   delete from rowcounts where table_name = i_table;
   query := 'insert into rowcounts(table_name, total_rows) select ''|| i_table ||'', count(*) from ' || i_table || ';';
   execute query;
   return total_rows from rowcounts where table_name = i_table;
end
$ language plpgsql;&lt;/pre&gt;
&lt;p&gt;If a table has already got data in it, then it&amp;#8217;s necessary to populate &lt;code&gt;rowcounts&lt;/code&gt; with an initial count.  Implementing such a function is straightforward, and is left as an exercise to the reader.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3_6" class="outline-3"&gt;
&lt;h3 id="sec-3_6"&gt;Further enhancements possible&lt;/h3&gt;
&lt;div id="text-3_6" class="outline-text-3"&gt;
&lt;p&gt;It is possible to shift some of the maintenance back into the &lt;code&gt;row_count()&lt;/code&gt; function, if we do some exception handling.&lt;/p&gt;
&lt;pre class="src src-SQL"&gt;create or replace function row_count(i_table text) returns integer as $$
declare
   prec record;
begin
   begin
      lock table rowcounts nowait;
      select sum(total_rows) as sum, count(*) as count from rowcounts where table_name = i_table;
      if count &amp;gt; 1 then
          delete from rowcounts where table_name = i_table;
          insert into rowcounts (table_name, total_rows) values (prec.table_name, prec.total_rows);
      end if;
      return prec.total_rows;
   exception
      return sum(total_rows) from rowcounts where table_name = i_table;
   end;
end
$ language plpgsql;&lt;/pre&gt;
&lt;p&gt;This is more than a little risky, as, if this function wins the lock, it will block other processes that wish to access row counts until it&amp;#8217;s done, this likely isn&amp;#8217;t a worthwhile exercise.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>Please Send A Patch</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=22</link>
      <guid>http://linuxdatabases.info/blog/?p=97</guid>
      <description>&lt;p&gt;Recent Debian blog entries with this title (by &lt;a href="http://www.lucas-nussbaum.net/blog/?p=630" &gt;Lucas Nussbaum&lt;/a&gt;, &lt;a href="http://hezmatt.org/~mpalmer/blog/general/please_send_a_patch.html" &gt;Matt Palmer&lt;/a&gt;) point out assortedly that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; Existing developers frequently know the code base so much better than newcomers that they&amp;#8217;re likely way more effective at improving things than some callow newcomer.&lt;/li&gt;
&lt;li&gt; Taking those developers&amp;#8217; time to do your pet thing instead of something they find useful mayn&amp;#8217;t be more effective.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both points are quite valid, and recent  &lt;a href="https://commitfest.postgresql.org/action/commitfest_view?id=9" &gt;PostgreSQL CommitFest&lt;/a&gt; activity suggests a way to at least &lt;i&gt;try&lt;/i&gt; to evaluate things.&lt;/p&gt;
&lt;p&gt;The PostgreSQL project has a number of committers that are unusually productive developers (&lt;i&gt;-1 from me, Tom?&lt;/i&gt; &lt;img src='http://linuxdatabases.info/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /&gt; ), and there have certainly been times when the &amp;#8220;best&amp;#8221; outcome has been for someone to come in suggesting ideas, and for one of the notably productive folk to implement it.&lt;/p&gt;
&lt;p&gt;But there has been some debate surrounding the 2011-01 CommitFest, which consists of some 98 proposed patches, all of which require review.  These are all, in fact, patches that came as some sort of response to &lt;b&gt;Please send a patch&lt;/b&gt; &lt;img src='http://linuxdatabases.info/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /&gt; .  The trouble with this particular CommitFest is that the patches have been overwhelming the reviewers in terms of sheer volume.  Developers that should be considering working on their own &amp;#8220;pet features&amp;#8221; have been drawn into the review process to look at others&amp;#8217; features instead.  None of these results are inherently a bad thing, except for the aggregate that falls out, which is that there&amp;#8217;s so much stuff outstanding that it&amp;#8217;s tough to get them all properly reviewed.&lt;/p&gt;
&lt;p&gt;If a project is busy and vital, it&amp;#8217;s pretty necessary for people to do a fair bit of &amp;#8220;scratching their own itches&amp;#8221; (in keeping with Matt Palmer&amp;#8217;s comment) in order to grow the community of people capable of giving real assistance to managing the code base.&lt;/p&gt;
&lt;p&gt;&amp;#8220;Growing community&amp;#8221; requires that some people struggle with the code base a bit so that they become familiar enough to become effective in the future.&lt;/p&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>NoSQL&#x2019;s next step &#x2013; stored procedures</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=21</link>
      <guid>http://linuxdatabases.info/blog/?p=93</guid>
      <description>&lt;p&gt;The latest discovery is that the &amp;#8220;bad old stored procedures&amp;#8221; of SQL&#x2026;  Are what NoSQL needs&#x2026; &lt;a href="http://highscalability.com/blog/2010/11/1/hot-trend-move-behavior-to-data-for-a-new-interactive-applic.html" &gt;http://highscalability.com/blog/2010/11/1/hot-trend-move-behavior-to-data-for-a-new-interactive-applic.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re calling them &lt;code&gt;coprocessors&lt;/code&gt; or &lt;code&gt;plugins&lt;/code&gt;, and it&amp;#8217;s truly not terribly surprising.  The High Scalability article makes a Battlestar Galactica joke, of &lt;a href="http://en.wikipedia.org/wiki/Eternal_return" &gt;http://en.wikipedia.org/wiki/Eternal\_return&lt;/a&gt;.  The BSG line that kept coming back over and over was: &lt;strong&gt;All this has happened before, and all this will happen again.&lt;/strong&gt; There&amp;#8217;s a rather depressing possibility that people will consider coprocessors to be the &lt;em&gt;greatest thing ever&lt;/em&gt;, not realizing that a substantial chunk of the same issues true (for better and worse) for SQL stored procedures will also hold true for &lt;code&gt;coprocessors&lt;/code&gt; and they may learn (or &lt;em&gt;fail to learn&lt;/em&gt;!) from scratch.&lt;/p&gt;
&lt;p&gt;The notion is that you colocate, along with your database, some kind of &amp;#8220;coprocessor engine&amp;#8221; that can run code locally, which solves a number of problems, some not new, but some somewhat unique to key/value stores:&lt;/p&gt;
&lt;div id="outline-container-1" class="outline-2"&gt;
&lt;h2 id="sec-1"&gt;Connectivity&lt;/h2&gt;
&lt;div id="text-1" class="outline-text-2"&gt;
&lt;p&gt;You&amp;#8217;re running your application in &lt;em&gt;the cloud&lt;/em&gt; and have somewhat spotty connectivity between the place where your application logic runs and the database where the data is stored.  A &lt;code&gt;coprocessor&lt;/code&gt; brings logic right near the database, resolving this problem.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-2" class="outline-2"&gt;
&lt;h2 id="sec-2"&gt;Bulk data transfer&lt;/h2&gt;
&lt;div id="text-2" class="outline-text-2"&gt;
&lt;p&gt;A difference between SQL and key/value stores is that SQL is quite happy shovelling sets of data back and forth, whereas key/value stores are all about singular key/value pairs.  An SQL request readily &amp;#8220;scales&amp;#8221; by transferring data in bulk, whereas key/value can get bogged down by there being a zillion network round trips.  A &lt;code&gt;coprocessor&lt;/code&gt; can keep a bunch of those &amp;#8220;round trips&amp;#8221; &lt;em&gt;inside&lt;/em&gt; the database layer, which will be a big win.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-3" class="outline-2"&gt;
&lt;h2 id="sec-3"&gt;Goodbye, foreign keys, hello, um, ???&lt;/h2&gt;
&lt;div id="text-3" class="outline-text-2"&gt;
&lt;p&gt;You may be able to shove some combination of logic maintenance and such into the &lt;code&gt;coprocessor&lt;/code&gt; area, thereby gaining back some of the things lost when NoSQL eschewed SQL &lt;strong&gt;foreign key references&lt;/strong&gt; and &lt;strong&gt;triggers&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-4" class="outline-2"&gt;
&lt;h2 id="sec-4"&gt;Data normalization analysis returns&lt;/h2&gt;
&lt;div id="text-4" class="outline-text-2"&gt;
&lt;p&gt;One of the typical things to do with NoSQL is to &amp;#8220;shard&amp;#8221; the database so each database server only has part of the data, and may operate independently of other database servers.&lt;/p&gt;
&lt;p&gt;Coprocessor use will require that all the data that is to be used is on the local server, otherwise you head back to the problem of shovelling tuples back and forth between DB servers with the &lt;em&gt;zillions of network roundtrips problem&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To guard against that, the data needs to be normalized in such a way that the data relevant to the coprocessors is available locally. (Perhaps not exclusively, but generally so.  A &lt;em&gt;few&lt;/em&gt; round trips may be OK, but not &lt;em&gt;zillions&lt;/em&gt;.)&lt;/p&gt;
&lt;p&gt;It seems to me that people have been excited by NoSQL in part because they could get away from all that &lt;strong&gt;irritating SQL   normalization rules&lt;/strong&gt; stuff.  But this bit implies that this benefit was something of a mirage.  Perhaps the &lt;em&gt;precise&lt;/em&gt; rules of &lt;strong&gt;Boyce-Codd Normal Form&lt;/strong&gt; are no longer crucial, but you&amp;#8217;ll still need to have some kind of calculus to ascertain which divisions work and which don&amp;#8217;t.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-5" class="outline-2"&gt;
&lt;h2 id="sec-5"&gt;Things still not clear about this&#x2026;&lt;/h2&gt;
&lt;div id="outline-container-5_1" class="outline-3"&gt;
&lt;h3 id="sec-5_1"&gt;Managing the &lt;code&gt;coprocessors&lt;/code&gt;&lt;/h3&gt;
&lt;div id="text-5_1" class="outline-text-3"&gt;
&lt;p&gt;One of the challenges faced in SQL systems that use a lot of stored procedures is that of managing these procedures, complete with versioning (because what goes into production on day #1 isn&amp;#8217;t what will be there &lt;em&gt;forever&lt;/em&gt;, right?).&lt;/p&gt;
&lt;p&gt;Windows always used to suffer (may still suffer, for all I know) from &lt;em&gt;dependency hell&lt;/em&gt;, where different applications may need competing versions of libraries.  (Entertainment of the week was seeing that the Haskell folks &lt;a href="http://www.haskell.org/pipermail/haskell-cafe/2010-April/076164.html" &gt;http://www.haskell.org/pipermail/haskell-cafe/2010-April/076164.html&lt;/a&gt; are, of late running into this. &#xA0;Not intended as insult; it&amp;#8217;s a problem that is nontrivial to avoid.)&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s surely needful to have some kind of &lt;strong&gt;coprocessor dictionary&lt;/strong&gt; to keep this sort of thing under some control.  It&amp;#8217;s never been trivial for any system, so there&amp;#8217;s room for:&lt;/p&gt;
&lt;p&gt;* Repeating yesteryear&amp;#8217;s errors&lt;/p&gt;
&lt;p&gt;* Learning from other systems&amp;#8217; mistakes&lt;/p&gt;
&lt;p&gt;* Discovering brand new kinds of mistakes&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-5_2" class="outline-3"&gt;
&lt;h3 id="sec-5_2"&gt;How rich should the &lt;code&gt;coprocessor&lt;/code&gt; environment be?&lt;/h3&gt;
&lt;div id="text-5_2" class="outline-text-3"&gt;
&lt;p&gt;On the powerful side, &lt;a href="http://nodejs.org" &gt;http://nodejs.org&lt;/a&gt; surely is neat, but having the ability to run arbitrary code there is risky&#x2026;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id="outline-container-5_3" class="outline-3"&gt;
&lt;h3 id="sec-5_3"&gt;How auditable will these systems be?&lt;/h3&gt;
&lt;div id="text-5_3" class="outline-text-3"&gt;
&lt;p&gt;On the positive side, it&amp;#8217;s presumably plausible to add &lt;code&gt;auditing    coprocessors&lt;/code&gt; to capture interesting information for regulatory purposes.&lt;/p&gt;
&lt;p&gt;On the other hand, &lt;em&gt;arbitrarily powerful&lt;/em&gt; things like &lt;code&gt;node.js&lt;/code&gt; might make it arbitrarily easy to evade regulation.&lt;/p&gt;
&lt;p&gt;There aren&amp;#8217;t necessarily easy answers to that.&lt;/p&gt;
&lt;p&gt;Aside: org2blog mode is pretty nifty&amp;#8230; &#xA0;Made it pretty easy to build this without much tagging effort&amp;#8230;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>Trying Out org2blog</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=20</link>
      <guid>http://linuxdatabases.info/blog/?p=89</guid>
      <description>&lt;p&gt;Hmm.  Let&amp;#8217;s see how &lt;a href="https://github.com/punchagan/org2blog" &gt;https://github.com/punchagan/org2blog&lt;/a&gt; works. &lt;/p&gt;
&lt;p&gt; It requires xml-rpc.el; el-get knows about that&amp;hellip; Splendid! &lt;/p&gt;
&lt;p&gt; I can login to my blog&amp;hellip;  It takes a very little bit of URL surgery to figure out the apropos URL&amp;hellip; &lt;/p&gt;
&lt;p&gt; I think I overdid the default categories, but that&amp;#8217;s not a huge problem. &lt;/p&gt;
&lt;p&gt; Now, let&amp;#8217;s see if it&amp;#8217;ll publish the entry&amp;hellip; &lt;/p&gt;
&lt;p&gt;&lt;b&gt; Hey, that worked fine!&lt;/b&gt;  Cool, I can publish blog entries without looking for my web browser.  Now, let&amp;#8217;s see if I can get it to stow the password for my website in the encrypted &lt;tt&gt; .authinfo&lt;/tt&gt; file that Emacs likes&amp;#8230;&lt;/p&gt;
&lt;p&gt; Nope, the &lt;tt&gt;.authinfo&lt;/tt&gt; extension is a Gnus thing, so that possibly goes further than we can readily get.  But the author&amp;#8217;s amenable to taking a peek at it &lt;img src='http://linuxdatabases.info/blog/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /&gt; .&lt;/p&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>PostgreSQL 9.0 released!</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=19</link>
      <guid>http://linuxdatabases.info/blog/?p=84</guid>
      <description>&lt;p&gt;A new release of the &lt;b&gt;most advanced open source database&lt;/b&gt; is now available!&lt;/p&gt;
&lt;p&gt;As always, as a new major release, there are great gobs of little features that have been added, most of which, individually, likely don&amp;#8217;t matter to any particular individual.  (For instance, there are a couple dozen enhancements to ECPG, and if you don&amp;#8217;t &lt;i&gt;know&lt;/i&gt; you&amp;#8217;re using that, you almost certainly aren&amp;#8217;t, and so those changes likely don&amp;#8217;t affect you.)&lt;/p&gt;
&lt;p&gt; But there are plenty that are liable to matter, and, indeed, to help improve behaviour of one&amp;#8217;s streams of queries, often without even needing any changes to applications.&lt;/p&gt;
&lt;p&gt; See also the &lt;a href="http://www.postgresql.org/about/news.1235" &gt; official release notice&lt;/a&gt;, for &amp;#8220;markety-speak.&amp;#8221;&lt;/p&gt;
&lt;p&gt; And see &lt;a href="http://www.postgresql.org/docs/9.0/static/release-9-0" &gt; official release notes &lt;/a&gt; (that are part of the documentation tree) for deeper details of all the changes in the new release.&lt;/p&gt;
</description>
    </item>
    <item>
      <pubDate>Mon, 18 Apr 2011 19:17:20 GMT</pubDate>
      <title>Gnus, Dovecot, OfflineIMAP</title>
      <link>http://www.advogato.org/person/cbbrowne/diary.html?start=18</link>
      <guid>http://linuxdatabases.info/blog/?p=82</guid>
      <description>&lt;p&gt;This is a followup, effectively, to Roland Mas&amp;#8217; article &lt;a href="http://roland.entierement.nu/blog/2010/09/08/gnus-dovecot-offlineimap-search-a-howto.html" &gt;Gnus, Dovecot, OfflineIMAP, search: a HOWTO &lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I went thru Roland&amp;#8217;s HOWTO, and have a few comments on variances that I noticed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I first installed OfflineIMAP; this worked pretty much fine as described.  I didn&amp;#8217;t bother adding the extra Python code for propagating Gnus expiry material, as I generally don&amp;#8217;t use it.&lt;/li&gt;
&lt;li&gt;I had a couple problems setting up Dovecot:
&lt;ol&gt;
&lt;li&gt; By default, Dovecot uses &lt;tt&gt;Maildir++&lt;/tt&gt; folder handling, which isn&amp;#8217;t consistent with how OfflineIMAP stores folders.There&amp;#8217;s an additional option needed to cope with this:&lt;br /&gt;
&lt;code&gt; mail_location = maildir:~/Maildir:LAYOUT=fs&lt;/code&gt;&lt;/li&gt;
&lt;li&gt; Perhaps because of the above, I couldn&amp;#8217;t readily get Gnus to talk over a pipe to a Dovecot process.Not a big deal &amp;#8211; I have Gnus speak to Dovecot via talking to the socket, which is the usual thing one would do with Dovecot anyways.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt; It seems to me as though Gnus should be able to talk directly to Maildir.  It does, after all, have a protocol for it (&lt;tt&gt;&lt;a href="http://www.gnu.org/software/emacs/manual/html_node/gnus/Maildir.html" &gt;nnmaildir&lt;/a&gt;&lt;/tt&gt;).I couldn&amp;#8217;t struggle my way thru the Gnus documentation to properly set up a &lt;strong&gt;virtual server&lt;/strong&gt; for &lt;tt&gt;nnmaildir&lt;/tt&gt; to do this.
&lt;p&gt;This would be pretty valuable in that it would eliminate the need for Dovecot altogether.  Perhaps it&amp;#8217;s a documentation problem that nobody seems to know how to do this.&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
  </channel>
</rss>

