<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9023816360631923026</id><updated>2012-03-04T22:43:26.959-06:00</updated><category term='GIS'/><category term='external data'/><category term='data recovery'/><category term='business_intelligence'/><category term='PostgreSQL internals'/><category term='Microsoft'/><category term='javascript'/><category term='admin'/><category term='latex'/><category term='CursoBI_UPIICSA'/><category term='acm programming problems'/><category term='requirements engineering'/><category term='plpython'/><category term='PITR'/><category term='algorithms'/><category term='full text search'/><category term='psql'/><category term='openGL'/><category term='Programming'/><category term='sql tuning'/><category term='software development'/><category term='data visualization'/><category term='pentaho BI'/><category term='repmgr'/><category term='chartbeans'/><category term='python'/><category term='Datawarehousing'/><category term='maintenance'/><category term='Computer Architecture'/><category term='webProgramming'/><category term='Networks'/><category term='supercomputing'/><category term='linux'/><category term='plpgsql'/><category term='MySQL'/><category term='opensuse'/><category term='java'/><category term='security'/><category term='Troubleshooting'/><category term='migration'/><category term='monitoring'/><category term='multiplexing'/><category term='postgis'/><category term='django'/><category term='Cell Processor'/><category term='Spago'/><category term='oracle'/><category term='kettle'/><category term='Life'/><category term='streaming_replication'/><category term='PostgreSQL'/><category term='sql'/><category term='database design'/><category term='general interest'/><category term='PT'/><category term='Tools'/><category term='Databases'/><category term='pgpool'/><category term='replication'/><title type='text'>Sharing Tech Knowledge - 2.0</title><subtitle type='html'>Linux, PostgreSQL, Pentaho BI, Python,Django, Data Visualization and other entertainments that I indulge myself with, when I can't sleep.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default?start-index=101&amp;max-results=100'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>272</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3042897387643104742</id><published>2012-03-04T22:30:00.002-06:00</published><updated>2012-03-04T22:43:26.968-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><title type='text'>Latex.- The powerdot class for presentations</title><content type='html'>I started working with the powerdot document class. I find it extremely easy to use and powerful.&lt;br /&gt;&lt;a href="http://ctan.org/tex-archive/macros/latex/contrib/powerdot"&gt;http://ctan.org/tex-archive/macros/latex/contrib/powerdot&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is my test presentation.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img215.imageshack.us/img215/6136/powerdot.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="401" width="802" src="http://img215.imageshack.us/img215/6136/powerdot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Wich I achieved with the following code&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:js"&gt;\documentclass{powerdot}&lt;br /&gt;\begin{document}&lt;br /&gt;\title{PostgreSQL replication concepts}&lt;br /&gt;\author{Rene Romero Benavides}&lt;br /&gt;\date{March 4,2012}&lt;br /&gt;\begin{slide}{PostgreSQL}&lt;br /&gt;\begin{itemize}&lt;br /&gt;\item Here is the first line on my slide&lt;br /&gt;\pause&lt;br /&gt;\item And now here's the next&lt;br /&gt;\end{itemize}&lt;br /&gt;\end{slide}&lt;br /&gt;\end{document}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;References.&lt;br /&gt;&lt;a href="www.bakoma-tex.com/doc/latex/powerdot/powerdot.pdf"&gt;www.bakoma-tex.com/doc/latex/powerdot/powerdot.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://csgsa.cs.clemson.edu/seminar/tools06/docbook/html/ch02s04.html#id2396476"&gt;http://csgsa.cs.clemson.edu/seminar/tools06/docbook/html/ch02s04.html#id2396476&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.miwie.org/presentations/html/powerdot.html"&gt;http://www.miwie.org/presentations/html/powerdot.html&lt;/a&gt;&lt;br /&gt;&lt;a href="doctorh.umwblogs.org/files/2010/12/courseC.pdf"&gt;doctorh.umwblogs.org/files/2010/12/courseC.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.dmi.me.uk/blog/2010/11/08/creating-a-presentation-with-latex-and-powerdot/"&gt;http://www.dmi.me.uk/blog/2010/11/08/creating-a-presentation-with-latex-and-powerdot/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mmmm...  second guessing, I'll try beamer too.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3042897387643104742?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3042897387643104742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/latex-powerdot-class-for-presentations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3042897387643104742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3042897387643104742'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/latex-powerdot-class-for-presentations.html' title='Latex.- The powerdot class for presentations'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3580434370902993159</id><published>2012-03-02T17:14:00.000-06:00</published><updated>2012-03-02T17:14:11.608-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='sql tuning'/><title type='text'>PostgreSQL - Forcing index scans</title><content type='html'>I'm following a &lt;a href="http://momjian.us/main/presentations/"&gt;presentation&lt;/a&gt; by Bruce Momjiam titled "Explainng the Postgres Query Optimizer", and I found an exercise where you can force the query optimizer to use index scans (RAF not long ago told me about this too). I don't quite understand the value of doing this as if a value is present in a table several times it could be more costly to carry on an index scan versus a sequential scan, but ... you never now&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SET enable_seqscan = false;&lt;br /&gt;SET enable_bitmapscan  = false;&lt;br /&gt;&lt;br /&gt;WITH letter (letter, count) AS ( SELECT letter, count(*) from sample GROUP by 1) SELECT letter AS "1", count,(SELECT * FROM lookup_letter(letter) AS "12" limit 1) AS lookup_letter FROM letter ORDER BY 2 DESC&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So now it uses index scan each time regardless.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;1 | count |                              lookup_letter                               &lt;br /&gt;---+-------+--------------------------------------------------------------------------&lt;br /&gt; p |   199 | Index Scan using i_sample on sample  (cost=0.00..39.05 rows=199 width=2)&lt;br /&gt; s |     9 | Index Scan using i_sample on sample  (cost=0.00..21.91 rows=9 width=2)&lt;br /&gt; c |     8 | Index Scan using i_sample on sample  (cost=0.00..19.64 rows=8 width=2)&lt;br /&gt; r |     7 | Index Scan using i_sample on sample  (cost=0.00..19.63 rows=7 width=2)&lt;br /&gt; t |     5 | Index Scan using i_sample on sample  (cost=0.00..15.09 rows=5 width=2)&lt;br /&gt; d |     4 | Index Scan using i_sample on sample  (cost=0.00..15.07 rows=4 width=2)&lt;br /&gt; v |     4 | Index Scan using i_sample on sample  (cost=0.00..15.07 rows=4 width=2)&lt;br /&gt; f |     4 | Index Scan using i_sample on sample  (cost=0.00..15.07 rows=4 width=2)&lt;br /&gt; _ |     3 | Index Scan using i_sample on sample  (cost=0.00..12.80 rows=3 width=2)&lt;br /&gt; a |     3 | Index Scan using i_sample on sample  (cost=0.00..12.80 rows=3 width=2)&lt;br /&gt; u |     3 | Index Scan using i_sample on sample  (cost=0.00..12.80 rows=3 width=2)&lt;br /&gt; e |     2 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt; i |     1 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt; k |     1 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where in cases of index scanning a value that repeats to a high degree it's related cost is higher too, comparing it to:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;RESET ALL;&lt;br /&gt;WITH letter (letter, count) AS ( SELECT letter, count(*) from sample GROUP by 1) SELECT letter AS "1", count,(SELECT * FROM lookup_letter(letter) AS "12" limit 1) AS lookup_letter FROM letter ORDER BY 2 DESC;&lt;br /&gt;&lt;br /&gt; 1 | count |                             lookup_letter                             &lt;br /&gt;---+-------+-----------------------------------------------------------------------&lt;br /&gt; p |   199 | Seq Scan on sample  (cost=0.00..13.16 rows=199 width=2)&lt;br /&gt; s |     9 | Seq Scan on sample  (cost=0.00..13.16 rows=9 width=2)&lt;br /&gt; c |     8 | Seq Scan on sample  (cost=0.00..13.16 rows=8 width=2)&lt;br /&gt; r |     7 | Seq Scan on sample  (cost=0.00..13.16 rows=7 width=2)&lt;br /&gt; t |     5 | Bitmap Heap Scan on sample  (cost=4.29..12.76 rows=5 width=2)&lt;br /&gt; v |     4 | Bitmap Heap Scan on sample  (cost=4.28..12.74 rows=4 width=2)&lt;br /&gt; f |     4 | Bitmap Heap Scan on sample  (cost=4.28..12.74 rows=4 width=2)&lt;br /&gt; d |     4 | Bitmap Heap Scan on sample  (cost=4.28..12.74 rows=4 width=2)&lt;br /&gt; a |     3 | Bitmap Heap Scan on sample  (cost=4.27..11.38 rows=3 width=2)&lt;br /&gt; u |     3 | Bitmap Heap Scan on sample  (cost=4.27..11.38 rows=3 width=2)&lt;br /&gt; _ |     3 | Bitmap Heap Scan on sample  (cost=4.27..11.38 rows=3 width=2)&lt;br /&gt; e |     2 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt; i |     1 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt; k |     1 | Index Scan using i_sample on sample  (cost=0.00..8.27 rows=1 width=2)&lt;br /&gt;(14 filas)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3580434370902993159?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3580434370902993159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/postgresql-forcing-index-scans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3580434370902993159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3580434370902993159'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/postgresql-forcing-index-scans.html' title='PostgreSQL - Forcing index scans'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7823119935987718566</id><published>2012-03-01T04:00:00.000-06:00</published><updated>2012-03-01T04:10:47.682-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - Common Table Expressions</title><content type='html'>I just stumbled upon this presentation by Bruce Momjian:&lt;br /&gt;&lt;a href="http://momjian.us/main/writings/pgsql/cte.pdf"&gt;http://momjian.us/main/writings/pgsql/cte.pdf&lt;/a&gt;&lt;br /&gt;I had heard of these beauties before but never really used them ... they're astonishing!&lt;br /&gt;&lt;br /&gt;I'm just going to replicate the given examples :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;test=# with source as ( select 1) SELECT * FROM source;&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt;        1&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;test=# WITH source AS ( SELECT 1 as col1) SELECT * FROM source;&lt;br /&gt; col1 &lt;br /&gt;------&lt;br /&gt;    1&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;test=# WITH source (col1) AS ( SELECT 1 ) SELECT * FROM source;&lt;br /&gt; col1 &lt;br /&gt;------&lt;br /&gt;    1&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;test=# WITH source (col2) AS ( SELECT 1 AS col1) SELECT col2 AS col3 FROM source;&lt;br /&gt; col3 &lt;br /&gt;------&lt;br /&gt;    1&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;test=# WITH source AS ( SELECT 1,2 ) SELECT * FROM source;&lt;br /&gt; ?column? | ?column? &lt;br /&gt;----------+----------&lt;br /&gt;        1 |        2&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;-- here it starts to get interesting&lt;br /&gt;&lt;br /&gt;test=# WITH source AS ( SELECT 1,2), source2 AS ( SELECT 3,4) select * from source UNION ALL SELECT * FROM source2;&lt;br /&gt; ?column? | ?column? &lt;br /&gt;----------+----------&lt;br /&gt;        1 |        2&lt;br /&gt;        3 |        4&lt;br /&gt;(2 rows)&lt;br /&gt;&lt;br /&gt;test=# WITH source AS ( select lanname, rolname FROM pg_language JOIN pg_roles ON lanowner = pg_roles.oid ORDER BY lanname) SELECT * FROM source UNION ALL SELECT MIN(lanname), NULL FROM source;&lt;br /&gt;  lanname   | rolname  &lt;br /&gt;------------+----------&lt;br /&gt; c          | postgres&lt;br /&gt; internal   | postgres&lt;br /&gt; plpgsql    | postgres&lt;br /&gt; plpython2u | postgres&lt;br /&gt; plpythonu  | postgres&lt;br /&gt; sql        | postgres&lt;br /&gt; c          | &lt;br /&gt;(7 rows)&lt;br /&gt;&lt;br /&gt;test=# WITH class (oid, relname) AS ( SELECT oid, relname FROM pg_class WHERE relkind = 'r' ) SELECT c.relname, pa.attname FROM pg_attribute pa JOIN  class c ON c.oid = pa.attrelid ORDER BY 1,2 LIMIT 5;&lt;br /&gt;  relname   | attname &lt;br /&gt;------------+---------&lt;br /&gt; child_test | cmax&lt;br /&gt; child_test | cmin&lt;br /&gt; child_test | col1&lt;br /&gt; child_test | col2&lt;br /&gt; child_test | ctid&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--and this is where I give up as I'm extreeeeeemly tired&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;By the way: cmin,cmax, and ctid are system columns:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;cmin&lt;br /&gt;&lt;br /&gt;The command identifier (starting at zero) within the inserting transaction.&lt;br /&gt;cmax&lt;br /&gt;&lt;br /&gt;The command identifier within the deleting transaction, or zero.&lt;br /&gt;ctid&lt;br /&gt;&lt;br /&gt;The physical location of the row version within its table. Note that although the ctid can be used to locate the row version very quickly, a row's ctid will change if it is updated or moved by VACUUM FULL. Therefore ctid is useless as a long-term row identifier. The OID, or even better a user-defined serial number, should be used to identify logical rows.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/current/static/ddl-system-columns.html"&gt;http://www.postgresql.org/docs/current/static/ddl-system-columns.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another set of statements that I find fascinating:&lt;br /&gt;&lt;pre class="brush:sql"&gt;test=# set statement_timeout = '1s';&lt;br /&gt;SET&lt;br /&gt;test=# WITH RECURSIVE source AS ( select 1 UNION ALL SELECT 1 FROM source ) SELECT * FROM source;&lt;br /&gt;ERROR:  canceling statement due to statement timeout&lt;br /&gt;&lt;br /&gt;test=# RESET statement_timeout;&lt;br /&gt;RESET&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And this one is absolutely epic:&lt;br /&gt;&lt;pre class="brush:sql"&gt;test=# WITH RECURSIVE source (counter) AS ( SELECT 1 UNION ALL SELECT counter + 1 FROM source WHERE counter &lt; 10) SELECT * FROM source;&lt;br /&gt; counter &lt;br /&gt;---------&lt;br /&gt;       1&lt;br /&gt;       2&lt;br /&gt;       3&lt;br /&gt;       4&lt;br /&gt;       5&lt;br /&gt;       6&lt;br /&gt;       7&lt;br /&gt;       8&lt;br /&gt;       9&lt;br /&gt;      10&lt;br /&gt;(10 rows)&lt;br /&gt;&lt;br /&gt;test=# WITH RECURSIVE source (counter,product) AS ( SELECT 1,1 UNION ALL SELECT counter +1 , product * (counter +1) FROM source WHERE counter &lt; 10) SELECT counter, product FROM source;&lt;br /&gt; counter | product &lt;br /&gt;---------+---------&lt;br /&gt;       1 |       1&lt;br /&gt;       2 |       2&lt;br /&gt;       3 |       6&lt;br /&gt;       4 |      24&lt;br /&gt;       5 |     120&lt;br /&gt;       6 |     720&lt;br /&gt;       7 |    5040&lt;br /&gt;       8 |   40320&lt;br /&gt;       9 |  362880&lt;br /&gt;      10 | 3628800&lt;br /&gt;(10 rows)&lt;br /&gt;&lt;br /&gt;test=# WITH RECURSIVE source (counter,product) AS ( SELECT 1,1 UNION ALL SELECT counter +1 , product * (counter +1) FROM source WHERE counter &lt; 12) SELECT counter, product FROM source WHERE counter = 12;&lt;br /&gt; counter |  product  &lt;br /&gt;---------+-----------&lt;br /&gt;      12 | 479001600&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7823119935987718566?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7823119935987718566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/postgresql-common-table-expressions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7823119935987718566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7823119935987718566'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/03/postgresql-common-table-expressions.html' title='PostgreSQL - Common Table Expressions'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4156370786958173707</id><published>2012-02-29T00:45:00.002-06:00</published><updated>2012-02-29T00:48:24.508-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Data Visualization . d3.js - Voronoi Tesselation</title><content type='html'>&lt;!DOCTYPE html&gt;&lt;html&gt;&lt;head&gt;&lt;meta http-equiv="Content-Type" content="text/html;charset=utf-8"&gt;&lt;script type="text/javascript" src="http://ec2-50-16-24-169.compute-1.amazonaws.com/d3.v2.js" type='text/javascript'&gt;&lt;/script&gt;&lt;link type="text/css" rel="stylesheet" href="http://ec2-50-16-24-169.compute-1.amazonaws.com/colorbrewer.css"/&gt;&lt;link type="text/css" rel="stylesheet" href="http://ec2-50-16-24-169.compute-1.amazonaws.com/voronoi.css"/&gt;&lt;/head&gt;&lt;body&gt;&lt;b&gt;Project home page:&lt;/b&gt;&lt;br&gt;&lt;a href="http://mbostock.github.com/d3/"&gt;http://mbostock.github.com/d3/&lt;/a&gt;&lt;br&gt;A beautiful framework to develop awesome data visualizations, but gosh,&lt;b&gt; too many lines of code to do simple things,&lt;/b&gt; and I need to master python and django first. I'll give a try latter ... maybe.&lt;br&gt;&lt;div id="chart"&gt;&lt;/div&gt;&lt;script type="text/javascript" src="http://ec2-50-16-24-169.compute-1.amazonaws.com/voronoi.js"&gt;&lt;/script&gt;&lt;br&gt;Though it is good to have the reference.&lt;/body&gt;&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4156370786958173707?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4156370786958173707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-d3js-voronoi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4156370786958173707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4156370786958173707'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-d3js-voronoi.html' title='Data Visualization . d3.js - Voronoi Tesselation'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6922754336916263986</id><published>2012-02-28T01:30:00.000-06:00</published><updated>2012-02-28T03:09:20.237-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Data Visualization . Colorbrewer. Vanity coloring your maps</title><content type='html'>I love this app that helps you choose just the right color combinations for your layers in maps.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://colorbrewer2.org/" target="_blank"&gt;http://colorbrewer2.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is how I used it on my first map:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img831.imageshack.us/img831/1425/mapcolorbrew.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="396" width="610" src="http://img831.imageshack.us/img831/1425/mapcolorbrew.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Cool, isn't it? Yay!&lt;br /&gt;P.S. By the way,darker means more violent...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6922754336916263986?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6922754336916263986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-colorbrewer-vanity.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6922754336916263986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6922754336916263986'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-colorbrewer-vanity.html' title='Data Visualization . Colorbrewer. Vanity coloring your maps'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7846099858695088030</id><published>2012-02-27T22:30:00.002-06:00</published><updated>2012-02-27T22:31:42.894-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pentaho BI'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Pentaho BI. Jpivot - java.util.EmptyStackException</title><content type='html'>&lt;br /&gt;I found my first bug with Pentaho BI while following this &lt;a href="http://hernandezpaul.wordpress.com/2012/02/10/dashboard-creation-with-pentaho-and-cde-step-by-step-screencast-tutorial/"&gt;tutorial&lt;/a&gt;, but the solution was very straightforward, to replace the jpivot jar file....(because &lt;b&gt;the old one was using an incorrect method&lt;/b&gt;).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:java"&gt;Java.util.EmptyStackException&lt;br /&gt;at java.util.Stack.peek(Stack.java:85)&lt;br /&gt;at mondrian.server.Locus.peek(Locus.java:63)&lt;br /&gt;at mondrian.rolap.SqlMemberSource.getMemberChildren2(SqlMemberSource.java:902)&lt;br /&gt;at mondrian.rolap.SqlMemberSource.getMemberChildren(SqlMemberSource.java:830)&lt;br /&gt;at mondrian.rolap.SqlMemberSource.getMemberChildren(SqlMemberSource.java:804)&lt;br /&gt;at mondrian.rolap.SmartMemberReader.readMemberChildren(SmartMemberReader.java:247)&lt;br /&gt;at mondrian.rolap.SmartMemberReader.getMemberChildren(SmartMemberReader.java:210)&lt;br /&gt;at mondrian.rolap.RolapCubeHierarchy$CacheRolapCubeHierarchyMemberReader.readMemberChildren(RolapCubeHierarchy.java:586)&lt;br /&gt;at mondrian.rolap.RolapCubeHierarchy$CacheRolapCubeHierarchyMemberReader.getMemberChildren(RolapCubeHierarchy.java:682)&lt;br /&gt;at mondrian.rolap.SmartMemberReader.getMemberChildren(SmartMemberReader.java:176)&lt;br /&gt;at mondrian.rolap.RolapSchemaReader.internalGetMemberChildren(RolapSchemaReader.java:170)&lt;br /&gt;at mondrian.rolap.RolapSchemaReader.getMemberChildren(RolapSchemaReader.java:152)&lt;br /&gt;at mondrian.rolap.RolapSchemaReader.getMemberChildren(RolapSchemaReader.java:146)&lt;br /&gt;at mondrian.olap.DelegatingSchemaReader.getMemberChildren(DelegatingSchemaReader.java:78)&lt;br /&gt;at com.tonbeller.jpivot.mondrian.MondrianMemberTree.internalGetChildren(MondrianMemberTree.java:209)&lt;br /&gt;at com.tonbeller.jpivot.mondrian.MondrianMemberTree.getChildren(MondrianMemberTree.java:193)&lt;br /&gt;at com.tonbeller.jpivot.navigator.member.TreeModelAdapter.getChildren(TreeModelAdapter.java:95)&lt;br /&gt;&lt;br /&gt;etc...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The solution was given by  dulci :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:python"&gt;dulci&lt;br /&gt;    Hey,&lt;br /&gt;    I have the solution! Do this!:&lt;br /&gt;&lt;br /&gt;    1.- stop-pentaho&lt;br /&gt;    2.- Rename the library biserver-ce/tomcat/webapp/pentaho/WEB-INF/lib/jpivot-1.8.0-100420.jar to jpivot-1.8.0-100420.jar.OLD&lt;br /&gt;    3.- Paste the library that we downloaded from http://www.stratebi.es/todobi/Ene12/jpivot-1.8.0-100420.jar&lt;br /&gt;    4 - start pentaho and that's it! &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And bingo!!! This is the beauty of open source.&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://forums.pentaho.com/showthread.php?89323-JPivot-error-want-to-check-the-solution"&gt;http://forums.pentaho.com/showthread.php?89323-JPivot-error-want-to-check-the-solution&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7846099858695088030?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7846099858695088030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-bi-jpivot-javautilemptystackexc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7846099858695088030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7846099858695088030'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-bi-jpivot-javautilemptystackexc.html' title='Pentaho BI. Jpivot - java.util.EmptyStackException'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2939175484803813093</id><published>2012-02-24T17:25:00.002-06:00</published><updated>2012-02-24T18:26:31.244-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - Example Database for Training (pagila improved . 540 MB once installed)</title><content type='html'>I just migrated from MySQL to PostgreSQL the example database based on pagila (mysql's sakila) but improved, as depicted in this book (which I highly recommend) :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470484322.html" target="_blank"&gt;http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470484322.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And I'm releasing it just like the original authors did, under the LGPL license.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;You have to create a user 'wcm' with the necessary privileges in order to load this db.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Compressed text dump 71 mb&lt;/b&gt;.&lt;br /&gt;&lt;a href="https://rapidshare.com/files/3990485799/wcm.sql.tar.gz" target="_blank"&gt;https://rapidshare.com/files/3990485799/wcm.sql.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Power Architect entity-relationship diagram.&lt;/b&gt;&lt;br /&gt;&lt;a href="https://rapidshare.com/files/2635761979/er_diagram_architect.architect" target="_blank"&gt;https://rapidshare.com/files/2635761979/er_diagram_architect.architect&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;wcm=# select version();                                     version                                                                                        &lt;br /&gt;-------------------------------------------------------------------------------------                                           &lt;br /&gt; PostgreSQL 9.1.1 on i586-suse-linux-gnu, compiled by gcc (SUSE Linux) 4.6.2, 32-bit                                                  &lt;br /&gt;(1 row) &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is what the tables look like:&lt;br /&gt;&lt;pre class="brush:sql"&gt;wcm=# set search_path = wcm;&lt;br /&gt;SET&lt;br /&gt;wcm=# \dt+&lt;br /&gt;                            Listado de relaciones&lt;br /&gt; Esquema |        Nombre        | Tipo  |  Dueño   |   Tamaño   | Descripción &lt;br /&gt;---------+----------------------+-------+----------+------------+-------------&lt;br /&gt; wcm     | actor                | tabla | rene     | 6304 kB    | &lt;br /&gt; wcm     | country              | tabla | rene     | 16 kB      | &lt;br /&gt; wcm     | customer             | tabla | rene     | 32 MB      | &lt;br /&gt; wcm     | customer_order       | tabla | rene     | 65 MB      | &lt;br /&gt; wcm     | customer_order_line  | tabla | rene     | 107 MB     | &lt;br /&gt; wcm     | director             | tabla | rene     | 840 kB     | &lt;br /&gt; wcm     | distributor          | tabla | rene     | 624 kB     | &lt;br /&gt; wcm     | dvd                  | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | dvd_release          | tabla | rene     | 23 MB      | &lt;br /&gt; wcm     | dvd_release_actor    | tabla | rene     | 22 MB      | &lt;br /&gt; wcm     | dvd_release_director | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | employee             | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | employee_job         | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | inventory            | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | job_description      | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | language             | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | lookup_type          | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | lookup_value         | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | promoted_dvd_release | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | promotion            | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | purchase_order       | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | purchase_order_line  | tabla | rene     | 0 bytes    | &lt;br /&gt; wcm     | region               | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | warehouse            | tabla | rene     | 8192 bytes | &lt;br /&gt; wcm     | website              | tabla | rene     | 8192 bytes | &lt;br /&gt;(25 filas)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Empty tables : purchase_order,promoted_dvd_release and purchase_order_line can be filled to your wish, the others&lt;br /&gt;are not important and are easy to fill as well. The structure is kind of self explanatory but  post a comment should you have any doubts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2939175484803813093?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2939175484803813093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-training-example-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2939175484803813093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2939175484803813093'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-training-example-database.html' title='PostgreSQL - Example Database for Training (pagila improved . 540 MB once installed)'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2868901514754972279</id><published>2012-02-24T13:11:00.003-06:00</published><updated>2012-02-24T13:11:55.303-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - Compressing text dumps on the fly</title><content type='html'>This one was missing in my recipes ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;&lt;br /&gt;pg_dump -U myUser myDB | gzip &gt; myDB.sql.gz&lt;br /&gt;&lt;br /&gt;Then, to restore:&lt;br /&gt;&lt;br /&gt;gzip -cd myDB.sql.gz | pg_restore ...&lt;br /&gt;&lt;br /&gt;or&lt;br /&gt;&lt;br /&gt;or zcat myDB.sql.gz |pg_restore&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The "tar" utility is for bundling up a bunch of files and directories into a single file (the name is a contraction of "tape archive"). In that respect, a "tar" file is kind-of like a "zip" file, except that "zip" always implies compression while "tar" does not.&lt;br /&gt;&lt;br /&gt;Note finally that "gzip" is not "zip." The "gzip" utility just compresses; it doesn't make archives.&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/2379482/shell-scripting-use-a-pipe-as-an-input-for-tar"&gt;http://stackoverflow.com/questions/2379482/shell-scripting-use-a-pipe-as-an-input-for-tar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2868901514754972279?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2868901514754972279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-compressing-text-dumps-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2868901514754972279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2868901514754972279'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-compressing-text-dumps-on.html' title='PostgreSQL - Compressing text dumps on the fly'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-993589536565931160</id><published>2012-02-23T17:01:00.002-06:00</published><updated>2012-02-23T17:25:56.173-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><category scheme='http://www.blogger.com/atom/ns#' term='migration'/><title type='text'>MySQL . mysqldump. exporting data with sql inserts to PostgreSQL</title><content type='html'>&lt;b&gt;Generating a working mysql data dump with inserts to load into PostgreSQL.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Key options for generating the dump.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;mysqldump -u user  --extended-insert=FALSE --no-create-info --compact --compatible=postgresql database &gt; file.sql&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Converting incompatible characters&lt;br /&gt;&lt;pre class="brush:shell"&gt;sed "s/\\\'/\'\'/g" file.sql &gt; file1.sql&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And importing into postgresql&lt;br /&gt;&lt;pre class="brush:sql"&gt;psql database &lt; file1.sql&lt;br /&gt;&lt;/pre&gt;That was quick, wasn't it?References:&lt;a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html"&gt;http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html&lt;/a&gt;&lt;a href="http://chriswa.wordpress.com/2008/02/20/mysqldump-data-only/"&gt;http://chriswa.wordpress.com/2008/02/20/mysqldump-data-only/&lt;/a&gt;&lt;a href="http://en.wikibooks.org/w/index.php?title=Programming:Converting_MySQL_to_PostgreSQL"&gt;http://en.wikibooks.org/w/index.php?title=Programming:Converting_MySQL_to_PostgreSQL&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-993589536565931160?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/993589536565931160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/mysql-mysqldump-data-with-sql-inserts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/993589536565931160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/993589536565931160'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/mysql-mysqldump-data-with-sql-inserts.html' title='MySQL . mysqldump. exporting data with sql inserts to PostgreSQL'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3560197947825732967</id><published>2012-02-23T15:16:00.001-06:00</published><updated>2012-02-23T15:19:10.805-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><title type='text'>MySQL . Error 1396 (HY000) &lt;- nasty bug</title><content type='html'>The error goes like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;mysql&gt; select version();&lt;br /&gt;+------------+&lt;br /&gt;| version()  |&lt;br /&gt;+------------+&lt;br /&gt;| 5.5.16-log |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;CREATE USER youruser IDENTIFIED BY 'youruser';&lt;br /&gt;ERROR 1396 (HY000) at line 4: Operation CREATE USER failed for 'youruser'@'%'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The bug is depicted here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bugs.mysql.com/bug.php?id=28331"&gt;http://bugs.mysql.com/bug.php?id=28331&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and the workaround that worked for me:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;mysql&gt; delete from mysql.db where user='youruser';&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; delete from mysql.user where user='youruser';&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; flush privileges;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another nuance that drives me off from using mysql (without needing to).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3560197947825732967?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3560197947825732967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/mysql-error-1396-hy000-nasty-bug.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3560197947825732967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3560197947825732967'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/mysql-error-1396-hy000-nasty-bug.html' title='MySQL . Error 1396 (HY000) &lt;- nasty bug'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8893947567056779088</id><published>2012-02-22T13:25:00.001-06:00</published><updated>2012-02-22T13:28:52.895-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pentaho BI'/><category scheme='http://www.blogger.com/atom/ns#' term='chartbeans'/><title type='text'>Pentaho . Chartbeans intro</title><content type='html'>I'm studying the way to adapt my favorite charting library to pentaho bi. I made a simple map.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img839.imageshack.us/img839/8462/chartbeans.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="831" width="900" src="http://img839.imageshack.us/img839/8462/chartbeans.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://wiki.pentaho.com/display/ServerDoc2x/Introduction+to+Pentaho+ChartBeans#IntroductiontoPentahoChartBeans-ExamplefromaJavaDeveloperPerspective"&gt;http://wiki.pentaho.com/display/ServerDoc2x/Introduction+to+Pentaho+ChartBeans#IntroductiontoPentahoChartBeans-ExamplefromaJavaDeveloperPerspective&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The provided example is a bit outdated, I needed to reconfigure some things, but I'm on my way. Once I accomplish it I'll publish a walkthrough tutorial.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8893947567056779088?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8893947567056779088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-chartbeans-intro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8893947567056779088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8893947567056779088'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-chartbeans-intro.html' title='Pentaho . Chartbeans intro'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3934598286218991679</id><published>2012-02-19T02:31:00.001-06:00</published><updated>2012-02-21T12:48:08.712-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pentaho BI'/><title type='text'>Pentaho. Pentaho Charts</title><content type='html'>I'm evaluating Pentaho BI, and I'm getting to like it very much. I'm interested in leveraging my own charts through chartbeans (the pentaho project to provide a wrapper to foreign charting libraries) as the ones from jfreechart don't appeal to me, and flash is not supported by some devices ,but they look very impressive like this one:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img832.imageshack.us/img832/5003/pentahocharts.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="667" width="702" src="http://img832.imageshack.us/img832/5003/pentahocharts.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;b&gt;Chartbeans project:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://wiki.pentaho.com/display/COM/The+Pentaho+ChartBeans+Project"&gt;http://wiki.pentaho.com/display/COM/The+Pentaho+ChartBeans+Project&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3934598286218991679?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3934598286218991679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-pentaho-charts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3934598286218991679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3934598286218991679'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/pentaho-pentaho-charts.html' title='Pentaho. Pentaho Charts'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6671475626331645654</id><published>2012-02-18T04:41:00.003-06:00</published><updated>2012-02-18T05:45:14.433-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - fuzzystrmatch . distance between strings</title><content type='html'>I think this feature could be useful for data cleansing, or in general, for tasks related with string comparisons.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.3/static/fuzzystrmatch.html"&gt;http://www.postgresql.org/docs/8.3/static/fuzzystrmatch.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;F.9.2. Levenshtein&lt;br /&gt;This function calculates the Levenshtein distance between two strings:&lt;br /&gt;   levenshtein(text source, text target) returns int&lt;br /&gt;Both source and target can be any non-null string, with a maximum of 255 characters.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;test=# Create extension fuzzystrmatch;&lt;br /&gt;CREATE EXTENSION&lt;br /&gt;&lt;br /&gt;test=# select levenshtein('john smith','john schmit');&lt;br /&gt; levenshtein &lt;br /&gt;-------------&lt;br /&gt;           3&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Calculating their degree of similarity between two words sounds easy... but I'll try that after a long nap. One thing that would be awesome, is to somehow implement an efficient auto-complete feature using postgresql...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6671475626331645654?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6671475626331645654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-fuzzystrmatch-distance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6671475626331645654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6671475626331645654'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-fuzzystrmatch-distance.html' title='PostgreSQL - fuzzystrmatch . distance between strings'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6595048334745522054</id><published>2012-02-18T03:19:00.001-06:00</published><updated>2012-02-18T14:45:19.219-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Visualization - Google charts API</title><content type='html'>Yet another charting API. &lt;blockquote&gt;Charts are rendered using HTML5/SVG technology to provide cross-browser compatibility and cross platform portability to iPhones, iPads and Android. No plugins are needed.&lt;/blockquote&gt;&lt;a href="http://code.google.com/intl/es-MX/apis/chart/interactive/docs/index.html"&gt;http://code.google.com/intl/es-MX/apis/chart/interactive/docs/index.html&lt;/a&gt;  &lt;html&gt; &lt;head&gt; &lt;!--Load the AJAX API--&gt; &lt;script type="text/javascript" src="https://www.google.com/jsapi"&gt;&lt;/script&gt; &lt;script type="text/javascript"&gt;      // Load the Visualization API and the piechart package.      google.load('visualization', '1.0', {'packages':['corechart']});      google.load('visualization', '1', {packages:['gauge']});      google.load('visualization', '1', {'packages':['motionchart']});      // Set a callback to run when the Google Visualization API is loaded.      google.setOnLoadCallback(drawChart);      // Callback that creates and populates a data table,      // instantiates the pie chart, passes in the data and      // draws it.      function drawChart() {        // Create the data table.        var data = new google.visualization.DataTable();        data.addColumn('string', 'Topping');        data.addColumn('number', 'Slices');        data.addRows([          ['Mushrooms', 6],          ['Onions', 2],          ['Olives', 2],          ['Zucchini', 2],          ['Pepperoni', 4]        ]);        // Set chart options        var options = {'title':'How Much Pizza I Ate Last Night',                       'width':400,                       'height':300};        var options2 = {          width: 700, height: 220,          redFrom: 3, redTo: 6,          yellowFrom:2, yellowTo: 3,          minorTicks: 3,          max: 6        };        var data1 = new google.visualization.DataTable();        data1.addColumn('string', 'Fruit');        data1.addColumn('date', 'Date');        data1.addColumn('number', 'Sales');        data1.addColumn('number', 'Expenses');        data1.addColumn('string', 'Location');        data1.addRows([          ['Apples',new Date (1988,0,1),1000,300,'East'],          ['Oranges',new Date (1988,0,1),1150,200,'West'],          ['Bananas',new Date (1988,0,1),300,250,'West'],          ['Apples',new Date (1989,6,1),1200,400,'East'],          ['Oranges',new Date (1989,6,1),750,150,'West'],          ['Bananas',new Date (1989,6,1),788,617,'West']          ]);                // Instantiate and draw our chart, passing in some options.        var chart = new google.visualization.PieChart(document.getElementById('chart_div'));        chart.draw(data, options);        var chart1 = new google.visualization.BarChart(document.getElementById('chart_div1'));        chart1.draw(data, options);         var chart2 = new google.visualization.Gauge(document.getElementById('chart_div2'));        chart2.draw(data, options2);        var chart3 = new google.visualization.MotionChart(document.getElementById('chart_div3'));        chart3.draw(data1, {width: 600, height:300});      }    &lt;/script&gt; &lt;/head&gt;  &lt;body&gt; &lt;!--Div that will hold the pie chart--&gt;&lt;br /&gt; &lt;div id="chart_div" align="center"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div id="chart_div1" align="center"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div id="chart_div2" align="center"&gt;&lt;/div&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;div id="chart_div3" align="center"&gt;&lt;/div&gt;&lt;/body&gt; &lt;/html&gt;  &lt;br /&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br /&gt;&lt;b&gt;Drawback (sort of): &lt;/b&gt;&lt;br /&gt;Can I use charts offline? &lt;br /&gt;No; your computer must have live access to http://www.google.com/jsapi in order to use charts. This is because the visualization libraries that your page requires are loaded dynamically before you use them. The code for loading the appropriate library is part of the included jsapi script, and is called when you invoke the google.load() method. Our terms of service do not allow you to download the google.load or google.visualization code to use offline.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And...the motion chart is fantastic!!!&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6595048334745522054?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6595048334745522054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/visualization-google-charts-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6595048334745522054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6595048334745522054'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/visualization-google-charts-api.html' title='Visualization - Google charts API'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3364850772506576538</id><published>2012-02-14T00:02:00.001-06:00</published><updated>2012-02-14T00:18:13.336-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL. Thesaurus dictionary - Normalizing political state names</title><content type='html'>I want to normalize the name of mexico states to some abbreviation in an automatic fashion as I'll be parsing a lot of documents containing statistical information about different variables in the whole country and they refer to states in heterogeneous ways. &lt;br /&gt;For instance, I want the strings 'edo. de mexico', 'estado de mexico','mexico','edo de mexico' to yield 'mex' instead, which is the abbreviation I've chosen for that particular state (which in time will help me assign it's proper numeric identifier for its respective polygon in maps).&lt;br /&gt;&lt;br /&gt;1.Creating the configuration file.&lt;br /&gt;&lt;pre class="brush:shell"&gt;vi /usr/pgsql-9.1/share/tsearch_data/mexican_states.ths&lt;br /&gt;&lt;br /&gt;? ? mexico : mex&lt;br /&gt;edo ? mexico : mex&lt;br /&gt;mexico : mex&lt;br /&gt;&lt;br /&gt;:wq&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2.Creating the text search dictionary&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE TEXT SEARCH DICTIONARY mexican_states_ths &lt;br /&gt;(&lt;br /&gt;TEMPLATE = thesaurus,&lt;br /&gt;DictFile = mexican_states,&lt;br /&gt;Dictionary = pg_catalog.spanish_stem&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;3. Altering the mapping of the text search configuration for the respective language (spanish).&lt;br /&gt;&lt;pre class="brush:sql"&gt;ALTER TEXT SEARCH CONFIGURATION spanish ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH mexican_states_ths, spanish_stem;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;4. And testing the results.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# SELECT plainto_tsquery('spanish','edo de mexico');&lt;br /&gt; plainto_tsquery &lt;br /&gt;-----------------&lt;br /&gt; 'mex'&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# SELECT plainto_tsquery('spanish','mexico');&lt;br /&gt; plainto_tsquery &lt;br /&gt;-----------------&lt;br /&gt; 'mex'&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# SELECT plainto_tsquery('spanish','estado de mexico');&lt;br /&gt; plainto_tsquery &lt;br /&gt;-----------------&lt;br /&gt; 'mex'&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# SELECT plainto_tsquery('spanish','edo. de mexico');&lt;br /&gt; plainto_tsquery &lt;br /&gt;-----------------&lt;br /&gt; 'mex'&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Certainly some previous treatment is necessary, such as lowercasing and unquoting, but that's easier than editing files by hand, which I find kind of silly.&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html"&gt;http://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html&lt;/a&gt;&lt;br /&gt;While learning how to achieve this, I blew away my spanish text search configuration. Here's how to get it back&lt;br /&gt;&lt;a href="http://forums.enterprisedb.com/posts/list/1575.page"&gt;http://forums.enterprisedb.com/posts/list/1575.page &lt;/a&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;pre class="brush:shell"&gt;Go to your $SHAREDIR i.e. (pg_config --sharedir)&lt;br /&gt;Check the contents of file: snowball_create.sql. &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3364850772506576538?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3364850772506576538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-thesaurus-dictionary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3364850772506576538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3364850772506576538'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-thesaurus-dictionary.html' title='PostgreSQL. Thesaurus dictionary - Normalizing political state names'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4036329912160668485</id><published>2012-02-12T04:19:00.001-06:00</published><updated>2012-02-12T04:34:17.679-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Virtualbox - could not find a valid medium format for the target disk - vmdk.gz</title><content type='html'>I just ran into the following issue while importing a virtual appliance (.ova) to virtualbox.&lt;br /&gt;&lt;pre class="brush:shell"&gt;Failed to import appliance /home/rene/Descargas/MusicBrainz NGS 2012-01-12.ova.&lt;br /&gt;Could not find a valid medium format for the target disk '/home/rene/VirtualBox VMs/vm/musicbrainz-server-2012-01-12-disk1.vmdk.gz'.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The thing is that this appliance was generated by vmware with gzip compression enabled for the vmdk disk. I don't know whether there's another workaround, but it turns out that the .ova file is in fact a tar file so :&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;tar -xvf MusicBrainz\ NGS\ 2012-01-12.ova&lt;br /&gt;gzip -d musicbrainz-server-2012-01-12-disk1.vmdk.gz&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And you're all set. &lt;br /&gt;&lt;br /&gt;Source:&lt;br /&gt;&lt;a href="http://itproctology.blogspot.com/2009/05/ovf-and-ova-dilemma.html"&gt;http://itproctology.blogspot.com/2009/05/ovf-and-ova-dilemma.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://communities.vmware.com/thread/283650"&gt;http://communities.vmware.com/thread/283650&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4036329912160668485?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4036329912160668485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/virtualbox-could-not-find-valid-medium.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4036329912160668485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4036329912160668485'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/virtualbox-could-not-find-valid-medium.html' title='Virtualbox - could not find a valid medium format for the target disk - vmdk.gz'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4991187127784321047</id><published>2012-02-11T21:32:00.000-06:00</published><updated>2012-02-13T00:08:48.405-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Flotr2 - Found another free charting library</title><content type='html'>To me, there's no excuse not to present our data in an attractive fashion.&lt;br /&gt;&lt;a href="http://www.humblesoftware.com/flotr2/documentation"&gt;http://www.humblesoftware.com/flotr2/documentation&lt;/a&gt;&lt;br /&gt;&lt;style type="text/css"&gt;      body {        margin: 0px;        padding: 0px;      }      #container {        width : 600px;        height: 384px;        margin: 8px auto;      }      #container1 {        width : 600px;        height: 384px;        margin: 8px auto;      }    &lt;/style&gt;&lt;br /&gt;&lt;div id="container"&gt;&lt;/div&gt;&lt;div id="container1"&gt;&lt;/div&gt;&lt;script type="text/javascript"&gt;      (function () {        var          container = document.getElementById('container'),          start = (new Date).getTime(),          data, graph, offset, i;          // Draw a sine curve at time t        function animate (t) {          data = [];          offset = 2 * Math.PI * (t - start) / 10000;          // Sample the sine function          for (i = 0; i &lt; 4 * Math.PI; i += 0.2) {            data.push([i, Math.sin(i - offset)]);          }          // Draw Graph          graph = Flotr.draw(container, [ data ], {            yaxis : {              max : 2,              min : -2            },        grid: {        backgroundColor: '#FFFFFF'        }          });          // Animate          setTimeout(function () {            animate((new Date).getTime());          }, 50);        }        animate(start);      })();&lt;/script&gt;&lt;script type="text/javascript"&gt;(function basic_bubble() {container1 = document.getElementById('container1'), start = (new Date).getTime(),          d1, d2, point,graph, i;    var d1 = [],        d2 = [],        point, graph, i;    for (i = 0; i &lt; 10; i++) {        point = [i, Math.ceil(Math.random() * 10), Math.ceil(Math.random() * 10)];        d1.push(point);        point = [i, Math.ceil(Math.random() * 10), Math.ceil(Math.random() * 10)];        d2.push(point);    }    graph = Flotr.draw(container1, [d1, d2], {        bubbles: {            show: true,            baseRadius: 5        },        xaxis: {            min: -4,            max: 14        },        yaxis: {            min: -4,            max: 14        },        grid: {        backgroundColor: '#FFFFFF'        }    });})();&lt;/script&gt;&lt;b&gt;Introduction&lt;/b&gt;&lt;b&gt;Flotr2&lt;/b&gt; is a library for drawing HTML5 charts and graphs. It is a branch of flotr which removes the Prototype dependency and includes many improvements.&lt;b&gt;Features:&lt;/b&gt;    mobile support    framework independent    extensible plugin framework    custom chart types    FF, Chrome, IE6+, Android, iOS    lines    bars    candles    pies    &lt;b&gt;bubbles&lt;/b&gt;&lt;br /&gt;Usage&lt;br /&gt;&lt;br /&gt;To use Flotr2, include the flotr2.min.js script in your page and create a visible div&lt;br /&gt;with positive width and height. A graph is drawn with the Flotr.draw(container, data, options) method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4991187127784321047?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4991187127784321047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/flotr2-found-another-free-chart-library.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4991187127784321047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4991187127784321047'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/flotr2-found-another-free-chart-library.html' title='Flotr2 - Found another free charting library'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5823401903892460388</id><published>2012-02-10T21:18:00.002-06:00</published><updated>2012-02-10T21:22:21.707-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plpython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>PostgreSQL. Mail merging-Part 2.The plpython function</title><content type='html'>Let's get this thing done.&lt;br /&gt;&lt;br /&gt;Creating an auxiliary view,to get the name of the columns tables and views.&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE VIEW columns AS SELECT&lt;br /&gt;  c.relname tab,&lt;br /&gt;  a.attname as col&lt;br /&gt;  FROM pg_catalog.pg_class c&lt;br /&gt;     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace&lt;br /&gt;     LEFT JOIN pg_catalog.pg_attribute a ON a.attrelid = c.relname::regclass   &lt;br /&gt;  WHERE&lt;br /&gt;       n.nspname &lt;&gt; 'pg_catalog'&lt;br /&gt;      AND n.nspname &lt;&gt; 'information_schema'&lt;br /&gt;      AND n.nspname !~ '^pg_toast'&lt;br /&gt;  AND pg_catalog.pg_table_is_visible(c.oid)&lt;br /&gt;  AND c.relkind IN ('v','r')&lt;br /&gt;  AND a.attnum &gt; 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Creating and populating the table where the "recipients" will be listed.&lt;br /&gt;&lt;pre class="brush:sql"&gt;test=# CREATE TABLE deceased (recipient_name text,name_of_deceased text, his_her text, positive_attribute text,my_signature text);&lt;br /&gt;CREATE TABLE&lt;br /&gt;test=# INSERT INTO deceased values ('Jim Morrison','his',' a great artist'),('Kurt Kobain','his',' a tormented soul'),('John Lenon','his',' a charismatic and charming person'),('Janis Joplin','her',' authentic, a punch of energy ');&lt;br /&gt;INSERT 0 3&lt;br /&gt;UPDATE deceased SET my_signature = 'Rene', recipient_name = 'Mr.X'; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And after some research and thought, I came up with this:&lt;br /&gt;&lt;pre class="brush:python"&gt;CREATE OR REPLACE FUNCTION mail_merge(source text,document text,path text) RETURNS void AS &lt;br /&gt;$$&lt;br /&gt;#source -&gt; the table or view that contains the list&lt;br /&gt;#document -&gt; the template with placeholders matching the field names of source prefixed with colons (:)&lt;br /&gt;#path -&gt; the directory where the generated documents will be created&lt;br /&gt;import re&lt;br /&gt;placeholders = []&lt;br /&gt;doc_text = ""&lt;br /&gt;columns = ""&lt;br /&gt;rv = plpy.execute("SELECT col from columns WHERE tab = %s order by 1" % (plpy.quote_literal(source)))&lt;br /&gt;for x in rv:&lt;br /&gt;  placeholders = placeholders + [x['col']] &lt;br /&gt;rv = plpy.execute("SELECT document from documents WHERE doc_name =  %s " % (plpy.quote_literal(document)))&lt;br /&gt;for x in rv:&lt;br /&gt;  doc_text = doc_text + x['document']&lt;br /&gt;for i in range(0,len(placeholders)):&lt;br /&gt;  columns = columns + placeholders[i]+" "&lt;br /&gt;  if i &lt; len(placeholders) -1:&lt;br /&gt;    columns = columns +","&lt;br /&gt;rv = plpy.execute("SELECT "+columns+" FROM "+source )&lt;br /&gt;for x in rv: &lt;br /&gt;  tmp = doc_text&lt;br /&gt;  for i in range(0,len(placeholders)):&lt;br /&gt;    tmp = re.sub(":"+str(placeholders[i]),str(x[placeholders[i]]),tmp)&lt;br /&gt;  #here you create the file containing tmp, in path &lt;br /&gt;$$ LANGUAGE plpython2u;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With this function you can, based on a table or a view create n documents (where n equals the number of rows in the table or view), based on a template, setup as described in my previous entry. The field names of the table or view will determine the placeholders names.&lt;br /&gt;&lt;br /&gt;The more I work with python, the more I like it =-).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5823401903892460388?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5823401903892460388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mail-merging-plpython.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5823401903892460388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5823401903892460388'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mail-merging-plpython.html' title='PostgreSQL. Mail merging-Part 2.The plpython function'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5071465334996211668</id><published>2012-02-09T00:56:00.000-06:00</published><updated>2012-02-10T21:27:04.350-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL . Mail merging ....with PostgreSQL ? Part 1</title><content type='html'>Yep , it's a weird concept, but the idea is to help a friend to automate a rather boring task. With mail merging, I'm talking about having a document template and you need to send it to a list of people. I know what you're thinking...gosh that's what office suites are for, but hell, I want to do it with PostgreSQL! hahahaha&lt;br /&gt;&lt;br /&gt;This is my test document in Libre Office Writer:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;Dear :recipient_name&lt;br /&gt;&lt;br /&gt;I know :name_of_deceased has passed away. I was dismayed to hear of :his_her passing and am writing to extend my deepest sympathies to you and your family.&lt;br /&gt;&lt;br /&gt;:name_of_deceased was :positive_attribute&lt;br /&gt;If there is anything I can do to help you through this difficult time, please let me know and I'd be more than willing to offer my assistance.&lt;br /&gt;&lt;br /&gt;With warmest regards,&lt;br /&gt;:my_signature&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Note that I'm using the following placeholders (variables if you wish):&lt;/b&gt;&lt;br /&gt;:name_of_deceased&lt;br /&gt;:his_her&lt;br /&gt;:positive_attribute&lt;br /&gt;:my_signature&lt;br /&gt;&lt;br /&gt;I've saved it with a html format so I can manipulate flat text (it would be more elegant to use something like Latex I reckon). &lt;br /&gt;&lt;br /&gt;Preprocessing and loading the document template:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Getting rid of the new line character:&lt;/li&gt;&lt;pre class="brush:shell"&gt;-bash-4.2$ tr '\n' ' ' &amp;lt; letter.html | tee &amp;gt; letter_new.html&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;Let's create the table that will hold my documents:  &lt;/li&gt;&lt;pre class="brush:sql"&gt;CREATE TABLE documents (id serial primary key,doc_name text, document text);&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;Load the template into the table &lt;/li&gt;&lt;pre class="brush:sql"&gt;letters=#\copy documents (document) FROM 'letter_new.html' WITH  DELIMITER AS '^';&lt;br /&gt;letters=# UPDATE documents SET doc_name = 'condolences' WHERE id = 1;&lt;br /&gt;&lt;/pre&gt;I used '^' as delimiter because it doesn't appear in the document, hence, it will be loaded completely into that field. &lt;/ol&gt;&lt;br /&gt;Now my template looks like this in the database:&lt;br /&gt;&lt;pre class="brush:sql"&gt;letters=# select * from documents;&lt;br /&gt;id       | 1&lt;br /&gt;doc_name | condolences&lt;br /&gt;document | &amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&amp;gt; &amp;lt;HTML&amp;gt; &amp;lt;HEAD&amp;gt;    &amp;lt;META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"&amp;gt;      &amp;lt;TITLE&amp;gt;&amp;lt;/TITLE&amp;gt;         &amp;lt;META NAME="GENERATOR" CONTENT="LibreOffice 3.4  (Win32)"&amp;gt;      &amp;lt;META NAME="CREATED" CONTENT="20120208;22492965"&amp;gt;       &amp;lt;META NAME="CHANGED" CONTENT="0;0"&amp;gt;     &amp;lt;STYLE TYPE="text/css"&amp;gt;         &amp;lt;!--            @page { margin: 2cm }           P { margin-bottom: 0.21cm }     --&amp;gt;     &amp;lt;/STYLE&amp;gt; &amp;lt;/HEAD&amp;gt; &amp;lt;BODY LANG="es-MX" DIR="LTR"&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;Dear :recipient_name&amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;I know :name_of_deceased  has passed away. I was dismayed to hear of  :his_her passing and am writing to extend my deepest sympathies to you and your family.&amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;:name_of_deceased was :positive_attribute&amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;If there is anything I can do to help you through this difficult time, please let me know and I'd be more than willing to offer my assistance.&amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;&amp;lt;BR&amp;gt; &amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;With warmest regards,&amp;lt;/P&amp;gt; &amp;lt;P STYLE="margin-bottom: 0cm"&amp;gt;:my_signature&amp;lt;/P&amp;gt; &amp;lt;/BODY&amp;gt; &amp;lt;/HTML&amp;gt;         &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the second part I'll construct a python function that outputs documents based on this template and on a table of deceased people =-). But that'll be after I try to get some sleep ... &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5071465334996211668?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5071465334996211668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mail-merging-with-postgresql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5071465334996211668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5071465334996211668'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mail-merging-with-postgresql.html' title='PostgreSQL . Mail merging ....with PostgreSQL ? Part 1'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8322319996328002091</id><published>2012-02-08T13:41:00.000-06:00</published><updated>2012-02-08T13:50:49.185-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='GIS'/><title type='text'>GeoServer - My first map served</title><content type='html'>I just served my first map with GeoServer&lt;br /&gt;&lt;a href="http://geoserver.org/display/GEOS/Welcome"&gt;http://geoserver.org/display/GEOS/Welcome&lt;/a&gt;&lt;br /&gt;and it was fairly easy. Their documentation is good enough for not being necessary to explain how did I do it, I just wanted to spread the word about this nice tool.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img824.imageshack.us/img824/2581/mexicocity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://img824.imageshack.us/img824/2581/mexicocity.png" width="311" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp; This is the contour of my hometown: México City.&lt;br /&gt;&lt;br /&gt;I just found some references for tutorials though.&lt;br /&gt;&lt;a href="http://gis.stackexchange.com/questions/7987/tutorials-for-geoserver" target="_blank"&gt;http://gis.stackexchange.com/questions/7987/tutorials-for-geoserver &lt;/a&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8322319996328002091?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8322319996328002091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/geoserver-my-first-map-served.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8322319996328002091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8322319996328002091'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/geoserver-my-first-map-served.html' title='GeoServer - My first map served'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3860606294837645605</id><published>2012-02-08T00:52:00.000-06:00</published><updated>2012-02-08T00:59:39.750-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python. Why should you learn python?</title><content type='html'>Today I was confronted with the question: &lt;b&gt;why should anybody learn python?&lt;/b&gt; &lt;br /&gt;And...gee, I couldn't give a strong argument besides: "because I like it, it's clear, fun to work with, and I you can do everything with it"&lt;br /&gt;&lt;br /&gt;So in this entry I'll "curate" some facts and opinions of people from the web advocating for the Python programming language.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sites.google.com/site/onlyjob/arena/memory_close.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Because it's a de-facto standard in the industry. [&lt;a href="http://www.python.org/about/success/" target="_blank"&gt;1&lt;/a&gt;] [&lt;a href="http://www.tiobe.com/index.php/paperinfo/tpci/Python.html" target="_blank"&gt;2&lt;/a&gt;][&lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" target="_blank"&gt;3&lt;/a&gt;]&lt;/li&gt;&lt;li&gt;Excellent&amp;nbsp; relation between speed/memory consumption/language features [&lt;a href="http://onlyjob.blogspot.com/2011/03/perl5-python-ruby-php-c-c-lua-tcl.html" target="_blank"&gt;1&lt;/a&gt;]&lt;/li&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sites.google.com/site/onlyjob/arena/memory_close.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="334" src="http://sites.google.com/site/onlyjob/arena/memory_close.png" width="832" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://sites.google.com/site/onlyjob/arena/speed_close.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="334" src="http://sites.google.com/site/onlyjob/arena/speed_close.png" width="833" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;li&gt; Very easy to learn [&lt;a href="http://www.makeuseof.com/tag/5-websites-learn-python-programming/" target="_blank"&gt;1&lt;/a&gt;][&lt;a href="http://wiki.python.org/moin/BeginnersGuide" target="_blank"&gt;2&lt;/a&gt;]&lt;/li&gt;&lt;li&gt;Elegant and clear syntax [&lt;a href="http://wiki.python.org/moin/SimplePrograms" target="_blank"&gt;1&lt;/a&gt;]:&lt;/li&gt;&lt;pre class="brush:python"&gt;class BankAccount(object):&lt;br /&gt;    def __init__(self, initial_balance=0):&lt;br /&gt;        self.balance = initial_balance&lt;br /&gt;    def deposit(self, amount):&lt;br /&gt;        self.balance += amount&lt;br /&gt;    def withdraw(self, amount):&lt;br /&gt;        self.balance -= amount&lt;br /&gt;    def overdrawn(self):&lt;br /&gt;        return self.balance &amp;lt; 0&lt;br /&gt;my_account = BankAccount(15)&lt;br /&gt;my_account.withdraw(5)&lt;br /&gt;print my_account.balance&lt;br /&gt;&lt;/pre&gt;&lt;li&gt;A huge variety of modules to accomplish anything you can think of. [&lt;a href="http://wiki.python.org/moin/UsefulModules" target="_blank"&gt;1&lt;/a&gt;][&lt;a href="http://www.scipy.org/" target="_blank"&gt;2&lt;/a&gt;]&lt;/li&gt;&lt;li&gt;Straight forward web programming [&lt;a href="http://wiki.python.org/moin/WebFrameworks" target="_blank"&gt;1&lt;/a&gt;][&lt;a href="http://www.infoworld.com/d/application-development/pillars-python-six-python-web-frameworks-compared-169442" target="_blank"&gt;2&lt;/a&gt;]&lt;/li&gt;&lt;/ol&gt;--------------------------------------------------------------------------------------------------------------- &lt;br /&gt;&lt;ol&gt;&lt;/ol&gt;Other &lt;a href="http://stackoverflow.com/questions/203862/why-should-i-learn-python" target="_blank"&gt;unsorted reasons&lt;/a&gt; from stack overflow:&lt;br /&gt;&lt;div class="post-text"&gt;&lt;blockquote class="tr_bq"&gt;&lt;b&gt;As for what tasks can be done:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Python is extremely fun to develop in.&lt;/li&gt;&lt;li&gt;Everything can be done with Python.&lt;/li&gt;&lt;li&gt;If something can't be done, you can create an extension for it.&lt;/li&gt;&lt;li&gt;Everything can not only be done, but it can be done fast.  For  example a program that takes you weeks in C++ might take you a day in  Python.&lt;/li&gt;&lt;li&gt;Great for prototyping, and even for usage in a commercial setting.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;As for language features:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Scripting language&lt;/li&gt;&lt;li&gt;Multi-paradigms (object oriented, imperative, functional)&lt;/li&gt;&lt;li&gt;Dynamic type system&lt;/li&gt;&lt;li&gt;Automatic memory management&lt;/li&gt;&lt;li&gt;Links to other dynamic languages&lt;/li&gt;&lt;li&gt;Embedding into other languages&lt;/li&gt;&lt;li&gt;Nice py2exe program that converts python scripts to executables for windows.  Other platforms include it by default. &lt;/li&gt;&lt;li&gt;Strongly typed without static typing&lt;/li&gt;&lt;li&gt;Large standard library&lt;/li&gt;&lt;li&gt;Includes lists, dictionaries, sets, and much more as basic data types&lt;/li&gt;&lt;li&gt;Some implementations of python compile directly to machine code&lt;/li&gt;&lt;li&gt;It is actively being worked on&lt;/li&gt;&lt;li&gt;It has an antigravity module as noted by Jeremy Cantrell &lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;As for resources available:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Python is free to use&lt;/li&gt;&lt;li&gt;There are a ton of online resources and free tutorials&lt;/li&gt;&lt;li&gt;There are a ton of books on Python&lt;/li&gt;&lt;li&gt;There is a large community of developers available for help&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;--&lt;br /&gt;&lt;div class="post-text"&gt;&lt;blockquote class="tr_bq"&gt;&lt;b&gt;Why should you learn Python?&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Because it is a modern, elegant, highest level OO language&lt;/li&gt;&lt;li&gt;Because it is highly expressive, i.e., you will earn higher productivity&lt;/li&gt;&lt;li&gt;Because it comes with "batteries included" i.e. libraries for whatever you want&lt;/li&gt;&lt;li&gt;Because it is well documented and has a well-established community&lt;/li&gt;&lt;li&gt;Because it is simple to learn (and easy to read!) if you already know another OO language&lt;/li&gt;&lt;li&gt;Because it is relatively portable (that is, portable until you use system-specific features)&lt;/li&gt;&lt;li&gt;Because it is free and already installed on any modern Linux distribution (and also on Mac OS X and *BSD, I guess)&lt;/li&gt;&lt;/ul&gt;As for what can be done in Python: everything except extremely  low-level things (i.e. kernels, drivers, programming a microcontroller).  Also, you should not use Python &lt;i&gt;directly&lt;/i&gt; for number crunching  (it is far too slow for that), but you can wrap C or C++ number  crunching libraries with Python modules (and it has already been done,  the most notable examples being &lt;a href="http://numpy.scipy.org/" rel="nofollow"&gt;Numpy&lt;/a&gt; and &lt;a href="http://www.scipy.org/" rel="nofollow"&gt;Scipy&lt;/a&gt;).&lt;/blockquote&gt;&lt;/div&gt;&lt;/div&gt;------------------------------------------------------------------------------------------------------------------&lt;br /&gt;I'll update this post as I find more convincing rationales advocating for python.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3860606294837645605?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3860606294837645605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/python-why-to-learn-python.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3860606294837645605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3860606294837645605'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/python-why-to-learn-python.html' title='Python. Why should you learn python?'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4479546603787992182</id><published>2012-02-06T22:01:00.002-06:00</published><updated>2012-02-06T22:09:54.341-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL internals'/><title type='text'>PostgreSQL - MVCC revisited</title><content type='html'>I had previously read about this topic but I needed to grasp it a little bit more, so I made this mental map:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/534/concurrencymvcc.png/" target="_blank"&gt;&lt;img src="http://img534.imageshack.us/img534/6728/concurrencymvcc.th.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And also deviced a very simple exercise based on this &lt;a href="http://devcenter.heroku.com/articles/postgresql-concurrency"&gt;document&lt;/a&gt; and this &lt;a href="http://www.postgresql.org/files/developer/transactions.pdf"&gt;one&lt;/a&gt; :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To me, the most important piece of information is this:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Basic idea:  tuple  is  visible if  xmin is  valid and  xmax  is  not."Valid" means "either committed or the  current transaction".&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# CREATE TABLE test(id int, time timestamp);&lt;br /&gt;CREATE TABLE&lt;br /&gt;postgres=# BEGIN;&lt;br /&gt;BEGIN&lt;br /&gt;postgres=# select txid_current();&lt;br /&gt; txid_current &lt;br /&gt;--------------&lt;br /&gt;        13756&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# INSERT INTO test values(generate_series(1,100),current_timestamp);&lt;br /&gt;INSERT 0 100&lt;br /&gt;postgres=# SELECT *,xmin,xmax FROM test LIMIT 5;&lt;br /&gt; id |           time            | xmin  | xmax &lt;br /&gt;----+---------------------------+-------+------&lt;br /&gt;  1 | 2012-02-06 21:45:00.11556 | 13756 |    0&lt;br /&gt;  2 | 2012-02-06 21:45:00.11556 | 13756 |    0&lt;br /&gt;  3 | 2012-02-06 21:45:00.11556 | 13756 |    0&lt;br /&gt;  4 | 2012-02-06 21:45:00.11556 | 13756 |    0&lt;br /&gt;  5 | 2012-02-06 21:45:00.11556 | 13756 |    0&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;postgres=# COMMIT;&lt;br /&gt;COMMIT&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now let's generate some dead tuples:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# BEGIN;&lt;br /&gt;BEGIN&lt;br /&gt;postgres=# SELECT txid_current();&lt;br /&gt; txid_current &lt;br /&gt;--------------&lt;br /&gt;        13758&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# UPDATE test SET time = current_timestamp WHERE id &lt; 6;&lt;br /&gt;UPDATE 100&lt;br /&gt;postgres=# SELECT *,xmin,xmax FROM test LIMIT 5;&lt;br /&gt; id |            time            | xmin  | xmax &lt;br /&gt;----+----------------------------+-------+------&lt;br /&gt;  1 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  2 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  3 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  4 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  5 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;postgres=# DELETE FROM test WHERE id &lt; 6;&lt;br /&gt;DELETE 5&lt;br /&gt;postgres=# SELECT *,xmin,xmax FROM test LIMIT 5;&lt;br /&gt; id |            time            | xmin  | xmax &lt;br /&gt;----+----------------------------+-------+------&lt;br /&gt;  6 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  7 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  8 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;  9 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt; 10 | 2012-02-06 21:48:03.560034 | 13758 |    0&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;postgres=# ROLLBACK;&lt;br /&gt;ROLLBACK&lt;br /&gt;&lt;br /&gt;postgres=# SELECT *,xmin,xmax FROM test LIMIT 5;&lt;br /&gt; id |           time            | xmin  | xmax  &lt;br /&gt;----+---------------------------+-------+-------&lt;br /&gt;  1 | 2012-02-06 21:45:00.11556 | 13756 | 13758&lt;br /&gt;  2 | 2012-02-06 21:45:00.11556 | 13756 | 13758&lt;br /&gt;  3 | 2012-02-06 21:45:00.11556 | 13756 | 13758&lt;br /&gt;  4 | 2012-02-06 21:45:00.11556 | 13756 | 13758&lt;br /&gt;  5 | 2012-02-06 21:45:00.11556 | 13756 | 13758&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;/pre&gt;How do we get a glance at how many dead tuples in a table?&lt;pre class="brush:sql"&gt;postgres=# select * from pg_stat_all_tables where relname = 'test';&lt;br /&gt;-[ RECORD 1 ]-----+------------------------------&lt;br /&gt;relid             | 16969&lt;br /&gt;schemaname        | public&lt;br /&gt;relname           | test&lt;br /&gt;seq_scan          | 7&lt;br /&gt;seq_tup_read      | 320&lt;br /&gt;idx_scan          | &lt;br /&gt;idx_tup_fetch     | &lt;br /&gt;n_tup_ins         | 100&lt;br /&gt;n_tup_upd         | 105&lt;br /&gt;n_tup_del         | 5&lt;br /&gt;n_tup_hot_upd     | 105&lt;br /&gt;n_live_tup        | 100&lt;br /&gt;n_dead_tup        | 5&lt;br /&gt;last_vacuum       | &lt;br /&gt;last_autovacuum   | 2012-02-06 21:51:33.926522-06&lt;br /&gt;last_analyze      | &lt;br /&gt;last_autoanalyze  | 2012-02-06 21:46:33.783941-06&lt;br /&gt;vacuum_count      | 0&lt;br /&gt;autovacuum_count  | 1&lt;br /&gt;analyze_count     | 0&lt;br /&gt;autoanalyze_count | 1&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;n_dead_tup = number of dead tuples&lt;/b&gt;And now, lets VACUUM the table.&lt;pre class="brush:sql"&gt;postgres=# VACUUM VERBOSE test;&lt;br /&gt;INFO:  vacuuming "public.test"&lt;br /&gt;INFO:  "test": found 5 removable, 100 nonremovable row versions in 1 out of 1 pages&lt;br /&gt;DETAIL:  0 dead row versions cannot be removed yet.&lt;br /&gt;There were 100 unused item pointers.&lt;br /&gt;0 pages are entirely empty.&lt;br /&gt;CPU 0.00s/0.00u sec elapsed 0.01 sec.&lt;br /&gt;VACUUM&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I still feel that I need to dive more into the subject. One thing that would be great is to peep into "deleted" row contents =-).&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4479546603787992182?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4479546603787992182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mvcc-revisited.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4479546603787992182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4479546603787992182'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-mvcc-revisited.html' title='PostgreSQL - MVCC revisited'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2765063346266867129</id><published>2012-02-05T14:41:00.000-06:00</published><updated>2012-02-06T22:10:15.602-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - SciPy. Concetrate on ideas not on implementations</title><content type='html'>I just discovered &lt;a href="http://www.scipy.org/"&gt;Scipy&lt;/a&gt;: &lt;br /&gt;&lt;blockquote&gt;SciPy (pronounced "Sigh Pie") is open-source software for mathematics, science, and engineering. It is also the name of a very popular conference on scientific programming with Python. The SciPy library depends on NumPy, which provides convenient and fast N-dimensional array manipulation. The SciPy library is built to work with NumPy arrays, and provides many user-friendly and efficient numerical routines such as routines for numerical integration and optimization. Together, they run on all popular operating systems, are quick to install, and are free of charge. NumPy and SciPy are easy to use, but powerful enough to be depended upon by some of the world's leading scientists and engineers. If you need to manipulate numbers on a computer and display or publish the results, give SciPy a try! &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I wanted to find the inverse of a matrix using plpython in the old way (row operations) ,so I could practice the python syntax, but now I'm just going to use SciPy. &lt;br /&gt;&lt;br /&gt;This is the guide to the linear algebra module:&lt;br /&gt;&lt;a href="http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html"&gt;http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# CREATE OR REPLACE FUNCTION inverse_matrix (m text)&lt;br /&gt;RETURNS text&lt;br /&gt;AS $$&lt;br /&gt;from scipy import linalg&lt;br /&gt;from numpy import matrix&lt;br /&gt;return linalg.inv(matrix(m));&lt;br /&gt;$$ LANGUAGE plpython2u;&lt;br /&gt;&lt;br /&gt;postgres=# select inverse_matrix($$'[1 3 5; 2 5 1; 2 3 8]'$$);&lt;br /&gt;-[ RECORD 1 ]--+----------------------&lt;br /&gt;inverse_matrix | [[-1.48  0.36  0.88]&lt;br /&gt;               |  [ 0.56  0.08 -0.36]&lt;br /&gt;               |  [ 0.16 -0.12  0.04]]&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As simple as that! =-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2765063346266867129?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2765063346266867129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/python-scipy-concetrate-on-ideas-not-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2765063346266867129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2765063346266867129'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/python-scipy-concetrate-on-ideas-not-on.html' title='Python - SciPy. Concetrate on ideas not on implementations'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5105240692097321414</id><published>2012-02-03T03:06:00.000-06:00</published><updated>2012-02-03T03:06:42.178-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Data Visualization - Word clouds</title><content type='html'>I'm using this javascript library to create simple word clouds:&lt;br&gt;&lt;a href="http://code.google.com/p/nebulos/wiki/UserGuide"&gt;http://code.google.com/p/nebulos/wiki/UserGuide&lt;/a&gt;&lt;br&gt;I just love creative people and javascript!&lt;br&gt;&lt;div id="mydiv" style="width: 300px; height: 200px;"&gt;&lt;/div&gt;&lt;script type="text/javascript"&gt;        var vis = new metaaps.nebulos(document.getElementById('mydiv'));        // or a predefined list of words and their weighing        var myTextList = [            {text: "PostgreSQL", weight: 80},            {text: "Python", weight: 100},{text: "Linux", weight: 100},{text: "Evolution", weight: 60},{text: "Databases", weight: 120},{text: "Documentaries", weight: 70},{text: "Piano", weight: 70},{text: "plpython", weight: 80},{text: "Logic", weight: 80},{text: "Maths", weight: 90},{text: "Psychology", weight: 60},{text: "Django", weight: 80},{text: "SQL", weight: 120},{text: "Satire", weight: 90},{text: "Love", weight: 140},{text: "Night", weight: 150},{text: "Meditation", weight: 140},{text: "Hacking", weight: 150},{text: "Darwin", weight: 140}        ];        vis.draw(myTextList);&lt;/script&gt;&lt;script type="text/javascript"&gt;      /*!       * Create an array of objects to be passed to jQCloud, each representing a word in the cloud       */      var word_list = [          {text: "Love", weight: 15},          {text: "Meditation", weight: 9, url: "http://jquery.com/", title: "I can haz URL"},          {text: "Reading", weight: 9},          {text: "Technology", weight: 7},          {text: "Jogging", weight: 10},          {text: "Sharing", weight: 8},          {text: "Sad Songs", weight: 9},          {text: "German", weight: 11},          {text: "English", weight: 12},          {text: "Memory", weight: 13},          {text: "Documentaries", weight: 14},          {text: "Javascript", weight: 18},          {text: "Darwin", weight: 16},          {text: "Piano", weight: 9},          {text: "Haikus", weight: 11}      ];      $(document).ready(function() {        // Call jQCloud on a jQuery object passing the word list as the first argument. Chainability of methods is maintained.        $("#example").jQCloud(word_list);      });    &lt;/script&gt;&lt;br&gt;&lt;br&gt;This is another example using: &lt;br&gt;&lt;a href="https://github.com/DukeLeNoir/jQCloud"&gt;https://github.com/DukeLeNoir/jQCloud&lt;/a&gt;&lt;div id="example" style="width: 650px; height: 450px; position: relative;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5105240692097321414?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5105240692097321414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-word-clouds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5105240692097321414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5105240692097321414'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/data-visualization-word-clouds.html' title='Data Visualization - Word clouds'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2354309923559477122</id><published>2012-02-01T16:33:00.001-06:00</published><updated>2012-02-01T16:33:46.778-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database design'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Domains</title><content type='html'>I'm studying good database design principles and discovered a beautiful concept : domains.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;You have a SQL database and you want a column to be restrained to one of a few values.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If the list will never change, and ordering is preset or doesn't matter: use an ENUM&lt;br /&gt;If the list might change but changes require programming, OR the list will not change but needs to be alpha sorted: use a DOMAIN&lt;br /&gt;If the list will change, and changes do not require other programming: use a lookup table.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://nigel.mcnie.name/blog/the-five-minute-guide-to-postgresql-domains-enums-on-steroids" target="_blank"&gt;&lt;br /&gt;http://nigel.mcnie.name/blog/the-five-minute-guide-to-postgresql-domains-enums-on-steroids&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For instance, I defined the following domains to enforce data validation to some extent.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE DOMAIN general_text TEXT&lt;br /&gt; CONSTRAINT max_length CHECK (LENGTH( VALUE ) &lt; 255 )&lt;br /&gt; ;&lt;br /&gt;&lt;br /&gt;CREATE DOMAIN email_string TEXT&lt;br /&gt; CONSTRAINT valid_email_form CHECK ( VALUE ~ '_*@_*._*')&lt;br /&gt; CONSTRAINT valid_email_length CHECK ( LENGTH(VALUE) &gt; 5)&lt;br /&gt; ;&lt;br /&gt; &lt;br /&gt;CREATE DOMAIN number_string TEXT&lt;br /&gt; CONSTRAINT valid_number CHECK (VALUE ~ '[0-9]+')&lt;br /&gt; ;&lt;br /&gt; &lt;br /&gt;CREATE DOMAIN telephone_string TEXT&lt;br /&gt; CONSTRAINT valid_telephone_form CHECK (VALUE ~ '[0-9\-]+')&lt;br /&gt; CONSTRAINT valid_telephone_length CHECK (LENGTH(VALUE) &gt;= 8 )&lt;br /&gt; ;&lt;br /&gt;&lt;br /&gt;CREATE DOMAIN counter int&lt;br /&gt; CONSTRAINT positive_number CHECK ( VALUE &gt;= 0)&lt;br /&gt; ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Defining a table that uses them:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE TABLE editoriales(&lt;br /&gt;  id serial primary key,&lt;br /&gt;  nombre general_text not null,&lt;br /&gt;  direccion general_text,&lt;br /&gt;  estado_id int,&lt;br /&gt;  pais_id int,&lt;br /&gt;  codigo_postal number_string , &lt;br /&gt;  telefono telephone_string&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The thing that got me into their use, is that they can be treated as if they were tables ,you can modify them / add new constraints and ... they are reusable!!!&lt;/b&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2354309923559477122?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2354309923559477122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-domains.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2354309923559477122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2354309923559477122'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/02/postgresql-domains.html' title='Postgresql - Domains'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8350851995736002780</id><published>2012-01-30T00:35:00.002-06:00</published><updated>2012-01-30T00:35:54.019-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plpython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - My first plpython function</title><content type='html'>I needed a function that is able to remove white spaces inside a string in order to rename table and columns to a more standard form. There are probably faster / easier ways to do this, but for now, this will suffice.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:python"&gt;postgres=# CREATE OR REPLACE FUNCTION remove_blanks (t text)&lt;br /&gt;RETURNS text&lt;br /&gt;AS $$&lt;br /&gt;import string&lt;br /&gt;result = ""&lt;br /&gt;for char in t:&lt;br /&gt;  if not(char in string.whitespace):&lt;br /&gt;    result = result + char&lt;br /&gt;return result&lt;br /&gt;$$ LANGUAGE plpython2u;&lt;br /&gt;CREATE FUNCTION&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# \df&lt;br /&gt;                                List of functions&lt;br /&gt; Schema |         Name          | Result data type | Argument data types |  Type  &lt;br /&gt;--------+-----------------------+------------------+---------------------+--------&lt;br /&gt;public | remove_blanks         | text             | t text              | normal&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;postgres=# select remove_blanks('This string contains spaces');&lt;br /&gt;      remove_blanks       &lt;br /&gt;--------------------------&lt;br /&gt; Thisstringcontainsspaces&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8350851995736002780?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8350851995736002780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/python-my-first-plpython-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8350851995736002780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8350851995736002780'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/python-my-first-plpython-function.html' title='Python - My first plpython function'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7479450018613856714</id><published>2012-01-29T12:03:00.000-06:00</published><updated>2012-01-29T12:04:59.945-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Python - Generating primes</title><content type='html'>I always make a generating primes program when I'm learning a new language, as if it were my "hello world". I'm using python 3.2&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:python"&gt;import math&lt;br /&gt;&lt;br /&gt;def cribe(size):&lt;br /&gt;    nums = [0]*size&lt;br /&gt;    for i in range(2,int(math.sqrt(size))):&lt;br /&gt;        if(nums[i] == 1):&lt;br /&gt;            continue&lt;br /&gt;        for j in range(2,size):&lt;br /&gt;            if i * j &gt; size - 1:&lt;br /&gt;                break&lt;br /&gt;            if nums[i*j] == 0:&lt;br /&gt;                nums[i*j] = 1&lt;br /&gt;    for i in range(2,size):&lt;br /&gt;        if(nums[i] ==0 ):&lt;br /&gt;            print(i)        &lt;br /&gt;limit = input('Up to what number? ')&lt;br /&gt;cribe(int(limit))&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;My IDE is by the moment aptana-studio, haven't found anything better.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://t0.gstatic.com/images?q=tbn:ANd9GcTuLLL6_SVgDLhQURMLprovs6bl--i_1etBmxeYkAKGpvMxqB3b" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="159" width="318" src="http://t0.gstatic.com/images?q=tbn:ANd9GcTuLLL6_SVgDLhQURMLprovs6bl--i_1etBmxeYkAKGpvMxqB3b" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;a href=" http://aptana.com/" target="_blank"&gt;&lt;br /&gt;http://aptana.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7479450018613856714?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7479450018613856714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/python-generating-primes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7479450018613856714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7479450018613856714'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/python-generating-primes.html' title='Python - Generating primes'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3035064673165677551</id><published>2012-01-29T01:47:00.001-06:00</published><updated>2012-01-29T02:54:40.636-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data visualization'/><title type='text'>Flot - Attractive Javascript plotting for jQuery - MIT License</title><content type='html'>&lt;head&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;$(function () {var data = [                { label: "Oficina1",  data: [[1,10]]},                { label: "Oficina2",  data: [[1,30]]},                { label: "Oficina3",  data: [[1,90]]},                { label: "Oficina4",  data: [[1,70]]},                { label: "Oficina5",  data: [[1,80]]},                { label: "Oficina6",  data: [[1,0]]}           ];        // DEFAULT    $.plot($("#placeholder"), data,         {                series: {                        pie: {                                 innerRadius: 0.5,                                show: true,                          label: {                                show: true                        }                        }                }        });})&lt;/script&gt;&lt;br /&gt;&lt;head&gt;&lt;br /&gt;&lt;body&gt;&lt;br /&gt;&lt;div id="placeholder" style="width:800px;height:500px"&gt;&lt;/div&gt;&lt;/body&gt;&lt;br /&gt;I just found out about this open source chart plotting library. This is quite a static example, but a very wide array of functionalities are available, many kinds of interactions with the charts are possible. I intent to use it in my personal proyects of data visualization.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/flot/" target="_blank"&gt;http://code.google.com/p/flot/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I tailored and customized this one, but here are some other examples:&lt;br /&gt;&lt;a href="http://people.iola.dk/olau/flot/examples/" target="_blank"&gt;http://people.iola.dk/olau/flot/examples/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3035064673165677551?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3035064673165677551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/flot.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3035064673165677551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3035064673165677551'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/flot.html' title='Flot - Attractive Javascript plotting for jQuery - MIT License'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2018887989710883585</id><published>2012-01-27T18:27:00.002-06:00</published><updated>2012-01-27T18:27:28.351-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - Forbid access to a database temporarily.</title><content type='html'>I found out about this feature, thanks to someone who asked how to do this in the postgresql-es-ayuda list.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;Disable connections to a PostgreSQL database temporarily&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Today I had to disable access to some PostgreSQL databases temporarily. This can be easily done using pgAdmin. Under database properties, set "Connection Limit " to 0 from the default of -1. The corresponding SQL statement is&lt;br /&gt;&lt;pre class="brush:sql"&gt; ALTER DATABASE "dbname" WITH CONNECTION LIMIT = 0;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When you are ready to allow connections, change this back to -1.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://vimalkumar.in/2011/01/27/disable-connections-to-a-postgresql-database-temporarily/" target="_blank"&gt;http://vimalkumar.in/2011/01/27/disable-connections-to-a-postgresql-database-temporarily/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2018887989710883585?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2018887989710883585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-forbid-access-to-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2018887989710883585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2018887989710883585'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-forbid-access-to-database.html' title='PostgreSQL - Forbid access to a database temporarily.'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6961135324116455206</id><published>2012-01-27T13:01:00.001-06:00</published><updated>2012-01-27T20:49:23.381-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - Renaming tables  and columns with mixed case names</title><content type='html'>I just imported a mysql database to postgresql, the thing is that tables and columns are written using both upper and lower case characters and we don't like that naming schema.&lt;br /&gt;&lt;br /&gt;1. I have this query that lists almost all objects in a particular schema (I stored it as a view named "tables").&lt;br /&gt;&lt;br /&gt;view "tables"&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT n.nspname as Schema,&lt;br /&gt;  c.relname as Name,&lt;br /&gt;  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' END as Type,&lt;br /&gt;  pg_catalog.obj_description(c.oid, 'pg_class') as Description&lt;br /&gt;FROM pg_catalog.pg_class c&lt;br /&gt;     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace&lt;br /&gt;WHERE c.relkind IN ('r','')&lt;br /&gt;      AND n.nspname &lt;&gt; 'pg_catalog'&lt;br /&gt;      AND n.nspname &lt;&gt; 'information_schema'&lt;br /&gt;      AND n.nspname !~ '^pg_toast'&lt;br /&gt;  AND pg_catalog.pg_table_is_visible(c.oid)&lt;br /&gt;ORDER BY 1,2;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, I generate the needed SQL to rename the tables:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT 'ALTER TABLE ' || $$"$$ || name ||$$"$$||' RENAME TO '|| lower(name)||' ; ' FROM (SELECT name FROM tables WHERE type = 'table') AS t1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;So far so good. But then, how to you rename table columns?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Well, this is my base query (attributes) for that:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT a.attname,&lt;br /&gt;  pg_catalog.format_type(a.atttypid, a.atttypmod),&lt;br /&gt;  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)&lt;br /&gt;   FROM pg_catalog.pg_attrdef d&lt;br /&gt;   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),&lt;br /&gt;  a.attnotnull, a.attnum,&lt;br /&gt;  (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t&lt;br /&gt;   WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation &lt;&gt; t.typcollation) AS attcollation&lt;br /&gt;FROM pg_catalog.pg_attribute a&lt;br /&gt;WHERE a.attrelid = '33954' AND a.attnum &gt; 0 AND NOT a.attisdropped&lt;br /&gt;ORDER BY a.attnum;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The part that needs to be parametrized is : WHERE a.attrelid = ? &lt;br /&gt;&lt;br /&gt;I might also use this one:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT&lt;br /&gt;    a.attname as "Column",&lt;br /&gt;    pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"&lt;br /&gt;    &lt;br /&gt;FROM&lt;br /&gt;    pg_catalog.pg_attribute a&lt;br /&gt;WHERE&lt;br /&gt;    a.attnum &gt; 0&lt;br /&gt;    AND NOT a.attisdropped&lt;br /&gt;    AND a.attrelid = (&lt;br /&gt;        SELECT c.oid&lt;br /&gt;        FROM pg_catalog.pg_class c&lt;br /&gt;            LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace&lt;br /&gt;        WHERE c.relname ~ '^(actividad)$'&lt;br /&gt;            AND pg_catalog.pg_table_is_visible(c.oid)&lt;br /&gt;    )&lt;br /&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;a href="http://bytes.com/topic/postgresql/answers/692471-how-get-column-names-table"&gt;&lt;br /&gt;http://bytes.com/topic/postgresql/answers/692471-how-get-column-names-table&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How to obtain the table's oid ?&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.0/static/datatype-oid.html"&gt;http://www.postgresql.org/docs/8.0/static/datatype-oid.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT oid::text FROM pg_attribute WHERE attrelid = 'mytable'::regclass;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For  instance, obtaining the oid of the table "activity" in my database:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT attrelid FROM pg_attribute WHERE attrelid = 'actividad'::regclass limit 1;&lt;br /&gt;-[ RECORD 1 ]---&lt;br /&gt;attrelid | 33954&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which is the number that my query "attributes" is embedding in the query. I'll finish this post when  I get home.&lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------&lt;br /&gt;Putting together all that info, I came to this query:&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE VIEW columns AS SELECT n.nspname as Schema,&lt;br /&gt;  c.relname as Name,&lt;br /&gt;  a.attname as Col &lt;br /&gt;FROM pg_catalog.pg_class c&lt;br /&gt;     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace&lt;br /&gt;     LEFT JOIN pg_catalog.pg_attribute a ON a.attrelid = c.relname::regclass    &lt;br /&gt;WHERE &lt;br /&gt;       n.nspname &lt;&gt; 'pg_catalog'&lt;br /&gt;      AND n.nspname &lt;&gt; 'information_schema'&lt;br /&gt;      AND n.nspname !~ '^pg_toast'&lt;br /&gt;  AND pg_catalog.pg_table_is_visible(c.oid)&lt;br /&gt;  AND c.relkind = 'r'&lt;br /&gt;  AND a.attnum &gt; 0&lt;br /&gt;ORDER BY 1,2&lt;br /&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now only remains switching to lower case those table columns:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;select 'ALTER TABLE ' ||schema||'.'||name||' RENAME COLUMN '||$$"$$||col||$$"$$||' TO '||$$"$$||lower(col)||$$"$$||' ;' FROM columns;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I  put the column's name double quoted, as another issue is having those names with blank spaces between words, for which I'll probably need a function, gosh!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6961135324116455206?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6961135324116455206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-renaming-tables-with-mixed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6961135324116455206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6961135324116455206'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-renaming-tables-with-mixed.html' title='PostgreSQL - Renaming tables  and columns with mixed case names'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3285379502129334020</id><published>2012-01-27T02:48:00.003-06:00</published><updated>2012-01-27T02:54:35.870-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Django and python - First steps</title><content type='html'>I've always wanted to learn python, and I've always wanted to learn to use a web framework. I'm giving Django a try.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.djangoproject.com/" target="_blank"&gt;https://www.djangoproject.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm developing my first app (tutorial 1), but they suggest that you get comfortable with the api before going through the second one.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img692.imageshack.us/img692/5622/djangowl.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="503" width="729" src="http://img692.imageshack.us/img692/5622/djangowl.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I'd never thought that developing a database driven web application would be so easy. I'm starting to like it very much (despite those "expected indent" messages =-) ).&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3285379502129334020?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3285379502129334020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/django-first-steps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3285379502129334020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3285379502129334020'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/django-first-steps.html' title='Django and python - First steps'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2250431337553124720</id><published>2012-01-26T17:48:00.002-06:00</published><updated>2012-01-27T12:36:00.690-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MySQL'/><title type='text'>MySQL - mini-migration to PostgreSQL</title><content type='html'>Today I had to perform a "nano-migration" from mysql (from a mysql dump) to postgresql, but gee I needed a refresher.&lt;br /&gt;&lt;br /&gt;These links were very useful.&lt;br /&gt;&lt;br /&gt;To install mysql (on opensuse).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.opensuse.org/SDB:MySQL_installation" target="_blank"&gt;http://en.opensuse.org/SDB:MySQL_installation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.debuntu.org/how-to-create-a-mysql-database-and-set-privileges-to-a-user"&gt;http://www.debuntu.org/how-to-create-a-mysql-database-and-set-privileges-to-a-user&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To import the sql dump to mysql.&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/faq/import-mysql-dumpfile-sql-datafile-into-my-database/"&gt;http://www.cyberciti.biz/faq/import-mysql-dumpfile-sql-datafile-into-my-database/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enterprisedb offers a migration wizard for this kind of boring and burdensome chores:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.enterprisedb.com/docs/en/8.4/migrate/Table%20of%20Contents.htm#TopOfPage"&gt;http://www.enterprisedb.com/docs/en/8.4/migrate/Table%20of%20Contents.htm#TopOfPage&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img10.imageshack.us/img10/6698/mysqlmigration.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="630" width="589" src="http://img10.imageshack.us/img10/6698/mysqlmigration.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Except that it didn't do an automatic conversion of the datetime mysql type, I'm really satisfied with the results.&lt;br /&gt;&lt;br /&gt;There are also lots of scripts and other tools available.&lt;br /&gt;h&lt;a href="http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL"&gt;ttp://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other interesting references:&lt;br /&gt;&lt;a href="http://www.raditha.com/postgres/"&gt;http://www.raditha.com/postgres/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2250431337553124720?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2250431337553124720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/mysql-mini-migration-to-postgresql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2250431337553124720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2250431337553124720'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/mysql-mini-migration-to-postgresql.html' title='MySQL - mini-migration to PostgreSQL'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8014253033537279064</id><published>2012-01-24T15:57:00.001-06:00</published><updated>2012-01-25T01:21:33.044-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opensuse'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux - OpenSUSE startup script with systemd</title><content type='html'>I've been struggling with my opensuse box to execute some scripts as root when the system starts, and I just found the answer to why it wasn't working.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;I have found out that in openSUSE 12.1, some startup scripts do not operate due to the usage of systemd. systemd really speeds up system startup by running the many startup processes in parallel and avoids the usage of shell scripts altogether. That is is good for speed, but not good if you are in need of running something in openSUSE as root when the system is restarted.&lt;a href="http://forums.opensuse.org/blogs/jdmcdaniel3/systemd-using-after-local-script-opensuse-12-1-71/" target="_blank"&gt;(1)&lt;/a&gt; &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;1. We need to create the text file after-local.service (shown below) in the folder /lib/systemd/system as root (Alt-F2):&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;br /&gt;kdesu kwrite /lib/systemd/system/after-local.service&lt;br /&gt;&lt;br /&gt;This is what you put into this file and save it:&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;br /&gt;#  This file is part of systemd.&lt;br /&gt;#&lt;br /&gt;#  systemd is free software; you can redistribute it and/or modify it&lt;br /&gt;#  under the terms of the GNU General Public License as published by&lt;br /&gt;#  the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;#  (at your option) any later version.&lt;br /&gt;&lt;br /&gt;[Unit]&lt;br /&gt;Description=/etc/init.d/after.local Compatibility&lt;br /&gt;ConditionFileIsExecutable=/etc/init.d/after.local&lt;br /&gt;&lt;br /&gt;[Service]&lt;br /&gt;Type=oneshot&lt;br /&gt;ExecStart=/etc/init.d/after.local&lt;br /&gt;TimeoutSec=0&lt;br /&gt;StandardOutput=tty&lt;br /&gt;RemainAfterExit=yes&lt;br /&gt;SysVStartPriority=99&lt;br /&gt;&lt;br /&gt;[Install]&lt;br /&gt;WantedBy=multi-user.target&lt;br /&gt;&lt;br /&gt;2. Next, we need to add the after-local.service to systemd. Open up a terminal session and run the following command:&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;br /&gt;sudo systemctl enable /lib/systemd/system/after-local.service&lt;br /&gt;&lt;br /&gt;3. Finally, you need to edit the file /etc/init.d/after.local as root and add in the stuff you want to run as root when you startup openSUSE &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8014253033537279064?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8014253033537279064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/linux-opensuse-startup-script-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8014253033537279064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8014253033537279064'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/linux-opensuse-startup-script-with.html' title='Linux - OpenSUSE startup script with systemd'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5065730424579965443</id><published>2012-01-23T02:31:00.001-06:00</published><updated>2012-01-23T02:35:34.961-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL internals'/><title type='text'>Postgresql - Studying the MVCC model</title><content type='html'>I intent to understand PostgreSQL throughly. I found a great presentation here:&lt;br /&gt;&lt;b&gt;PostgreSQL Through Pictures.&lt;/b&gt;&lt;br /&gt;&lt;a href="http://momjian.us/main/writings/pgsql/internalpics.pdf"&gt;http://momjian.us/main/writings/pgsql/internalpics.pdf&lt;/a&gt;&lt;br /&gt;It has a section dealing with this particular issue.&lt;br /&gt;&lt;br /&gt;I also like this resource which depicts a practical example.&lt;br /&gt;&lt;a href="http://devcenter.heroku.com/articles/postgresql-concurrency"&gt;http://devcenter.heroku.com/articles/postgresql-concurrency&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I find interesting following the examples illustrated with the explanations, I never learn more than when doing, but for now, I'm a bit tired and it's quite late.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5065730424579965443?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5065730424579965443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-studying-mvcc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5065730424579965443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5065730424579965443'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-studying-mvcc.html' title='Postgresql - Studying the MVCC model'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2582828712085773876</id><published>2012-01-20T23:18:00.000-06:00</published><updated>2012-01-20T23:20:02.618-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Installing Postgresql 9.1 on Amazon Linux</title><content type='html'>First of all, there's such thing as a Linux from Amazon&lt;br /&gt;&lt;br /&gt;&lt;a href="http://aws.amazon.com/amazon-linux-ami/"&gt;http://aws.amazon.com/amazon-linux-ami/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Amazon Linux AMI&lt;br /&gt;&lt;br /&gt;The Amazon Linux AMI is a supported and maintained Linux image provided by Amazon Web Services for use on Amazon Elastic Compute Cloud (Amazon EC2). It is designed to provide a stable, secure, and high performance execution environment for applications running on Amazon EC2. It also includes packages that enable easy integration with AWS, including launch configuration tools and many popular AWS libraries and tools. Amazon Web Services provides ongoing security and maintenance updates to all instances running the Amazon Linux AMI. The Amazon Linux AMI is provided at no additional charge to Amazon EC2 users.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;It comes bundled with postgresql 8.4 which is good enough, but gee, I like bleeding edge stuff and postgresql has improved much since  =-)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I followed this tutorial made by some altruistic guy that also shares his discoveries (what would it be the internet without people like that?)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://"&gt;http://imperialwicket.com/aws-install-postgresql-90-on-amazon-linux&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And everything went smoothly, so smoothly that I'm smiling =-).&lt;br /&gt;&lt;br /&gt;I'm reproducing the important parts here as a  backup.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;Update the yum repositories&lt;br /&gt;&lt;br /&gt;I want to install the latest stable postgresql from pgrpms.org. We could just download the rpm and manually install from the file, but that inevitably results in some dependency issues. I prefer to configure an alternate yum repository for a particular keyword. So we need to update the configuration for the Amazon repositories (be sure to update both "main" and "updates", and do not forget the asterisk).&lt;br /&gt;&lt;br /&gt;sudo vim /etc/yum.repos.d/amzn-main.repo&lt;br /&gt;[At the bottom of the "[amzn-main]" section, after "enabled=1", add "exclude=postgresql*"]&lt;br /&gt;sudo vim /etc/yum.repos.d/amzn-updates.repo&lt;br /&gt;[Add the same exclude to the bottom of the "[amzn-updates]" section]&lt;br /&gt;&lt;br /&gt;Download the repository/key installation rpm from pgrpms.org&lt;br /&gt;&lt;br /&gt;wget http://yum.pgrpms.org/reporpms/9.0/pgdg-redhat-9.0-2.noarch.rpm&lt;br /&gt;sudo rpm -ivh pgdg-redhat-9.0-2.noarch.rpm&lt;br /&gt;&lt;br /&gt;Since this rpm is generated for RHEL6, we need to make a minor change to the resulting /etc/yum.repos.d/pgdg-90-redhat.repo file. Update the URLs, replacing the $releaseserver value with '6'. The Amazon Linux $releaseserver value is a date, instead of the primary version number that this repository configuration is expecting.&lt;br /&gt;&lt;br /&gt;sudo vim /etc/yum.repos.d/pgdg-90-redhat.repo&lt;br /&gt;&lt;br /&gt;The updated base url values should look like this (update two of them):&lt;br /&gt;&lt;br /&gt;## ORIGINAL&lt;br /&gt;# baseurl=http://yum.pgrpms.org/9.0/redhat/rhel-$releasever-$basearch&lt;br /&gt;## UPDATED&lt;br /&gt;baseurl=http://yum.pgrpms.org/9.0/redhat/rhel-6-$basearch&lt;br /&gt;&lt;br /&gt;All we have done is told yum that it should use the amzn repositories for everything except packages that meet the "postgresql*" criteria. After that, install a new repository configuration for the pgrpms.org repository.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2582828712085773876?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2582828712085773876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-installing-postgresql-91-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2582828712085773876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2582828712085773876'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-installing-postgresql-91-on.html' title='Postgresql - Installing Postgresql 9.1 on Amazon Linux'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8709356095372332341</id><published>2012-01-20T23:16:00.001-06:00</published><updated>2012-01-20T23:19:29.176-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webProgramming'/><title type='text'>webProgramming - http://api.themoviedb.org.  Getting info about movies</title><content type='html'>I have a friend that among other things sells movies. I decided to give him a hand to fetch the relevant info about them so he can publish his own movie catalog. &lt;br /&gt;With the api from http://api.themoviedb.org, it couldn't be easier.  You need to request an access key first (it's free) for personal use or to develop an open source application.&lt;br /&gt;&lt;br /&gt;I'm using this implementation for php&lt;br /&gt;&lt;a href="http://sourceforge.net/projects/simpletmdb/"&gt;http://sourceforge.net/projects/simpletmdb/&lt;/a&gt;&lt;br /&gt;and an example by  Dan Bettles &lt;dan@danbettles.net&gt;&lt;br /&gt;&lt;br /&gt;Fetching the info is as simple as this:&amp;nbsp;&lt;/dan@danbettles.net&gt;&lt;br /&gt;&lt;br /&gt;&lt;dan@danbettles.net&gt;&lt;br /&gt;&lt;/dan@danbettles.net&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&lt;?php&lt;br /&gt;/**&lt;br /&gt; * SimpleTmdb Demo&lt;br /&gt; *&lt;br /&gt; * @author Dan Bettles &lt;dan@danbettles.net&gt;&lt;br /&gt; * modified a little bit by René Romero&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;$title = basename(__FILE__, '.php') . ' Demo';&lt;br /&gt;&lt;br /&gt;$oResults = false;&lt;br /&gt;&lt;br /&gt;if (isset($_GET['sendRequest'])) {&lt;br /&gt;    require_once dirname(dirname(__DIR__)) . '/include/boot.php';&lt;br /&gt;    $oResults = simpletmdb\Tmdb::create('here you put your access key')&lt;br /&gt;        -&gt;Movie&lt;br /&gt;        -&gt;getInfo($_GET['id']);&lt;br /&gt;}&lt;br /&gt;?&gt;&lt;br /&gt;&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;&lt;br /&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"&gt;&lt;br /&gt;    &lt;head&gt;&lt;br /&gt;        &lt;meta http-equiv="content-type" content="text/html; charset=UTF-8" /&gt;&lt;br /&gt;        &lt;title&gt;&lt;?php echo $title ?&gt;&lt;/title&gt;&lt;br /&gt;        &lt;link rel="stylesheet" type="text/css" href="main.css" /&gt;&lt;br /&gt;    &lt;/head&gt;&lt;br /&gt;    &lt;body&gt;&lt;br /&gt;        &lt;h1&gt;&lt;?php echo $title ?&gt;&lt;/h1&gt;&lt;form method="get" action="&lt;?php echo $_SERVER['PHP_SELF'] ?&gt;"&gt;&lt;br /&gt;            &lt;p&gt;&lt;label&gt;&lt;span&gt;ID&lt;/span&gt;&lt;input type="text" name="id" /&gt;&lt;/label&gt;&lt;/p&gt;&lt;p&gt;&lt;input type="submit" name="sendRequest" value="Go" /&gt;&lt;/p&gt;&lt;/form&gt;&lt;?php if (isset($_GET['sendRequest'])) { ?&gt;&lt;br /&gt;            &lt;?php if ($oResults) { ?&gt;&lt;br /&gt;                        &lt;?php echo $oResults-&gt;id ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;name ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;tagline ?&gt; |&lt;br /&gt;            &lt;?php echo 'http://www.imdb.com/title/'.$oResults-&gt;imdb_id ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;certification ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;language ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;released ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;homepage ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;url ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;runtime ?&gt; |&lt;br /&gt;            &lt;?php echo $oResults-&gt;trailer ?&gt; |&lt;br /&gt;                        &lt;?php if ($oImages = $oResults-&gt;images-&gt;xpath("image[(@type = 'poster') and (@size = 'cover')]")) { ?&gt;&lt;br /&gt;                        &lt;?php echo $oImages[0]['url'] ?&gt;&lt;br /&gt;                        &lt;?php } ?&gt; |&lt;br /&gt;                        &lt;?php echo $oResults-&gt;overview ?&gt;|&lt;br /&gt;               &lt;?php if ($oResults-&gt;categories &amp;&amp; ($oGenres = $oResults-&gt;categories-&gt;xpath("category[@type = 'genre']"))) { ?&gt;&lt;br /&gt;                            &lt;?php foreach ($oGenres as $oGenre) { ?&gt;&lt;br /&gt;                            &lt;?php echo $oGenre['name'].',' ?&gt;&lt;br /&gt;                            &lt;?php } ?&gt;&lt;br /&gt;            &lt;?php } ?&gt;&lt;br /&gt;        &lt;?php echo '|' ?&gt;&lt;br /&gt;        &lt;?php if ($oResults-&gt;studios &amp;&amp; ($oStudios = $oResults-&gt;studios-&gt;xpath("studio"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oStudios as $oStudio) { ?&gt;&lt;br /&gt;                &lt;?php echo $oStudio['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt; |&lt;br /&gt;               &lt;?php if ($oResults-&gt;countries &amp;&amp; ($oCountries = $oResults-&gt;countries-&gt;xpath("country"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCountries as $oCountry) { ?&gt;           &lt;br /&gt;        &lt;?php echo $oCountry['name'].',' ?&gt;&lt;br /&gt;        &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;                &lt;?php if ($oResults-&gt;cast &amp;&amp; ($oCast = $oResults-&gt;cast-&gt;xpath("person[@job = 'Director']"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCast as $oDirector) { ?&gt;&lt;br /&gt;                &lt;?php echo $oDirector['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;        &lt;?php if ($oResults-&gt;cast &amp;&amp; ($oCast = $oResults-&gt;cast-&gt;xpath("person[@job = 'Producer']"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCast as $oProducer) { ?&gt;&lt;br /&gt;                &lt;?php echo $oProducer['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;        &lt;?php if ($oResults-&gt;cast &amp;&amp; ($oCast = $oResults-&gt;cast-&gt;xpath("person[@job = 'Original Music Composer']"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCast as $oMusic) { ?&gt;&lt;br /&gt;                &lt;?php echo $oMusic['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;        &lt;?php if ($oResults-&gt;cast &amp;&amp; ($oCast = $oResults-&gt;cast-&gt;xpath("person[@job = 'Author']"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCast as $oWritter) { ?&gt;&lt;br /&gt;                &lt;?php echo $oWritter['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;        &lt;?php if ($oResults-&gt;cast &amp;&amp; ($oCast = $oResults-&gt;cast-&gt;xpath("person[@job = 'Actor']"))){?&gt;&lt;br /&gt;                &lt;?php foreach ($oCast as $oActor) { ?&gt;&lt;br /&gt;                &lt;?php echo $oActor['name'].',' ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;&lt;br /&gt;                &lt;?php } ?&gt;|&lt;br /&gt;            &lt;?php } else { ?&gt;&lt;br /&gt;                &lt;p&gt;Movie not found&lt;/p&gt;&lt;?php } ?&gt;&lt;br /&gt;        &lt;?php } ?&gt;&lt;br /&gt;    &lt;/body&gt;&lt;br /&gt;&lt;/html&gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;TODO: Batch processing, and remove trailing commas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8709356095372332341?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8709356095372332341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/webprogramming-httpapithemoviedborg.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8709356095372332341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8709356095372332341'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/webprogramming-httpapithemoviedborg.html' title='webProgramming - http://api.themoviedb.org.  Getting info about movies'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1369959031198605792</id><published>2012-01-14T20:15:00.000-06:00</published><updated>2012-01-14T20:15:29.981-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>PostgreSQL. fsync and speed</title><content type='html'>I was startled to read about data corruption in PostgreSQL in the pgsql-general list, I had never heard  of such thing. In Oracle it struck me as well, the ones that get corrupted once in a while are the database blocks in the database buffer, and there's nothing to do about it, but nevermind. &lt;br /&gt;It turns out that the person having this issue was running his server with the &lt;b&gt;fsync&lt;/b&gt; option turned off.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;What does fsync do?&lt;/b&gt;&lt;br /&gt;&lt;blockquote&gt;The fsync() function can be used by an application to indicate that all data for the open file description named by fildes is to be transferred to the storage device associated with the file described by fildes in an implementation-dependent manner. The fsync() function does not return until the system has completed that action or until an error is detected. &lt;/blockquote&gt;&lt;a href="http://pubs.opengroup.org/onlinepubs/7908799/xsh/fsync.html"&gt;http://pubs.opengroup.org/onlinepubs/7908799/xsh/fsync.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So changes to a file are made over a memory buffer and then you close it or use fsync to "commit" the changes to disk. If you disable it, might gain some boost on your database speed, but under the risk of loosing data should a system crash or error occur.&lt;br /&gt;&lt;br /&gt;As a side note, I stumbled upon this stack overflow question:&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/3736533/why-doesnt-mongodb-use-fsync"&gt;http://stackoverflow.com/questions/3736533/why-doesnt-mongodb-use-fsync&lt;/a&gt;&lt;br /&gt;Where never_had_a_name asks why on earth doesn't MongoDB use fsync on each write, and the most important answer is:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;This is going against ACID, more specifically against the D, which stands for durability:&lt;br /&gt;Durability [guarantees] that once the user has been notified of a transaction's success the transaction will not be lost, the transaction's data changes will survive system failure, and that all integrity constraints have been satisfied, so the DBMS won't need to reverse the transaction.&lt;br /&gt;&lt;br /&gt;ACID properties mostly apply to traditional RDBMS systems. NoSQL systems, which includes MongoDB, give up on one or more of the ACID properties in order to achieve better scalability. In MongoDB's case durability has been sacrificed for better performance when handling large amounts of updates.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Should the necessity arise, here is one good piece of advice from Craig Ringer in the pgsql-general discussion list:&lt;br /&gt;&lt;blockquote&gt;Since you were running with fsync off, you must have had good backups or replication configured, because the documentation warns you that running with fsync=off will probably destroy your data and is only for expert users.&lt;br /&gt;&lt;br /&gt;In case you don't have a current replica or backup: first, before you do ANYTHING ELSE follow the instructions here:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/Corruption"&gt;http://wiki.postgresql.org/wiki/Corruption &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now - **AFTER** following the instructions above - start the database in single user recovery mode. See:&lt;br /&gt;&lt;a href=" http://www.postgresql.org/docs/current/static/app-postgres.html"&gt;&lt;br /&gt;http://www.postgresql.org/docs/current/static/app-postgres.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;where the "--single" command line argument for the "postgres" executable is documented.&lt;br /&gt;&lt;br /&gt;Once you have a single user mode backend running you can REINDEX then shut the backend down, start back up in multi-user mode, and see if you have any luck. &lt;/blockquote&gt;&lt;br /&gt;IMHO I would never sacrifice data integrity over performance, but you never know when a client would come with a problem like this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1369959031198605792?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1369959031198605792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-fsync-and-speed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1369959031198605792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1369959031198605792'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-fsync-and-speed.html' title='PostgreSQL. fsync and speed'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4925994278839952375</id><published>2012-01-14T18:22:00.001-06:00</published><updated>2012-01-14T20:15:40.142-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>PostgreSQL - export to CSV or any other character delimited files</title><content type='html'>Just a small tip. &lt;br /&gt;&lt;br /&gt;Exporting output to CSV format.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# \copy (select * from pgbench_history limit 30) TO 'test.csv' CSV&lt;br /&gt;&lt;br /&gt;pgbenchdb=# \! cat test.csv&lt;br /&gt;98,3,256655,-2623,2012-01-11 17:28:15.200909,&lt;br /&gt;43,2,94378,2717,2012-01-11 17:28:15.200909,&lt;br /&gt;46,1,414961,1716,2012-01-11 17:28:15.201082,&lt;br /&gt;45,8,246477,3341,2012-01-11 17:28:15.200927,&lt;br /&gt;84,7,743181,-1348,2012-01-11 17:28:15.201073,&lt;br /&gt;20,1,713970,4518,2012-01-11 17:28:15.20119,&lt;br /&gt;76,8,778718,-2588,2012-01-11 17:28:15.200988,&lt;br /&gt;9,2,683187,-1675,2012-01-11 17:28:15.201074,&lt;br /&gt;71,3,793922,-748,2012-01-11 17:28:15.261927,&lt;br /&gt;93,6,484349,1816,2012-01-11 17:28:15.261776,&lt;br /&gt;2,4,47256,2383,2012-01-11 17:28:15.261615,&lt;br /&gt;64,2,567480,-4884,2012-01-11 17:28:15.201201,&lt;br /&gt;75,8,716626,-293,2012-01-11 17:28:15.2013,&lt;br /&gt;82,9,74376,-4112,2012-01-11 17:28:15.284261,&lt;br /&gt;74,5,13936,-2220,2012-01-11 17:28:15.284299,&lt;br /&gt;70,3,365642,-4313,2012-01-11 17:28:15.284375,&lt;br /&gt;81,4,82626,2974,2012-01-11 17:28:15.285328,&lt;br /&gt;27,2,379620,3392,2012-01-11 17:28:15.261669,&lt;br /&gt;87,8,561117,-153,2012-01-11 17:28:15.284997,&lt;br /&gt;85,9,953844,-4951,2012-01-11 17:28:15.296038,&lt;br /&gt;38,5,447869,-3591,2012-01-11 17:28:15.307329,&lt;br /&gt;73,4,130721,4496,2012-01-11 17:28:15.307251,&lt;br /&gt;1,7,200428,-4388,2012-01-11 17:28:15.307193,&lt;br /&gt;72,2,907918,-4323,2012-01-11 17:28:15.216612,&lt;br /&gt;30,1,76931,4226,2012-01-11 17:28:15.318388,&lt;br /&gt;27,7,87543,3849,2012-01-11 17:28:15.307277,&lt;br /&gt;5,9,963441,-2585,2012-01-11 17:28:15.307221,&lt;br /&gt;19,4,584590,-2414,2012-01-11 17:28:15.331634,&lt;br /&gt;78,5,543756,476,2012-01-11 17:28:15.333069,&lt;br /&gt;99,10,867181,-2597,2012-01-11 17:28:15.332944,&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;&lt;br /&gt;About \copy:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;\copy invokes COPY FROM STDIN or COPY TO STDOUT, and then fetches/stores the data in a file accessible to the psql client. Thus, file accessibility and access rights depend on the client rather than the server when \copy is used.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Or using any other delimiter instead of comma, '|' for instance which I regard as being more reliable as commas are sometimes used inside text fields.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# COPY (select * from pgbench_history limit 30) TO '/var/lib/pgsql/test.csv' WITH DELIMITER '|';&lt;br /&gt;COPY 30&lt;br /&gt;-- with this variant of the copy command only absolute paths are allowed&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the another variant:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# \copy (select * from pgbench_history limit 30) TO 'test.csv' WITH DELIMITER '|';&lt;br /&gt;pgbenchdb=# \! cat test.csv&lt;br /&gt;98|3|256655|-2623|2012-01-11 17:28:15.200909|\N&lt;br /&gt;43|2|94378|2717|2012-01-11 17:28:15.200909|\N&lt;br /&gt;46|1|414961|1716|2012-01-11 17:28:15.201082|\N&lt;br /&gt;45|8|246477|3341|2012-01-11 17:28:15.200927|\N&lt;br /&gt;84|7|743181|-1348|2012-01-11 17:28:15.201073|\N&lt;br /&gt;20|1|713970|4518|2012-01-11 17:28:15.20119|\N&lt;br /&gt;76|8|778718|-2588|2012-01-11 17:28:15.200988|\N&lt;br /&gt;9|2|683187|-1675|2012-01-11 17:28:15.201074|\N&lt;br /&gt;71|3|793922|-748|2012-01-11 17:28:15.261927|\N&lt;br /&gt;93|6|484349|1816|2012-01-11 17:28:15.261776|\N&lt;br /&gt;2|4|47256|2383|2012-01-11 17:28:15.261615|\N&lt;br /&gt;64|2|567480|-4884|2012-01-11 17:28:15.201201|\N&lt;br /&gt;75|8|716626|-293|2012-01-11 17:28:15.2013|\N&lt;br /&gt;82|9|74376|-4112|2012-01-11 17:28:15.284261|\N&lt;br /&gt;74|5|13936|-2220|2012-01-11 17:28:15.284299|\N&lt;br /&gt;70|3|365642|-4313|2012-01-11 17:28:15.284375|\N&lt;br /&gt;81|4|82626|2974|2012-01-11 17:28:15.285328|\N&lt;br /&gt;27|2|379620|3392|2012-01-11 17:28:15.261669|\N&lt;br /&gt;87|8|561117|-153|2012-01-11 17:28:15.284997|\N&lt;br /&gt;85|9|953844|-4951|2012-01-11 17:28:15.296038|\N&lt;br /&gt;38|5|447869|-3591|2012-01-11 17:28:15.307329|\N&lt;br /&gt;73|4|130721|4496|2012-01-11 17:28:15.307251|\N&lt;br /&gt;1|7|200428|-4388|2012-01-11 17:28:15.307193|\N&lt;br /&gt;72|2|907918|-4323|2012-01-11 17:28:15.216612|\N&lt;br /&gt;30|1|76931|4226|2012-01-11 17:28:15.318388|\N&lt;br /&gt;27|7|87543|3849|2012-01-11 17:28:15.307277|\N&lt;br /&gt;5|9|963441|-2585|2012-01-11 17:28:15.307221|\N&lt;br /&gt;19|4|584590|-2414|2012-01-11 17:28:15.331634|\N&lt;br /&gt;78|5|543756|476|2012-01-11 17:28:15.333069|\N&lt;br /&gt;99|10|867181|-2597|2012-01-11 17:28:15.332944|\N&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;You could also fire something like this up:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In order to pass the output to the client, you could do something like this:&lt;br /&gt;&lt;pre class="brush:sql"&gt;rene@linux-2561:~&gt; psql -h 10.0.0.113 -U postgres -c "COPY (SELECT * FROM pgbench_history limit 10) TO STDOUT WITH CSV;" pgbenchdb &gt; test.csv&lt;br /&gt;rene@linux-2561:~&gt; cat test.csv&lt;br /&gt;98,3,256655,-2623,2012-01-11 17:28:15.200909,&lt;br /&gt;43,2,94378,2717,2012-01-11 17:28:15.200909,&lt;br /&gt;46,1,414961,1716,2012-01-11 17:28:15.201082,&lt;br /&gt;45,8,246477,3341,2012-01-11 17:28:15.200927,&lt;br /&gt;84,7,743181,-1348,2012-01-11 17:28:15.201073,&lt;br /&gt;20,1,713970,4518,2012-01-11 17:28:15.20119,&lt;br /&gt;76,8,778718,-2588,2012-01-11 17:28:15.200988,&lt;br /&gt;9,2,683187,-1675,2012-01-11 17:28:15.201074,&lt;br /&gt;71,3,793922,-748,2012-01-11 17:28:15.261927,&lt;br /&gt;93,6,484349,1816,2012-01-11 17:28:15.261776,&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now I'm curious about my statement of some text having embedded commas:&lt;br /&gt;&lt;pre class="brush:sql"&gt;rene@linux-2561:~&gt; psql -h 10.0.0.113 -U postgres -c "COPY (SELECT  'this, is, a,nasty, field') TO STDOUT WITH CSV;" pgbenchdb &gt; test.csv&lt;br /&gt;rene@linux-2561:~&gt; cat test.csv &lt;br /&gt;"this, is, a,nasty, field"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nevermind, if it does detect embedded commas &lt;b&gt;it double quotes the field&lt;/b&gt;. Nice!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The "\! COMMAND" psql's internal command is great, I just figured it out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4925994278839952375?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4925994278839952375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-export-to-csv-or-any-other.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4925994278839952375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4925994278839952375'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-export-to-csv-or-any-other.html' title='PostgreSQL - export to CSV or any other character delimited files'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-239511686557046865</id><published>2012-01-13T19:15:00.001-06:00</published><updated>2012-01-13T19:17:54.434-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><title type='text'>PosgreSQL - monitoring. User auditing "on steroids"</title><content type='html'>I'm taking a deep look into the latest PostgreSQL added features (in 9.0 &gt;), and I'm very happy with this one:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Instead of being able to set up configuration variables per database or per user, one can now set them up for a certain user in a certain database:&lt;br /&gt;&lt;br /&gt;marc=# ALTER ROLE marc IN database marc set log_statement to 'all';&lt;br /&gt;ALTER ROLE&lt;br /&gt;&lt;br /&gt;To know who has which variables set-up in which user+database, there is a new psql command:&lt;br /&gt;&lt;br /&gt;marc=# \drds&lt;br /&gt;List of settings&lt;br /&gt;role | database |     settings&lt;br /&gt;-----+----------+-----------------&lt;br /&gt;marc | marc     | log_statement=all&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;For instance, I've enabled log_statement = 'all' to my testing role 'rene' on a database called 'rene', even though, the general setting is established to 'none'. &lt;br /&gt;And this is what the log (set as a foreign table) looks like when I execute something like a 'create table' statement.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;-[ RECORD 1 ]----------+---------------------------------------------------------&lt;br /&gt;log_time               | 2012-01-13 18:47:17.46-06&lt;br /&gt;user_name              | rene&lt;br /&gt;database_name          | rene&lt;br /&gt;process_id             | 8584&lt;br /&gt;connection_from        | [local]&lt;br /&gt;session_id             | 4f10d072.2188&lt;br /&gt;session_line_num       | 2&lt;br /&gt;command_tag            | idle&lt;br /&gt;session_start_time     | 2012-01-13 18:46:42-06&lt;br /&gt;virtual_transaction_id | 2/89&lt;br /&gt;transaction_id         | 0&lt;br /&gt;error_severity         | LOG&lt;br /&gt;sql_state_code         | 00000&lt;br /&gt;message                | statement: create table test(a int primary key);&lt;br /&gt;detail                 | &lt;br /&gt;hint                   | &lt;br /&gt;internal_query         | &lt;br /&gt;internal_query_pos     | &lt;br /&gt;context                | &lt;br /&gt;query                  | &lt;br /&gt;query_pos              | &lt;br /&gt;location               | &lt;br /&gt;application_name       | psql&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To me, this level of customization of the  auditing feature is just beautiful.&lt;br /&gt;&lt;br /&gt;This is what the &lt;b&gt;new \drds psql internal command&lt;/b&gt; does behind the scenes.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;SELECT rolname AS role, datname AS database,pg_catalog.array_to_string(setconfig, E'\n') AS settings&lt;br /&gt;                       FROM pg_db_role_setting AS s&lt;br /&gt;                       LEFT JOIN pg_database ON pg_database.oid = setdatabase&lt;br /&gt;                       LEFT JOIN pg_roles ON pg_roles.oid = setrole&lt;br /&gt;                       WHERE pg_roles.rolname ~ '^(rene)$'&lt;br /&gt;                       ORDER BY role, database;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Obviously I figured that out through the logs =-).&lt;br /&gt;&lt;br /&gt;The novelty created in order to implement this feature is the &lt;b&gt;pg_db_role_setting&lt;/b&gt; table, that internally has this structure: &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# \d pg_catalog.pg_db_role_setting&lt;br /&gt;Table "pg_catalog.pg_db_role_setting"&lt;br /&gt;   Column    |  Type  | Modifiers &lt;br /&gt;-------------+--------+-----------&lt;br /&gt; setdatabase | oid    | not null&lt;br /&gt; setrole     | oid    | not null&lt;br /&gt; setconfig   | text[] | &lt;br /&gt;Indexes:&lt;br /&gt;    "pg_db_role_setting_databaseid_rol_index" UNIQUE, btree (setdatabase, setrole), tablespace "pg_global"&lt;br /&gt;Tablespace: "pg_global"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#Per_database.2Brole_configuration"&gt;&lt;br /&gt;http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#Per_database.2Brole_configuration&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And something as simple as that, is what it takes to make someone like me happy =-D.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-239511686557046865?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/239511686557046865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/posgresql-monitoring-user-auditing-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/239511686557046865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/239511686557046865'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/posgresql-monitoring-user-auditing-on.html' title='PosgreSQL - monitoring. User auditing &quot;on steroids&quot;'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2639614362538086743</id><published>2012-01-11T18:05:00.001-06:00</published><updated>2012-01-11T19:06:41.343-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='data recovery'/><title type='text'>PostgreSQL - PITR . Getting back lost data, due to "user error".</title><content type='html'>There are circumstances in which something bad happens in the database (like dropping a table or deleting important data), but if you've got a base backup and a series  of consistent wal segments, there's nothing to worry about.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Case: Important data was deleted by a malicious or careless database user.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt; &lt;br /&gt;&lt;b&gt;Assumptions:&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A base backup created before the data was deleted.&lt;/li&gt;&lt;li&gt;wal archiving enabled&amp;nbsp; and working&lt;/li&gt;&lt;li&gt;log reports set with log_statement(mod)&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;&lt;br /&gt;Let's say the "malicious" user performs the following operations:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@linux-2561:~&gt; psql -p 5433 pgbenchdb&lt;br /&gt;psql (9.1.1)&lt;br /&gt;Type "help" for help.&lt;br /&gt;&lt;br /&gt;pgbenchdb=# select count(*) from pgbench_history;&lt;br /&gt; count &lt;br /&gt;-------&lt;br /&gt; 10000&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# delete from pgbench_history where extract(second from mtime)::int % 7 = 0;&lt;br /&gt;DELETE 1350&lt;br /&gt;pgbenchdb=# delete from pgbench_history where extract(second from mtime)::int % 11 = 0;&lt;br /&gt;DELETE 611&lt;br /&gt;pgbenchdb=# delete from pgbench_history where extract(second from mtime)::int % 13 = 0;&lt;br /&gt;DELETE 289&lt;br /&gt;pgbenchdb=# delete from pgbench_history where extract(second from mtime)::int % 17 = 0;&lt;br /&gt;DELETE 779&lt;br /&gt;pgbenchdb=# select count(*) from pgbench_history;&lt;br /&gt; count &lt;br /&gt;-------&lt;br /&gt;  6971&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;After some time we get a call, telling us that today, some data was deleted from one very important table called pgbench_history.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Problem 1. When was this data deleted?&lt;/b&gt;&lt;br /&gt;If we've got the reporting logs set to an appropriate level, this is a rather simple task.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# select log_time,message from pglog where log_time::date = current_date and message like '%delete%' and message like '%history%' order by log_time asc;&lt;br /&gt;          log_time          |                                        message                                         &lt;br /&gt;----------------------------+----------------------------------------------------------------------------------------&lt;br /&gt; 2012-01-11 17:30:26.378-06 | statement: delete from pgbench_history where extract(second from mtime)::int % 7 = 0;&lt;br /&gt; 2012-01-11 17:30:34.854-06 | statement: delete from pgbench_history where extract(second from mtime)::int % 11 = 0;&lt;br /&gt; 2012-01-11 17:30:41.01-06  | statement: delete from pgbench_history where extract(second from mtime)::int % 13 = 0;&lt;br /&gt; 2012-01-11 17:30:45.457-06 | statement: delete from pgbench_history where extract(second from mtime)::int % 17 = 0;&lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, we roll forward (starting from the time that the base backup was taken) up to the time, just before any of those deletions took place, that is, before 2012-01-11 17:30:26.378-06.&lt;br /&gt;&lt;br /&gt;To make sure all transactions are present in the archiving directory.&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# select pg_switch_xlog();&lt;br /&gt; pg_switch_xlog &lt;br /&gt;----------------&lt;br /&gt; 0/2A1A0A80&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The only thing we have to do is  to start our base backup with a recovery.conf file that specifies the "recovery_target_time" as  '2012-01-11 17:30:26' for example.&lt;br /&gt;&lt;br /&gt;Now, when you're not sure about up to what time to replay the wal files, I think there's no other means than by trial and error. &lt;b&gt;In such cases you better make a copy of your base backup before replaying the wal files.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;vi recovery.conf&lt;br /&gt;&lt;pre class="brush:shell"&gt;restore_command = 'cp /var/lib/pgsql/wal_archive/%f %p'&lt;br /&gt;recovery_target_time = '2012-01-11 17:30:26'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once the recovery finishes, querying the pgbench_history table:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@linux-2561:~/pitr2/pg_log&gt; psql -p 5436 pgbenchdb&lt;br /&gt;psql (9.1.1)&lt;br /&gt;Type "help" for help.&lt;br /&gt;&lt;br /&gt;pgbenchdb=# select count(*) from pgbench_history;&lt;br /&gt; count &lt;br /&gt;-------&lt;br /&gt; 10000&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One thing that would be wonderful is to go back again in time. The thing here is that WAL replaying means that the changes to the database are reproduced and applied to the data files, then no going back is possible. But nothing could stop you from going further ahead ... I think. &lt;br /&gt;&lt;br /&gt;Well you can actually go back by restoring your copy of the base backup and setting an earlier "recovery_target_time" =-) . On this terms it's obvious to infer that you cannot go further back from the time at which the base backup was created.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2639614362538086743?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2639614362538086743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pitr-getting-back-lost-data.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2639614362538086743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2639614362538086743'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pitr-getting-back-lost-data.html' title='PostgreSQL - PITR . Getting back lost data, due to &quot;user error&quot;.'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2562862262219772591</id><published>2012-01-11T13:15:00.003-06:00</published><updated>2012-01-11T15:14:34.076-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='monitoring'/><title type='text'>Postgresql - monitoring. log_statement (mod)</title><content type='html'>That option enables logging (like the auditing feature in Oracle) in this way:&lt;br /&gt;mod logs all ddl statements, plus data-modifying statements such as INSERT, UPDATE, DELETE, TRUNCATE, and COPY FROM. PREPARE, EXECUTE, and EXPLAIN ANALYZE statements are also logged if their contained command is of an appropriate type.&lt;br /&gt;&lt;br /&gt;This is what there is to know about this setting from the pg_settings view:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;name       | log_statement&lt;br /&gt;setting    | mod&lt;br /&gt;unit       | &lt;br /&gt;category   | Reporting and Logging / What to Log&lt;br /&gt;short_desc | Sets the type of statements logged.&lt;br /&gt;extra_desc | &lt;br /&gt;context    | superuser&lt;br /&gt;vartype    | enum&lt;br /&gt;source     | configuration file&lt;br /&gt;min_val    | &lt;br /&gt;max_val    | &lt;br /&gt;enumvals   | {none,ddl,mod,all}&lt;br /&gt;boot_val   | none&lt;br /&gt;reset_val  | mod&lt;br /&gt;sourcefile | /var/lib/pgsql/pitr1/postgresql.conf&lt;br /&gt;sourceline | 400&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;blockquote&gt;side note about the superuser context: &lt;br /&gt;superuser&lt;br /&gt;These settings can be set from postgresql.conf, or within a session via the SET command; but only superusers can change them via SET. Changes in postgresql.conf will affect existing sessions only if no session-local value has been established with SET.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/current/static/view-pg-settings.html"&gt;http://www.postgresql.org/docs/current/static/view-pg-settings.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'm experimenting with PITR, and I'll need to know up to what point to recover. Ideally just before the deletion of some important data.&lt;br /&gt;&lt;br /&gt;Then I execute , some ddl operations to test that they're effectively being logged:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1/pg_log&gt; pgbench -c 4 -j 2 -s 10 -t 10 -p 5433 pgbenchdb&lt;br /&gt;Scale option ignored, using pgbench_branches table count = 10&lt;br /&gt;starting vacuum...end.&lt;br /&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 10&lt;br /&gt;query mode: simple&lt;br /&gt;number of clients: 4&lt;br /&gt;number of threads: 2&lt;br /&gt;number of transactions per client: 10&lt;br /&gt;number of transactions actually processed: 40/40&lt;br /&gt;tps = 30.567626 (including connections establishing)&lt;br /&gt;tps = 30.718934 (excluding connections establishing)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And see that effectively they where logged:&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1/pg_log&gt; tail -f postgresql-2012-01-11_125210.csv&lt;br /&gt;2012-01-11 13:08:14.660 CST,"postgres","pgbenchdb",10577,"[local]",4f0dde1d.2951,38,"idle in transaction",2012-01-11 13:08:13 CST,2/59,2516,LOG,00000,"statement: UPDATE pgbench_tellers SET tbalance = tbalance + -3973 WHERE tid = 15;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.660 CST,"postgres","pgbenchdb",10577,"[local]",4f0dde1d.2951,39,"idle in transaction",2012-01-11 13:08:13 CST,2/59,2516,LOG,00000,"statement: UPDATE pgbench_branches SET bbalance = bbalance + -3973 WHERE bid = 3;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.661 CST,"postgres","pgbenchdb",10577,"[local]",4f0dde1d.2951,40,"idle in transaction",2012-01-11 13:08:13 CST,2/59,2516,LOG,00000,"statement: INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (15, 3, 286453, -3973, CURRENT_TIMESTAMP);",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.683 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,34,"idle in transaction",2012-01-11 13:08:13 CST,4/10,2517,LOG,00000,"statement: UPDATE pgbench_tellers SET tbalance = tbalance + 1104 WHERE tid = 94;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.683 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,35,"idle in transaction",2012-01-11 13:08:13 CST,4/10,2517,LOG,00000,"statement: UPDATE pgbench_branches SET bbalance = bbalance + 1104 WHERE bid = 10;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.683 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,36,"idle in transaction",2012-01-11 13:08:13 CST,4/10,2517,LOG,00000,"statement: INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (94, 10, 413230, 1104, CURRENT_TIMESTAMP);",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.708 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,37,"idle in transaction",2012-01-11 13:08:13 CST,4/11,0,LOG,00000,"statement: UPDATE pgbench_accounts SET abalance = abalance + 2487 WHERE aid = 112736;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.724 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,38,"idle in transaction",2012-01-11 13:08:13 CST,4/11,2518,LOG,00000,"statement: UPDATE pgbench_tellers SET tbalance = tbalance + 2487 WHERE tid = 85;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.725 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,39,"idle in transaction",2012-01-11 13:08:13 CST,4/11,2518,LOG,00000,"statement: UPDATE pgbench_branches SET bbalance = bbalance + 2487 WHERE bid = 2;",,,,,,,,,""&lt;br /&gt;2012-01-11 13:08:14.725 CST,"postgres","pgbenchdb",10579,"[local]",4f0dde1d.2953,40,"idle in transaction",2012-01-11 13:08:13 CST,4/11,2518,LOG,00000,"statement: INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (85, 2, 112736, 2487, CURRENT_TIMESTAMP);",,,,,,,,,""&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In a more structured fashion (setting up the log as a foreign table):&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# select * from pglog where message like '%UPDATE%';&lt;br /&gt;&lt;br /&gt;log_time               | 2012-01-11 13:38:34.642-06&lt;br /&gt;user_name              | postgres&lt;br /&gt;database_name          | pgbenchdb&lt;br /&gt;process_id             | 12719&lt;br /&gt;connection_from        | [local]&lt;br /&gt;session_id             | 4f0de53a.31af&lt;br /&gt;session_line_num       | 1&lt;br /&gt;command_tag            | idle in transaction&lt;br /&gt;session_start_time     | 2012-01-11 13:38:34-06&lt;br /&gt;virtual_transaction_id | 5/1216&lt;br /&gt;transaction_id         | 0&lt;br /&gt;error_severity         | LOG&lt;br /&gt;sql_state_code         | 00000&lt;br /&gt;message                | statement: UPDATE pgbench_accounts SET abalance = abalance + 2131 WHERE aid = 423974;&lt;br /&gt;detail                 | &lt;br /&gt;hint                   | &lt;br /&gt;internal_query         | &lt;br /&gt;internal_query_pos     | &lt;br /&gt;context                | &lt;br /&gt;query                  | &lt;br /&gt;query_pos              | &lt;br /&gt;location               | &lt;br /&gt;application_name       |&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now, there's no place for doubts about who did what.  &lt;br /&gt;&lt;br /&gt;Source:&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/runtime-config-logging.html"&gt;http://www.postgresql.org/docs/9.1/static/runtime-config-logging.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other references:&lt;br /&gt;&lt;a href="http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html"&gt;http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, in a busy system having such granular level of logging will generate huge logs, so specifying a log rotation setting is a must.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2562862262219772591?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2562862262219772591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-monitoring-logstatement-mod.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2562862262219772591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2562862262219772591'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-monitoring-logstatement-mod.html' title='Postgresql - monitoring. log_statement (mod)'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2510807442290827517</id><published>2012-01-10T20:30:00.001-06:00</published><updated>2012-01-10T21:43:13.463-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - the pg_xlog directory</title><content type='html'>I'll talk about this topic on the light of my previous entry:&lt;br /&gt;&lt;a href="http://sharingtechknowledge.blogspot.com/2012/01/postgresql-recovery-through-archiving.html"&gt;http://sharingtechknowledge.blogspot.com/2012/01/postgresql-recovery-through-archiving.html&lt;/a&gt;&lt;br /&gt;The sub-directory pg_xlog inside the database cluster ($PGDATA) keeps transaction logs (or Write Ahead Log - WAL).&lt;br /&gt;&lt;br /&gt;I noticed that when archiving is enabled a couple of WAL segments are kept here and it's only after a pg_switch_pgxlog(),  that they're transfered to the target archiving directory. &lt;br /&gt;&lt;br /&gt;In the docs they mention that it's wise to keep this directory on a separate device for performance reasons, by making a symbolic link to a directory outside the data cluster.&lt;br /&gt;&lt;br /&gt;If you don't specify a restore command or if it fails consistently , pg_xlog will grow indefinitely, that's one good thing to have in mind.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2510807442290827517?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2510807442290827517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgxlog-directory.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2510807442290827517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2510807442290827517'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgxlog-directory.html' title='Postgresql - the pg_xlog directory'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5342667523281373012</id><published>2012-01-10T15:40:00.001-06:00</published><updated>2012-01-10T20:12:21.953-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PITR'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Recovery through archiving (PITR). Simple example</title><content type='html'>Ok, I have a brand new PostgreSQL 9.1 installation and I'll set up a simple recovery scenario.&lt;br /&gt;My (brand new)database cluster path:&lt;br /&gt;/var/lib/pgsql/pitr1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step1. Before starting the server, enable archiving.&lt;/b&gt;&lt;br /&gt;a. Define where the WAL logs will be archived. &lt;br /&gt;For these purposes I'll use the directory /var/lib/pgsql/wal_archive&lt;br /&gt;&lt;br /&gt;b.Configure the connection and archiving options (I changed these from the default values):&lt;br /&gt;&lt;br /&gt;vi postgresql.conf&lt;br /&gt;&lt;pre class="brush:sql"&gt;listen_addresses = '*'          # what IP address(es) to listen on;&lt;br /&gt;port = 5433                     # I have the 5432 busy with another experiment&lt;br /&gt;wal_level = archive             # minimal, archive, or hot_standby&lt;br /&gt;                                # (change requires restart)&lt;br /&gt;archive_mode = on               # allows archiving to be done&lt;br /&gt;                                # (change requires restart)&lt;br /&gt;archive_command = 'cp %p /var/lib/pgsql/wal_archive/%f'&lt;br /&gt;max_wal_senders = 5             # max number of walsender processes&lt;br /&gt;                                # (change requires restart)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The part worth explaining is this:&lt;br /&gt;&lt;b&gt;archive_command = 'cp %p /var/lib/pgsql/wal_archive/%f'&lt;/b&gt;&lt;br /&gt;with this command we instruct postgresql to archive each wal segment (equivalent to a redo log in Oracle) it generates, represented with the variable %p (this variable will be replaced with its full path) to the directory /var/lib/pgsql/wal_archive. %f stands for the name of the wal segment and it will be replaced with the actual wal segment name behind the scenes too. PostgreSQL will handle for us those %p and %f variables.&lt;br /&gt;The default value for the parameter &lt;b&gt;max_wal_senders&lt;/b&gt; must be set to a positive integer value greater than cero for this to work.&lt;br /&gt;&lt;br /&gt;c. Configure the connection settings. (I'll make the base backup through the pg_basebackup function, so authentication for replication is required.&lt;br /&gt;vi pg_hba.conf&lt;br /&gt;&lt;pre class="brush:shell"&gt;# TYPE  DATABASE        USER            ADDRESS                 METHOD&lt;br /&gt;&lt;br /&gt;# "local" is for Unix domain socket connections only&lt;br /&gt;local   all             all                                     trust&lt;br /&gt;# IPv4 local connections:&lt;br /&gt;host    all             all             127.0.0.1/32            trust&lt;br /&gt;# IPv6 local connections:&lt;br /&gt;host    all             all             ::1/128                 trust&lt;br /&gt;# Allow replication connections from localhost, by a user with the&lt;br /&gt;# replication privilege.&lt;br /&gt;local   replication     postgres                                trust&lt;br /&gt;host    replication     postgres        127.0.0.1/32            trust&lt;br /&gt;#host    replication     postgres        ::1/128                 trust&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;Step2. Start up the server, create a test database, make some ddl/dml operations and confirm that wal segments are being sent to the location specified.&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Starting the server up:&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1&gt; pg_ctl start -D .&lt;br /&gt;postgres@linux-2561:~/pitr1&gt; cd pg_log/&lt;br /&gt;postgres@linux-2561:~/pitr1/pg_log&gt; ls&lt;br /&gt;postgresql-2012-01-10_114123.log&lt;br /&gt;postgres@linux-2561:~/pitr1/pg_log&gt; tail -f postgresql-2012-01-10_114123.log &lt;br /&gt;2012-01-10 11:41:23 CST   LOG:  database system was shut down at 2012-01-10 11:10:12 CST&lt;br /&gt;2012-01-10 11:41:23 CST   LOG:  database system is ready to accept connections&lt;br /&gt;2012-01-10 11:41:23 CST   LOG:  autovacuum launcher started&lt;br /&gt;#so it started without error&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Creating the database and filling it with dummy data:&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1/pg_log&gt; createdb -p 5433 pgbenchdb&lt;br /&gt;postgres@linux-2561:~/pitr1/pg_log&gt; pgbench -i -s 10 -p 5433 pgbenchdb&lt;br /&gt;NOTICE:  table "pgbench_branches" does not exist, skipping&lt;br /&gt;NOTICE:  table "pgbench_tellers" does not exist, skipping&lt;br /&gt;NOTICE:  table "pgbench_accounts" does not exist, skipping&lt;br /&gt;NOTICE:  table "pgbench_history" does not exist, skipping&lt;br /&gt;creating tables...&lt;br /&gt;1000000 tuples done.&lt;br /&gt;set primary key...&lt;br /&gt;NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_branches_pkey" for table "pgbench_branches"&lt;br /&gt;NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_tellers_pkey" for table "pgbench_tellers"&lt;br /&gt;NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "pgbench_accounts_pkey" for table "pgbench_accounts"&lt;br /&gt;vacuum...done.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;verifying that wal segments are being archived.&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1/pg_log&gt; ls ../../wal_archive/&lt;br /&gt;000000010000000000000001  000000010000000000000004  000000010000000000000007  00000001000000000000000A&lt;br /&gt;000000010000000000000002  000000010000000000000005  000000010000000000000008&lt;br /&gt;000000010000000000000003  000000010000000000000006  000000010000000000000009&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;make some more transactions that among other thing affect the pgbench_history table that keeps track of the time an insertion was made.&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@linux-2561:~/pitr1/pg_log&gt; pgbench -s 10 -c 6 -j 2 -t 100 -p 5433 pgbenchdb &lt;br /&gt;Scale option ignored, using pgbench_branches table count = 10&lt;br /&gt;starting vacuum...end.&lt;br /&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 10&lt;br /&gt;query mode: simple&lt;br /&gt;number of clients: 6&lt;br /&gt;number of threads: 2&lt;br /&gt;number of transactions per client: 100&lt;br /&gt;number of transactions actually processed: 600/600&lt;br /&gt;tps = 187.111393 (including connections establishing)&lt;br /&gt;tps = 187.944077 (excluding connections establishing)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Step3. Make the base backup .&lt;/b&gt;&lt;br /&gt;In this case I'll perform the recovery on the same machine.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr1&gt; cd &lt;br /&gt;postgres@linux-2561:~&gt; ls&lt;br /&gt;data_sr  pgbench_transaction.sql  pgpool_scripts_backup  pitr1  repmgr  unclassified  wal_archive&lt;br /&gt;postgres@linux-2561:~&gt; mkdir pitr2&lt;br /&gt;postgres@linux-2561:~&gt; pg_basebackup -p 5433 -D /var/lib/pgsql/pitr2/&lt;br /&gt;NOTICE:  pg_stop_backup complete, all required WAL segments have been archived&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A file with backup extension was generated with the following contents:&lt;br /&gt;&lt;pre class="brush:shell"&gt;START WAL LOCATION: 0/E000020 (file 00000001000000000000000E) &lt;- the name of the starting wal file&lt;br /&gt;STOP WAL LOCATION: 0/E000094 (file 00000001000000000000000E)&lt;br /&gt;CHECKPOINT LOCATION: 0/E000020&lt;br /&gt;BACKUP METHOD: streamed&lt;br /&gt;START TIME: 2012-01-10 13:10:00 CST &lt;- the time at which pg_start_backup was run&lt;br /&gt;LABEL: pg_basebackup base backup &lt;- label given in pg_start_backup (executed automatically by pg_basebackup)&lt;br /&gt;STOP TIME: 2012-01-10 13:10:02 CST&lt;br /&gt;&lt;/pre&gt;a. Change this backup server port so I does not conflict with the original one.&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr2&gt; ls&lt;br /&gt;backup_label  global   pg_hba.conf    pg_log        pg_notify  pg_stat_tmp  pg_tblspc    PG_VERSION  postgresql.conf&lt;br /&gt;base          pg_clog  pg_ident.conf  pg_multixact  pg_serial  pg_subtrans  pg_twophase  pg_xlog     postmaster.opts&lt;br /&gt;postgres@linux-2561:~/pitr2&gt; vi postgresql.conf &lt;br /&gt;listen_addresses = '*'          # what IP address(es) to listen on;&lt;br /&gt;                                        # comma-separated list of addresses;&lt;br /&gt;                                        # defaults to 'localhost', '*' = all&lt;br /&gt;                                        # (change requires restart)&lt;br /&gt;port = 5434 &lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Step4. Create the recovery.conf file on the backup cluster&lt;/b&gt;The backup server will read this file on start up and it will "know" that it has to perform recovery (read wal segments from the specified location and apply them to data files) starting from the first wal segment generated during backup.&lt;pre class="brush:shell"&gt;vi /var/lib/pgsql/pitr2/recovery.conf&lt;br /&gt;recovery_command = 'cp /var/lib/pgsql/wal_archive/%f %p' #this is the only mandatory setting.&lt;br /&gt;&lt;/pre&gt;Before starting up the server, I'd like to generate more WAL segments on the master.&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr2&gt; pgbench -s 10 -c 6 -j 2 -t 100 -p 5433 pgbenchdb &lt;br /&gt;Scale option ignored, using pgbench_branches table count = 10&lt;br /&gt;starting vacuum...end.&lt;br /&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 10&lt;br /&gt;query mode: simple&lt;br /&gt;number of clients: 6&lt;br /&gt;number of threads: 2&lt;br /&gt;number of transactions per client: 100&lt;br /&gt;number of transactions actually processed: 600/600&lt;br /&gt;tps = 191.475816 (including connections establishing)&lt;br /&gt;tps = 192.120436 (excluding connections establishing)&lt;br /&gt;&lt;/pre&gt;Take note of the last transaction timestamp.&lt;pre class="brush:sql"&gt;pgbenchdb=# SELECT max(mtime) from pgbench_history;&lt;br /&gt;            max             &lt;br /&gt;----------------------------&lt;br /&gt; 2012-01-10 13:54:47.366648&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;Now, there's the possibility that the last transactions on the principal server aren't still stored in the last wal segment, so we force a log switch (that executes with a previous checkpoint).&lt;b&gt;Also, you can force a segment switch manually with pg_switch_xlog, if you want to ensure that a just-finished transaction is archived as soon as possible&lt;/b&gt;&lt;a href="http://www.postgresql.org/docs/8.2/static/functions-admin.html"&gt;http://www.postgresql.org/docs/8.2/static/functions-admin.html&lt;/a&gt;&lt;pre class="brush:sql"&gt;postgres@linux-2561:~/pitr2&gt; psql -p 5433 -c "select pg_switch_xlog();"&lt;br /&gt; pg_switch_xlog &lt;br /&gt;----------------&lt;br /&gt; 0/F879168&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;One thing I need to review is this info in the manual.&lt;blockquote&gt;you should at least save the contents of the cluster’s pg_xlog subdirectory, as it might contain logs which were not archived before the system went down.&lt;/blockquote&gt;&lt;b&gt;Step5. Having everything set up. Let's start up the backup server.&lt;/b&gt;Expected result: to have an exact copy of the master server being the last transaction timestamp: 2012-01-10 13:54:47.366648&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/pitr2&gt; pg_ctl start -D .&lt;br /&gt;server starting&lt;br /&gt;postgres@linux-2561:~/pitr2&gt; 2012-01-10 21:21:04 GMT   FATAL:  data directory "/var/lib/pgsql/pitr2" has group or world access&lt;br /&gt;2012-01-10 21:21:04 GMT   DETAIL:  Permissions should be u=rwx (0700).&lt;br /&gt;&lt;/pre&gt;Yikes!!!!! Ok then.&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; chmod 700 -R pitr2&lt;br /&gt;&lt;/pre&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; pg_ctl start -D pitr2/&lt;br /&gt;server starting&lt;br /&gt;postgres@linux-2561:~&gt; tail -f pitr2/pg_log/postgresql-2012-01-10_1&lt;br /&gt;postgresql-2012-01-10_114123.log  postgresql-2012-01-10_130842.log  postgresql-2012-01-10_152456.log&lt;br /&gt;postgres@linux-2561:~&gt; tail -f pitr2/pg_log/postgresql-2012-01-10_152456.log &lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  could not open file "pg_xlog/000000010000000000000010" (log file 0, segment 16): No such file or directory&lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  redo done at 0/F87914C&lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  last completed transaction was at log time 2012-01-10 13:55:13.965712-06&lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  restored log file "00000001000000000000000F" from archive&lt;br /&gt;cp: cannot stat `/var/lib/pgsql/wal_archive/00000002.history': No such file or directory&lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  selected new timeline ID: 2&lt;br /&gt;cp: cannot stat `/var/lib/pgsql/wal_archive/00000001.history': No such file or directory&lt;br /&gt;2012-01-10 15:24:56 CST   LOG:  archive recovery complete&lt;br /&gt;2012-01-10 15:24:59 CST   LOG:  autovacuum launcher started&lt;br /&gt;2012-01-10 15:24:59 CST   LOG:  database system is ready to accept connections&lt;br /&gt;&lt;/pre&gt;&lt;blockquote&gt;Regarding to the .history files not found, the docs say: You may also see an error message at the start of recovery for a ﬁle named something like 00000001.history. This is also normal and does not indicate a problem in simple recovery situations. &lt;/blockquote&gt;Now, to make some generic tests for consistency.Data in the primary server:&lt;pre class="brush:sql"&gt;postgres@linux-2561:~&gt; psql -p 5433 pgbenchdb&lt;br /&gt;psql (9.1.1)&lt;br /&gt;Type "help" for help.&lt;br /&gt;&lt;br /&gt;pgbenchdb=# \dt+&lt;br /&gt;                          List of relations&lt;br /&gt; Schema |       Name       | Type  |  Owner   |  Size  | Description &lt;br /&gt;--------+------------------+-------+----------+--------+-------------&lt;br /&gt; public | pgbench_accounts | table | postgres | 124 MB | &lt;br /&gt; public | pgbench_branches | table | postgres | 40 kB  | &lt;br /&gt; public | pgbench_history  | table | postgres | 88 kB  | &lt;br /&gt; public | pgbench_tellers  | table | postgres | 40 kB  | &lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# select max(mtime) from pgbench_history;&lt;br /&gt;            max             &lt;br /&gt;----------------------------&lt;br /&gt; 2012-01-10 13:54:47.366648&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;Data in the backup server:&lt;pre class="brush:sql"&gt;postgres@linux-2561:~&gt; psql -p 5434 pgbenchdb&lt;br /&gt;psql (9.1.1)&lt;br /&gt;Type "help" for help.&lt;br /&gt;&lt;br /&gt;pgbenchdb=# \dt+&lt;br /&gt;                          List of relations&lt;br /&gt; Schema |       Name       | Type  |  Owner   |  Size  | Description &lt;br /&gt;--------+------------------+-------+----------+--------+-------------&lt;br /&gt; public | pgbench_accounts | table | postgres | 124 MB | &lt;br /&gt; public | pgbench_branches | table | postgres | 40 kB  | &lt;br /&gt; public | pgbench_history  | table | postgres | 88 kB  | &lt;br /&gt; public | pgbench_tellers  | table | postgres | 40 kB  | &lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# select max(mtime) from pgbench_history;&lt;br /&gt;            max             &lt;br /&gt;----------------------------&lt;br /&gt; 2012-01-10 13:54:47.366648&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Now my wal_archive directory looks like this:&lt;pre class="brush:shell"&gt;postgres@linux-2561:~/wal_archive&gt; ls&lt;br /&gt;000000010000000000000001  000000010000000000000006  00000001000000000000000B  00000001000000000000000F&lt;br /&gt;000000010000000000000002  000000010000000000000007  00000001000000000000000C  00000002000000000000000F&lt;br /&gt;000000010000000000000003  000000010000000000000008  00000001000000000000000D  00000002.history&lt;br /&gt;000000010000000000000004  000000010000000000000009  00000001000000000000000E&lt;br /&gt;000000010000000000000005  00000001000000000000000A  00000001000000000000000E.00000020.backup&lt;br /&gt;&lt;/pre&gt;This recovery produced an 00000002.history file that contains this timeline:&lt;pre class="brush:shell"&gt;1       00000001000000000000000F        no recovery target specified&lt;br /&gt;&lt;/pre&gt;So this is the last wal segment that was applied to data files in this recovery.After that wal segment a new series was created, namely:&lt;pre class="brush:shell"&gt;00000002000000000000000F&lt;br /&gt;&lt;/pre&gt;So, it only incremented the left most hexadecimal number to create this new wal segment series.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5342667523281373012?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5342667523281373012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-recovery-through-archiving.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5342667523281373012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5342667523281373012'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-recovery-through-archiving.html' title='Postgresql - Recovery through archiving (PITR). Simple example'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5929022711752626362</id><published>2012-01-10T00:03:00.001-06:00</published><updated>2012-01-10T00:17:16.534-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='full text search'/><title type='text'>PostgreSQL - Full text search. Installing a new german dictionary</title><content type='html'>It really startled me PostgreSQL not being able to tell that 'Freundin' belongs to the same word family as 'Freund'. I looked it up and turned out that no appropriate german dictionary was installed on my system.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step1. Install the dictionary.&lt;/b&gt;&lt;br /&gt;Main website:&lt;br /&gt;&lt;a href="http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/"&gt;http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/&lt;/a&gt;&lt;br /&gt;File:&lt;br /&gt;&lt;a href="http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/dicts/ispell/ispell-german-compound.tar.gz"&gt;http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/dicts/ispell/ispell-german-compound.tar.gz&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Extract it and place it into this directory or equivalent:&lt;br /&gt;&lt;b&gt;/usr/pgsql-9.1/share/tsearch_data&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step2. We'll need to do some encoding conversion:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;[root@localhost german_compound]# &lt;br /&gt;iconv -f ISO8859-1 -t utf8 german.dic &gt; ../german.dict&lt;br /&gt;iconv -f ISO8859-1 -t utf8 german.aff &gt; ../german.affix&lt;br /&gt;iconv -f ISO8859-1 -t utf8 german.stop &gt; ../german.stop&lt;br /&gt;&lt;/pre&gt;&lt;a href="http://archives.postgresql.org/pgsql-general/2009-02/msg00121.php"&gt;http://archives.postgresql.org/pgsql-general/2009-02/msg00121.php&lt;/a&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;Step3. Follow this configuration track:&lt;/b&gt;&lt;br /&gt;&lt;a href="http://domas.monkus.lt/full-text-search-postgresql"&gt;http://domas.monkus.lt/full-text-search-postgresql&lt;/a&gt;&lt;br /&gt;I named my configuration 'de'&lt;br /&gt;&lt;br /&gt;Step4. Test the results.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# SELECT to_tsvector('de','Freundin') @@ to_tsquery('de','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres=# SELECT to_tsvector('de','Studentin') @@ to_tsquery('de','Student');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;postgres=# SELECT to_tsvector('de','Freunde') @@ to_tsquery('de','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;postgres=# SELECT to_tsvector('de','freundlich') @@ to_tsquery('de','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now I'll add a good spanish one. So it seems I'll be able to sleep tonight, at least as soon as I play around with PITR a little bit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5929022711752626362?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5929022711752626362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-full-text-search-installing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5929022711752626362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5929022711752626362'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-full-text-search-installing.html' title='PostgreSQL - Full text search. Installing a new german dictionary'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2643596983080365904</id><published>2012-01-09T18:29:00.000-06:00</published><updated>2012-01-09T19:27:03.384-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Tools - Flowcharting software . yEd</title><content type='html'>I'm using this app to make some flowcharts and I'm liking it very much. It runs on Windows, Linux and Mac.&lt;br /&gt;&lt;br /&gt;&lt;a target='_blank' href='http://imageshack.us/photo/my-images/109/yed.png/'&gt;&lt;img src='http://img109.imageshack.us/img109/3521/yed.th.png' border='0'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.yworks.com/en/products_yed_about.html"&gt;http://www.yworks.com/en/products_yed_about.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And guess what? It's free!.&lt;br /&gt;&lt;br /&gt;Other alternatives are discussed here.&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/358304/good-freeware-for-flowcharts-on-windows"&gt;http://stackoverflow.com/questions/358304/good-freeware-for-flowcharts-on-windows&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2643596983080365904?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2643596983080365904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/tools-flowcharting-software-yed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2643596983080365904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2643596983080365904'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/tools-flowcharting-software-yed.html' title='Tools - Flowcharting software . yEd'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5130984756762712243</id><published>2012-01-09T11:55:00.000-06:00</published><updated>2012-01-09T12:43:43.748-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='full text search'/><title type='text'>Postgresql - Full text search. First encounter</title><content type='html'>I'm amazed about the text searching capabilities embedded into PostgreSQL. It has the 'ability' to tell apart word variants and classify them as belonging to the same family (through their normalization).&lt;br /&gt;&lt;br /&gt;My default configuration&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# show default_text_search_config;&lt;br /&gt; default_text_search_config &lt;br /&gt;----------------------------&lt;br /&gt; pg_catalog.english&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Though ,I better make it explicit in each case. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;For instance:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Base word: friend&lt;br /&gt;variants: friends , friendly&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;--in english&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('english','friends') @@ to_tsquery('english','friend');                                     &lt;br /&gt; ?column?                                                                                                                     &lt;br /&gt;----------                                                                                                                    &lt;br /&gt; t                                                                                                                            &lt;br /&gt;(1 row)    &lt;br /&gt;--it matches                                                                                                                   &lt;br /&gt;                                                                                                                              &lt;br /&gt;pgbenchdb=# SELECT to_tsvector('english','friendly') @@ to_tsquery('english','friend');                                       &lt;br /&gt; ?column?                                                                                                                     &lt;br /&gt;----------                                                                                                                    &lt;br /&gt; t                                                                                                                            &lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;--in spanish&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('spanish','amigos') @@ to_tsquery('spanish','amigo');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('spanish','amigable') @@ to_tsquery('spanish','amigo');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;--in german&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('german','Freunde') @@ to_tsquery('german','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('german','Freundin') @@ to_tsquery('german','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; f&lt;br /&gt;(1 row)&lt;br /&gt;--it doesn't match!!!???&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT to_tsvector('german','freundlich') @@ to_tsquery('german','Freund');&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; f&lt;br /&gt;(1 row)&lt;br /&gt;--it doesn't match!!!???&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Well, the german configuration needs further development, it ain't an easy language, that's a fact.&lt;br /&gt;&lt;br /&gt;Here is a very good insight about different text search options, including this one.&lt;br /&gt;&lt;a href="http://www.slideshare.net/billkarwin/full-text-search-in-postgresql"&gt;http://www.slideshare.net/billkarwin/full-text-search-in-postgresql &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'll look up the Postgresql extension network, I might find something useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5130984756762712243?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5130984756762712243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-full-text-search-first.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5130984756762712243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5130984756762712243'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-full-text-search-first.html' title='Postgresql - Full text search. First encounter'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2166894923036388073</id><published>2012-01-09T00:47:00.003-06:00</published><updated>2012-01-09T01:13:32.607-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - the pg_settings view</title><content type='html'>This view is roughly the equivalent to the v$spparameter/v$parameter views in Oracle. Each setting related with the running instance is detailed and documented here . From now on I'll try to relate everything I study about PostgreSQL with its counterpart on Oracle, so I reinforce the topics I learned in the OCA certification.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;pg_settings&lt;br /&gt;&lt;br /&gt;The view pg_settings provides access to run-time parameters of the server. It is essentially an alternative interface to the SHOW and SET commands. It also provides access to some facts about each parameter that are not directly available from SHOW, such as minimum and maximum values.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/view-pg-settings.html"&gt;http://www.postgresql.org/docs/9.1/static/view-pg-settings.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How many such settings are there?&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# select count(*) from pg_settings;&lt;br /&gt; count &lt;br /&gt;-------&lt;br /&gt;   219&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One thing I regard worth looking up, is how to tell what settings were changed but are not yet applied as you need to restart the server for them to take effect (those with the postmaster context).&lt;br /&gt;&lt;br /&gt;Let's play around a little bit. What are those settings?&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# select name,setting from pg_settings where context = 'postmaster';&lt;br /&gt;              name              |               setting                &lt;br /&gt;--------------------------------+--------------------------------------&lt;br /&gt; allow_system_table_mods        | off&lt;br /&gt; archive_mode                   | off&lt;br /&gt; autovacuum_freeze_max_age      | 200000000&lt;br /&gt; autovacuum_max_workers         | 3&lt;br /&gt; bonjour                        | off&lt;br /&gt; bonjour_name                   | &lt;br /&gt; config_file                    | /var/lib/pgsql/data1/postgresql.conf&lt;br /&gt; data_directory                 | /var/lib/pgsql/data1&lt;br /&gt; external_pid_file              | &lt;br /&gt; hba_file                       | /var/lib/pgsql/data1/pg_hba.conf&lt;br /&gt; hot_standby                    | off&lt;br /&gt; ident_file                     | /var/lib/pgsql/data1/pg_ident.conf&lt;br /&gt; listen_addresses               | localhost&lt;br /&gt; logging_collector              | on&lt;br /&gt; max_connections                | 100&lt;br /&gt; max_files_per_process          | 1000&lt;br /&gt; max_locks_per_transaction      | 64&lt;br /&gt; max_pred_locks_per_transaction | 64&lt;br /&gt; max_prepared_transactions      | 0&lt;br /&gt; max_wal_senders                | 0&lt;br /&gt; port                           | 5432&lt;br /&gt; shared_buffers                 | 3072&lt;br /&gt; shared_preload_libraries       | &lt;br /&gt; silent_mode                    | off&lt;br /&gt; ssl                            | off&lt;br /&gt; ssl_ciphers                    | ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH&lt;br /&gt; superuser_reserved_connections | 3&lt;br /&gt; track_activity_query_size      | 1024&lt;br /&gt; unix_socket_directory          | &lt;br /&gt; unix_socket_group              | &lt;br /&gt; unix_socket_permissions        | 0777&lt;br /&gt; wal_buffers                    | 96&lt;br /&gt; wal_level                      | minimal&lt;br /&gt;(33 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's say I want to restrict the max_connections setting to half its default value.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# update pg_catalog.pg_settings set setting = '50' where name = 'max_connections';&lt;br /&gt;ERROR:  parameter "max_connections" cannot be changed without restarting the server&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Aha! So, it's much more simple than that, it won't let you do it through this view! Well,on these grounds, my question does not apply to PostgreSQL.&lt;br /&gt;&lt;br /&gt;So I guess, this implementation is analogous to starting the Oracle instance with a pfile, so no need to have two views as oracle does, one for current settings and one for those written in the spfile that might not be effective just yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2166894923036388073?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2166894923036388073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgsettings-view.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2166894923036388073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2166894923036388073'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgsettings-view.html' title='Postgresql - the pg_settings view'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6834338924735517880</id><published>2012-01-08T11:31:00.000-06:00</published><updated>2012-01-09T01:03:33.692-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='external data'/><title type='text'>Postgresql - Foreign Tables. twitter_fdw. advanced twitter searches</title><content type='html'>&lt;b&gt;&lt;br /&gt;Case scenario: &lt;br /&gt;Postgresql 9.1 on Fedora 15&lt;br /&gt;&lt;br /&gt;Objective: find the latest 100 tweets, that talk about postgresql  and  contain the word 'query' . &lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;My latest experience with this topic:&lt;br /&gt;&lt;a href="http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html"&gt;http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Prerequisite: Postgresql 9.1 with contrib modules and postgresql9.1-server-devel (or whatever is called in your distro).&lt;br /&gt;Step1. Install the twitter_fdw wrapper:&lt;br /&gt;&lt;a href="http://pgxn.org/dist/twitter_fdw/"&gt;http://pgxn.org/dist/twitter_fdw/&lt;/a&gt;  &lt;br /&gt;&lt;br /&gt;Step2. Create the extension in the database you'll use for this purpose.&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# CREATE EXTENSION twitter_fdw;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Step3. Fire the query away. (The CREATE EXTENSION statement creates not only FDW handlers but also Data Wrapper, Foreign Server, User Mapping and twitter table) &lt;- isn't that great?&lt;pre class="brush:sql"&gt;&lt;br /&gt;&lt;br /&gt;postgres=# SELECT from_user AS user , text::varchar(144) AS message FROM twitter WHERE q = '#postgresql' and text::varchar(144) ilike '%query%'; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The result:&lt;br /&gt;&lt;pre class="brush:sql"&gt;user     |                                                                  message                       &lt;br /&gt;                                           &lt;br /&gt;--------------+------------------------------------------------------------------------------------------------ -------------------------------------------&lt;br /&gt; postgresqlbr | Parallel query processing may finally be coming to #PostgreSQL http://t.co/cFgNsQHx - Parallel query processing m... http://t.co/hbfAdytF&lt;br /&gt; chenghlee    | Parallel query processing may finally be coming to #PostgreSQL http://t.co/TZZ4gM7a&lt;br /&gt;(2 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I didn't like a column named 'text', so I renamed it to 'message' but the thing stopped working (I should have known better --&gt; the mapping! duh), so I switched the change back. I'll define a custom foreign server, user mapping , and foreign table latter just for practice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6834338924735517880?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6834338924735517880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-twitterfdw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6834338924735517880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6834338924735517880'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-twitterfdw.html' title='Postgresql - Foreign Tables. twitter_fdw. advanced twitter searches'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7040808492706708035</id><published>2012-01-07T20:35:00.000-06:00</published><updated>2012-01-08T21:27:23.459-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='external data'/><title type='text'>Postgresql - Foreign tables. file_fdw wrapper. querying the log file</title><content type='html'>The foreign table functionality has been around for quite some time in the SQL Standard. A foreign table derives from the concept of  &lt;b&gt;External Data Management (SQL/MED) .&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;SQL/MED is Management of External Data, a part of the SQL standard that deals with how a database management system can integrate data stored outside the database. There are two components in SQL/MED:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Foreign Table&lt;/b&gt;&lt;br /&gt;a transparent access method for external data &lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/SQL/MED"&gt;&lt;br /&gt;http://wiki.postgresql.org/wiki/SQL/MED&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Another reference:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In 2003, a new extension called SQL/MED ("SQL Management of External Data") was added to the SQL standard. It is a standardized way of handling access to remote objects in SQL databases. In 2011, PostgreSQL 9.1 was released with a great support of this standard.&lt;br /&gt;&lt;br /&gt;In a nutshell, you can now use various &lt;b&gt;Foreign Data Wrappers&lt;/b&gt; (FDW) to connect a PostgreSQL Server to remote data stores. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/Foreign_data_wrappers"&gt;http://wiki.postgresql.org/wiki/Foreign_data_wrappers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this post I'll be using the &lt;b&gt;file_fdw &lt;/b&gt;extension:&lt;br /&gt;&lt;br /&gt;What does it do?&lt;br /&gt;&lt;blockquote&gt;The file_fdw module provides the foreign-data wrapper file_fdw, which can be used to access data files in the server's file system. Data files must be in a format that can be read by COPY FROM; see COPY for details.&lt;/blockquote&gt;&lt;br /&gt;Case scenario. Setup a foreign table to read the server log directly within the database manager.&lt;br /&gt;&lt;b&gt;Postgresql version 9.1.1 on Debian squeeze &lt;/b&gt;&lt;br /&gt;Step 0. Install if you haven't done  it, the contrib module&lt;br /&gt;&lt;pre class="brush:shell"&gt;root@debian1:~# apt-get install postgresql-contrib-9.1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Step 1. Reconfigure your postgresql.conf file so that logs are generated in a csv format and appropriate rotation of the log is chosen, and reload the configuration.&lt;br /&gt;&lt;br /&gt;I though of these parameters (note that a static name for the generated log file is required for obvious reasons).&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;# - Where to Log -&lt;br /&gt;&lt;br /&gt;log_destination = 'csvlog'              # Valid values are combinations of&lt;br /&gt;                                        # stderr, csvlog, syslog, and eventlog,&lt;br /&gt;                                        # depending on platform.  csvlog&lt;br /&gt;                                        # requires logging_collector to be on.&lt;br /&gt;&lt;br /&gt;# This is used when logging to stderr:&lt;br /&gt;logging_collector = on                  # Enable capturing of stderr and csvlog&lt;br /&gt;                                        # into log files. Required to be on for&lt;br /&gt;                                        # csvlogs.&lt;br /&gt;                                        # (change requires restart)&lt;br /&gt;&lt;br /&gt;# These are only used if logging_collector is on:&lt;br /&gt;log_directory = 'pg_log'                # directory where log files are written,&lt;br /&gt;                                        # can be absolute or relative to PGDATA&lt;br /&gt;log_filename = 'postgresql_log' # log file name pattern,&lt;br /&gt;#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'        # log file name pattern,&lt;br /&gt;                                        # can include strftime() escapes&lt;br /&gt;#log_file_mode = 0600                   # creation mode for log files,&lt;br /&gt;                                        # begin with 0 to use octal notation&lt;br /&gt;log_truncate_on_rotation = on         # If on, an existing log file with the&lt;br /&gt;                                        # same name as the new log file will be&lt;br /&gt;                                        # truncated rather than appended to.&lt;br /&gt;                                        # But such truncation only occurs on&lt;br /&gt;                                        # time-driven rotation, not on restarts&lt;br /&gt;                                        # or size-driven rotation.  Default is&lt;br /&gt;                                        # off, meaning append to existing files&lt;br /&gt;                                        # in all cases.&lt;br /&gt;log_rotation_age = 5d                   # Automatic rotation of logfiles will&lt;br /&gt;                                        # happen after that time.  0 disables.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Step 2. Read through and follow along the example depicted in this link (the only change needed is the path to your logfile):&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/devel/static/file-fdw.html"&gt;http://www.postgresql.org/docs/devel/static/file-fdw.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Step 3. Query the log in whatever fashion you like.&lt;br /&gt;For example:&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@debian1:~/data_sr$ psql -p 5432 pgbenchdb&lt;br /&gt;psql (9.1.1)&lt;br /&gt;Type "help" for help.&lt;br /&gt;pgbenchdb=# select log_time, error_severity, message from pglog order by log_time desc;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output&lt;br /&gt;&lt;pre class="brush:sql"&gt;log_time          | error_severity |                                                         message                                                         &lt;br /&gt;----------------------------+----------------+-------------------------------------------------------------------------------------------------------------------------&lt;br /&gt; 2012-01-07 20:00:43.223-06 | ERROR          | column "logtime" does not exist&lt;br /&gt; 2012-01-07 19:58:57.02-06  | WARNING        | transaction log file "000000020000000000000041" could not be archived: too many failures&lt;br /&gt; 2012-01-07 19:58:57.02-06  | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:58:56.009-06 | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:58:54.998-06 | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:57:54.93-06  | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:57:54.93-06  | WARNING        | transaction log file "000000020000000000000041" could not be archived: too many failures&lt;br /&gt; 2012-01-07 19:57:53.92-06  | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:57:52.91-06  | LOG            | archive command failed with exit code 1&lt;br /&gt; 2012-01-07 19:56:52.837-06 | WARNING        | transaction log file "000000020000000000000041" could not be archived: too many failures&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On that warning:the transaction log file couldn't be archived,  as the target machine where I was sending it to, was down. =-)&lt;br /&gt;Publishing from my fortress of solitude, they gave me back my keys. Yay!!!!&lt;br /&gt;&lt;br /&gt;Other references:&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/sql-createforeigntable.html"&gt;http://www.postgresql.org/docs/9.1/static/sql-createforeigntable.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.depesz.com/index.php/2011/03/14/waiting-for-9-1-foreign-data-wrapper/"&gt;http://www.depesz.com/index.php/2011/03/14/waiting-for-9-1-foreign-data-wrapper/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://pgxn.org/"&gt;http://pgxn.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://vibhorkumar.wordpress.com/2011/12/06/postgresql-9-1-new-in-object-manipulation/"&gt;http://vibhorkumar.wordpress.com/2011/12/06/postgresql-9-1-new-in-object-manipulation/&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7040808492706708035?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7040808492706708035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7040808492706708035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7040808492706708035'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-foreign-tables-filefdw.html' title='Postgresql - Foreign tables. file_fdw wrapper. querying the log file'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1745539572276003933</id><published>2012-01-06T17:35:00.001-06:00</published><updated>2012-01-08T18:15:40.562-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='streaming_replication'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Streaming replication: synchronous replication</title><content type='html'>One cool new feature in postgresql 9.1 is the ability to set up synchronous streaming replication. What does that mean? That one transaction will be committed only when it has been written to wal records (being sent) and applied to the standby servers that are replicating data in a synchronous manner. This sounds like an extra overhead to dml operations, so I guess it's advisable for you to have an excellent communication pathway between the master and the synchronous standby servers. The main advantage of this set up is that you can guarantee to a great deal the reliability of data in case of failure, if one transaction was given the status of committed it will become available instantly in all the synchronous standby's as well, so you'll have virtually no data loss in case of contingencies. &lt;br /&gt;&lt;br /&gt;Here are the steps to configure this kind of streaming replication:&lt;br /&gt;&lt;a href="http://vibhorkumar.wordpress.com/2011/10/20/asynchronoussynchronous-streaming-replication-in-postgresql-9-1/"&gt;http://vibhorkumar.wordpress.com/2011/10/20/asynchronoussynchronous-streaming-replication-in-postgresql-9-1/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The important part being:&lt;br /&gt;&lt;br /&gt;To switch Asynchronous replication to Synchronous Replication,use following steps:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;1. Change following parameter in postgresql.conf on Primary Server:&lt;br /&gt;synchronous_standby_names = 'sync_replication'&lt;br /&gt;&lt;br /&gt;2. Reload the above changes on primary using following command:&lt;br /&gt;pg_ctl -D [primary data directory] reload&lt;br /&gt;&lt;br /&gt;3. Change following parameter in recovery.conf file on Standby:&lt;br /&gt;primary_conninfo = 'host=localhost port=5432 application_name=sync_replication'&lt;br /&gt;4. Restart the standby using following command:&lt;br /&gt;pg_ctl -D [standby directory] restart -m fast&lt;/blockquote&gt;Then ,the difference is that :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;you specify the synchronous_standby_names in the master's configuration, for the standby servers that will replicate in a synchronous fashion.&lt;/li&gt;&lt;li&gt;reload the master's configuration &lt;/li&gt;&lt;li&gt;add the application_name option to the primary_conninfo string in the recovery.conf file in each synchronous standby.&lt;/li&gt;&lt;li&gt;restart the standby server.&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Testing case:&lt;/b&gt;&lt;br /&gt;+ Start a big transaction on the master server and kill one synchronous slave in the middle of it. &lt;br /&gt;Expected result:&lt;br /&gt;+ The transaction will&amp;nbsp; be rolled back. No more transactions will be allowed 'till the synchronous standby server becomes available and re-synchronizes.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Results:&lt;/b&gt;&lt;br /&gt;+ The transaction is stuck!!!&lt;br /&gt;This is what the master says about it:&lt;br /&gt;&lt;br /&gt;in the log:&lt;br /&gt;&lt;pre class="brush:shell"&gt;2012-01-06 17:09:58 CST [unknown] postgres LOG:  could not send data to client: Connection reset by peer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;current activity in pg_stat_activity:&lt;br /&gt;&lt;pre class="brush:shell"&gt;-[ RECORD 2 ]----+--------------------------------&lt;br /&gt;datid            | 24576&lt;br /&gt;datname          | pgbenchdb&lt;br /&gt;procpid          | 13296&lt;br /&gt;usesysid         | 10&lt;br /&gt;usename          | postgres&lt;br /&gt;application_name | psql&lt;br /&gt;client_addr      | &lt;br /&gt;client_hostname  | &lt;br /&gt;client_port      | -1&lt;br /&gt;backend_start    | 2012-01-06 17:09:50.726341-06&lt;br /&gt;xact_start       | 2012-01-06 17:09:50.728063-06&lt;br /&gt;query_start      | 2012-01-06 17:10:01.36678-06&lt;br /&gt;waiting          | f&lt;br /&gt;current_query    | commit;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;the replication state in pg_stat_replication:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# select * from pg_stat_replication;&lt;br /&gt;(No rows)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I was kind of expecting that.&lt;br /&gt;&lt;br /&gt;There's no remedy for me other than to kill the transaction manually (there must me some sort of replication timeout parameter somewhere!). &lt;br /&gt;&lt;b&gt;But before that, am I able to execute dml operations through another session?&lt;br /&gt;Yes!!!! Oops! (but this happens after I cancel it) &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;If I cancel manually the hung up transaction I get the following message:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# insert into pgbench_history (tid) values ( generate_series(1,100));&lt;br /&gt;^CCancel request sent&lt;br /&gt;WARNING:  canceling wait for synchronous replication due to user request&lt;br /&gt;DETAIL:  The transaction has already committed locally, but might not have been replicated to the standby.&lt;br /&gt;INSERT 0 100&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@debian1:~$ psql -p 5432 pgbenchdb &lt; test_sync_replication.sql&lt;br /&gt;BEGIN&lt;br /&gt;INSERT 0 100000&lt;br /&gt;INSERT 0 100000&lt;br /&gt;INSERT 0 100000&lt;br /&gt;INSERT 0 100000&lt;br /&gt;INSERT 0 100000&lt;br /&gt;INSERT 0 100000&lt;br /&gt;^CCancel request sent&lt;br /&gt;WARNING:  canceling wait for synchronous replication due to user request&lt;br /&gt;DETAIL:  The transaction has already committed locally, but might not have been replicated to the standby.&lt;br /&gt;COMMIT&lt;br /&gt;&lt;/pre&gt;Well, canceling a request is not something that applications usually are programmed to. But the issue that worries me is that it won't return an error message, it will freeze waiting for the synchronous standby to reply!Need to dive in the docs to figure out what the hell is going on.&lt;b&gt;Despite the above results, I think it's important to pinpoint that the status of committed was not granted in neither the transactions.&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1745539572276003933?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1745539572276003933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-streaming-replication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1745539572276003933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1745539572276003933'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-streaming-replication.html' title='Postgresql - Streaming replication: synchronous replication'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4385426340678063375</id><published>2012-01-06T14:02:00.000-06:00</published><updated>2012-01-06T15:50:48.318-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='psql'/><title type='text'>Postgresql - psql passing variables to a sql script</title><content type='html'>It could arise the necessity to parametrize the scripts that we pass to psql, maybe just for testing purposes. For instance, this is the script that pgbench uses for each transaction that simulated clients execute:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;BEGIN;&lt;br /&gt;&lt;br /&gt;    UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;&lt;br /&gt;&lt;br /&gt;    SELECT abalance FROM pgbench_accounts WHERE aid = :aid;&lt;br /&gt;&lt;br /&gt;    UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;&lt;br /&gt;&lt;br /&gt;    UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;&lt;br /&gt;&lt;br /&gt;    INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);&lt;br /&gt;&lt;br /&gt;    END;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I called this script : pgbench_transaction.sql&lt;br /&gt;As you can see, each variable has a colon as  prefix. You can execute manually by invoking psql like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; psql -p 9999 -v tid=1 -v bid=2 -v aid=3 -v delta=4  pgbenchdb &lt; pgbench_transaction.sql&lt;br /&gt;&lt;/pre&gt;so you prefix each variable=value pair with a -v flagAnd the output:&lt;pre class="brush:sql"&gt;BEGIN&lt;br /&gt;UPDATE 1&lt;br /&gt; abalance &lt;br /&gt;----------&lt;br /&gt;        8&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;UPDATE 1&lt;br /&gt;UPDATE 1&lt;br /&gt;INSERT 0 1&lt;br /&gt;COMMIT&lt;br /&gt;&lt;/pre&gt;an alternative way to do this "parameter passing" is by including set statements inside the script, obviously this approach is less flexible.&lt;pre class="brush:sql"&gt;BEGIN;&lt;br /&gt;        \set tid 1&lt;br /&gt;        \set bid 2&lt;br /&gt;        \set aid 3&lt;br /&gt;        \set delta 4&lt;br /&gt;&lt;br /&gt;    UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;&lt;br /&gt;    SELECT abalance FROM pgbench_accounts WHERE aid = :aid;&lt;br /&gt;    UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;&lt;br /&gt;    UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;&lt;br /&gt;    INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);&lt;br /&gt;    END;&lt;br /&gt;&lt;/pre&gt;but useful nonetheless.There's an issue with using quotes, they must be escaped.For instance:&lt;pre class="brush:sql"&gt;\set myvariable '\'somestring\'' SELECT * FROM FOO WHERE BAR = :myvariable&lt;br /&gt;&lt;/pre&gt;&lt;a href="http://stackoverflow.com/questions/36959/how-do-you-use-script-variables-in-postgresql"&gt;http://stackoverflow.com/questions/36959/how-do-you-use-script-variables-in-postgresql&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4385426340678063375?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4385426340678063375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-psql-passing-variables-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4385426340678063375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4385426340678063375'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-psql-passing-variables-to.html' title='Postgresql - psql passing variables to a sql script'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5689151108835222130</id><published>2012-01-06T11:51:00.000-06:00</published><updated>2012-01-06T12:11:51.669-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pgpool : num_init_children</title><content type='html'>Yesterday I was hitting my head against a wall trying to figure out why pgbench got stuck while doing a simple test involving 50 concurrent clients. It turns out that I was overlooking the "num_init_children" parameter in the pgpool configuration.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; &lt;b&gt;pgpool-II accepts up to num_init_children concurrent sessions.&lt;/b&gt;    If the number of concurrent sessions reach num_init_children, new session will be queued&lt;/li&gt;&lt;li&gt;pgbench creates concurrent connections before    starting actual transactions. So if the number of concurrent transactions specified by "-c" exceeds num_init_children,    pgbench will stuck because it will wait for pgpool accepting connections forever.&lt;/li&gt;&lt;li&gt;    On the other hand PostgreSQL does not accept concurrent sessions more than max_connections.&lt;/li&gt;&lt;li&gt;   &lt;b&gt;If you want to test pgpool-II's connection queuing, you can use psql instead of pgbench.&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;Reference. Question number 10.&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/FAQ.html" target="_blank"&gt;http://pgpool.projects.postgresql.org/FAQ.html &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I guess I need to follow what's usually told in this cases : RTFM!&lt;br /&gt;Then the default value for that parameter is 32, setting it up to 51:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 10&lt;br /&gt;query mode: simple&lt;br /&gt;number of clients: 50&lt;br /&gt;number of threads: 2&lt;br /&gt;number of transactions per client: 10&lt;br /&gt;number of transactions actually processed: 500/500&lt;br /&gt;tps = 33.339290 (including connections establishing)&lt;br /&gt;tps = 33.685822 (excluding connections establishing)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not that bad, but it can improve, that's for sure.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5689151108835222130?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5689151108835222130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgpool-numinitchildren.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5689151108835222130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5689151108835222130'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-pgpool-numinitchildren.html' title='Postgresql - pgpool : num_init_children'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7771687250791683738</id><published>2012-01-06T02:01:00.000-06:00</published><updated>2012-01-06T01:01:35.567-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Spotting differences between schemas</title><content type='html'>&lt;b&gt;How do you tell the difference between database schemas in an automatic fashion?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;One approach is to make a sql dump from both schemas and apply the diff unix command.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://linux.101hacks.com/linux-commands/diff-command-examples/"&gt;http://linux.101hacks.com/linux-commands/diff-command-examples/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I'll use a toy database called switch_books&lt;br /&gt;&lt;br /&gt;First make the first backup (the "before" backup)&lt;br /&gt;&lt;pre class="brush:shell"&gt;-bash-4.2$ pg_dump switch_books &gt; switch_books_before.sql&lt;br /&gt;-bash-4.2$ psql switch_books&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then I create a dummy table:&lt;br /&gt;&lt;pre class="brush:sql"&gt;switch_books=# create table fake_table (id integer primary key);&lt;br /&gt;NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "fake_table_pkey" for table "fake_table"&lt;br /&gt;CREATE TABLE&lt;br /&gt;switch_books=# \q&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And take a new shot (the after backup)&lt;br /&gt;&lt;pre class="brush:shell"&gt;-bash-4.2$ pg_dump switch_books &gt; switch_books_after.sql&lt;br /&gt;&lt;br /&gt;# generate the diff file&lt;br /&gt;-bash-4.2$ diff switch_books_before.sql switch_books_after.sql &gt; switch_books_diff.sql&lt;br /&gt;&lt;br /&gt;-bash-4.2$ cat switch_books_diff.sql | less&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And reviewing the results:&lt;br /&gt;&lt;pre class="brush:sql"&gt;164a165,175&lt;br /&gt;&gt; -- Name: fake_table; Type: TABLE; Schema: public; Owner: postgres; Tablespace:&lt;br /&gt;&gt; --&lt;br /&gt;&gt;&lt;br /&gt;&gt; CREATE TABLE fake_table (&lt;br /&gt;&gt;     id integer NOT NULL&lt;br /&gt;&gt; );&lt;br /&gt;&gt;&lt;br /&gt;&gt;&lt;br /&gt;&gt; ALTER TABLE public.fake_table OWNER TO postgres;&lt;br /&gt;&gt;&lt;br /&gt;&gt; --&lt;br /&gt;358a370,377&lt;br /&gt;&gt; -- Data for Name: fake_table; Type: TABLE DATA; Schema: public; Owner: postgres&lt;br /&gt;&gt; --&lt;br /&gt;&gt;&lt;br /&gt;&gt; COPY fake_table (id) FROM stdin;&lt;br /&gt;&gt; \.&lt;br /&gt;&gt;&lt;br /&gt;&gt;&lt;br /&gt;&gt; --&lt;br /&gt;583a603,610&lt;br /&gt;&gt; -- Name: fake_table_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:&lt;br /&gt;&gt; --&lt;br /&gt;&gt;&lt;br /&gt;&gt; ALTER TABLE ONLY fake_table&lt;br /&gt;&gt;     ADD CONSTRAINT fake_table_pkey PRIMARY KEY (id);&lt;br /&gt;&gt;&lt;br /&gt;&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;RAF mentioned today this utility in a conversation.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are other tools that go one step beyond by generating a sql script that will make the differences go away.&lt;br /&gt;&lt;a href="http://apgdiff.startnet.biz/"&gt;http://apgdiff.startnet.biz/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7771687250791683738?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7771687250791683738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-spotting-differences-between.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7771687250791683738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7771687250791683738'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-spotting-differences-between.html' title='Postgresql - Spotting differences between schemas'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8684565863577084717</id><published>2012-01-05T18:12:00.000-06:00</published><updated>2012-01-05T18:17:19.117-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='maintenance'/><title type='text'>Postgresql - Maintenaince. Cleaning up the pg_attribute table</title><content type='html'>What is the pg_attribute table? &lt;a href="http://www.postgresql.org/docs/9.1/static/catalog-pg-attribute.html"&gt;http://www.postgresql.org/docs/9.1/static/catalog-pg-attribute.html&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;The catalog pg_attribute stores information about table columns. There will be exactly one pg_attribute row for every column in every table in the database. (There will also be attribute entries for indexes, and indeed all objects that have pg_class entries.)The term attribute is equivalent to column and is used for historical reasons.&lt;/blockquote&gt;Sometimes it could become "bloated", that is, it will have unnecessary information (due  to invalid database objects) and some cleaning up would be in order for performance reasons.I found this reference about the issue:&lt;a href="http://www.chasingnuts.com/2010/cleaning_pg_attribute_bloat/comment-page-1/#comment-54458"&gt;http://www.chasingnuts.com/2010/cleaning_pg_attribute_bloat/comment-page-1/#comment-54458&lt;/a&gt;As simple as this&lt;pre class="brush:sql"&gt;&lt;br /&gt;VACUUM FULL  pg_catalog.pg_class;&lt;br /&gt;REINDEX TABLE pg_catalog.pg_class;&lt;br /&gt;&lt;/pre&gt;Damn, life would be so fucking beautiful if we all shared what we know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8684565863577084717?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8684565863577084717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-maintenaince-cleaning-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8684565863577084717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8684565863577084717'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-maintenaince-cleaning-up.html' title='Postgresql - Maintenaince. Cleaning up the pg_attribute table'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2091978098392929732</id><published>2012-01-03T02:42:00.000-06:00</published><updated>2012-01-03T02:15:01.767-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Life'/><title type='text'>Life . Small time Oracle Certification</title><content type='html'>I really hate conformism and self deception. I invested about two months on an Oracle certification course, and I don't think it was really worth it. The thing I loath the most is that they made us memorize what is called "a brain dump" to have the right to present the certification tests. So each one of us had a very easy time approving them. I kind of like Oracle and study on my own when I can't sleep (like just now), but it doesn't feel right ... they took all the joy, all the sense of achievement away from me. From the business standpoint I realize that in that way, they generate returning happy (and conformists) customers, and hence more profits, but it's just not right! &lt;br /&gt;So,I say, screw you small timers! Shame on you!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2091978098392929732?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2091978098392929732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/life-small-time-oracle-certification.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2091978098392929732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2091978098392929732'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/life-small-time-oracle-certification.html' title='Life . Small time Oracle Certification'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3551059483541482558</id><published>2012-01-03T00:37:00.003-06:00</published><updated>2012-01-03T01:04:45.567-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Postgresql - Security : Enabling server-side SSL support</title><content type='html'>In the last post, I made a client connect through a SSH tunnel in order to avoid sending plain text messages to the backend. Now I'm testing the enabling of SSL support on the postgresql server.&lt;br /&gt;&lt;br /&gt;I'm following this walktrough:&lt;br /&gt;&lt;a href="http://vibhorkumar.wordpress.com/2011/07/17/how-to-enable-ssl-in-postgresqlppas/"&gt;http://vibhorkumar.wordpress.com/2011/07/17/how-to-enable-ssl-in-postgresqlppas/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And I've already executed successfully the first part. &lt;br /&gt;Tip:&lt;br /&gt;+ SSL support seems to be available in the binary packages of some distros (so you don't have to compile postgresql from source to have this feature, just enable ssl through the postgresql.conf file ssl = on in the respective step)&lt;br /&gt;&lt;br /&gt;This is how it looks a successful connection to the server, using SSL (in spanish =-( ):&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img209.imageshack.us/img209/9500/psqlssl.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="241" width="669" src="http://img209.imageshack.us/img209/9500/psqlssl.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now, how does this communication channel look  to a sniffer ? ( wireshark for instance)&lt;br /&gt;&lt;br /&gt;Well, following the TCP stream, you only get a bunch of non-readable rubish.&lt;br /&gt;&lt;a target='_blank' href='http://imageshack.us/photo/my-images/402/psqlssl1.png/'&gt;&lt;img src='http://img402.imageshack.us/img402/6638/psqlssl1.th.png' border='0'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wich is great! It would be awesome to break this encryption somehow ... nah, just kidding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3551059483541482558?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3551059483541482558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-enable-server-side.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3551059483541482558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3551059483541482558'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-enable-server-side.html' title='Postgresql - Security : Enabling server-side SSL support'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5709563283274390640</id><published>2012-01-02T19:20:00.004-06:00</published><updated>2012-01-02T19:33:45.912-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Networks'/><title type='text'>Linux - Which process is bound to a particular port</title><content type='html'>I found this neat script, for you to use whenever in doubt about what process is bound to a particular port.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;#!/bin/bash&lt;br /&gt;# See Linux Server Hacks #54&lt;br /&gt;# $Id: whosOnPort.sh,v 1.5 2007/03/28 06:50:09 oracle Exp $&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;port=$1&lt;br /&gt;# get the process info (pid/name). restricted to tcp only&lt;br /&gt;procinfo=$( netstat --numeric-ports -nlp 2&gt; /dev/null | \&lt;br /&gt;            grep ^tcp | grep -w ${port} | tail -n 1 | awk '{print $7}' )&lt;br /&gt;&lt;br /&gt;case "${procinfo}" in&lt;br /&gt;"")&lt;br /&gt;  echo "No process listening on port ${port}"&lt;br /&gt;  ;;&lt;br /&gt;&lt;br /&gt;"-")&lt;br /&gt;  echo "Process is running on ${port}, but current user does not have rights to see process information."&lt;br /&gt;  ;;&lt;br /&gt;&lt;br /&gt;*)&lt;br /&gt;  echo "${procinfo} is running on port ${port}"&lt;br /&gt;  ps uwep ${procinfo%/*}&lt;br /&gt;  ;;&lt;br /&gt;&lt;br /&gt;esac&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Source &lt;br /&gt;&lt;a href="https://github.com/tardate/sources/blob/master/whosOnPort.sh"&gt;&lt;br /&gt;https://github.com/tardate/sources/blob/master/whosOnPort.sh&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It parses netstat info.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;wwwrun@linux-2561:~&gt; ./whosOnPort.sh  9999&lt;br /&gt;9591/pgpool is running on port 9999&lt;br /&gt;USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND&lt;br /&gt;wwwrun    9591  0.0  0.1  10000  4128 ?        S    18:55   0:00 /usr/local/bin/pgpool -f /usr/local/etc/pgpool.conf -F /usr/local/e&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Mmm, alternatively you can grep the /etc/services file (I own that one to RAF). For instance:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@debian1:~$ cat /etc/services | grep 5432&lt;br /&gt;postgresql      5432/tcp        postgres        # PostgreSQL Database&lt;br /&gt;postgresql      5432/udp        postgres&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But I like the script mentioned above better as it gives you more useful info.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5709563283274390640?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5709563283274390640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/linux-what-process-is-bound-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5709563283274390640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5709563283274390640'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/linux-what-process-is-bound-to.html' title='Linux - Which process is bound to a particular port'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-5733610618815500167</id><published>2012-01-02T12:49:00.002-06:00</published><updated>2012-01-02T22:04:19.390-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='multiplexing'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Microsoft - Licenciamiento. Multiplexing y Client Access License - Afterthoughts</title><content type='html'>Estoy buscando una forma de darle la vuelta al asunto del multiplexing. Estas son mis ideas de momento :&lt;br /&gt;&lt;br /&gt;&lt;a target='_blank' href='http://imageshack.us/photo/my-images/13/hipotesis2.png/'&gt;&lt;img src='http://img13.imageshack.us/img13/2946/hipotesis2.th.png' border='0'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Lamentablemente no hay demasiada información o feedback de usuarios que se refieran a experiencias y criterios (o workarounds) adoptados por empresas respecto a este asunto. &lt;br /&gt;Creo que hasta aquí llega mi papel como abogado del diablo =-) . Supongo que es tiempo de consultar a un auditor de tecnología.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-5733610618815500167?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/5733610618815500167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/microsoft-licenciamiento-multiplexing-y.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5733610618815500167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/5733610618815500167'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/microsoft-licenciamiento-multiplexing-y.html' title='Microsoft - Licenciamiento. Multiplexing y Client Access License - Afterthoughts'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8915914059225420340</id><published>2012-01-02T01:48:00.003-06:00</published><updated>2012-01-02T10:40:43.451-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Postgresql - Security : SSH Tunneling your PostgreSQL communications</title><content type='html'>In my previous entry, I highlighted the importance of having encrypted communications between the clients and the backend server. The first approach I'll attack, is to use the ssh tunneling facility as depicted on the official docs, I regard it as being the most straightforward option (or at least the fastest to implement).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/ssh-tunnels.html"&gt;http://www.postgresql.org/docs/9.1/static/ssh-tunnels.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Testing scenario&lt;br /&gt;+ one postgresql client running on a windows machine (IP 192.168.56.66)&lt;br /&gt;+ one postgresql backend server running on fedora linux (IP 192.168.56.101)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Prerequisites:&lt;br /&gt;+ A ssh server running where the postgresql backend server lives.&lt;br /&gt;+ A linux account with which you can connect to the postgresql server host (and it's properly configured in the pg_hba.conf file (if necessary) .&lt;br /&gt;+ Putty for windows&lt;br /&gt;+ Having understood what the on-line postgresql documentation says on this matter.&lt;br /&gt;&lt;br /&gt;This is the tutorial I'm using for the putty configuration:&lt;br /&gt;&lt;a href="http://oldsite.precedence.co.uk/nc/putty.html"&gt;http://oldsite.precedence.co.uk/nc/putty.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- Note that I'm connecting through the port 22 (default port for ssh)&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/862/68424982.png/" target="_blank"&gt;&lt;img src="http://img862.imageshack.us/img862/8724/68424982.th.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- 63333 is the port that will listen for connections on the client host, and it will be the port the I'll specify in the psql connection.&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/215/57021650.png/" target="_blank"&gt;&lt;img src="http://img215.imageshack.us/img215/764/57021650.th.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Make the ssh connection to the host where the postgresql server is running (this is the tunnel).&lt;br /&gt;&lt;a href="http://img848.imageshack.us/img848/2262/82292019.th.png"&gt;http://img848.imageshack.us/img848/2262/82292019.th.png&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Using the ssh tunnel : Connect to the server using psql -h localhost -p 63333&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/690/68176177.png/" target="_blank"&gt;&lt;img src="http://img690.imageshack.us/img690/4176/68176177.th.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt; Drawbacks: &lt;br /&gt;+ Encryption is not enforced for the clients to be able to connect to the server. &lt;br /&gt;+ I think that relying on the clients to set the tunnel might not be a good idea&lt;br /&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8915914059225420340?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8915914059225420340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-ssh-tunneling-your.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8915914059225420340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8915914059225420340'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-ssh-tunneling-your.html' title='Postgresql - Security : SSH Tunneling your PostgreSQL communications'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3683590129823333197</id><published>2012-01-01T10:08:00.009-06:00</published><updated>2012-01-01T11:55:04.305-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>Postgresql - Security : Sniffing PostgreSQL communications</title><content type='html'>This is the kind of info that wireshark can give you about any particular unencrypted network message using the pgsql protocol:&lt;br /&gt;&lt;br /&gt;&lt;table class="shaded" summary=""&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Field name&lt;/th&gt; &lt;th&gt;Type&lt;/th&gt; &lt;th&gt;Description&lt;/th&gt; &lt;th&gt;Versions&lt;/th&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.authtype&lt;/td&gt; &lt;td&gt;Signed 32-bit integer&lt;/td&gt; &lt;td&gt;Authentication type&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.code&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Code&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.col.index&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;Column index&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.col.name&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Column name&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.col.typemod&lt;/td&gt; &lt;td&gt;Signed 32-bit integer&lt;/td&gt; &lt;td&gt;Type modifier&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.condition&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Condition&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.copydata&lt;/td&gt; &lt;td&gt;Byte array&lt;/td&gt; &lt;td&gt;Copy data&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.detail&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Detail&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.error&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Error&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.file&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;File&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.format&lt;/td&gt; &lt;td&gt;Unsigned 16-bit integer&lt;/td&gt; &lt;td&gt;Format&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.frontend&lt;/td&gt; &lt;td&gt;Boolean&lt;/td&gt; &lt;td&gt;Frontend&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.hint&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Hint&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.key&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;Key&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.length&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;Length&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.line&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Line&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.message&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Message&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.oid&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;OID&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.oid.table&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;Table OID&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.oid.type&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;Type OID&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.parameter_name&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Parameter name&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.parameter_value&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Parameter value&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.password&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Password&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.pid&lt;/td&gt; &lt;td&gt;Unsigned 32-bit integer&lt;/td&gt; &lt;td&gt;PID&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.portal&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Portal&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.position&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Position&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.query&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Query&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.routine&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Routine&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.salt&lt;/td&gt; &lt;td&gt;Byte array&lt;/td&gt; &lt;td&gt;Salt value&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.severity&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Severity&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.statement&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Statement&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.status&lt;/td&gt; &lt;td&gt;Unsigned 8-bit integer&lt;/td&gt; &lt;td&gt;Status&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.tag&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Tag&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.text&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Text&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.type&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Type&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.val.data&lt;/td&gt; &lt;td&gt;Byte array&lt;/td&gt; &lt;td&gt;Data&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.val.length&lt;/td&gt; &lt;td&gt;Signed 32-bit integer&lt;/td&gt; &lt;td&gt;Column length&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;pgsql.where&lt;/td&gt; &lt;td&gt;String&lt;/td&gt; &lt;td&gt;Context&lt;/td&gt; &lt;td&gt;1.0.0 to 1.6.4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;a href="http://www.wireshark.org/docs/dfref/p/pgsql.html"&gt;http://www.wireshark.org/docs/dfref/p/pgsql.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is for example one very innocent looking capture result of executing psql internal command \l (list databases):&lt;br /&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/515/capturawireshark.png/" target="_blank"&gt;&lt;img src="http://img515.imageshack.us/img515/1452/capturawireshark.th.png" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Extended descriptions:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img829.imageshack.us/img829/5039/pgsqlwiresharkfilter.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="697" width="543" src="http://img829.imageshack.us/img829/5039/pgsqlwiresharkfilter.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img24.imageshack.us/img24/3168/pgsqlwiresharkfilter1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="395" width="530" src="http://img24.imageshack.us/img24/3168/pgsqlwiresharkfilter1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;+ Well, not everything regarding sniffing communications is bad, I guess you can troubleshoot a variety of problems with its help.&lt;br /&gt;&lt;br /&gt;But I'm a lazy kind of guy in the sense that I'd rather capture automatically any communication related to PostgreSQL and have it saved in a txt file. How to accomplish such thing?&lt;br /&gt;&lt;br /&gt;One option is using tshark:&lt;br /&gt;&lt;a href="http://blog.timstoop.nl/2008/11/03/sniffing-postgresql-queries-with-tsharkwireshark/"&gt;http://blog.timstoop.nl/2008/11/03/sniffing-postgresql-queries-with-tsharkwireshark/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Conclusions:&lt;br /&gt;+ Added another tool for troubleshooting postgresql issues.&lt;br /&gt;+ Of course it must be documented somewhere in the web, but using this technique you get a glance at what psql internal commands do.&lt;br /&gt;+&lt;b&gt; Only very lame postgresql administrators don't encrypt postgresql  messages for sensitive communications. &lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3683590129823333197?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3683590129823333197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-sniffing-postgresql.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3683590129823333197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3683590129823333197'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-security-sniffing-postgresql.html' title='Postgresql - Security : Sniffing PostgreSQL communications'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7225871056564488107</id><published>2012-01-01T00:23:00.002-06:00</published><updated>2012-01-01T00:26:00.787-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - psql : list of available datatypes</title><content type='html'>This post is just to honor the wide array of data types available in PostgreSQL. This list is available using psql's internal command \dT [pattern]&lt;br /&gt;&lt;br /&gt;For instance:&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# \dT+ *&lt;br /&gt;                                                               Listado de tipos de dato&lt;br /&gt;  Esquema   |           Nombre            |  Nombre interno  | Tamaño | Elementos |                            Descripción                            &lt;br /&gt;------------+-----------------------------+------------------+--------+-----------+-------------------------------------------------------------------&lt;br /&gt; pg_catalog | "any"                       | any              | 4      |           | &lt;br /&gt; pg_catalog | "char"                      | char             | 1      |           | single character&lt;br /&gt; pg_catalog | abstime                     | abstime          | 4      |           | absolute, limited-range date and time (Unix system time)&lt;br /&gt; pg_catalog | aclitem                     | aclitem          | 12     |           | access control list&lt;br /&gt; pg_catalog | anyarray                    | anyarray         | var    |           | &lt;br /&gt; pg_catalog | anyelement                  | anyelement       | 4      |           | &lt;br /&gt; pg_catalog | anyenum                     | anyenum          | 4      |           | &lt;br /&gt; pg_catalog | anynonarray                 | anynonarray      | 4      |           | &lt;br /&gt; pg_catalog | bigint                      | int8             | 8      |           | ~18 digit integer, 8-byte storage&lt;br /&gt; pg_catalog | bit                         | bit              | var    |           | fixed-length bit string&lt;br /&gt; pg_catalog | bit varying                 | varbit           | var    |           | variable-length bit string&lt;br /&gt; pg_catalog | boolean                     | bool             | 1      |           | boolean, 'true'/'false'&lt;br /&gt; pg_catalog | box                         | box              | 32     |           | geometric box '(lower left,upper right)'&lt;br /&gt; pg_catalog | bytea                       | bytea            | var    |           | variable-length string, binary values escaped&lt;br /&gt; pg_catalog | character                   | bpchar           | var    |           | char(length), blank-padded string, fixed storage length&lt;br /&gt; pg_catalog | character varying           | varchar          | var    |           | varchar(length), non-blank-padded string, variable storage length&lt;br /&gt; pg_catalog | cid                         | cid              | 4      |           | command identifier type, sequence in transaction id&lt;br /&gt; pg_catalog | cidr                        | cidr             | var    |           | network IP address/netmask, network address&lt;br /&gt; pg_catalog | circle                      | circle           | 24     |           | geometric circle '(center,radius)'&lt;br /&gt; pg_catalog | cstring                     | cstring          | var    |           | &lt;br /&gt; pg_catalog | date                        | date             | 4      |           | date&lt;br /&gt; pg_catalog | double precision            | float8           | 8      |           | double-precision floating point number, 8-byte storage&lt;br /&gt; pg_catalog | fdw_handler                 | fdw_handler      | 4      |           | &lt;br /&gt; pg_catalog | gtsvector                   | gtsvector        | var    |           | GiST index internal text representation for text search&lt;br /&gt; pg_catalog | inet                        | inet             | var    |           | IP address/netmask, host address, netmask optional&lt;br /&gt; pg_catalog | int2vector                  | int2vector       | var    |           | array of int2, used in system tables&lt;br /&gt; pg_catalog | integer                     | int4             | 4      |           | -2 billion to 2 billion integer, 4-byte storage&lt;br /&gt; pg_catalog | internal                    | internal         | 4      |           | &lt;br /&gt; pg_catalog | interval                    | interval         | 16     |           | @ &lt;number&gt; &lt;units&gt;, time interval&lt;br /&gt; pg_catalog | language_handler            | language_handler | 4      |           | &lt;br /&gt; pg_catalog | line                        | line             | 32     |           | geometric line (not implemented)&lt;br /&gt; pg_catalog | lseg                        | lseg             | 32     |           | geometric line segment '(pt1,pt2)'&lt;br /&gt; pg_catalog | macaddr                     | macaddr          | 6      |           | XX:XX:XX:XX:XX:XX, MAC address&lt;br /&gt; pg_catalog | money                       | money            | 8      |           | monetary amounts, $d,ddd.cc&lt;br /&gt; pg_catalog | name                        | name             | 64     |           | 63-character type for storing system identifiers&lt;br /&gt; pg_catalog | numeric                     | numeric          | var    |           | numeric(precision, decimal), arbitrary precision number&lt;br /&gt; pg_catalog | oid                         | oid              | 4      |           | object identifier(oid), maximum 4 billion&lt;br /&gt; pg_catalog | oidvector                   | oidvector        | var    |           | array of oids, used in system tables&lt;br /&gt; pg_catalog | opaque                      | opaque           | 4      |           | &lt;br /&gt; pg_catalog | path                        | path             | var    |           | geometric path '(pt1,...)'&lt;br /&gt; pg_catalog | pg_node_tree                | pg_node_tree     | var    |           | string representing an internal node tree&lt;br /&gt; pg_catalog | point                       | point            | 16     |           | geometric point '(x, y)'&lt;br /&gt; pg_catalog | polygon                     | polygon          | var    |           | geometric polygon '(pt1,...)'&lt;br /&gt; pg_catalog | real                        | float4           | 4      |           | single-precision floating point number, 4-byte storage&lt;br /&gt; pg_catalog | record                      | record           | var    |           | &lt;br /&gt; pg_catalog | refcursor                   | refcursor        | var    |           | reference to cursor (portal name)&lt;br /&gt; pg_catalog | regclass                    | regclass         | 4      |           | registered class&lt;br /&gt; pg_catalog | regconfig                   | regconfig        | 4      |           | registered text search configuration&lt;br /&gt; pg_catalog | regdictionary               | regdictionary    | 4      |           | registered text search dictionary&lt;br /&gt; pg_catalog | regoper                     | regoper          | 4      |           | registered operator&lt;br /&gt; pg_catalog | regoperator                 | regoperator      | 4      |           | registered operator (with args)&lt;br /&gt; pg_catalog | regproc                     | regproc          | 4      |           | registered procedure&lt;br /&gt; pg_catalog | regprocedure                | regprocedure     | 4      |           | registered procedure (with args)&lt;br /&gt; pg_catalog | regtype                     | regtype          | 4      |           | registered type&lt;br /&gt; pg_catalog | reltime                     | reltime          | 4      |           | relative, limited-range time interval (Unix delta time)&lt;br /&gt; pg_catalog | smallint                    | int2             | 2      |           | -32 thousand to 32 thousand, 2-byte storage&lt;br /&gt; pg_catalog | smgr                        | smgr             | 2      |           | storage manager&lt;br /&gt; pg_catalog | text                        | text             | var    |           | variable-length string, no limit specified&lt;br /&gt; pg_catalog | tid                         | tid              | 6      |           | (block, offset), physical location of tuple&lt;br /&gt; pg_catalog | time with time zone         | timetz           | 12     |           | time of day with time zone&lt;br /&gt; pg_catalog | time without time zone      | time             | 8      |           | time of day&lt;br /&gt; pg_catalog | timestamp with time zone    | timestamptz      | 8      |           | date and time with time zone&lt;br /&gt; pg_catalog | timestamp without time zone | timestamp        | 8      |           | date and time&lt;br /&gt; pg_catalog | tinterval                   | tinterval        | 12     |           | (abstime,abstime), time interval&lt;br /&gt; pg_catalog | trigger                     | trigger          | 4      |           | &lt;br /&gt; pg_catalog | tsquery                     | tsquery          | var    |           | query representation for text search&lt;br /&gt; pg_catalog | tsvector                    | tsvector         | var    |           | text representation for text search&lt;br /&gt; pg_catalog | txid_snapshot               | txid_snapshot    | var    |           | txid snapshot&lt;br /&gt; pg_catalog | unknown                     | unknown          | var    |           | &lt;br /&gt; pg_catalog | uuid                        | uuid             | 16     |           | UUID datatype&lt;br /&gt; pg_catalog | void                        | void             | 4      |           | &lt;br /&gt; pg_catalog | xid                         | xid              | 4      |           | transaction id&lt;br /&gt; pg_catalog | xml                         | xml              | var    |           | XML content&lt;br /&gt;(73 filas)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And if they're not enough, you can always define your very own data types.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7225871056564488107?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7225871056564488107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-psql-list-of-available.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7225871056564488107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7225871056564488107'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2012/01/postgresql-psql-list-of-available.html' title='Postgresql - psql : list of available datatypes'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4002321681281812295</id><published>2011-12-30T14:49:00.001-06:00</published><updated>2012-01-02T16:09:51.256-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='multiplexing'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>Microsoft - Licenciamiento. Multiplexing y Client Access License - Introducción</title><content type='html'>Estoy haciendo una pequeña investigación sobre el esquema de licenciamiento de Microsoft para sus productos server con especial énfasis a SQL server.&lt;br /&gt;&lt;br /&gt;&lt;a target='_blank' href='http://imageshack.us/photo/my-images/809/mapa3k.png/'&gt;&lt;img src='http://img809.imageshack.us/img809/7167/mapa3k.th.png' border='0'/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Uploaded with &lt;a target='_blank' href='http://imageshack.us'&gt;ImageShack.us&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;La verdad es que sale extremadamente caro incurrir en alguna infracción por incumplimiento de los términos de licenciamiento para los clientes que lo utilizan. Y pensar que hay alternativas gratuitas como Postgresql que igualan o superan las prestaciones de SQL server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4002321681281812295?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4002321681281812295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/microsoft-licenciamiento-multiplexing-y.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4002321681281812295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4002321681281812295'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/microsoft-licenciamiento-multiplexing-y.html' title='Microsoft - Licenciamiento. Multiplexing y Client Access License - Introducción'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4059282281579261696</id><published>2011-12-29T19:31:00.001-06:00</published><updated>2012-01-02T19:45:05.347-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - pgpool - a wary pgpool_failover script</title><content type='html'>I came up with this script to issue  automatic failover of the master node in the cluster.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;#!/bin/bash&lt;br /&gt;# Failover command for streaming replication&lt;br /&gt;# If standby goes down, does nothing. &lt;br /&gt;# If primary goes down, create a trigger file so that one standby&lt;br /&gt;# takes over the primary node role&lt;br /&gt;&lt;br /&gt;failed_node=$1&lt;br /&gt;old_master=$2&lt;br /&gt;trigger_file=$3&lt;br /&gt;&lt;br /&gt;standby1=10.0.0.201&lt;br /&gt;standby2=10.0.0.202&lt;br /&gt;standby3=10.0.0.113&lt;br /&gt;&lt;br /&gt;if [ $failed_node = $old_master ]; then&lt;br /&gt;#create the trigger file in the first available standby&lt;br /&gt;#test for the next available standby &lt;br /&gt;CMD=`ssh postgres@$standby1 "pg_ctl status | grep PID"`&lt;br /&gt;ANSWER=`echo $CMD`&lt;br /&gt;if [ -n "$ANSWER" ]; then&lt;br /&gt; CMD=`ssh postgres@$standby1 "touch $trigger_file"`&lt;br /&gt; echo $CMD&lt;br /&gt; exit 0;&lt;br /&gt;fi&lt;br /&gt;CMD=`ssh postgres@$standby2 "pg_ctl status | grep PID"`&lt;br /&gt;ANSWER=`echo $CMD`&lt;br /&gt;if [ -n "$ANSWER" ]; then&lt;br /&gt; CMD=`ssh postgres@$standby2 "touch $trigger_file"`&lt;br /&gt; echo $CMD&lt;br /&gt; exit 0;&lt;br /&gt;fi&lt;br /&gt;CMD=`ssh postgres@$standby3 "pg_ctl status | grep PID"`&lt;br /&gt;ANSWER=`echo $CMD`&lt;br /&gt;if [ -n "$ANSWER" ]; then&lt;br /&gt; CMD=`ssh postgres@$standby3 "touch $trigger_file"`&lt;br /&gt; echo $CMD&lt;br /&gt; exit 0;&lt;br /&gt;fi&lt;br /&gt;exit 1;&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I say it's wary as it tests whether  the first standby node is up and running, if not tests if the second is,then the thrid... else returns a failure code (non cero integer). &lt;br /&gt;Note: when a standby node (in constant recovery state) identifies the existence of the trigger file defined in the recovery.conf  file it stops replicating from the allegedly dead master and becomes an independent server and enables write capabilities. &lt;br /&gt;&lt;br /&gt;I used this piece of advice:&lt;br /&gt;&lt;a href="http://www.panix.com/~elflord/unix/bash-tute.html"&gt;http://www.panix.com/~elflord/unix/bash-tute.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Using Quotes to enclose your variables&lt;br /&gt;&lt;br /&gt;Sometimes, it is a good idea to protect variable names in double quotes. This is usually the most important if your variables value either (a) contains spaces or (b) is the empty string. An example is as follows:&lt;br /&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;X=""&lt;br /&gt;if [ -n $X ]; then  # -n tests to see if the argument is non empty&lt;br /&gt;echo "the variable X is not the empty string"&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This script will give the following output:&lt;br /&gt;&lt;br /&gt;the variable X is not the empty string&lt;br /&gt;&lt;br /&gt;Why ? because the shell expands $X to the empty string. The expression [ -n ] returns true (since it is not provided with an argument). A better script would have been:&lt;br /&gt;&lt;br /&gt;#!/bin/bash&lt;br /&gt;X=""&lt;br /&gt;if [ -n "$X" ]; then  # -n tests to see if the argument is non empty&lt;br /&gt;echo "the variable X is not the empty string"&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this example, the expression expands to [ -n "" ] which returns false, since the string enclosed in inverted commas is clearly empty. &lt;/blockquote&gt;&lt;br /&gt;Sometimes scripts are a reflexion of the  writer's personality =-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4059282281579261696?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4059282281579261696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-paranoid.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4059282281579261696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4059282281579261696'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-paranoid.html' title='Postgresql - pgpool - a wary pgpool_failover script'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3565086002528251058</id><published>2011-12-29T16:42:00.000-06:00</published><updated>2011-12-31T10:50:14.806-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Networks'/><title type='text'>Linux - change a network interface name</title><content type='html'>&lt;a href="http://ergodicthoughts.blogspot.com/2009/03/rename-interface-eth-in-linux.html"&gt;http://ergodicthoughts.blogspot.com/2009/03/rename-interface-eth-in-linux.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I need to have homogenous names for my network interfaces in the whole cluster. Some were named eth0 others eth1 and so on. Now all of them are called eth0, this unlikely requirement is due to the fact that getting the ip from the master server depends on one network interface called eth0.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Instructions:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Edit the file -&lt;br /&gt;    vi /etc/udev/rules.d/70-persistent-net.rules&lt;br /&gt;&lt;br /&gt;as root or a power user and change entries with eth0 to whatever you desire.&lt;br /&gt;udev support is available for most kernels in the 2.6 generation.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is how I'm getting the ip info:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;MASTERNODE=`/sbin/ifconfig eth0 | grep inet | awk '{print $2}' | sed 's/addr://'`&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3565086002528251058?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3565086002528251058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-change-network-interface-name.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3565086002528251058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3565086002528251058'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-change-network-interface-name.html' title='Linux - change a network interface name'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-381858063810864115</id><published>2011-12-29T13:53:00.000-06:00</published><updated>2011-12-31T10:50:14.834-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - pgpool - getting it done without repmgr</title><content type='html'>Formerly I had used repmgr to aid my recovery and failover scripts in pgpool, but recently changed my mind and now I'm removing that extra layer.&lt;br /&gt;&lt;br /&gt;The recovery script should look like this now:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;#!/bin/bash&lt;br /&gt; # first stage recovery&lt;br /&gt; # $1 datadir&lt;br /&gt; # $2 desthost&lt;br /&gt; # $3 destdir&lt;br /&gt; MASTERNODE=`/sbin/ifconfig eth0 | grep inet | awk '{print $2}' | sed 's/addr://'`&lt;br /&gt; CMD=`ssh postgres@$2 "pg_basebackup --pgdata=$3 --host=$MASTERNODE --xlog --port=5432"`&lt;br /&gt; CMD1=`ssh postgres@$2 "echo standby_mode = \'on\'  &gt; $3/recovery.conf"`&lt;br /&gt; CMD2=`ssh postgres@$2 "echo primary_conninfo = \'host=$MASTERNODE port=5432 user=postgres password=pgsql\' &gt;&gt; $3/recovery.conf"`&lt;br /&gt; echo $CMD&lt;br /&gt; echo $CMD1&lt;br /&gt; echo $CMD2&lt;br /&gt;exit 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;+ One thing that had me scratching my head a little was the single quote inside double quotes that are inside back ticks -&gt; but then my old friend the back slash came to rescue. =-)&lt;br /&gt;&lt;br /&gt;+ &lt;b&gt;The issue that emerges now, is: how does pg_basebackup behave when the cluster directory is not empty?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;+ I had previously modified the /etc/ssh/ssh_config parameter file so that user environment variables are permited. So I aggregated them in the ~/.ssh/environment file, this in order to enter only the binary name instead of the whole path. Well,second guessing I think that it's better to leave the ssh environment variables alone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-381858063810864115?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/381858063810864115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-getting-it-done.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/381858063810864115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/381858063810864115'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-getting-it-done.html' title='Postgresql - pgpool - getting it done without repmgr'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6522942219769721630</id><published>2011-12-28T14:03:00.000-06:00</published><updated>2011-12-31T10:50:14.860-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pg_archivecleanup</title><content type='html'>I left open one question raised when configuring log shipping. How to prevent the wal directory from consuming all the available space?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/devel/static/pgarchivecleanup.html"&gt;&lt;br /&gt;http://www.postgresql.org/docs/devel/static/pgarchivecleanup.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;F.25. pg_archivecleanup&lt;br /&gt;&lt;br /&gt;pg_archivecleanup is designed to be used as an archive_cleanup_command to clean up WAL file archives when running as a standby server (see Section 25.2). pg_archivecleanup can also be used as a standalone program to clean WAL file archives.&lt;br /&gt;&lt;br /&gt;F.25.1. Usage&lt;br /&gt;&lt;br /&gt;To configure a standby server to use pg_archivecleanup, put this into its recovery.conf configuration file:&lt;br /&gt;&lt;br /&gt;archive_cleanup_command = 'pg_archivecleanup archivelocation %r'&lt;br /&gt;&lt;br /&gt;where archivelocation is the directory from which WAL segment files should be removed.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;It looks like you have to specify up to what file you intent to remove from the wal history.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6522942219769721630?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6522942219769721630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgarchivecleanup.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6522942219769721630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6522942219769721630'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgarchivecleanup.html' title='Postgresql - pg_archivecleanup'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1977545312021487336</id><published>2011-12-28T13:52:00.000-06:00</published><updated>2011-12-31T10:50:14.883-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - System Administration Functions</title><content type='html'>&lt;a href="http://www.postgresql.org/docs/9.1/static/functions-admin.html" target="_blank"&gt;http://www.postgresql.org/docs/9.1/static/functions-admin.html&amp;nbsp;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With postgresql you've got functions for :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Configuration Settings&lt;/li&gt;&lt;li&gt;Server Signalling &lt;/li&gt;&lt;li&gt;Backup Control&lt;/li&gt;&lt;li&gt;Recovery Information &lt;/li&gt;&lt;li&gt;Recovery Control&lt;/li&gt;&lt;li&gt;Database Object Size &lt;/li&gt;&lt;li&gt; Database Object Location&lt;/li&gt;&lt;li&gt;Generic File Access &lt;/li&gt;&lt;li&gt;Advisory Lock&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The ones that I like the most:&lt;/b&gt;&lt;br /&gt;pg_cancel_backend(pid int) Cancel a backend's current query&lt;br /&gt;pg_reload_conf() Cause server processes to reload their configuration files&lt;br /&gt;pg_is_in_recovery()  True if recovery is still in progress.&lt;br /&gt;pg_database_size(name) Disk space used by the database with the specified name&lt;br /&gt;pg_indexes_size(regclass) Total disk space used by indexes attached to the specified table&lt;br /&gt;pg_size_pretty(bigint) Converts a size in bytes into a human-readable format with size units&lt;br /&gt;pg_table_size(regclass) Disk space used by the specified table, excluding indexes (but including TOAST, free space map, and visibility map)&lt;br /&gt;pg_tablespace_size(oid) Disk space used by the tablespace with the specified OID&lt;br /&gt;pg_tablespace_size(name) Disk space used by the tablespace with the specified name&lt;br /&gt;pg_total_relation_size(regclass) Total disk space used by the specified table, including all indexes and TOAST data&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One concept that caught my eye is "Advisory Lock"&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Advisory locks are 'long-term, cooperative' locks.  They are long-term  in the sense that they do not follow mvcc rules, and are in fact  completely orthogonal to transactional locks.  This is a slightly  long-winded way of saying that advisory locks are not released upon  transaction commit/rollback and can be held outside of a transaction.   This is noteworthy because advisory locks are one of the very few things  that can be used to maintain session state without using persistent  storage (prepared statements, temporary tables, and listen/notify also  qualify here), and especially noteworthy because they are the only  mechanism in PostgreSQL that I know that can affect the behavior of  another session without consideration of either session's transactional  state.  Advisory locks are cooperative in that all users of them are on  the honor system -- this is quite different from standard mvcc locks  which follow very strict rules.  Anything can be locked at any time.   Advisory locks can be thought of as a low level interface to the  internal locking engine and will generally need some scaffolding to make  them useful.&lt;/blockquote&gt;&lt;br /&gt;I'll study them and I'll make some tests using them later.&lt;br /&gt;&lt;a href="http://merlinmoncure.blogspot.com/2006/12/postgresql-8.html" target="_blank"&gt;http://merlinmoncure.blogspot.com/2006/12/postgresql-8.html &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1977545312021487336?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1977545312021487336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-system-administration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1977545312021487336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1977545312021487336'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-system-administration.html' title='Postgresql - System Administration Functions'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3450201680896722767</id><published>2011-12-28T13:10:00.000-06:00</published><updated>2011-12-31T10:50:14.906-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='streaming_replication'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - Sending wal segments to the standby servers</title><content type='html'>I'm reviewing this function in the context of this error that it's being generated in one hot standby server with streaming replication:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@debian1:~/data_sr/pg_log$ tail -f postgresql-2011-12-27_172357.log &lt;br /&gt;2011-12-27 17:54:45 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/functions-admin.html"&gt;http://www.postgresql.org/docs/9.1/static/functions-admin.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;pg_last_xlog_receive_location()  &lt;br /&gt;text  &lt;br /&gt;Get last transaction log location received and synced to disk by streaming replication. &lt;br /&gt;While streaming replication is in progress this will increase monotonically. If recovery has completed this will remain static at the value of the last WAL record received and synced to disk during recovery. If streaming replication is disabled, or if it has not yet started, the function returns NULL.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Apparently the recovery remains in progress eternally, as the recovery.conf file is still in the cluster (when the recovery process ends it should be renamed to recovery.done).&lt;br /&gt;how to stop it? &lt;br /&gt;&lt;br /&gt;I think, there's the issue:&lt;br /&gt;&lt;blockquote&gt;T&lt;b&gt;he one thing that you absolutely must specify in recovery.conf is the restore_command, which tells PostgreSQL how to get back archived WAL file segments. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;The simplest useful command is something like:&lt;br /&gt;restore_command = 'cp /mnt/server/archivedir/%f %p'&lt;br /&gt;which will copy previously archived WAL segments from the directory /mnt/server/archivedir. &lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;a href="http://www.postgresql.org/docs/8.4/interactive/continuous-archiving.html"&gt;http://www.postgresql.org/docs/8.4/interactive/continuous-archiving.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The thing with this parameter setting is that is optional for streaming replication.&lt;br /&gt;&lt;blockquote&gt;26.1. Archive Recovery Settings&lt;br /&gt;&lt;br /&gt;restore_command (string)&lt;br /&gt;&lt;br /&gt;The shell command to execute to retrieve an archived segment of the WAL file series. This parameter is required for archive recovery, but optional for streaming replication.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/archive-recovery-settings.html#RESTORE-COMMAND"&gt;http://www.postgresql.org/docs/9.1/static/archive-recovery-settings.html#RESTORE-COMMAND&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This document gave me very good insights about how streaming replication works "under the hood".&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/images/9/90/FOSDEM2010-Streaming_Replication.pdf"&gt;http://wiki.postgresql.org/images/9/90/FOSDEM2010-Streaming_Replication.pdf&lt;/a&gt;&lt;br /&gt;And this one too:&lt;br /&gt;&lt;a href="http://www.korokithakis.net/posts/how-postgresqls-sr-streaming-replication-works/"&gt;http://www.korokithakis.net/posts/how-postgresqls-sr-streaming-replication-works/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Solution:&lt;br /&gt;Send wal segments from master to slaves and include the restore_command to the recovery.conf file in the slaves. Sending wal segments to the standby servers assures that if they fall too far behind from the master they will be able to still resync using the archived wall segments.&lt;br /&gt;The solution implies very small modifications:&lt;br /&gt;&lt;br /&gt;On the master server, in the postgresql.conf change this:&lt;br /&gt;&lt;br /&gt;archive_command = 'cd .'&lt;br /&gt;&lt;br /&gt;to &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;archive_command ='scp %p postgres@10.0.0.201:/tmp/%f' # command to use to archive a logfile segment&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and on the standby, add this to the recovery.conf &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;restore_command ='cp /tmp/%f "%p"'&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and after that:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@debian1:~/data_sr/pg_log$ tail -f postgresql-2011-12-28_130051.log &lt;br /&gt;2011-12-28 13:00:51 CST   LOG:  database system was interrupted; last known up at 2011-12-28 12:55:12 CST&lt;br /&gt;2011-12-28 13:00:51 CST   LOG:  creating missing WAL directory "pg_xlog/archive_status"&lt;br /&gt;2011-12-28 13:00:51 CST   LOG:  entering standby mode&lt;br /&gt;2011-12-28 13:00:51 CST   LOG:  restored log file "000000010000000000000020" from archive&lt;br /&gt;2011-12-28 13:00:52 CST   LOG:  redo starts at 0/20000020&lt;br /&gt;2011-12-28 13:00:52 CST   LOG:  consistent recovery state reached at 0/21000000&lt;br /&gt;2011-12-28 13:00:52 CST   LOG:  database system is ready to accept read only connections&lt;br /&gt;cp: cannot stat `/tmp/000000010000000000000021': No such file or directory&lt;br /&gt;2011-12-28 13:00:52 CST   LOG:  streaming replication successfully connected to primary&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;No more output, which usually means that everything is just fine. But the recovery.conf file is still there ... well, no errors, no problem, good enough to me.&lt;br /&gt;&lt;br /&gt;It remains in recovery state:&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# select pg_is_in_recovery();&lt;br /&gt; pg_is_in_recovery &lt;br /&gt;-------------------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now, how to prevent the wal directory in the standby from becoming bloated, waste and potentially consume all the space?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3450201680896722767?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3450201680896722767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-sending-wal-segments-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3450201680896722767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3450201680896722767'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-sending-wal-segments-to.html' title='Postgresql - Sending wal segments to the standby servers'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8733613144814987516</id><published>2011-12-27T19:10:00.000-06:00</published><updated>2011-12-31T10:50:14.930-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cell Processor'/><title type='text'>Cellprogramming - Multicore Programming Primer: Learn and Compete in Programming the PLAYSTATION®3 Cell Processor.</title><content type='html'>I found about this site just now. I had been procrastinating the cell processor for a while due to some compromises such as the stupid Oracle OCA certification, but now I'm going to commit myself to this proyect. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.csail.mit.edu/cag/ps3/index.shtml"&gt;http://groups.csail.mit.edu/cag/ps3/index.shtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Parallel programming has been an issue I've been interested in since I took my computer architecture course at UAM Azcapotzalco, and I intent to get very good at it =-).&lt;br /&gt;&lt;br /&gt;I'm re-posting a small mental map I did before deleting my previous blog.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://imageshack.us/photo/my-images/593/programmingcellprocesso.jpg/" target="_blank"&gt;&lt;img src="http://img593.imageshack.us/img593/2095/programmingcellprocesso.th.jpg" border="0"/&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here another interesting resources:&lt;br /&gt;&lt;a href="http://users.ece.gatech.edu/lanterma/mpg08/"&gt;http://users.ece.gatech.edu/lanterma/mpg08/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://users.ece.gatech.edu/lanterma/mpg08/CBE_Programming_Tutorial_v3.0.pdf"&gt;http://users.ece.gatech.edu/lanterma/mpg08/CBE_Programming_Tutorial_v3.0.pdf&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/power/library/l-powarch/index.html"&gt;http://www.ibm.com/developerworks/power/library/l-powarch/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SDK's:&lt;br /&gt;&lt;a href="http://www.ief.u-psud.fr/~lacas/Download/Download.html"&gt;http://www.ief.u-psud.fr/~lacas/Download/Download.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And more:&lt;br /&gt;&lt;a href="http://www.ps3devwiki.com/index.php?title=Cell_Programming_IBM"&gt;http://www.ps3devwiki.com/index.php?title=Cell_Programming_IBM&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8733613144814987516?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8733613144814987516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/cellprogramming-multicore-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8733613144814987516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8733613144814987516'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/cellprogramming-multicore-programming.html' title='Cellprogramming - Multicore Programming Primer: Learn and Compete in Programming the PLAYSTATION®3 Cell Processor.'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-404091222319675740</id><published>2011-12-27T17:56:00.000-06:00</published><updated>2011-12-31T10:50:14.951-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - pg_basebackup - forget about rsync ?</title><content type='html'>What's new in PostgreSQL 9.1&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.1"&gt;http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;pg_basebackup &lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/app-pgbasebackup.html"&gt;http://www.postgresql.org/docs/9.1/static/app-pgbasebackup.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;this is amazing stuff! &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;pg_basebackup is used to take base backups of a running PostgreSQL database cluster. These are taken without affecting other clients to the database, and can be used both for point-in-time recovery (see Section 24.3) and as the starting point for a log shipping or streaming replication standby servers (see Section 25.2).&lt;br /&gt;&lt;b&gt;pg_basebackup makes a binary copy of the database cluster files, while making sure the system is automatically put in and out of backup mode automatically. &lt;/b&gt;&lt;br /&gt;The backup is made over a regular PostgreSQL connection, and uses the replication protocol. The connection must be made with a user having REPLICATION permissions (see Section 20.2), and the user must be granted explicit permissions in pg_hba.conf. The server must also be configured with max_wal_senders set high enough to leave at least one session available for the backup.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Then let's make some dummy example:&lt;br /&gt;+Let's have a server configured with the following options:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;listen_addresses='*'&lt;br /&gt;wal_level = 'hot_standby'&lt;br /&gt;archive_mode = on&lt;br /&gt;archive_command = 'cd .'       # we can also use exit 0, anything that&lt;br /&gt;                           # just does nothing&lt;br /&gt;max_wal_senders = 10&lt;br /&gt;wal_keep_segments = 5000     # 80 GB required on pg_xlog&lt;br /&gt;hot_standby = on&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basic replication options taken from &lt;br /&gt;&lt;a href="https://github.com/greg2ndQuadrant/repmgr"&gt;https://github.com/greg2ndQuadrant/repmgr&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1. Creating a database with data:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres@linux-2561:~&gt; createdb pgbenchdb&lt;br /&gt;&lt;br /&gt;postgres@linux-2561:~&gt; pgbench -i -F 10 -s 10 -h 10.0.0.113 -p 5432 pgbenchdb&lt;br /&gt;pgbenchdb=# \dt+&lt;br /&gt;                          List of relations&lt;br /&gt; Schema |       Name       | Type  |  Owner   |  Size   | Description &lt;br /&gt;--------+------------------+-------+----------+---------+-------------&lt;br /&gt; public | pgbench_accounts | table | postgres | 1302 MB | &lt;br /&gt; public | pgbench_branches | table | postgres | 40 kB   | &lt;br /&gt; public | pgbench_history  | table | postgres | 0 bytes | &lt;br /&gt; public | pgbench_tellers  | table | postgres | 80 kB   | &lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;pgbenchdb=# SELECT pg_size_pretty(pg_database_size('pgbenchdb'));&lt;br /&gt; pg_size_pretty &lt;br /&gt;----------------&lt;br /&gt; 1326 MB&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;2. Make a base backup on the standby node:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@debian1:~$ time pg_basebackup --pgdata=/var/lib/postgresql/data_sr --xlog --progress --verbose --host=10.0.113 --port=5432 &lt;br /&gt;xlog start point: 0/1B000020&lt;br /&gt;1392758/1392758 kB (100%), 1/1 tablespace                                    &lt;br /&gt;xlog end point: 0/1B0000C4&lt;br /&gt;pg_basebackup: base backup completed&lt;br /&gt;&lt;br /&gt;real    0m36.909s&lt;br /&gt;user    0m0.740s&lt;br /&gt;sys     0m11.565s&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not bad for a 1.3GB database !&lt;br /&gt;&lt;br /&gt;3. Set the backup server to behave as a hot standby streaming replication server, by creating a recovery.conf file in $PGDATA.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;standby_mode = 'on'&lt;br /&gt;primary_conninfo = 'host=10.0.0.113 port=5432 user=postgres password=pgsql'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4. Startup the standby server&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;pg_ctl start&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;5. Query on the master the replication status:&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# \x &lt;br /&gt;Expanded display is on.&lt;br /&gt;pgbenchdb=# select * from pg_stat_replication;&lt;br /&gt;-[ RECORD 1 ]----+-----------------------------&lt;br /&gt;procpid          | 7776&lt;br /&gt;usesysid         | 10&lt;br /&gt;usename          | postgres&lt;br /&gt;application_name | walreceiver&lt;br /&gt;client_addr      | 10.0.0.201&lt;br /&gt;client_hostname  | &lt;br /&gt;client_port      | 56744&lt;br /&gt;backend_start    | 2011-12-27 17:23:57.15636-06&lt;br /&gt;state            | streaming&lt;br /&gt;sent_location    | 0/1E000120&lt;br /&gt;write_location   | 0/1E000120&lt;br /&gt;flush_location   | 0/1E000120&lt;br /&gt;replay_location  | 0/1E000120&lt;br /&gt;sync_priority    | 0&lt;br /&gt;sync_state       | async&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;6. Make some changes on the master&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; pgbench -c 50 -d -j 2 -t 100 -h 10.0.0.113 pgbenchdb&lt;br /&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 10&lt;br /&gt;query mode: simple&lt;br /&gt;number of clients: 50&lt;br /&gt;number of threads: 2&lt;br /&gt;number of transactions per client: 100&lt;br /&gt;number of transactions actually processed: 5000/5000&lt;br /&gt;tps = 89.336188 (including connections establishing)&lt;br /&gt;tps = 89.461080 (excluding connections establishing)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;pgbenchdb=# \dt+&lt;br /&gt;                          List of relations&lt;br /&gt; Schema |       Name       | Type  |  Owner   |  Size   | Description &lt;br /&gt;--------+------------------+-------+----------+---------+-------------&lt;br /&gt; public | pgbench_accounts | table | postgres | 1302 MB | &lt;br /&gt; public | pgbench_branches | table | postgres | 168 kB  | &lt;br /&gt; public | pgbench_history  | table | postgres | 792 kB  | &lt;br /&gt; public | pgbench_tellers  | table | postgres | 248 kB  | &lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;6. Log in to the standby and see if changes are there (in a very lazy fashion).&lt;br /&gt;&lt;pre class="brush:sql"&gt;postgres=# \c pgbenchdb&lt;br /&gt;You are now connected to database "pgbenchdb" as user "postgres".&lt;br /&gt;pgbenchdb=# \dt+&lt;br /&gt;                          List of relations&lt;br /&gt; Schema |       Name       | Type  |  Owner   |  Size   | Description &lt;br /&gt;--------+------------------+-------+----------+---------+-------------&lt;br /&gt; public | pgbench_accounts | table | postgres | 1302 MB | &lt;br /&gt; public | pgbench_branches | table | postgres | 168 kB  | &lt;br /&gt; public | pgbench_history  | table | postgres | 792 kB  | &lt;br /&gt; public | pgbench_tellers  | table | postgres | 248 kB  | &lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;pgbenchdb=# insert into pgbench_history (tid) values (generate_series(1,1000));&lt;br /&gt;ERROR:  cannot execute INSERT in a read-only transaction&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Other references:&lt;br /&gt;&lt;a href="http://postgresql.ru.net/manual/pgbench.html"&gt;&lt;br /&gt;http://postgresql.ru.net/manual/pgbench.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/warm-standby.html"&gt;http://www.postgresql.org/docs/9.1/static/warm-standby.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.1/interactive/backup-online.html"&gt;http://www.postgresql.org/docs/8.1/interactive/backup-online.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/Streaming_Replication"&gt;http://wiki.postgresql.org/wiki/Streaming_Replication&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then, what's rsync? =-)&lt;br /&gt;&lt;br /&gt;TODO:&lt;br /&gt;What the hell are these errors about?&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@debian1:~/data_sr/pg_log$ tail -f postgresql-2011-12-27_172357.log &lt;br /&gt;2011-12-27 17:54:45 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:54:55 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:55:05 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres ERROR:  recovery is in progress&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres HINT:  WAL control functions cannot be executed during recovery.&lt;br /&gt;2011-12-27 17:55:15 CST postgres postgres STATEMENT:  SELECT pg_current_xlog_location()&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-404091222319675740?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/404091222319675740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgbasebackup-forget-about.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/404091222319675740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/404091222319675740'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgbasebackup-forget-about.html' title='Postgresql - pg_basebackup - forget about rsync ?'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1438785068458510576</id><published>2011-12-26T19:59:00.000-06:00</published><updated>2011-12-31T10:50:14.970-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='postgis'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='repmgr'/><title type='text'>Postgresql - streaming replication - new features in 9.1</title><content type='html'>&amp;nbsp;I just found this info:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&lt;b&gt;What's new in 9.1&lt;/b&gt;&lt;br /&gt;&lt;b&gt;pg_stat_replication makes non-wizard monitoring possible&lt;/b&gt;&lt;br /&gt;max_standby_*_delay can be big&lt;br /&gt;hot_standby_feedback makes MVCC style snapshot export easy&lt;br /&gt;&lt;b&gt;Base backups possible using the database connection&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Synchronous replication - Improvements in b-tree delete handling&lt;/b&gt;&lt;/blockquote&gt;+This makes the functions of repmgr kind of redundant (most of them, and those that excel the aforementioned are provided by pgpool) , my rationale behind it's usage was its rsync optimization, but now you're able to manage base backups through the database connection, I'll give that a try.&lt;br /&gt;&lt;br /&gt;+To leverage repmgr was really easy but removing additional ( and maybe unnecessary)&amp;nbsp; layers is the best approach (in my opinion). &lt;br /&gt;+Also, synchronous replication is&amp;nbsp; very good news, with it you can really assure a great deal of reliability.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.2ndquadrant.com/static/2quad/media/pdfs/talks/char11/FastRepmgrScaling.pdf"&gt;http://www.2ndquadrant.com/static/2quad/media/pdfs/talks/char11/FastRepmgrScaling.pdf&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1438785068458510576?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1438785068458510576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-streaming-replication-new.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1438785068458510576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1438785068458510576'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-streaming-replication-new.html' title='Postgresql - streaming replication - new features in 9.1'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1526320035859814053</id><published>2011-12-26T13:37:00.000-06:00</published><updated>2011-12-31T10:50:14.988-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - System Information Functions - querying for an IP</title><content type='html'>I need to ask the PostgreSQL server for its IP. One answer I found is using one of the "System Information Functions" called &lt;b&gt;inet_server_addr()&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The big gotcha regarding this function is that it returns NULL should the connection be made via a unix-domain socket.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;inet_client_addr returns the IP address of the current client, and inet_client_port returns the port number. inet_server_addr returns the IP address on which the server accepted the current connection, and inet_server_port returns the port number. &lt;b&gt;All these functions return NULL if the current connection is via a Unix-domain socket.&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;As a side note, the array of functions to get information about the system is pretty cool.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/functions-info.html"&gt;http://www.postgresql.org/docs/9.1/static/functions-info.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Among many other things you can issue queries about the session, access privileges, comments, schema visibility, the catalog, transaction id's and snapshots.&lt;br /&gt;&lt;br /&gt;I guess I'll need to do it the linux way or figure out how to use something else than unix-domain sockets for my connections.&lt;br /&gt;&lt;br /&gt;This sort of does the trick:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;/sbin/ifconfig eth0 | grep inet | awk '{print $2}' | sed 's/addr://'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But it relies on two assumptions:  that there's an eth0 interface and that the node is connected through that interface to the cluster's network.&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/faq/bash-shell-command-to-find-get-ip-address/"&gt;&lt;br /&gt;http://www.cyberciti.biz/faq/bash-shell-command-to-find-get-ip-address/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1526320035859814053?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1526320035859814053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-system-information-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1526320035859814053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1526320035859814053'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-system-information-functions.html' title='Postgresql - System Information Functions - querying for an IP'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-1486690544863244349</id><published>2011-12-25T23:00:00.000-06:00</published><updated>2011-12-31T10:50:15.009-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='plpgsql'/><title type='text'>Postgresql -plpgsql. Generating primes as SETOF RECORD</title><content type='html'>In my previous attempt I returned the result by just printing the prime numbers as messages, but obviously you couldn't use them for further processing. One solution is to return the result as a SETOF RECORD.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE OR REPLACE FUNCTION primes( upLim INTEGER ) &lt;br /&gt;RETURNS SETOF RECORD  AS&lt;br /&gt;$$&lt;br /&gt;DECLARE&lt;br /&gt;nums boolean [];&lt;br /&gt;BEGIN&lt;br /&gt; &lt;br /&gt;FOR i IN 2..upLim LOOP&lt;br /&gt;nums[i] = true;&lt;br /&gt;END LOOP;&lt;br /&gt;FOR i IN 2..TRUNC(|/upLim) LOOP&lt;br /&gt; IF nums[i] = true&lt;br /&gt; THEN&lt;br /&gt;  FOR j IN 2..upLim LOOP&lt;br /&gt;  nums[i*j] = false;&lt;br /&gt;  EXIT WHEN i * j &gt; upLim;&lt;br /&gt;  END LOOP;&lt;br /&gt; END IF;&lt;br /&gt;END LOOP;&lt;br /&gt; &lt;br /&gt;FOR i IN 2..upLim LOOP&lt;br /&gt; IF nums[i] = true THEN&lt;br /&gt; RETURN QUERY SELECT i;&lt;br /&gt; END IF;&lt;br /&gt;END LOOP;&lt;br /&gt;END;&lt;br /&gt;$$ LANGUAGE plpgsql;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT * from primes(1000) as foo(prime int);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I'm getting the impression of plpgsql being a very dense topic ... but I'm getting to love it too!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-1486690544863244349?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/1486690544863244349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-plpgsql-generating-primes-as.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1486690544863244349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/1486690544863244349'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-plpgsql-generating-primes-as.html' title='Postgresql -plpgsql. Generating primes as SETOF RECORD'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-9052695482008235780</id><published>2011-12-25T13:00:00.000-06:00</published><updated>2011-12-31T10:50:15.030-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux - the DISPLAY environment variable</title><content type='html'>One interesting option regarding the DBCA (Database Configuration Assistant in Oracle ) , and I guess from many other programs,  is to specify them through the DISPLAY environment variable where to send the windows they open .&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;This is standard X Window System—you set an environment variable DISPLAY to tell the program where to send the windows it opens. For example,export DISPLAY=10.10.10.65:0.0 will redirect all X windows to the machine identified by IP address 10.10.10.65, no matter which machine you are actually running the DBCA on.&lt;/blockquote&gt;&lt;br /&gt;This is great stuff! and it's kind of weird me just discovering it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-9052695482008235780?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/9052695482008235780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-display-environment-variable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/9052695482008235780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/9052695482008235780'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-display-environment-variable.html' title='Linux - the DISPLAY environment variable'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2070484665483355499</id><published>2011-12-25T12:29:00.000-06:00</published><updated>2011-12-31T10:50:15.051-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux - Simulating global variables - the /etc/profile  file.</title><content type='html'>From some book I'm reading:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;To simulate setting what might be thought of as “global” variables applying to all sessions by all users, set them in the /etc/profile file, which is executed at each logon.&lt;/blockquote&gt;&lt;br /&gt;A seemingly good reference:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.hot.ee/airm/linux/BLFS6.3/postlfs/profile.html"&gt;http://www.hot.ee/airm/linux/BLFS6.3/postlfs/profile.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;After the stupid oca certification I'll get one of Linux, but a real one, not bullshit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2070484665483355499?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2070484665483355499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-simulating-global-variables.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2070484665483355499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2070484665483355499'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-simulating-global-variables.html' title='Linux - Simulating global variables - the /etc/profile  file.'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8207132687059155266</id><published>2011-12-25T02:09:00.000-06:00</published><updated>2011-12-31T10:50:15.070-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='plpgsql'/><title type='text'>Postgresql - plpgsql - Generating primes</title><content type='html'>I deemed it appropriate to start with plpgsql once and for all. So this is the plpgsql version of the algorithm (Eratosthenes' sieve) I implemented with javascript. This is my first plpgsql function ever, so I guess many improvements/corrections are in order. &lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:sql"&gt;CREATE OR REPLACE FUNCTION primes( upLim INTEGER ) RETURNS VOID AS&lt;br /&gt;$$&lt;br /&gt;DECLARE&lt;br /&gt;nums boolean [];&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;FOR i IN 2..upLim LOOP&lt;br /&gt;nums[i] = true;&lt;br /&gt;END LOOP;&lt;br /&gt;FOR i IN 2..TRUNC(|/upLim) LOOP&lt;br /&gt; IF nums[i] = true &lt;br /&gt; THEN&lt;br /&gt;  FOR j IN 2..upLim LOOP&lt;br /&gt;  nums[i*j] = false;&lt;br /&gt;  EXIT WHEN i * j &gt; upLim;&lt;br /&gt;  END LOOP;&lt;br /&gt; END IF;&lt;br /&gt;END LOOP;&lt;br /&gt;&lt;br /&gt;FOR i IN 2..upLim LOOP&lt;br /&gt; IF nums[i] = true THEN&lt;br /&gt; RAISE NOTICE '% ',i;&lt;br /&gt; END IF;&lt;br /&gt;END LOOP;&lt;br /&gt;END;&lt;br /&gt;$$ LANGUAGE plpgsql;&lt;br /&gt;&lt;br /&gt;SELECT primes(100000) ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Total query runtime: 242672 ms.&lt;br /&gt;1 row retrieved.&lt;br /&gt;&lt;br /&gt;Kinda slow, I must admit...mmmm&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8207132687059155266?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8207132687059155266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-plpgsql-generating-primes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8207132687059155266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8207132687059155266'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-plpgsql-generating-primes.html' title='Postgresql - plpgsql - Generating primes'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7162485238487777186</id><published>2011-12-24T10:57:00.000-06:00</published><updated>2011-12-31T10:50:15.096-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webProgramming'/><title type='text'>javascript - Generating primes</title><content type='html'>I'm interested in learning and mastering javascript, so I'll be writing some toy programs once in a while. Of course, the greater the upper limit the longer it will take to calculate them.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&lt;html&gt;&lt;br /&gt;&lt;head&gt;&lt;br /&gt; &lt;script type="text/javascript"&gt;&lt;br /&gt; function cribe(size){&lt;br /&gt; clear();&lt;br /&gt;  var nums=new Array();&lt;br /&gt;  for(i=0; i&lt;= size; i++) nums[i]=0;&lt;br /&gt;  for (i=2; i&lt;= Math.sqrt(size) ; i++){&lt;br /&gt;  if(nums[i] == 1) continue;&lt;br /&gt;  for(j=2; i*j &lt;= size ; j++){&lt;br /&gt;  if (nums[i*j] == 0){&lt;br /&gt;  nums[i*j] = 1;&lt;br /&gt;  }&lt;br /&gt;  }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  var output = document.getElementById("content");&lt;br /&gt; for (i = 2; i&lt;= size; i++){&lt;br /&gt; if(nums[i] == 0) {&lt;br /&gt; output.innerHTML += " " + i;&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; &lt;/script&gt;&lt;br /&gt; &lt;br /&gt; &lt;script type="text/javascript"&gt;&lt;br /&gt; function clear(){&lt;br /&gt;  var output = document.getElementById("content");&lt;br /&gt;  output.innerHTML = "";&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt; &lt;/script&gt;&lt;br /&gt;&lt;/head&gt;&lt;br /&gt;&lt;body&gt;&lt;br /&gt;Generador de numeros primos &lt;br /&gt;&lt;br /&gt;Proporciona el limite superior &lt;br /&gt;&lt;form&gt;&lt;input type="text" id="size" /&gt;&lt;br /&gt;&lt;/form&gt;&lt;!-- &lt;button onclick='cribe()'&gt; Enviar &lt;/button&gt; --&gt;&lt;br /&gt;&lt;button onclick='cribe(document.getElementById("size").value)'&gt; Enviar &lt;/button&gt; &lt;br /&gt;&lt;div id="content"&gt;&amp;nbsp &lt;/div&gt;&lt;/body&gt;&lt;br /&gt;&lt;br /&gt;&lt;/html&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;html&gt;&lt;br /&gt;&lt;head&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt; function cribe(size){ clear();  var nums=new Array();  for(i=0; i&lt;= size; i++) nums[i]=0;  for (i=2; i&lt;= Math.sqrt(size) ; i++){  if(nums[i] == 1) continue;  for(j=2; i*j &lt;= size ; j++){  if (nums[i*j] == 0){  nums[i*j] = 1;  }  }  }    var output = document.getElementById("content"); for (i = 2; i&lt;= size; i++){ if(nums[i] == 0) { output.innerHTML += " " + i; } } } &lt;/script&gt;  &lt;script type="text/javascript"&gt; function clear(){  var output = document.getElementById("content");  output.innerHTML = "";  }   &lt;/script&gt;&lt;br /&gt;&lt;/head&gt;&lt;br /&gt;&lt;body&gt;&lt;br /&gt;Generador de numeros primos &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Proporciona el limite superior &lt;br /&gt;&lt;form&gt;&lt;input type="text" id="size" /&gt;&lt;br /&gt;&lt;/form&gt;&lt;!-- &lt;button onclick='cribe()'&gt; Enviar &lt;/button&gt; --&gt;&lt;br /&gt;&lt;button onclick='cribe(document.getElementById("size").value)'&gt; Enviar &lt;/button&gt; &lt;br /&gt;&lt;div id="content"&gt;&amp;nbsp &lt;/div&gt;&lt;/body&gt;&lt;br /&gt;&lt;br /&gt;&lt;/html&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7162485238487777186?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7162485238487777186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/javascript-generating-primes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7162485238487777186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7162485238487777186'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/javascript-generating-primes.html' title='javascript - Generating primes'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8149602811426179788</id><published>2011-12-23T19:02:00.003-06:00</published><updated>2012-01-03T11:02:47.266-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - pgpool - analysis of  the recovery, failover and failback operations</title><content type='html'>I realized I had misunderstood the concepts related to the administration of a pgpool cluster. I have summarize those concepts here. &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Recovery -&amp;gt; &lt;br /&gt;&lt;b&gt;Commands (1st stage and 2nd stage) run by the master&lt;/b&gt; to incorporate a new slave node. &lt;/blockquote&gt;These scripts are run by the postgresql server (naturally, by the same user that started the instance...right? )&lt;br /&gt;&lt;blockquote&gt;Thus the recovery procedure requires that the primary server is up and running. &lt;br /&gt;The cluster variables such as %m %M are not available for this operation. As the parameters (three) are&amp;nbsp; passed by the pgpool_recovery function. &lt;/blockquote&gt;&lt;pre&gt;% pgpool_recovery datadir remote_host remote_datadir&lt;br /&gt;datadir:        Database cluster path of a master node.&lt;br /&gt;remote_host:    Hostname of a recovery target node.&lt;br /&gt;remote_datadir: Database cluster path of a recovery target node.&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;What do the provided examples do?&lt;br /&gt;recovery_1st_stage_command = 'basebackup.sh' -&amp;gt; Performs a base backup of the primary and sends it to the new (or in recovery) node&lt;br /&gt;recovery_2nd_stage_command = '' -&amp;gt; does nothing&lt;br /&gt;&lt;br /&gt;This is what happens behind the curtain:&lt;br /&gt;&lt;blockquote&gt;For your reference, here are the steps taken in the recovery procedure.&lt;br /&gt;&lt;br /&gt;Pgpool-II connects to primary server's template1 database as user = recovery_user, password = recovery_password.&lt;br /&gt;Primary server executes pgpool_recovery function.&lt;br /&gt;pgpool_recovery function executes recovery_1st_stage_command. Note that PostgreSQL executes functions with database cluster as the current directory. Thus recovery_1st_stage_command is executed in the database cluster directory.&lt;br /&gt;Primary server executes pgpool_remote_start function. This function executes a script named "pgpool_remote_start" in the database cluster directory, and it executes pg_ctl command on the standby server to be recovered via ssh. pg_ctl will start postmaster in background. So we need to make sure that postmaster on the standby actually starts.&lt;br /&gt;pgpool-II tries to connect to the standby PostgreSQL as user = recovery_user and password = recovery_password. The database to be connected is "postgres" if possible. Otherwise "template1" is used. pgpool-II retries for recovery_timeout seconds. If success, go to next step.&lt;br /&gt;If failback_command is not empty, pgpool-II parent process executes the script.&lt;br /&gt;After failback_command finishes, pgpool-II restart all child processes. &lt;/blockquote&gt;&lt;br /&gt;+ The unusual thing for me at this point is that this functions are executed by the postgresql server. I need to analyze how does it do it.&lt;br /&gt;&lt;br /&gt;This is the signature for the pgpool functions:&lt;br /&gt;&lt;pre class="brush:sql"&gt;template1=# \df&lt;br /&gt;List of functions&lt;br /&gt;Schema |         Name         | Result data type | Argument data types |  Type  &lt;br /&gt;--------+----------------------+------------------+---------------------+--------&lt;br /&gt;public | pgpool_recovery      | boolean          | text, text, text    | normal&lt;br /&gt;public | pgpool_regclass      | oid              | cstring             | normal&lt;br /&gt;public | pgpool_remote_start  | boolean          | text, text          | normal&lt;br /&gt;public | pgpool_switch_xlog   | text             | text                | normal&lt;br /&gt;public | pgpool_walrecrunning | boolean          |                     | normal&lt;br /&gt;(5 rows)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;+ pgpool_remote_start has two arguments:&lt;br /&gt;DEST=$1       -&amp;gt; the slave server&lt;br /&gt;DESTDIR=$2    -&amp;gt; the cluster (datadir) on the slave server&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Then, this is why you can't specify parameters for these commands in the pgpool.conf file, as they're passed implicitly.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Now, where the hell is this script located? It must be present in the database cluster (datadir) where the master is running).&lt;br /&gt;&lt;br /&gt;Corollary. my recovery_1st_stage_command would look like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;#!/bin/bash&lt;br /&gt;# first stage recovery  &lt;br /&gt;# $1 datadir&lt;br /&gt;# $2 desthost&lt;br /&gt;# $3 destdir&lt;br /&gt;&lt;br /&gt;#as I'm using repmgr it's not necessary for me to know datadir(master) $1&lt;br /&gt;RECOVERY_NODE=$2&lt;br /&gt;CLUSTER_PATH=$3&lt;br /&gt;#repmgr needs to know the master's ip&lt;br /&gt;MASTERNODE=`/sbin/ifconfig eth0 | grep inet | awk '{print $2}' | sed 's/addr://'`&lt;br /&gt;&lt;br /&gt;cmd1=`ssh postgres@$RECOVERY_NODE "repmgr -D $CLUSTER_PATH --force standby clone $MASTERNODE"`&lt;br /&gt;echo $cmd1  &lt;br /&gt;#-------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The location of the failback and failover scripts is not relative to the database  cluster, the absolute path is needed, these are executed by the apache  (or wwwrun ) user.&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Failback -&amp;gt; &lt;br /&gt;failback_command. command to run when a node is attached. If not empty, pgpool-II parent process executes the script. &lt;br /&gt;After it finishes,child processes are restarted.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Failover -&amp;gt;&lt;br /&gt;failover_command.&lt;br /&gt;command to run when a node is detached&lt;br /&gt;--an alert maybe ?&lt;br /&gt;side effects. &lt;br /&gt;1. pgpool kills all its child processes, which will in turn terminate all active sessions to pgpool&lt;br /&gt;2. pgpool invokes the failover_command and waits for its completion&lt;br /&gt;3. after this, pgpool starts new child processes and is ready again to accept connection from clients&lt;br /&gt;&lt;br /&gt;follow_master_command. &lt;br /&gt;command to run only after a master failover.Typically the command should be used to recover the slave from the new master by call the pcp_recovery_node command for example&lt;br /&gt;1. If follow_master_command is not empty, when a master failover is completed:&lt;br /&gt;a) pgpool degenerates all nodes except the new master &lt;br /&gt;b) starts new child processes to be ready to accept connections from clients&lt;br /&gt;c) after this, pgpool run the command set into the 'follow_master_command' for each degenerated nodes ( typically the command should be used to recover the slave from the new master by call the pcp_recovery_node command for example ).&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;Other concepts&lt;br /&gt;What do we understand for node degeneration? disconnection from the cluster.&lt;br /&gt;&lt;br /&gt;For the failover_command, failback_command and follow_master_command you can use these parameters in your scripts:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Special character Description&lt;br /&gt;%d Backend ID of an attached node.&lt;br /&gt;%h Hostname of an attached node.&lt;br /&gt;%p Port number of an attached node.&lt;br /&gt;%D Database cluster path of an attached node.&lt;br /&gt;%M Old master node&lt;br /&gt;%m New master node&lt;br /&gt;%H Hostname of the new master node.&lt;br /&gt;%P Old primary node ID.&lt;br /&gt;%% '%' character&lt;br /&gt;&lt;br /&gt;They're not available for the recovery commands.&lt;br /&gt;&lt;br /&gt;In summary:&lt;br /&gt;Recovery. applies when attaching a new slave node, or reattaching a previously detached slave node, the master is required to be up and running.&lt;br /&gt;Failback. command that runs when a node is attached (or after a recovery)&lt;br /&gt;Failover. when a node is detached (master or slave)&lt;br /&gt;&lt;br /&gt;Possible failover strategy.&lt;br /&gt;1. If the master is detached, promote the first slave node that is available.&lt;br /&gt;2. Degenerate all the slave nodes except the new master.&lt;br /&gt;3. Tell all the other nodes to now follow the new master.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8149602811426179788?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8149602811426179788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-analysis-of-recovery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8149602811426179788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8149602811426179788'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-analysis-of-recovery.html' title='Postgresql - pgpool - analysis of  the recovery, failover and failback operations'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-449309708120573825</id><published>2011-12-23T16:08:00.000-06:00</published><updated>2011-12-31T10:50:15.144-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='repmgr'/><title type='text'>Postgresql - pgpool, repmgr - the failback process</title><content type='html'>The process of failback refers to attaching a formerly detached (due to failover) back to the cluster.&lt;br /&gt;&lt;br /&gt;Using repmgr the process of failback, comes to this:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;repmgr -D /var/lib/pgsql/9.0 --force standby clone node1&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The rationale behind this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;And if a previously failed node becomes available again, such as the lost node1 above, you can get it to resynchronize by only copying over changes made while it was down . That happens with this what's called a forced clone, which overwrites existing data rather than assuming it starts with an empty database directory tree: &lt;br /&gt;&lt;br /&gt;This can be much faster than creating a brand new node that must copy over every file in the database.&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;+ Of course, in the detached node, the database server is in shutdown state. Then you do the force clone and then start the database up. &lt;br /&gt;&lt;br /&gt;Behind the scenes I guess repmgr writes the appropriate recovery.conf file so as to tell the newly incorporated node to follow the cluster's master.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-449309708120573825?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/449309708120573825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-repmgr-failback.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/449309708120573825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/449309708120573825'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-repmgr-failback.html' title='Postgresql - pgpool, repmgr - the failback process'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-265255968200611493</id><published>2011-12-23T16:04:00.000-06:00</published><updated>2011-12-31T10:50:15.278-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux - whereis / type</title><content type='html'>It's incredible that up to this day I lived without knowing about these commands.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;You can use "type" or "whereis" command to find out which command shell executes and to print binary (command) file location for specified command.&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://www.cyberciti.biz/tips/find-linux-unix-command-location.html"&gt;http://www.cyberciti.biz/tips/find-linux-unix-command-location.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For instance:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; whereis repmgr&lt;br /&gt;repmgr: /usr/bin/repmgr /usr/bin/X11/repmgr&lt;br /&gt;postgres@linux-2561:~&gt; type -a repmgr&lt;br /&gt;repmgr is /usr/bin/repmgr&lt;br /&gt;repmgr is /usr/bin/X11/repmgr&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Update: the 'which' utility seems to accomplish the same.&lt;br /&gt;&lt;a href="http://linux.about.com/library/cmd/blcmdl1_which.htm"&gt;http://linux.about.com/library/cmd/blcmdl1_which.htm&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-265255968200611493?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/265255968200611493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-whereis-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/265255968200611493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/265255968200611493'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-whereis-type.html' title='Linux - whereis / type'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4254797750197997869</id><published>2011-12-22T20:00:00.000-06:00</published><updated>2011-12-31T10:50:15.299-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><category scheme='http://www.blogger.com/atom/ns#' term='repmgr'/><title type='text'>Postgresql - repmgr: Promoting standby repmgr: restarting  server using pg_ctl sh: pg_ctl: not found . Can't restart PostgreSQL server</title><content type='html'>I was issuing this command through a remote ssh session. repmgr needs pg_ctl and pg_config to be in the PATH environment variable. &lt;br /&gt;Issue: through ssh you only can use (by default) some env. variables that are not necessarily all the variables you need:&lt;br /&gt;&lt;br /&gt;for instance, in my linux box with the postgres user:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;postgres@linux-2561:~&gt; ssh localhost env&lt;br /&gt;LESSKEY=/etc/lesskey.bin&lt;br /&gt;NNTPSERVER=news&lt;br /&gt;MANPATH=/usr/local/man:/usr/local/share/man:/usr/share/man&lt;br /&gt;XDG_SESSION_ID=38&lt;br /&gt;HOSTNAME=linux-2561.site&lt;br /&gt;XKEYSYMDB=/usr/X11R6/lib/X11/XKeysymDB&lt;br /&gt;HOST=linux-2561.site&lt;br /&gt;SHELL=/bin/bash&lt;br /&gt;PROFILEREAD=true&lt;br /&gt;HISTSIZE=1000&lt;br /&gt;SSH_CLIENT=::1 53239 22&lt;br /&gt;MORE=-sl&lt;br /&gt;USER=postgres&lt;br /&gt;XNLSPATH=/usr/share/X11/nls&lt;br /&gt;HOSTTYPE=i386&lt;br /&gt;CONFIG_SITE=/usr/share/site/i686-pc-linux-gnu&lt;br /&gt;FROM_HEADER=&lt;br /&gt;PAGER=less&lt;br /&gt;CSHEDIT=emacs&lt;br /&gt;XDG_CONFIG_DIRS=/etc/xdg&lt;br /&gt;MINICOM=-c on&lt;br /&gt;MAIL=/var/mail/postgres&lt;br /&gt;PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/opt/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin&lt;br /&gt;CPU=i686&lt;br /&gt;SSH_SENDS_LOCALE=yes&lt;br /&gt;INPUTRC=/etc/inputrc&lt;br /&gt;PWD=/var/lib/pgsql&lt;br /&gt;LANG=en_US.UTF-8&lt;br /&gt;PYTHONSTARTUP=/etc/pythonstart&lt;br /&gt;GPG_TTY=not a tty&lt;br /&gt;QT_SYSTEM_DIR=/usr/share/desktop-data&lt;br /&gt;SHLVL=1&lt;br /&gt;HOME=/var/lib/pgsql&lt;br /&gt;SDL_AUDIODRIVER=pulse&lt;br /&gt;ALSA_CONFIG_PATH=/etc/alsa-pulse.conf&lt;br /&gt;LESS_ADVANCED_PREPROCESSOR=no&lt;br /&gt;OSTYPE=linux&lt;br /&gt;XCURSOR_THEME=DMZ&lt;br /&gt;WINDOWMANAGER=/usr/bin/startkde&lt;br /&gt;G_FILENAME_ENCODING=@locale,UTF-8,ISO-8859-15,CP1252&lt;br /&gt;LESS=-M -I -R&lt;br /&gt;MACHTYPE=i686-suse-linux&lt;br /&gt;LOGNAME=postgres&lt;br /&gt;CVS_RSH=ssh&lt;br /&gt;XDG_DATA_DIRS=/usr/local/share:/usr/share&lt;br /&gt;SSH_CONNECTION=::1 53239 ::1 22&lt;br /&gt;LESSOPEN=lessopen.sh %s&lt;br /&gt;XDG_RUNTIME_DIR=/run/user/postgres&lt;br /&gt;LESSCLOSE=lessclose.sh %s %s&lt;br /&gt;G_BROKEN_FILENAMES=1&lt;br /&gt;COLORTERM=1&lt;br /&gt;_=/usr/bin/env&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Solution:&lt;br /&gt;&lt;br /&gt;This can be achieved in 2 steps:&lt;br /&gt;- Add ‘PermitUserEnvironment yes’ to your sshd_config file and restart the ssh service.&lt;br /&gt;Rem: Default value is set to ‘No’.&lt;br /&gt;&lt;b&gt;Update:  on opensuse this parameter is set into the /etc/ssh/sshd_config file&lt;/b&gt;&lt;br /&gt;- Define your environment variables in .ssh/environment on the target host.&lt;br /&gt;eg LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib&lt;br /&gt;&lt;br /&gt;Reference:&lt;br /&gt;&lt;a href="http://www.netexpertise.eu/en/ssh/environment-variables-and-ssh.html"&gt;http://www.netexpertise.eu/en/ssh/environment-variables-and-ssh.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Once followed the aforementioned steps, everything goes just fine =-).&lt;br /&gt;repmgr: Promoting  standby   &lt;br /&gt;repmgr: restarting  server  using pg_ctl    &lt;br /&gt;repmgr: STANDBY  PROMOTE  successful. You should REINDEX any hash indexes you have.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4254797750197997869?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4254797750197997869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-repmgr-promoting-standby.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4254797750197997869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4254797750197997869'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-repmgr-promoting-standby.html' title='Postgresql - repmgr: Promoting standby repmgr: restarting  server using pg_ctl sh: pg_ctl: not found . Can&amp;#39;t restart PostgreSQL server'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6357320448979904414</id><published>2011-12-22T19:46:00.000-06:00</published><updated>2012-02-01T13:41:37.994-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webProgramming'/><title type='text'>webProgramming - BookInfo.0.5</title><content type='html'>I'm just making a back up of the last version, some improvements are in order but I achieved the functionality I was expecting, I'm leaving the key, should someone be interested in using it. &lt;br /&gt;&lt;br /&gt;Don't forget to download jquery-1.7.1.min.js and jquery.jsonp-2.2.0.min.js in the same folder where the html file lives.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .inputtext { width: 754px; height: 154px; }&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript" src="jquery-1.7.1.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript" src="jquery.jsonp-2.2.0.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; function nvl(node){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return node == undefined ? " " : node;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;lt;script type="text/javascript" &amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function getBook(isbn) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $.jsonp({&lt;br /&gt;&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; "url": "https://www.googleapis.com/books/v1/volumes?key=amp;callback=?&amp;amp;q=isbn:"+ isbn,&lt;br /&gt;&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; "success": function(response){&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; console.log("sucess ,isbn: "); &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; console.log(isbn);&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (response.totalItems &amp;gt; 0){&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (var i = 0; i &amp;lt; response.items.length; i++) {&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var item = response.items[i];&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // in production code, item.text should have the HTML entities escaped.&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += " &amp;lt;br&amp;gt; " +isbn+ " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.title) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.authors) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.publisher) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.publishedDate) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.description) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.pageCount) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.printType) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.categories) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.averageRating) +" | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.ratingsCount) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.language) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.previewLink)&amp;nbsp; + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.infoLink) + " | ";&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (item.volumeInfo.imageLinks != undefined){&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nvl(item.volumeInfo.imageLinks.smallThumbnail) + " | " &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.imageLinks.thumbnail) + " | " ;&lt;br /&gt;&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; }&lt;br /&gt;&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; else document.getElementById("content").innerHTML +=&amp;nbsp; " | | ";&lt;br /&gt;&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; &lt;br /&gt;&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; if (item.volumeInfo.industryIdentifiers != undefined){&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nvl(item.volumeInfo.industryIdentifiers[0].type) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.industryIdentifiers[0].identifier) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.industryIdentifiers[1].type) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.volumeInfo.industryIdentifiers[1].identifier) + " | "&lt;br /&gt;&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; }&lt;br /&gt;&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; else document.getElementById("content").innerHTML +=&amp;nbsp; " | | | |";&lt;br /&gt;&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; &lt;br /&gt;&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; &lt;br /&gt;&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; if (item.saleInfo != undefined){&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; nvl(item.saleInfo.country) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.saleInfo.saleability) + " | "&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; + nvl(item.saleInfo.isEbook) + " | ";&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&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; }&lt;br /&gt;&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; else document.getElementById("content").innerHTML +=&amp;nbsp; " | | |";&lt;br /&gt;&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; &lt;br /&gt;&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; &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += "&amp;lt;br&amp;gt; &amp;lt;br&amp;gt;";&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; document.getElementById("content").innerHTML += isbn &lt;br /&gt;&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;lt;br&amp;gt; &amp;lt;br&amp;gt;";&lt;br /&gt;&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; &lt;br /&gt;&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; },&lt;br /&gt;&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; "error": function(d,msg) {&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; alert("Could not find book ");&lt;br /&gt;&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; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function parseInput(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var input = document.getElementById("isbnList").value.split('\n');&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (i=0; i&amp;lt; input.length ; i++){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; console.log(input[i]);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; getBook(input[i].trim());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Books API Example&amp;lt;/title&amp;gt;&lt;br /&gt;Introduce el ISBN&lt;br /&gt;&amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;textarea id='isbnList' class='inputtext'&amp;gt; &amp;lt;/textarea&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;br&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button type="button" onclick='parseInput()'&amp;gt;Click&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;div id="content"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6357320448979904414?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6357320448979904414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/webprogramming-bookinfo05.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6357320448979904414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6357320448979904414'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/webprogramming-bookinfo05.html' title='webProgramming - BookInfo.0.5'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-9093650500480361389</id><published>2011-12-22T16:54:00.000-06:00</published><updated>2011-12-31T10:50:15.349-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><title type='text'>Linux - making wwwrun a real user</title><content type='html'>I needed to give the apache server process (wwwrun in opensuse, apache in other distros) , treatment of a regular user , as it's the one who runs commands behind pgpooladmin. I need to generate it's public key in order for him to be able to run remote commands on all the nodes it has access to.&lt;br /&gt;&lt;br /&gt;It boils down to:&lt;br /&gt;&lt;blockquote&gt;If you REALLY want to do all this, change the 'wwwrun' user line in /etc/passwd so that /bin/false is set to /bin/bash, and then set the password for that user (`passwd wwwrun`) and off you go.&lt;/blockquote&gt;&lt;br /&gt;A word of advise here is that there are many security concerns when carrying on with such unusual proceedings, but I'm on the testing stage and security is not by the moment an issue.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.opensuse.org/english/get-technical-help-here/applications/397685-logging-user-wwwrun.html"&gt;http://forums.opensuse.org/english/get-technical-help-here/applications/397685-logging-user-wwwrun.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-9093650500480361389?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/9093650500480361389/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-making-wwwrun-real-user.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/9093650500480361389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/9093650500480361389'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-making-wwwrun-real-user.html' title='Linux - making wwwrun a real user'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4560556514544634309</id><published>2011-12-22T07:22:00.000-06:00</published><updated>2011-12-31T10:50:15.374-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webProgramming'/><title type='text'>webProgramming - The Google Book Search API v1 - Part 2</title><content type='html'>This is my first working code for the small application I'm working on. It would have taken me so much more time if weren't for HJRT.&lt;br /&gt;&lt;br /&gt;Note the use of jquery-1.7.1.min.js and jquery.jsonp-2.2.0.min.js&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; .inputtext { width: 754px; height: 154px; }&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript" src="jquery-1.7.1.min.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript" src="jquery.jsonp-2.2.0.min.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&amp;lt;script type="text/javascript" &amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; function getBook(isbn) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $.jsonp({&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "url": "https://www.googleapis.com/books/v1/volumes?callback=?&amp;amp;q=isbn:"+ isbn,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "success": function(response){&lt;br /&gt;&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; console.log("sucess ,isbn: ");&lt;br /&gt;&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; console.log(isbn);&lt;br /&gt;&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; for (var i = 0; i &amp;lt; response.items.length; i++) {&lt;br /&gt;&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; var item = response.items[i];&lt;br /&gt;&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; // in production code, item.text should have the HTML entities escaped.&lt;br /&gt;&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; document.getElementById("content").innerHTML += " " +isbn+ " | "&lt;br /&gt;&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; + item.volumeInfo.industryIdentifiers[0].type + " | "&lt;br /&gt;&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; + item.volumeInfo.industryIdentifiers[0].identifier + " | "&lt;br /&gt;&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; + item.volumeInfo.industryIdentifiers[1].type + " | "&lt;br /&gt;&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; + item.volumeInfo.industryIdentifiers[1].identifier + " | "&lt;br /&gt;&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; + item.volumeInfo.title +" | " &lt;br /&gt;&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; + item.volumeInfo.authors +" | "&lt;br /&gt;&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; + item.volumeInfo.publisher +" | "&lt;br /&gt;&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; + item.volumeInfo.publishedDate +" | "&lt;br /&gt;&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; + item.volumeInfo.description + " | "&lt;br /&gt;&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; + item.volumeInfo.pageCount +" | "&lt;br /&gt;&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; + item.volumeInfo.printType +" | "&lt;br /&gt;&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; + item.volumeInfo.categories +" | "&lt;br /&gt;&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; + item.volumeInfo.averageRating +" | "&lt;br /&gt;&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; + item.volumeInfo.ratingsCount + " | "&lt;br /&gt;&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; + item.volumeInfo.imageLinks.smallThumbnail +" | "&lt;br /&gt;&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; + item.volumeInfo.imageLinks.thumbnail + " | "&lt;br /&gt;&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; + item.volumeInfo.language + " | "&lt;br /&gt;&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; + item.volumeInfo.previewLink&amp;nbsp; + " | "&lt;br /&gt;&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; + item.volumeInfo.infoLink + " | "&lt;br /&gt;&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; + item.saleInfo.country + " | "&lt;br /&gt;&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; + item.saleInfo.saleability + " | "&lt;br /&gt;&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; + item.saleInfo.isEbook + " ~ ";&lt;br /&gt;&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; }&lt;br /&gt;&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; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; },&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; "error": function(d,msg) {&lt;br /&gt;&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; console.log("Error");&lt;br /&gt;&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; alert("Could not find book ");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function parseInput(){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; var input = document.getElementById("isbnList").value.trim();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; console.log(input);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; getBook(input);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Books API Example&amp;lt;/title&amp;gt;&lt;br /&gt;Introduce el ISBN &lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;textarea id='isbnList' class='inputtext'&amp;gt; &amp;lt;/textarea&amp;gt;&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;button type="button" onclick='parseInput()'&amp;gt;Click&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;div id="content"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Firebug was of invaluable help as well&lt;br /&gt;&lt;a href="https://addons.mozilla.org/es-es/firefox/addon/firebug/"&gt;https://addons.mozilla.org/es-es/firefox/addon/firebug/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One point to have in mind is that you'll need an access key from google if you are to use the API on a regular basis.&lt;br /&gt;&lt;br /&gt;TODO: &lt;br /&gt;+ to genuinely receive several ISBN as currently is only accepting one &lt;br /&gt;+ trim any new line character that might be inside of any of the fields&lt;br /&gt;&lt;a href="http://www.webtoolkit.info/javascript-trim.html"&gt;http://www.webtoolkit.info/javascript-trim.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4560556514544634309?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4560556514544634309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/webprogramming-google-book-search-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4560556514544634309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4560556514544634309'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/webprogramming-google-book-search-api.html' title='webProgramming - The Google Book Search API v1 - Part 2'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-2646920295568392565</id><published>2011-12-21T11:52:00.000-06:00</published><updated>2011-12-31T10:50:15.403-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='repmgr'/><title type='text'>Postgresql - streaming replication, trigger file vs. repmgr 'promote' command</title><content type='html'>The trigger file is a file&amp;nbsp; that get's created ( it's up to us when) when you want a failover to happen (i.e. to make the streaming replication stopped), hence, the slave that 'discovers' the trigger file becomes a master or independent node.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Such file location is specified in the recovery.conf configuration file.&lt;br /&gt;&lt;br /&gt;# Specifies a trigger file whose presence should cause streaming replication to&lt;br /&gt;# end (i.e., failover).&lt;br /&gt;trigger_file = '/path_to/trigger'&lt;br /&gt;&lt;br /&gt;I suppose the server continuously monitors for the presence of such file.&lt;br /&gt;&lt;br /&gt;In the example I'm following both master and slave run on the same machine on different ports, so&lt;br /&gt;&lt;br /&gt;the failover script creates the trigger file locally, so as I'm running the master on one machine and the slave on another, I'll need to create the trigger file remotely to one of the slaves.&lt;br /&gt;&lt;br /&gt;One question remains: ¿how to tell repmgr where to look for the trigger file?&lt;br /&gt;&lt;br /&gt;Well, it turns out to not being necessary as a "promote" command is available in repmr."Such command is designed to be more efficient" &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/repmgr/browse_thread/thread/cdb463bc399e1842?pli=1%20" target="_blank"&gt;http://groups.google.com/group/repmgr/browse_thread/thread/cdb463bc399e1842?pli=1 &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; On Fri, Aug 12, 2011 at 11:35 PM, Joshua Sierles ...@gmail.com&amp;gt; wrote: &amp;gt; Is there an advantage to using repmgr's 'promote' command on the slave since it requires a restart? What's the difference from using the 'trigger file' method?&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; repmgr follow is designed to be fast. That requires you to use repmgr &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; promote to make that work correctly. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; The trigger file works, but will cause problems when running multiple standbys. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; -- &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Simon Riggs&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;&amp;nbsp;&amp;nbsp;&amp;nbsp; http://www.2ndQuadrant.com/&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; PostgreSQL Development, 24x7 Support, Training &amp;amp; Services &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Other references:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/%20" target="_blank"&gt;http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/&amp;nbsp;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/Streaming_Replication" target="_blank"&gt;http://wiki.postgresql.org/wiki/Streaming_Replication &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The gotcha in my implementation is that I'm using repmgr to abstract the streaming replication&amp;nbsp; configuration , in my opinion this reduces administration complexity but the tradeoff is a more elaborated initial deployment.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, the failover script reduces itself to:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:shell"&gt;#!/bin/sh&lt;br /&gt;# Execute command by failover.&lt;br /&gt;# special values:&amp;nbsp; %d = node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %h = host name&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %p = port number&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %D = database cluster path&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %m = new master node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %M = old master node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %H = new master node host name&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %P = old primary node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %% = '%' character&lt;br /&gt;failed_node_id=$1&lt;br /&gt;failed_host_name=$2&lt;br /&gt;failed_port=$3&lt;br /&gt;failed_db_cluster=$4&lt;br /&gt;new_master_id=$5&lt;br /&gt;old_master_id=$6&lt;br /&gt;new_master_host_name=$7&lt;br /&gt;old_primary_node_id=$8&lt;br /&gt;&lt;br /&gt;standby_node=10.0.0.201&lt;br /&gt;&lt;br /&gt;cmd=`ssh $standby_node "/var/lib/postgresql/repmgr -f /var/lib/postgresql/repmgr/repmgr.conf standby promote"`&lt;br /&gt;if [ $failed_node_id = $old_primary_node_id ];then&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # master failed&lt;br /&gt;# the standby server is promoted &lt;br /&gt;echo $cmd&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now it's time to kill the master.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-2646920295568392565?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/2646920295568392565/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-streaming-replication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2646920295568392565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/2646920295568392565'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-streaming-replication.html' title='Postgresql - streaming replication, trigger file vs. repmgr &amp;#39;promote&amp;#39; command'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8592751650920240922</id><published>2011-12-21T10:48:00.000-06:00</published><updated>2011-12-31T10:50:15.426-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pgpool, bind(/tmp/.s.PGSQL.9898) failed. reason: Address already in use</title><content type='html'>When starting pgpool from pgadmin I got this message in the log file, then tried to remove the file in question, linux said: "hey it ain't such file", tried again, fired pgpool up , and there you go.&lt;br /&gt;&lt;br /&gt;I'm adopting as temporary solution to delete that file at startup (nevertheless linux say's it doesn't exist).&lt;br /&gt;&lt;br /&gt;rene@linux-2561:~&amp;gt; cat /var/log/pgpool/pgpool.log &lt;br /&gt;2011-12-21 10:35:37 LOG:&amp;nbsp;&amp;nbsp; pid 3531: Backend status file /var/log/pgpool//pgpool_status discarded&lt;br /&gt;2011-12-21 10:35:37 LOG:&amp;nbsp;&amp;nbsp; pid 3531: pgpool-II successfully started. version 3.1.1 (hatsuiboshi)&lt;br /&gt;2011-12-21 10:35:37 ERROR: pid 3531: bind(/tmp/.s.PGSQL.9898) failed. reason: Address already in use&lt;br /&gt;rene@linux-2561:~&amp;gt; sudo rm /tmp/.s.PGSQL.9898&lt;br /&gt;rm: cannot remove `/tmp/.s.PGSQL.9898': No such file or directory&lt;br /&gt;rene@linux-2561:~&amp;gt; cat /var/log/pgpool/pgpool.log &lt;br /&gt;2011-12-21 10:37:15 LOG:&amp;nbsp;&amp;nbsp; pid 3651: Backend status file /var/log/pgpool//pgpool_status discarded&lt;br /&gt;2011-12-21 10:37:15 LOG:&amp;nbsp;&amp;nbsp; pid 3651: pgpool-II successfully started. version 3.1.1 (hatsuiboshi)&lt;br /&gt;2011-12-21 10:37:15 LOG:&amp;nbsp;&amp;nbsp; pid 3651: find_primary_node: primary node id is 0&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm sending this one to the mailing list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8592751650920240922?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8592751650920240922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-bindtmpspgsql9898.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8592751650920240922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8592751650920240922'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-bindtmpspgsql9898.html' title='Postgresql - pgpool, bind(/tmp/.s.PGSQL.9898) failed. reason: Address already in use'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4849169056885237312</id><published>2011-12-21T02:53:00.000-06:00</published><updated>2011-12-31T10:50:15.447-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='general interest'/><title type='text'>General - The Google Book Search API v1</title><content type='html'>Searching book info with the The Google Book Search API v1 is as easy as it gets!&lt;br /&gt;For example, I was asked to find the available info of a book from a given ISBN number.&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush:html"&gt;&lt;title&gt;Books API Example&lt;/title&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;    &lt;div id="content"&gt;&lt;/div&gt;&lt;script&gt;&lt;br /&gt;      function handleResponse(response) {&lt;br /&gt;      for (var i = 0; i &lt; response.items.length; i++) {&lt;br /&gt;        var item = response.items[i];&lt;br /&gt;        // in production code, item.text should have the HTML entities escaped.&lt;br /&gt;        document.getElementById("content").innerHTML += "&lt;br /&gt;" + item.volumeInfo.title + " | Autor: " &lt;br /&gt;+item.volumeInfo.authors + " | fecha de publicacion: " + item.volumeInfo.publishedDate + " | editorial : "&lt;br /&gt;+ item.volumeInfo.publisher;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;&lt;/script&gt;&lt;br /&gt;    &lt;script src="https://www.googleapis.com/books/v1/volumes?q=isbn:9789681848828&amp;amp;callback=handleResponse"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The cute part being:&lt;br /&gt;&amp;lt;script src="https://www.googleapis.com/books/v1/volumes?q=isbn:9789681848828&amp;amp;callback=handleResponse"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;Output from the above query:&lt;br /&gt;&lt;br /&gt;Introducción a la lógica | Autor: Irving M. Copi,Carl Cohen | fecha de publicacion: 1999 | editorial : Limusa Noriega Editores&lt;br /&gt;&lt;br /&gt;References&lt;br /&gt;&lt;a href="http://code.google.com/intl/es-MX/apis/books/"&gt;http://code.google.com/intl/es-MX/apis/books/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.google.com/intl/es-MX/apis/books/docs/v1/using.html#query-params"&gt;http://code.google.com/intl/es-MX/apis/books/docs/v1/using.html#query-params&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.google.com/intl/es-MX/apis/books/docs/v1/using.html#RetrievingVolume" target="_blank"&gt;http://code.google.com/intl/es-MX/apis/books/docs/v1/using.html#RetrievingVolume&amp;nbsp;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are another quirks into handling this information, but I deemed the callback mechanism to be a very straightforward approach, nevertheless is not that smooth to store the results in this way. &lt;br /&gt;&lt;br /&gt;Now, I'll enter this info into postgresql, I'll have tons of fun =-)&lt;br /&gt;You can test this snippet by entering the ISBN you're interested in, save it as a html file and open it with firefox (is there another web browser?).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4849169056885237312?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4849169056885237312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/general-google-book-search-api-v1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4849169056885237312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4849169056885237312'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/general-google-book-search-api-v1.html' title='General - The Google Book Search API v1'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4895248545028709256</id><published>2011-12-21T01:41:00.000-06:00</published><updated>2011-12-31T10:50:15.472-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='general interest'/><title type='text'>General - Beautifying code snippets in your blogs</title><content type='html'>Syntax Highlighter is a javascript library that helps you format your code snippets within a blog or some other stuff sharing site.&lt;br /&gt;&lt;br /&gt;You'll need only to add this block at the end of your  tag &amp;lt;head&amp;gt; in your html template:&lt;br /&gt;&lt;pre class="brush:html"&gt;&lt;link href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" rel="stylesheet" type="text/css"&gt;&lt;/link&gt;&lt;br /&gt;&lt;link href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" rel="stylesheet" type="text/css"&gt;&lt;/link&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js" type="text/javascript"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script language="javascript"&gt;&lt;br /&gt;SyntaxHighlighter.config.bloggerMode = true;&lt;br /&gt;SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';&lt;br /&gt;SyntaxHighlighter.all();&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The trick is to embed your code within something like this:&lt;br /&gt;&amp;lt;pre class="brush:html"&amp;gt;&lt;br /&gt;Your 'HTML' code goes here&lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;br /&gt;Sources:&lt;br /&gt;&lt;a href="http://www.cyberack.com/2007/07/adding-syntax-highlighter-to-blogger.html"&gt;http://alexgorbatchev.com/SyntaxHighlighter/integration.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cyberack.com/2007/07/adding-syntax-highlighter-to-blogger.html"&gt;http://www.cyberack.com/2007/07/adding-syntax-highlighter-to-blogger.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4895248545028709256?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4895248545028709256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/general-beautifying-code-snippets-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4895248545028709256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4895248545028709256'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/general-beautifying-code-snippets-in.html' title='General - Beautifying code snippets in your blogs'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7622853745209986594</id><published>2011-12-20T20:17:00.000-06:00</published><updated>2011-12-31T10:50:15.492-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><title type='text'>Linux - variables inside strings</title><content type='html'>&lt;a href="http://systemsboy.com/2006/11/using-ssh-to-send-variables-in-scripts.html"&gt;http://systemsboy.com/2006/11/using-ssh-to-send-variables-in-scripts.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: inherit;"&gt;I needed to execute a remote command through ssh, and I used the proposed solution (something like this)&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;cmd=`ssh $1 "/usr/lib/postgresql/9.1/bin/pg_ctl start -D $2 2&amp;gt;/dev/null 1&amp;gt;/dev/null &amp;lt; /dev/null &amp;amp;"`&lt;br /&gt;echo $cmd&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Notice the back quote or back tick (or grave)&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;On this respect:&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;The back quote is &lt;b&gt;not&lt;/b&gt; used for quoting characters.  That character is used for command substitution, where the characters  between them are executed by the shell and the results is inserted on  that line. &lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: inherit;"&gt;Example: &lt;/div&gt;&lt;pre&gt;&lt;code&gt;% &lt;b&gt;echo the date is `date`&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;More about quotes on scripts:&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;&lt;a href="http://www.grymoire.com/Unix/Quote.html"&gt;&lt;b&gt;http://www.grymoire.com/Unix/Quote.html&amp;nbsp;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div style="font-family: inherit;"&gt;&lt;br /&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;pre style="font-family: inherit;"&gt;&lt;code&gt;&lt;span style="font-size: 85%;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;code&gt;&lt;span style="font-size: 85%;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7622853745209986594?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7622853745209986594/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-variables-inside-strings.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7622853745209986594'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7622853745209986594'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-variables-inside-strings.html' title='Linux - variables inside strings'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4778220306922210323</id><published>2011-12-20T18:57:00.000-06:00</published><updated>2011-12-31T10:50:15.513-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pgpool + failover</title><content type='html'>This is the provided script for failover in the example I'm following.&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/failover.sh"&gt;http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/failover.sh&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;#----------------------------------------------------------------------------------------------------------&lt;br /&gt;#!/bin/sh&lt;br /&gt;# Execute command by failover.&lt;br /&gt;# special values:&amp;nbsp; %d = node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %h = host name&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %p = port number&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %D = database cluster path&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %m = new master node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %M = old master node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %H = new master node host name&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %P = old primary node id&lt;br /&gt;#&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;&amp;nbsp;&amp;nbsp; %% = '%' character&lt;br /&gt;failed_node_id=$1&lt;br /&gt;failed_host_name=$2&lt;br /&gt;failed_port=$3&lt;br /&gt;failed_db_cluster=$4&lt;br /&gt;new_master_id=$5&lt;br /&gt;old_master_id=$6&lt;br /&gt;new_master_host_name=$7&lt;br /&gt;old_primary_node_id=$8&lt;br /&gt;trigger=/var/log/pgpool/trigger/trigger_file1&lt;br /&gt;&lt;br /&gt;if [ $failed_node_id = $old_primary_node_id ];then&amp;nbsp;&amp;nbsp;&amp;nbsp; # master failed&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; touch $trigger&amp;nbsp;&amp;nbsp;&amp;nbsp; # let standby take over&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;#---------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;The reasoning behind the trigger file is that when the standby server finds the file it will decide to promote to primary. It's the health check process the one that will determine whether the primary is down.&lt;br /&gt;&lt;br /&gt;Doubts:&lt;br /&gt;1.Where is specified the order in which the parameters are given, where is it documented? Well, I guess that I'll take his word for it, as he's a guy from the development team.&lt;br /&gt;2.&amp;nbsp; In case I have&amp;nbsp; another slave server, which one will be promoted?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4778220306922210323?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4778220306922210323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-failover.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4778220306922210323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4778220306922210323'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-failover.html' title='Postgresql - pgpool + failover'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-3574296887349877213</id><published>2011-12-20T16:10:00.000-06:00</published><updated>2011-12-31T10:50:15.534-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pgpool online recovery</title><content type='html'>What's online recovery ?&lt;br /&gt;+ It's available in replication mode.&lt;br /&gt;+ It means attaching a node while still servicing clients.&lt;br /&gt;&lt;br /&gt;Prerrequisites&lt;br /&gt;+ A recovery target node must be in detached&amp;nbsp; state before doing online recovery&lt;br /&gt;+ If the target PostgreSQL server has already started,&lt;b&gt; it's necessary to shut it down. &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Stages&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; CHECKPOINT     &lt;/li&gt;&lt;li&gt; First stage of online recovery - custom script&lt;/li&gt;&lt;li&gt; Wait until all clients have disconnected     &lt;/li&gt;&lt;li&gt; CHECKPOINT     &lt;/li&gt;&lt;li&gt; Second stage of online recovery- custom script&lt;/li&gt;&lt;li&gt; Start up postmaster (perform pgpool_remote_start)     &lt;/li&gt;&lt;li&gt; Node attach&amp;nbsp;&lt;/li&gt;&lt;/ol&gt;In my opinion, the script for the first stage of online recovery can be left alone, as I'm using repmgr to make things easier to handle.&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: inherit;"&gt;The only instruction I'll need for attaching the new node will be something like this:&lt;/div&gt;&lt;pre style="font-family: inherit;"&gt;repmgr -D /var/lib/pgsql/9.0 standby clone masterNode&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;There's also the possibility to specify this instruction in the first stage and in the second one&amp;nbsp;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;something like:&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;repmgr -D /var/lib/pgsql/9.0 --force standby clone masterClone &lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;The first stage will create the equivalent to a base backup, and the second stage will catch&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;up with the latest changes that clients made during the first stage of recovery.&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;As with many things, the only way to know for sure the effects (positives and negatives) of&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;this approach will be doing some tests. &lt;/pre&gt;&lt;blockquote class="tr_bq"&gt;You can specify a script executed during the first stage. pgpool-II   passes three arguments to the script.    &lt;br /&gt;&lt;ol&gt;&lt;li&gt; The database cluster path of a master node.     &lt;/li&gt;&lt;li&gt; The hostname of a recovery target node.     &lt;/li&gt;&lt;li&gt; The database cluster path of a recovery target node.   &lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;Taking into account the parameters passed by pgpool both scripts could be like the following:&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;If you wish to add a PostgreSQL server dynamically, add 'backend_hostname' and&lt;br /&gt;its associated parameters and reload pgpool.conf. pgpool-II registers this new&lt;br /&gt;node as a detached node.&lt;br /&gt;&amp;nbsp;&lt;/pre&gt;#!/bin/bash&lt;br /&gt;# first stage recovery&amp;nbsp; &lt;br /&gt;&amp;nbsp;# $1 The database cluster path of a master node.&lt;br /&gt;&amp;nbsp;# $2 The hostname of a recovery target node.&lt;br /&gt;&amp;nbsp;# $3 The database cluster path of a recovery target node. &lt;br /&gt;&amp;nbsp; MASTERNODE=10.0.0.113&lt;br /&gt;&amp;nbsp; cmd1=`ssh $2 "rm -r $3"`&lt;br /&gt;&amp;nbsp; cmd2=`ssh $2 "/usr/lib/postgresql/9.1/bin/repmgr -D $3&amp;nbsp; standby clone $MASTERNODE"`&lt;br /&gt;echo $cmd1&lt;br /&gt;echo $cmd2 &lt;br /&gt;&lt;pre style="font-family: inherit;"&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;#-------------------------------------------------------------------------------------------------&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;#!/bin/bash&lt;br /&gt;# second stage recovery&amp;nbsp; &lt;br /&gt;&amp;nbsp;# $1 The database cluster path of a master node.&lt;br /&gt;&amp;nbsp;# $2 The hostname of a recovery target node.&lt;br /&gt;&amp;nbsp;# $3 The database cluster path of a recovery target node. &lt;br /&gt;&amp;nbsp; MASTERNODE=10.0.0.113&lt;br /&gt;&amp;nbsp; cmd1=`ssh $2 "/usr/lib/postgresql/9.1/bin/repmgr -D $3&amp;nbsp; --force standby clone $MASTERNODE"`&lt;br /&gt;echo $cmd1&lt;/pre&gt;&lt;br /&gt;&lt;pre style="font-family: inherit;"&gt;#-----------------------------------------------------------------------------------------------&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre style="font-family: inherit;"&gt;#!/bin/bash&lt;br /&gt;#&lt;br /&gt;# Start PostgreSQL on the recovery target node&lt;br /&gt;#&lt;br /&gt;if [ $# -ne 2 ]&lt;br /&gt;then&lt;br /&gt;    echo "pgpool_remote_start remote_host remote_datadir"&lt;br /&gt;    exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;cmd=`ssh $1 "/usr/lib/postgresql/9.1/bin/pg_ctl start -D $2 2&amp;gt;/dev/null 1&amp;gt;/dev/null &amp;lt; /dev/null &amp;amp;"`&lt;br /&gt;echo $cmd&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;pre style="font-family: inherit;"&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span style="font-family: inherit;"&gt; &lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-3574296887349877213?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/3574296887349877213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-online-recovery.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3574296887349877213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/3574296887349877213'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-online-recovery.html' title='Postgresql - pgpool online recovery'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6519202573083561293</id><published>2011-12-20T13:03:00.000-06:00</published><updated>2011-12-31T10:50:15.554-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><title type='text'>Linux - startup script</title><content type='html'>&lt;b&gt;I never had the necessity of creating a start up script, but I need one for creating a folder within the /var/run path as it gets delete it on each reboot.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;open a konsole and do the following:&lt;br /&gt;1.cd /etc/init.d/&lt;br /&gt;2.touch makedir&lt;br /&gt;3.vim makedir&lt;br /&gt;4. enter mkdir /var/run/pgpool&amp;nbsp; | chown wwwrun -R /var/run/pgpool&lt;br /&gt;5.save the file&lt;br /&gt;6.chmod +x makedir&lt;br /&gt;7.chkconfig -a makedir&lt;br /&gt;&lt;br /&gt;The above commands does the following&lt;br /&gt;1. changes directory to a directory which contains the startup scripts&lt;br /&gt;2. creates a file named makedir&lt;br /&gt;3. edit the file makedir (vim is a text editor....use man vim if you are not familiar with it)&lt;br /&gt;4. write your command in this file&lt;br /&gt;5. save the file (again....use man vim to learn how to save the file)&lt;br /&gt;6. change the file to executable making it a script&lt;br /&gt;7. add makedir script to startup so it starts even after reboot&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.opensuse.org/archives/sf-archives/archives-install-boot/340570-how-run-custom-script-startup.html"&gt;http://forums.opensuse.org/archives/sf-archives/archives-install-boot/340570-how-run-custom-script-startup.html &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6519202573083561293?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6519202573083561293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-startup-script.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6519202573083561293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6519202573083561293'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-startup-script.html' title='Linux - startup script'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6318993961203278962</id><published>2011-12-19T19:53:00.000-06:00</published><updated>2011-12-31T10:50:15.572-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pgpool'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - pgpool + streaming replication</title><content type='html'>I'm following this guide to set up a simple pgpool deployment with streaming replication:&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/"&gt;http://pgpool.projects.postgresql.org/contrib_docs/simple_sr_setting/ &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;+ the apache2 user process is called wwwrun in opensuse 12.1 ( don't know whether this is also true for other distributions)&lt;br /&gt;+ the apache directory is located in /svr/www/htdocs &lt;br /&gt;&lt;br /&gt;+ to enable the apache service you'll need to issue a systemctl &lt;br /&gt;systemctl enable apache2.service&lt;br /&gt;systemctl start apache2.service&lt;br /&gt;&lt;br /&gt;+ in order for pgpooladmin to run, it's necessary to grant the wwwrun process user with the appropriate permissions over the underlying pgpool configuration files.&lt;br /&gt;&lt;br /&gt;+ gotcha: specifying the health check user is necessary for pgpool to detect which server is master and which slave (whilst in streaming replication).&lt;br /&gt;&lt;br /&gt;+ parallel query applies when you partition your tables over several nodes .&lt;br /&gt;&lt;br /&gt;Questions:&lt;br /&gt;Apparently pgpool determines which sql statements are dml (which are directed to the master ) and which are only dql (data query language ) which may be balanced. Obviously database permission subsists. pgpool acts as if were another client. &lt;br /&gt;&lt;br /&gt;related links.&lt;br /&gt;&lt;a href="http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4"&gt;http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/pgpoolAdmin/doc/en/install.html"&gt;http://pgpool.projects.postgresql.org/pgpoolAdmin/doc/en/install.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pgpool.projects.postgresql.org/pgpool-II/doc/pgpool-en.html"&gt;http://pgpool.projects.postgresql.org/pgpool-II/doc/pgpool-en.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6318993961203278962?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6318993961203278962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-streaming-replication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6318993961203278962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6318993961203278962'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgpool-streaming-replication.html' title='Postgresql - pgpool + streaming replication'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4215947719123887374</id><published>2011-12-16T11:56:00.000-06:00</published><updated>2011-12-31T10:50:15.590-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Postgresql - Logging (messages)</title><content type='html'>Apparently log messages are stored by default in the &lt;b&gt;pg_log&lt;/b&gt; directory inside the directory cluster. Supposedly you must configure the server to redirect all error messages to a file , for example in csv format.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/9.1/static/runtime-config-logging.html"&gt;http://www.postgresql.org/docs/9.1/static/runtime-config-logging.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4215947719123887374?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4215947719123887374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-logging-messages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4215947719123887374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4215947719123887374'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-logging-messages.html' title='Postgresql - Logging (messages)'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-484921537404886523</id><published>2011-12-15T13:31:00.004-06:00</published><updated>2011-12-31T10:50:15.609-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Troubleshooting'/><title type='text'>Postgresql Troubleshooting - FATAL:  valor no válido para el parámetro «lc_messages»: «en_US.UTF-8»</title><content type='html'>Source machine: opensuse 12.1 en_US.UTF8&lt;br /&gt;Target machine: debian squezze es_MX.utf8&lt;br /&gt;&lt;br /&gt;This issue arose when trying to start a database cluster (inside a machine configured in spanish) based on a copy of a cluster in another machine that is configured with the english language.&lt;br /&gt;&lt;br /&gt;The problem was that the only "locales" installed in the target machine were:&lt;br /&gt;&lt;br /&gt;postgres@debian1:~$ locale -a&lt;br /&gt;C&lt;br /&gt;es_MX.utf8&lt;br /&gt;POSIX&lt;br /&gt;&lt;br /&gt;In Debian, there are several ways to configure a new locale:&lt;br /&gt;&lt;a href="http://people.debian.org/~schultmc/locales.html"&gt;http://people.debian.org/~schultmc/locales.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I followed successfully the easy way:&lt;br /&gt;&lt;b&gt;&lt;br /&gt;The Easy Way&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Install debconf (i.e. run apt-get update then apt-get install debconf, as root)&lt;br /&gt;Run dpkg-reconfigure locales as root&lt;br /&gt;&lt;br /&gt;And now,I list the locales again:&lt;br /&gt;&lt;br /&gt;postgres@debian1:~$ locale -a&lt;br /&gt;C&lt;br /&gt;en_US.utf8&lt;br /&gt;es_MX.utf8&lt;br /&gt;POSIX&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-484921537404886523?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/484921537404886523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-troubleshooting-fatal-valor_15.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/484921537404886523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/484921537404886523'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-troubleshooting-fatal-valor_15.html' title='Postgresql Troubleshooting - FATAL:  valor no válido para el parámetro «lc_messages»: «en_US.UTF-8»'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-4548721843670561635</id><published>2011-12-14T13:35:00.002-06:00</published><updated>2011-12-31T10:50:15.635-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - pg_config</title><content type='html'>pg_config is a small application that provides information of the current postgresql installation.Many of the utilities that you install to support your postgresql server, rely on this utility to get the necessary parameters for postgresql binaries and libraries.&lt;br /&gt;&lt;br /&gt;It's contained in the postgresql-contrib package and in my case, it's installed in this path:&lt;br /&gt;/usr/pgsql-9.0/bin/pg_config&lt;br /&gt;i.e. in the same path that the other postgresql binaries.&lt;br /&gt;&lt;br /&gt;Of course, in order for the program that requires such information to find pg_config it must be included in the PATH environment variable.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.1/static/app-pgconfig.html"&gt;http://www.postgresql.org/docs/8.1/static/app-pgconfig.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-4548721843670561635?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/4548721843670561635/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgconfig_14.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4548721843670561635'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/4548721843670561635'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-pgconfig_14.html' title='Postgresql - pg_config'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-7385443093428699064</id><published>2011-12-14T12:18:00.003-06:00</published><updated>2011-12-31T10:50:15.660-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='replication'/><title type='text'>Postgresql - repmgr (Replication Manager for PostgreSQL clusters)</title><content type='html'>This tool is related with replication capabilities, it's very young (but the streaming replication and hot standby features are also very recent) &lt;br /&gt;and claims to allow:&lt;br /&gt;+ monitor the replication process.&lt;br /&gt;+ allow DBAs to issue high availability operations such as switch-overs and fail-overs.&lt;br /&gt;&lt;br /&gt;http://repmgr.org/&lt;br /&gt;&lt;br /&gt;I've read about a lot of other replication monitoring solutions and they all are not that easy to install/configure, let's give this one a try.&lt;br /&gt;&lt;br /&gt;I got to know about this through:&lt;br /&gt;&lt;a href="http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4-p2"&gt;http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4-p2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the official documentation for setting everything up.&lt;br /&gt;https://github.com/greg2ndQuadrant/repmgr&lt;br /&gt;&lt;br /&gt;Arguments for using repmgr&lt;br /&gt;1. Less steps -&gt; less errors&lt;br /&gt;2. Easy to set up and easy to use&lt;br /&gt;3. Monitoring facilities. &lt;br /&gt;4. Company is known&lt;br /&gt;5. You can set the replication in a database basis.&lt;br /&gt;&lt;br /&gt;Shortcomings:&lt;br /&gt;1. It must be installed additionally to the normal postgresql installation.&lt;br /&gt;2. The limitations of streaming replication are also limitations of repmgr.&lt;br /&gt;3. Development is in early stages (but this is expected as the streaming replication technology is also recent)&lt;br /&gt;4. Prerequisites that must be met to be able to install repmgr.&lt;br /&gt;5. The inner configuration issues to stream replication are hidden.&lt;br /&gt;&lt;br /&gt;Independently of adopting this tool or not as the entry point for streaming replication, it's important to master the concepts lying behind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-7385443093428699064?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/7385443093428699064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-repmgr-replication-manager_14.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7385443093428699064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/7385443093428699064'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-repmgr-replication-manager_14.html' title='Postgresql - repmgr (Replication Manager for PostgreSQL clusters)'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8927794493531045574</id><published>2011-12-13T16:38:00.001-06:00</published><updated>2011-12-31T10:50:15.689-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>linux - ssh-copy-id</title><content type='html'>I used this tool today to copy one machine public key into the known hosts of another in order to set "trusted" communication. The other way to do this is to copy the they to the other machine and then copying it directly in the knownhosts file, which is obviously more complicated.&lt;br /&gt;&lt;br /&gt;I need this kind of set up to enable streaming replication in postgresql with hot stand by capabilities.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://linux.die.net/man/1/ssh-copy-id"&gt;http://linux.die.net/man/1/ssh-copy-id&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4"&gt;http://www.howtoforge.com/how-to-set-up-a-postgresql-9.0-hot-standby-streaming-replication-server-with-repmgr-on-opensuse-11.4&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The command to copy public keys &lt;br /&gt;ssh-copy-id -i ~/.ssh/id_rsa.pub pgslave&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8927794493531045574?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8927794493531045574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-ssh-copy-id_13.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8927794493531045574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8927794493531045574'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/linux-ssh-copy-id_13.html' title='linux - ssh-copy-id'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-8553572905786961254</id><published>2011-12-07T02:48:00.001-06:00</published><updated>2011-12-31T10:50:15.714-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - timing</title><content type='html'>One simple yet powerful tip is to activate the timing feature:&lt;br /&gt;&lt;br /&gt;dellstore2=# \timing&lt;br /&gt;Timing is on.&lt;br /&gt;dellstore2=# SELECT count(*) FROM customers;&lt;br /&gt; count &lt;br /&gt;-------&lt;br /&gt; 20000&lt;br /&gt;Time: 7.994 ms&lt;br /&gt;&lt;br /&gt;The material I read this from, titles this particular section "Timing overhead". Is the timing feature supposed to cause some sort of overhead upon our queries?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-8553572905786961254?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/8553572905786961254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-timing_07.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8553572905786961254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/8553572905786961254'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/12/postgresql-timing_07.html' title='Postgresql - timing'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9023816360631923026.post-6390814284997353359</id><published>2011-11-25T13:51:00.001-06:00</published><updated>2011-12-31T10:50:15.737-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><title type='text'>Postgresql - Handling 'NaN'::float -&gt; crosstab function</title><content type='html'>Today AVR asked me: how do I compare against a NaN ? And I was like you mean to an AND negated ? LOL.&lt;br /&gt;It turns out that 'NaN' is a simbolic value meaning "Not a number".&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;In addition to ordinary numeric values, the numeric type allows the special value NaN, meaning "not-a-number". Any operation on NaN yields another NaN. When writing this value as a constant in an SQL command, you must put quotes around it, for example UPDATE table SET x = 'NaN'. On input, the string NaN is recognized in a case-insensitive manner.&lt;br /&gt;&lt;br /&gt;    Note: In most implementations of the "not-a-number" concept, NaN is not considered equal to any other numeric value (including NaN). In order to allow numeric values to be sorted and used in tree-based indexes, PostgreSQL treats NaN values as equal, and greater than all non-NaN values. &lt;br /&gt;&lt;br /&gt;In addition to ordinary numeric values, the floating-point types have several special values:&lt;br /&gt;Infinity&lt;br /&gt;-Infinity&lt;br /&gt;NaN&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://developer.postgresql.org/pgdocs/postgres/datatype-numeric.html"&gt;http://developer.postgresql.org/pgdocs/postgres/datatype-numeric.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;If you want to compare against the 'NaN' ("not a number") float value, then do an explicit cast to float: float('NaN').&lt;/blockquote&gt;&lt;br /&gt;&lt;a href="http://stackoverflow.com/questions/5401455/is-there-a-database-independent-way-with-sqlalchemy-to-query-filtered-by-none"&gt;http://stackoverflow.com/questions/5401455/is-there-a-database-independent-way-with-sqlalchemy-to-query-filtered-by-none&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here are some very good insights regarding this topic.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ivoa.net/internal/IVOA/InterOpOct2011Applications/null_nan-3.pdf"&gt;http://www.ivoa.net/internal/IVOA/InterOpOct2011Applications/null_nan-3.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This issue arose due to the apparent fact that the function crosstab returns this symbolic constant.&lt;br /&gt;&lt;br /&gt;In the end she did this:&lt;br /&gt;&lt;blockquote&gt;CASE WHEN CHALCO = 'NaN'::float OR CHALCO IS NULL THEN 0 ELSE CHALCO END,&lt;br /&gt;&lt;/blockquote&gt;and seemed to work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9023816360631923026-6390814284997353359?l=sharingtechknowledge.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sharingtechknowledge.blogspot.com/feeds/6390814284997353359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/11/postgresql-handling-crosstab-function.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6390814284997353359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9023816360631923026/posts/default/6390814284997353359'/><link rel='alternate' type='text/html' href='http://sharingtechknowledge.blogspot.com/2011/11/postgresql-handling-crosstab-function.html' title='Postgresql - Handling &amp;#39;NaN&amp;#39;::float -&amp;gt; crosstab function'/><author><name>ichbinrene</name><uri>http://www.blogger.com/profile/03548697428629139268</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://1.bp.blogspot.com/-068B-WKjMRQ/TsdWtlU9g_I/AAAAAAAAADs/9ZUYmH8rATY/s220/rene_avatar.jpg'/></author><thr:total>0</thr:total></entry></feed>
