<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CEcBSXs-fCp7ImA9WhRSEks.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166</id><updated>2011-11-14T13:14:18.554+04:00</updated><category term="pg_total_relation_size" /><category term="seq scan" /><category term="over partition" /><category term="pitr" /><category term="dialog" /><category term="postgresql" /><category term="logs" /><category term="news" /><category term="fsm" /><category term="sniplet" /><category term="bug" /><category term="pg84" /><category term="pgsql-general" /><category term="create table" /><category term="order by" /><category term="temp tables" /><category term="ps" /><category term="array_agg" /><category term="column" /><category term="psql" /><category term="recheck cond" /><category term="with recursive" /><category term="junction" /><category term="values" /><category term="pg_locks" /><category term="autovacuum" /><category term="locks" /><category term="with" /><category term="frames" /><category term="GSoC" /><category term="cursor" /><category term="loosy index" /><category term="configuration" /><category term="thoughts" /><category term="function" /><category term="Bruce Momjian" /><category term="idle" /><category term="pg85" /><category term="nosql" /><category term="pg_relation_size" /><category term="performance" /><category term="collation" /><category term="strings" /><category term="russian" /><category term="limit" /><category term="work" /><category term="reverse" /><category term="londiste" /><category term="cpu" /><category term="backup" /><category term="offset" /><category term="scripting" /><category term="Tom Lane" /><category term="buffers" /><category term="foreign key" /><category term="Pavel Stehule" /><category term="visibility maps" /><category term="mysql" /><category term="group by" /><category term="floating" /><category term="skytools" /><category term="lock" /><category term="in" /><category term="arrays" /><category term="schema" /><category term="left" /><category term="pg91" /><category term="postgresmen" /><category term="order" /><category term="window functions" /><category term="battery" /><category term="Regina Obe" /><category term="profession" /><category term="Joshua Drake" /><category term="krasnodar" /><category term="rule" /><category term="Andreas Scherbaum" /><category term="contrib" /><category term="dzen" /><category term="transposition" /><category term="desktop" /><category term="aggregate" /><category term="string_agg" /><category term="Leo Hsu" /><category term="Hubert Lubaczewski" /><category term="wal" /><category term="view" /><category term="Vhubuo" /><category term="stats" /><category term="fun" /><category term="sql-standart" /><category term="sql.ru" /><category term="statistics" /><category term="release" /><category term="pg_stat_statements" /><category term="blogging" /><category term="pgfouine" /><category term="sharding" /><category term="returning" /><category term="pg90" /><category term="pgq" /><category term="conky" /><category term="digest" /><category term="pg_indexes_size" /><category term="cluster" /><category term="pg_xlog" /><category term="concat" /><category term="locale" /><category term="alter table" /><category term="acpi" /><category term="conninfo" /><category term="unnest" /><category term="graph" /><category term="ctype" /><category term="Sergey Konoplev" /><category term="tander" /><category term="pg_buffercache" /><category term="conditional" /><category term="pg_migrator" /><category term="pg_table_size" /><category term="hot standby" /><category term="shell" /><category term="python" /><category term="pg_restore" /><category term="tag cloud" /><category term="analysis" /><category term="btree_gist" /><category term="consulting" /><category term="notice" /><category term="reindex" /><category term="right" /><category term="maintenance" /><category term="windows" /><category term="oid" /><category term="if not exists" /><category term="port" /><category term="generate_series" /><category term="count" /><category term="Bernd Helmle" /><category term="bitmap heap scan" /><category term="social network" /><category term="moscow" /><category term="linux" /><category term="srf" /><category term="plproxy" /><category term="enum" /><category term="plpgsql" /><category term="cassandra" /><category term="emacs" /><category term="transaction" /><category term="standby" /><category term="primary key" /><category term="pg_dump" /><category term="pg_stat_activity" /><category term="english" /><category term="translation" /><category term="process" /><category term="explain" /><category term="q and a" /><category term="trigger" /><category term="streaming" /><category term="files" /><category term="concat_ws" /><category term="ssh" /><category term="David Fetter" /><category term="size" /><category term="monitoring" /><category term="cube" /><category term="not in" /><category term="mongodb" /><category term="xmonad" /><category term="null" /><category term="system tables" /><category term="pagination" /><category term="xxkb" /><category term="vacuum" /><category term="data types" /><category term="sql" /><category term="administration" /><category term="index" /><category term="exception" /><category term="ddl" /><category term="information_schema" /><category term="dired" /><category term="sql-mode" /><category term="replication" /><category term="bitmap index scan" /><title>gray-hemp: PostgreSQL, Emacs, Linux, etc.</title><subtitle type="html">one flew east one flew west one flew over the cuckoo's nest</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://gray-hemp.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>102</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/gray-hemp" /><feedburner:info uri="gray-hemp" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DUANQn44eyp7ImA9Wx5bFUQ.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1941517074583755875</id><published>2010-11-01T09:03:00.005+03:00</published><updated>2010-11-01T10:49:53.033+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-01T10:49:53.033+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tom Lane" /><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="pgsql-general" /><category scheme="http://www.blogger.com/atom/ns#" term="null" /><category scheme="http://www.blogger.com/atom/ns#" term="in" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Как получить пустое множество в IN</title><content type="html">Прочитал в рассылке &lt;a href="http://archives.postgresql.org/pgsql-general/2010-10/msg01135.php"&gt;интересную дискуссию&lt;/a&gt;. Вопрос довольно злободневный, но, честно говоря, раньше не знал об этом.&lt;br /&gt;&lt;br /&gt;Допустим надо проверить, что поле входит в какое-то множество. Очевидно, что надо использовать конструкцию типа &lt;br /&gt;&lt;br /&gt;&lt;code&gt;field IN (1, 2, 3, ...)&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;Но что если это множество пустое. Как его указать?&lt;br /&gt;&lt;br /&gt;&lt;code&gt;field IN (???)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Действительно, просто пустые скобки указать нельзя, получим ошибку. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;postgres@localhost:5432 test=#&lt;br /&gt;SELECT 1 IN ();&lt;br /&gt;ERROR:  syntax error at or near ")"&lt;br /&gt;LINE 1: SELECT 1 IN ();&lt;br /&gt;                     ^&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Просто NULL тоже нельзя.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;postgres@localhost:5432 test=#&lt;br /&gt;SELECT 1 IN NULL;&lt;br /&gt;ERROR:  syntax error at or near "NULL"&lt;br /&gt;LINE 1: SELECT 1 IN NULL;&lt;br /&gt;                    ^&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;NULL в скобках опять нельзя, т.к. в результате всегда будет NULL.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;postgres@localhost:5432 test=#&lt;br /&gt;SELECT 1 IN (NULL);&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; &lt;NULL&gt;&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Как тогда быть? Ответ получается из вопроса - просто &lt;b&gt;получить&lt;/b&gt; пустое множество.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;postgres@localhost:5432 test=#&lt;br /&gt;SELECT 1 IN (SELECT 1 WHERE FALSE);&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; f&lt;br /&gt;(1 row)&lt;br /&gt;&lt;br /&gt;postgres@localhost:5432 test=#&lt;br /&gt;SELECT 1 NOT IN (SELECT 1 WHERE FALSE);&lt;br /&gt; ?column? &lt;br /&gt;----------&lt;br /&gt; t&lt;br /&gt;(1 row)&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-1941517074583755875?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/awc3ZpBaR4Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1941517074583755875/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/11/in.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1941517074583755875?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1941517074583755875?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/awc3ZpBaR4Q/in.html" title="Как получить пустое множество в IN" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/11/in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUGR3g7fCp7ImA9Wx5bE04.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-4822725321382544840</id><published>2010-10-29T08:44:00.003+04:00</published><updated>2010-10-29T10:03:46.604+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-29T10:03:46.604+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="pgsql-general" /><category scheme="http://www.blogger.com/atom/ns#" term="schema" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Как перенести объекты из одной схемы в другую</title><content type="html">Этот вопрос довольно часто задают на форумах и в рассылке. Вот &lt;a href="http://archives.postgresql.org/pgsql-general/2010-10/msg01007.php"&gt;очередное такое письмо&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Стандартное решение проблемы:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ALTER TABLE table_name SET SCHEMA new_schema;&lt;br /&gt;ALTER FUCNTION function_name SET SCHEMA new_schema;&lt;br /&gt;-- и т.д.&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-4822725321382544840?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/Wyik6smZgkk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/4822725321382544840/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/10/blog-post.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/4822725321382544840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/4822725321382544840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/Wyik6smZgkk/blog-post.html" title="Как перенести объекты из одной схемы в другую" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/10/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIDQHo7cCp7ImA9Wx5bEUg.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-4084908754979156058</id><published>2010-10-27T09:37:00.005+04:00</published><updated>2010-10-27T09:49:31.408+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-27T09:49:31.408+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="foreign key" /><category scheme="http://www.blogger.com/atom/ns#" term="pgsql-general" /><category scheme="http://www.blogger.com/atom/ns#" term="index" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Зачем CASCADE в DROP INDEX</title><content type="html">Читая рассылку pgsql-general, cделал для себя интересное замечание. Вопрос был - для чего указывать CASCADE в DROP INDEX, что может зависеть от индекса? Ответ - если индекс UNIQUE, то FOREIGN KEY.&lt;br /&gt;&lt;br /&gt;Источник &lt;a href="http://archives.postgresql.org/pgsql-general/2010-10/msg00931.php"&gt;тут&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-4084908754979156058?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/oRRXcS4qAzU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/4084908754979156058/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/10/cascade-drop-index.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/4084908754979156058?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/4084908754979156058?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/oRRXcS4qAzU/cascade-drop-index.html" title="Зачем CASCADE в DROP INDEX" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/10/cascade-drop-index.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIMQng5cCp7ImA9Wx5bEUg.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1973223758825745498</id><published>2010-10-27T09:19:00.003+04:00</published><updated>2010-10-27T09:49:43.628+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-27T09:49:43.628+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="plpgsql" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="trigger" /><title>Заметка про RENAME и триггера</title><content type="html">В plpgsql триггерах удобно использовать &lt;a href="http://www.postgresql.org/docs/8.4/interactive/plpgsql-declarations.html#PLPGSQL-DECLARATION-RENAMING-VARS"&gt;RENAME&lt;/a&gt; для того чтобы абстрагироваться от NEW и OLD. Например:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;IF TG_OP = 'DELETE' THEN&lt;br /&gt;    RENAME OLD TO myrow;&lt;br /&gt;ELSE&lt;br /&gt;    RENAME NEW TO myrow;    &lt;br /&gt;END IF;&lt;br /&gt;&lt;br /&gt;-- Далее работаем с myrow не задумываясь о типе триггера&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-1973223758825745498?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/1ctjOdz38KY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1973223758825745498/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/10/rename.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1973223758825745498?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1973223758825745498?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/1ctjOdz38KY/rename.html" title="Заметка про RENAME и триггера" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/10/rename.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIMQng4eSp7ImA9Wx5bEUg.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-9174739207993083247</id><published>2010-10-27T08:54:00.006+04:00</published><updated>2010-10-27T09:49:43.631+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-27T09:49:43.631+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="foreign key" /><category scheme="http://www.blogger.com/atom/ns#" term="primary key" /><category scheme="http://www.blogger.com/atom/ns#" term="sql.ru" /><category scheme="http://www.blogger.com/atom/ns#" term="system tables" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Какие колонки таблицы входят в PK/FK</title><content type="html">Вчера на sql.ru увидел вопрос - &lt;a href="http://www.sql.ru/forum/actualthread.aspx?bid=7&amp;tid=801186"&gt;возможно ли при помощи запроса узнать какая колонка в таблице является PK а какая FK&lt;/a&gt;. Небольшое замечание к формулировке - в обоих случаях может быть несколько столбцов. &lt;br /&gt;&lt;br /&gt;Собственно запрос получается такой:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT &lt;br /&gt;    contype, -- тип ограничения (PK/FK)&lt;br /&gt;    attname -- имя атрибута&lt;br /&gt;FROM pg_constraint&lt;br /&gt;JOIN pg_attribute ON&lt;br /&gt;    attrelid = conrelid AND&lt;br /&gt;    attnum = any(conkey)&lt;br /&gt;WHERE&lt;br /&gt;    contype in ('p', 'f') AND&lt;br /&gt;    conrelid = 'yourtablename'::regclass::oid&lt;br /&gt;ORDER BY 1, attnum;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-9174739207993083247?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/8dyWRNoe9m4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/9174739207993083247/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/10/pkfk.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/9174739207993083247?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/9174739207993083247?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/8dyWRNoe9m4/pkfk.html" title="Какие колонки таблицы входят в PK/FK" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/10/pkfk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYDSHwzeCp7ImA9Wx5XGUU.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-3933371677436126387</id><published>2010-09-20T16:08:00.004+04:00</published><updated>2010-09-20T17:09:39.280+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-20T17:09:39.280+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pg90" /><category scheme="http://www.blogger.com/atom/ns#" term="release" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Доступен PostgreSQL 9.0 Final Release!</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.postgresql.org/about/news.1235"&gt;PostgreSQL 9.0 Final Release Available Now!&lt;/a&gt; с &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Опубликовано &lt;b&gt;2010-09-20, press@postgresql.org&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Вышел PostgreSQL 9.0! The PostgreSQL Global Development Group анонсирует выход долгожданного релиза. PostgreSQL 9.0 включает встроенную бинарную репликацию и более дюжины других больших нововведений расчитанных на всех от web разработчиков до хакеров БД.&lt;br /&gt;&lt;br /&gt;9.0 реализует большее количество крупных возможностей, чем любой релиз до этого, включая:&lt;br /&gt;&lt;br /&gt;- Hot standby&lt;br /&gt;- Потоковую репликацию&lt;br /&gt;- In-place обновления&lt;br /&gt;- 64-bit Windows сборки&lt;br /&gt;- Облегченное массовое управления правами&lt;br /&gt;- Анонимные блоки и именованные параметры для хранимых процедур&lt;br /&gt;- Новые windowing функции и упорядоченные агрегаты&lt;br /&gt;&lt;br /&gt;... и многое другое. Более детальное описание свыше 200 дополнений и улучшений в этой версии, разработанные более чем сотней людей, вы сможете найти в &lt;a href="http://www.postgresql.org/docs/9.0/static/release-9-0"&gt;замечаниях к релизу&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"Такие нововведения являются прочным основанием тому, что критически важные технические задачи могут продолжать опираться на мощь, гибкость и надёжность PostgreSQL", Afilias CTO Ram Mohan&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Больше информации о PostgreSQL 9.0:&lt;br /&gt;- &lt;a href="http://www.postgresql.org/docs/9.0/static/release-9-0"&gt;Замечания к релизу&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.postgresql.org/about/press/presskit90"&gt;Пресс-кит&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://wiki.postgresql.org/wiki/What's_new_in_PostgreSQL_9.0"&gt;Руководство по 9.0&lt;/a&gt;&lt;br /&gt; &lt;br /&gt;Скачать 9.0 сейчас:&lt;br /&gt;- &lt;a href="http://www.postgresql.org/download"&gt;Главная страница загрузки&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.postgresql.org/ftp/source/v9.0.0"&gt;Исходный код&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.postgresql.org/ftp/binary/v9.0.0"&gt;Бинарные пакеты&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://www.enterprisedb.com/products/pgdownload.do"&gt;Установка в один клик, включая пакеты для Windows&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-3933371677436126387?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/sniDKTaFJ3c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/3933371677436126387/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/09/postgresql-90-final-release.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/3933371677436126387?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/3933371677436126387?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/sniDKTaFJ3c/postgresql-90-final-release.html" title="Доступен PostgreSQL 9.0 Final Release!" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/09/postgresql-90-final-release.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8BQH48eCp7ImA9Wx5XEU4.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-2365815672237584130</id><published>2010-09-07T18:45:00.007+04:00</published><updated>2010-09-10T19:00:51.070+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-10T19:00:51.070+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="port" /><category scheme="http://www.blogger.com/atom/ns#" term="ssh" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Локально работаем с PostgreSQL закрытом на сервере</title><content type="html">Уже не в первый раз мне задают такой вопрос.&lt;br /&gt;&lt;br /&gt;Как подключиться, например с помощью pgAdmin, к кластеру PostgreSQL, когда он где-то на сервере, где его порт доступен только локально, т.е. к нему закрыт доступ извне? При этом есть ssh на этот сервер, но по нему работать в консоли с psql и тестировать работающее с базой приложение очень не удобно.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Всё очень просто - нам поможет старый добрый ssh-туннелинг. Допустим есть сервер servername где на локальном порту 5432 крутится PostgreSQL, и есть пользователь username, который может ходить по ssh на этот сервер. Надо сделать так чтобы обращаясь к локальному порту 5432 на вашей рабочей машине вы фактически попадали на локальный порт 5432 нашего сервера.&lt;br /&gt;&lt;br /&gt;Если вы на Windows, то смотрите в сторону утилиты &lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/docs.html"&gt;PuTTY&lt;/a&gt;, я в своё время на ней такое делал. Если вы на Linux, как и я сейчас, то вам нужна такая комманда:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ssh -L 5432:localhost:5432 username@servername&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;У меня, кстати, несколько серверов пробрасываются на разные локальные порты на рабочей машине:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;ssh -L 5432:localhost:5432 gray@server1&lt;br /&gt;ssh -L 6432:localhost:5432 gray@server2&lt;br /&gt;ssh -L 7432:localhost:5432 gray@server3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Очень удобно.&lt;br /&gt;&lt;br /&gt;p.s. Ещё одна &lt;a href="http://linuxproblem.org/art_9.html"&gt;полезная ссылка&lt;/a&gt;, где рассказывается как пользоваться ssh по сертификату, т.е. без надобности вводить каждый раз пароль.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-2365815672237584130?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/5uAGmLh26fQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/2365815672237584130/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/09/postgresql.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2365815672237584130?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2365815672237584130?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/5uAGmLh26fQ/postgresql.html" title="Локально работаем с PostgreSQL закрытом на сервере" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/09/postgresql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkICSH05eip7ImA9Wx5QGEo.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-2991796156777725367</id><published>2010-09-07T15:48:00.004+04:00</published><updated>2010-09-07T18:42:49.322+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-07T18:42:49.322+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="reverse" /><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="concat_ws" /><category scheme="http://www.blogger.com/atom/ns#" term="right" /><category scheme="http://www.blogger.com/atom/ns#" term="left" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="concat" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><title>В ожидании 9.1 - concat, concat_ws, right, left, reverse</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/08/24/waiting-for-9-1-concat-concat_ws-right-left-reverse/"&gt;Waiting for 9.1 - concat, concat_ws, right, left, reverse&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;24 августа Takahiro Itagaki применил патч:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Добавлены строковые функции: concat(), concat_ws(), left(), right()&lt;br /&gt;и reverse().&lt;br /&gt;&lt;br /&gt;Pavel Stehule, проверено мной.&lt;/code&gt;&lt;br /&gt; &lt;br /&gt;Что это за функции?&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;concat() это просто функциональный аналог оператора || с возможностью обработки нескольких строк за раз:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT concat( 'post', 'gres', 'ql' );&lt;br /&gt;   concat   &lt;br /&gt;------------&lt;br /&gt; postgresql&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Очень просто и полезно если надо сделать много конкатенаций.&lt;br /&gt;&lt;br /&gt;concat_ws() похожа, но воспринимает первый аргумент как разделитель:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT concat_ws( ' ', 'hubert', 'depesz', 'lubaczewski' );&lt;br /&gt;         concat_ws         &lt;br /&gt;---------------------------&lt;br /&gt; hubert depesz lubaczewski&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;left() и right() делают одно и то же, но с разных сторон строки:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT LEFT( 'postgresql', 4 );&lt;br /&gt; LEFT &lt;br /&gt;------&lt;br /&gt; post&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;В общем это работает как substring(), но тут есть одна приятная возможность:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT LEFT( 'postgresql', -2 );&lt;br /&gt;   LEFT   &lt;br /&gt;----------&lt;br /&gt; postgres&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это значит, что если параметр длинны отрицательный, то функция будет обрезать abs(length) символов с "другой стороны".&lt;br /&gt;&lt;br /&gt;Примеры для right():&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT RIGHT( 'postgresql', 3 );&lt;br /&gt; RIGHT &lt;br /&gt;-------&lt;br /&gt; sql&lt;br /&gt;(1 row)&lt;br /&gt; &lt;br /&gt;$ SELECT RIGHT( 'postgresql', -4 );&lt;br /&gt; RIGHT  &lt;br /&gt;--------&lt;br /&gt; gresql&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это всё относительно просто можно было сделать раньше. Но последняя функция, по моему не такому уж скромному мнению, является наиболее важной - reverse(). Её задача тривиальна:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT reverse( 'postgresql' );&lt;br /&gt;  reverse   &lt;br /&gt;------------&lt;br /&gt; lqsergtsop&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Но то, что она в ядре PostgreSQL означает что мы теперь можем сделать быстрый (индексный поиск) с условием вида LIKE '%something' ('%' в начале!). Техника для этого была &lt;a href="http://www.depesz.com/index.php/2007/07/30/indexable-field-like-something/"&gt;описана&lt;/a&gt; ранее, но тогда небыло быстрой reverse().&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-2991796156777725367?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/4wVIg_aUppw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/2991796156777725367/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/09/91-concat-concatws-right-left-reverse.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2991796156777725367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2991796156777725367?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/4wVIg_aUppw/91-concat-concatws-right-left-reverse.html" title="В ожидании 9.1 - concat, concat_ws, right, left, reverse" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/09/91-concat-concatws-right-left-reverse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAMSXk_fSp7ImA9Wx5QGEg.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1294278142415847543</id><published>2010-09-07T15:26:00.000+04:00</published><updated>2010-09-07T15:26:28.745+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-07T15:26:28.745+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="floating" /><category scheme="http://www.blogger.com/atom/ns#" term="configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="dialog" /><category scheme="http://www.blogger.com/atom/ns#" term="xmonad" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><title>Правила для окон в XMonad</title><content type="html">Задача - сделать так чтобы все диалоговые окна, некоторые окна по имени класса, некоторые по заголовку и некоторые по ресурсу появлялись плавающими (floating), т.е. не были "тайловыми".&lt;br /&gt;&lt;br /&gt;Решение - приводим ~/.xmonad/xmonad.hs в соответствие с нижеследующим примером.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;code&gt;import XMonad.Hooks.ManageDocks&lt;br /&gt;import XMonad.Hooks.ManageHelpers&lt;br /&gt;...&lt;br /&gt;main = do&lt;br /&gt;  ...&lt;br /&gt;  xmonad $ myUrgencyHook $ defaultConfig {&lt;br /&gt;    ...&lt;br /&gt;    manageHook = myManageHook &lt;+&gt; manageDocks &lt;+&gt; manageHook defaultConfig,&lt;br /&gt;    ...&lt;br /&gt;    }&lt;br /&gt;...&lt;br /&gt;-- Window rules&lt;br /&gt;myManageHook = composeAll . concat $ [&lt;br /&gt;  [isDialog --&gt; doFloat],&lt;br /&gt;  [className =? c --&gt; doFloat | c &lt;- myCFloats],&lt;br /&gt;  [title =? t --&gt; doFloat | t &lt;- myTFloats],&lt;br /&gt;  [resource =? r --&gt; doFloat | r &lt;- myRFloats],&lt;br /&gt;  [resource =? i --&gt; doIgnore | i &lt;- myIgnores]&lt;br /&gt;  ]&lt;br /&gt;  where&lt;br /&gt;    myCFloats = ["Xmessage"]&lt;br /&gt;    myTFloats = ["Save As...", "Save File"]&lt;br /&gt;    myRFloats = []&lt;br /&gt;    myIgnores = ["XXkb"]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;В переменную myCFloats прописываем имена всех классов окон, которые нужно отображать плавающими, соответственно в myTFloats заголовки и в myRFloats ресурсы.&lt;br /&gt;&lt;br /&gt;Мою последнюю конфигурацию Xmonad и всё её сопровождающее найдёте здесь &lt;a href="http://haskell.org/haskellwiki/Xmonad/Config_archive"&gt;Xmonad/Config_archive&lt;/a&gt; (поищите gray_hemp).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-1294278142415847543?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/c5rkb_cM_wM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1294278142415847543/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/08/xmonad.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1294278142415847543?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1294278142415847543?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/c5rkb_cM_wM/xmonad.html" title="Правила для окон в XMonad" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/08/xmonad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIMQHw_eSp7ImA9Wx5REUw.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1333007888670836293</id><published>2010-08-18T10:29:00.002+04:00</published><updated>2010-08-18T10:39:41.241+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-18T10:39:41.241+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="process" /><category scheme="http://www.blogger.com/atom/ns#" term="ps" /><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><title>Уведомить когда процесс остановиться (shell)</title><content type="html">Это маленький, но очень полезный сниплет, который позволяет сэкономить время и сохранить внимание. Я его использую очень часто, когда жду, например, окончания загрузки чего-то куда-то.&lt;br /&gt;&lt;br /&gt;10708 - pid процесса который мы ждём:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(while [ $(ps -p 10708 ho pid) ]; do sleep 5; done; echo -e "\a") &amp;&lt;/code&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/193160215117996166-1333007888670836293?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/0MxdIWlQ1aI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1333007888670836293/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/08/shell.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1333007888670836293?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1333007888670836293?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/0MxdIWlQ1aI/shell.html" title="Уведомить когда процесс остановиться (shell)" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/08/shell.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUCQXY5eSp7ImA9Wx5SFk4.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-8644115894031444224</id><published>2010-08-11T20:45:00.010+04:00</published><updated>2010-08-12T20:24:20.821+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-12T20:24:20.821+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="group by" /><category scheme="http://www.blogger.com/atom/ns#" term="primary key" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><title>В ожидании 9.1 - Распознавание функциональной зависимости от первичных ключей</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/08/08/waiting-for-9-1-recognize-functional-dependency-on-primary-keys/"&gt;Waiting for 9.1 – Recognize functional dependency on primary keys&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Вчера (7 августа) Tom Lane применил:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Распознавание функциональной зависимости от первичных ключей. Это позволяет &lt;br /&gt;колонкам не присутствовать в GROUP BY, если там присутствует первичный ключ.&lt;br /&gt;&lt;br /&gt;В дальнейшем нам стоит также разрешить функциональную зависимость от UNIQUE &lt;br /&gt;ограничений при условии, что колонка помечена как NOT NULL, но это будет ждать пока &lt;br /&gt;NOT NULL ограничения не будут представлены в pg_constraint, т.к. нам будут нужны &lt;br /&gt;pg_constraint OID-ы для всех условий, где будет разрешаться функциональная &lt;br /&gt;зависимость. &lt;br /&gt;&lt;br /&gt;Peter Eisentraut, проверено Alex Hunsaker и Tom Lane&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Одна из наиболее частых проблем, с которой люди сталкиваются при переходе с MySQL на PostgreSQL, заключается вот в таких запросах:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT field_a, field_b, count(*)&lt;br /&gt;FROM TABLE&lt;br /&gt;GROUP BY field_a&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это нормально для MySQL, но не работало в PostgreSQL. &lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Теперь, с новым патчем, это подмножество запросов будет работать и в PostgreSQL. Во первых, что это за подмножество? Всё просто - если field_a первичный ключ данной таблицы и мы группируем по нему, то очевидно, что мы не получим более чем одной строки и значения field_b для каждого из значений field_a. Но если это не первичный ключ, то может получиться что для каких-то значений field_a будет несколько значений field_b, и в этом случае запрос уже не подходит.&lt;br /&gt;&lt;br /&gt;Рассмотрим пример:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;CREATE TABLE people (&lt;br /&gt;    id serial PRIMARY KEY,&lt;br /&gt;    firstname TEXT,&lt;br /&gt;    lastname TEXT&lt;br /&gt;);&lt;br /&gt; &lt;br /&gt;CREATE TABLE visits (&lt;br /&gt;    id serial PRIMARY KEY,&lt;br /&gt;    person_id INT4 NOT NULL REFERENCES people (id),&lt;br /&gt;    when_logged timestamptz&lt;br /&gt;);&lt;br /&gt; &lt;br /&gt;INSERT INTO people (firstname, lastname)&lt;br /&gt;VALUES&lt;br /&gt;    ('Bill', 'Hicks'),&lt;br /&gt;    ('George', 'Carlin'),&lt;br /&gt;    ('Louis', 'C.K.'),&lt;br /&gt;    ('Robin', 'Williams'),&lt;br /&gt;    ('Zach', 'Galifianakis');&lt;br /&gt; &lt;br /&gt;INSERT INTO visits (person_id, when_logged)&lt;br /&gt;    SELECT&lt;br /&gt;        1 + floor(random() * 5),&lt;br /&gt;        now() - '1 year'::INTERVAL * random()&lt;br /&gt;    FROM&lt;br /&gt;        generate_series(1,1000);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Теперь положим что надо получить список людей со счётчиками посещений. Ранее надо было делать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    p.id,&lt;br /&gt;    count(*)&lt;br /&gt;FROM&lt;br /&gt;    people p&lt;br /&gt;    JOIN visits v ON p.id = v.person_id&lt;br /&gt;GROUP BY p.id;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Или так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    p.id,&lt;br /&gt;    p.firstname,&lt;br /&gt;    p.lastname,&lt;br /&gt;    count(*)&lt;br /&gt;FROM&lt;br /&gt;    people p&lt;br /&gt;    JOIN visits v ON p.id = v.person_id&lt;br /&gt;GROUP BY p.id, p.firstname, p.lastname;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;(или трюкачить с min(firstname))&lt;br /&gt;&lt;br /&gt;Но теперь можно сделать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    p.id,&lt;br /&gt;    p.firstname,&lt;br /&gt;    p.lastname,&lt;br /&gt;    count(*)&lt;br /&gt;FROM&lt;br /&gt;    people p&lt;br /&gt;    JOIN visits v ON p.id = v.person_id&lt;br /&gt;GROUP BY p.id;&lt;/code&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/193160215117996166-8644115894031444224?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/v81W3A8tCL8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/8644115894031444224/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/08/91.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8644115894031444224?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8644115894031444224?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/v81W3A8tCL8/91.html" title="В ожидании 9.1 - Распознавание функциональной зависимости от первичных ключей" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/08/91.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8ESXc4eyp7ImA9Wx5SFUk.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-8062805824281961738</id><published>2010-08-11T19:32:00.008+04:00</published><updated>2010-08-11T20:23:28.933+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-11T20:23:28.933+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="locks" /><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="alter table" /><category scheme="http://www.blogger.com/atom/ns#" term="lock" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="trigger" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><title>В ожидании 9.1 - Снижаем уровни блокировок для ALTER TABLE</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/08/08/waiting-for-9-1-reduced-lock-levels-for-alter-table/"&gt;Waiting for 9.1 – Reduced lock levels for ALTER TABLE&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;28 июля Simon Riggs применил патч:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Снижает уровни блокировок CREATE TRIGGER и некоторых действий ALTER TABLE, &lt;br /&gt;CREATE RULE. Убирает прописанные на прямую в коде режимы блокировок, используемые во &lt;br /&gt;множестве команд изменения DDL, позволяя более легко менять уровни блокировок в &lt;br /&gt;будущем. Реализован начальный анализ DDL подкомманд, так что многие уровни блокировок &lt;br /&gt;теперь будут ShareUpdateExclusiveLock или ShareRowExclusiveLock, позволяя конкретным &lt;br /&gt;коммандам не блокировать чтение/запись. Это первое изменение из числа запланированных &lt;br /&gt;в этом направлении; будет нужна дополнительная документация когда весь проект &lt;br /&gt;завершится.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Во первых - это только начало. Конечная цель - сделать все (большинство?) выражения ALTER TABLE менее навязчивыми.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Ранее все ALTER TABLE блокировали всякий доступ к таблице:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Сессия 1: # begin;&lt;br /&gt;Сессия 2: # begin;&lt;br /&gt;Сессия 1: *# create trigger q after insert on table_name &lt;br /&gt;            for each row execute procedure test();&lt;br /&gt;...тут засыпает на 10 минут...&lt;br /&gt;Сессия 2: *# select * from table_name;&lt;br /&gt;...а тут ждёт 10 минут...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это было потому что все ALTER TABLE и CREATE TRIGGER требовали AccessExclusiveLock на таблицу:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;*# create trigger q after insert on table_name for each row execute procedure test();&lt;br /&gt;CREATE TRIGGER&lt;br /&gt; &lt;br /&gt;*# SELECT * FROM pg_locks where pid = pg_backend_pid();&lt;br /&gt;   locktype    | database | relation |  page  | tuple  | virtualxid | transactionid | classid | objid  | objsubid | virtualtransaction | pid  |        mode         | granted&lt;br /&gt;---------------+----------+----------+--------+--------+------------+---------------+---------+--------+----------+--------------------+------+---------------------+---------&lt;br /&gt; virtualxid    |   [null] |   [null] | [null] | [null] | 13/674866  |        [null] |  [null] | [null] |   [null] | 13/674866          | 9492 | ExclusiveLock       | t&lt;br /&gt; relation      |    48535 |    69187 | [null] | [null] | [null]     |        [null] |  [null] | [null] |   [null] | 13/674866          | 9492 | AccessExclusiveLock | t&lt;br /&gt; transactionid |   [null] |   [null] | [null] | [null] | [null]     |        632704 |  [null] | [null] |   [null] | 13/674866          | 9492 | ExclusiveLock       | t&lt;br /&gt; relation      |    48535 |    10969 | [null] | [null] | [null]     |        [null] |  [null] | [null] |   [null] | 13/674866          | 9492 | AccessShareLock     | t&lt;br /&gt;(4 rows)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;И как мы знаем (или &lt;a href="http://www.postgresql.org/docs/current/interactive/explicit-locking.html#TABLE-LOCK-COMPATIBILITY"&gt;можем найти в документации&lt;/a&gt;) данный тип блокировки конфликтует со всем.&lt;br /&gt;&lt;br /&gt;В 9.1 полученная блокировка будет другой:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;*$ SELECT * FROM pg_locks where pid = pg_backend_pid();&lt;br /&gt;   locktype    | database | relation |  page  | tuple  | virtualxid | transactionid | classid | objid  | objsubid | virtualtransaction |  pid  |         mode          | granted&lt;br /&gt;---------------+----------+----------+--------+--------+------------+---------------+---------+--------+----------+--------------------+-------+-----------------------+---------&lt;br /&gt; transactionid |   [null] |   [null] | [null] | [null] | [null]     |           752 |  [null] | [null] |   [null] | 2/386              | 27199 | ExclusiveLock         | t&lt;br /&gt; relation      |    16398 |    16419 | [null] | [null] | [null]     |        [null] |  [null] | [null] |   [null] | 2/386              | 27199 | ShareRowExclusiveLock | t&lt;br /&gt; virtualxid    |   [null] |   [null] | [null] | [null] | 2/386      |        [null] |  [null] | [null] |   [null] | 2/386              | 27199 | ExclusiveLock         | t&lt;br /&gt; relation      |    16398 |    10987 | [null] | [null] | [null]     |        [null] |  [null] | [null] |   [null] | 2/386              | 27199 | AccessShareLock       | t&lt;br /&gt;(4 rows)&lt;br /&gt; &lt;br /&gt;(depesz@[local]:5900) 15:12:55 [depesz]&lt;br /&gt;*$ select 16419::regclass, 10987::regclass;&lt;br /&gt;  regclass  | regclass&lt;br /&gt;------------+----------&lt;br /&gt; table_name | pg_locks&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;В этот раз мы видим, что CREATE TRIGGER получает только ShareRowExclusiveLock, что разрешает делать SELECT запросы. Операции модификации (UPDATE, INSERT, DELETE) и другие DDL запросы к этой таблице всё ещё не будут разрешены. Но возможность хотя бы делать операции чтения это уже большой выигрыш. &lt;br /&gt;&lt;br /&gt;Я не нашел окончательный список всех вариантов ALTER TABLE, которые получают такой уровень блокировки, но это и не так важно - всё ещё поменяется, и новые варианты будут добавляться. Сейчас я знаю что добавление триггеров и установка значения по умолчанию используют ShareUpdateExclusiveLock вместо AccessExclusiveLock. Что будет следующим - посмотрим.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-8062805824281961738?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/ryBJOyd6oJU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/8062805824281961738/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/08/91-alter-table.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8062805824281961738?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8062805824281961738?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/ryBJOyd6oJU/91-alter-table.html" title="В ожидании 9.1 - Снижаем уровни блокировок для ALTER TABLE" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/08/91-alter-table.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QMRHY9fSp7ImA9Wx5SFU4.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-799170349278520302</id><published>2010-08-11T18:56:00.003+04:00</published><updated>2010-08-11T19:09:45.865+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-11T19:09:45.865+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="pgsql-general" /><category scheme="http://www.blogger.com/atom/ns#" term="column" /><category scheme="http://www.blogger.com/atom/ns#" term="information_schema" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Как получить имена всех таблиц содержащих колонку с заданным именем</title><content type="html">&lt;span style="font-style:italic;"&gt;На основе обсуждения &lt;a href="http://archives.postgresql.org/pgsql-general/2010-08/msg00329.php"&gt;filter tables from database&lt;/a&gt; с &lt;a href="http://archives.postgresql.org/pgsql-general/"&gt;pgsql-general&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Всё очень просто:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT table_name&lt;br /&gt;FROM information_schema.columns&lt;br /&gt;WHERE column_name = 'put_column_name_here';&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-799170349278520302?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/KQEh0OEsyb0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/799170349278520302/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/08/blog-post.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/799170349278520302?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/799170349278520302?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/KQEh0OEsyb0/blog-post.html" title="Как получить имена всех таблиц содержащих колонку с заданным именем" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/08/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08MR3kyfip7ImA9Wx5TFE8.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-8596236069562675799</id><published>2010-07-29T20:39:00.004+04:00</published><updated>2010-07-29T21:51:26.796+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-29T21:51:26.796+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql" /><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="create table" /><category scheme="http://www.blogger.com/atom/ns#" term="conditional" /><category scheme="http://www.blogger.com/atom/ns#" term="if not exists" /><category scheme="http://www.blogger.com/atom/ns#" term="ddl" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><title>В ожидании 9.1 - CREATE TABLE IF NOT EXISTS</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/07/28/waiting-for-9-1-create-table-if-not-exists/"&gt;Waiting for 9.1 – CREATE TABLE IF NOT EXISTS&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;25 июля Robert Haas применил патч, добавляющий CREATE IF NOT EXISTS для таблиц.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;CREATE TABLE IF NOT EXISTS.&lt;br /&gt;&lt;br /&gt;Reviewed by Bernd Helmle.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Пример тривиален:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ create table if not exists tesit (x text);&lt;br /&gt;CREATE TABLE&lt;br /&gt;&lt;br /&gt;$ create table if not exists tesit (x text);&lt;br /&gt;NOTICE:  relation "tesit" already exists, skipping&lt;br /&gt;CREATE TABLE&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Как можно видеть ошибки нет - просто дружелюбное замечание.&lt;br /&gt;&lt;br /&gt;Скорее всего такое же будет для схем, индексов, вью и других объектов базы, и нам не потребуется больше все эти корявые &lt;a href="http://www.depesz.com/index.php/2008/06/18/conditional-ddl/"&gt;воркэраунды&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-8596236069562675799?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/c-jZKtY90uk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/8596236069562675799/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/07/91-create-table-if-not-exists.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8596236069562675799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/8596236069562675799?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/c-jZKtY90uk/91-create-table-if-not-exists.html" title="В ожидании 9.1 - CREATE TABLE IF NOT EXISTS" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/07/91-create-table-if-not-exists.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcERns8eyp7ImA9Wx5TEU4.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1386630785662872087</id><published>2010-07-26T13:14:00.006+04:00</published><updated>2010-07-26T13:53:27.573+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-26T13:53:27.573+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="window functions" /><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="generate_series" /><category scheme="http://www.blogger.com/atom/ns#" term="values" /><category scheme="http://www.blogger.com/atom/ns#" term="order" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="unnest" /><title>Как можно задать порядок результата</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/07/25/how-to-order-by-some-random-query-defined-values/"&gt;How to order by some random - query defined - values?&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Представим простую ситуацию - есть таблица каких-то объектов (каждый со своим id) откуда надо достать объекты с id 3, 71, 5 и 16. И, самое главное, в том же порядке!&lt;br /&gt;&lt;br /&gt;Как это сделать?&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Во-первых, добавим тестовых данных:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;CREATE TABLE test_data (&lt;br /&gt;    id       INT4 PRIMARY KEY,&lt;br /&gt;    codename TEXT&lt;br /&gt;);&lt;br /&gt;INSERT INTO test_data ( id, codename )&lt;br /&gt;    SELECT i, 'codename for: ' || i&lt;br /&gt;    FROM generate_series( 1, 100 ) i;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Теперь, чтобы получить эти 4 строки, можно сделать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT * FROM test_data WHERE id IN (3, 71, 5, 16);&lt;br /&gt; id |     codename     &lt;br /&gt;----+------------------&lt;br /&gt;  3 | codename FOR: 3&lt;br /&gt;  5 | codename FOR: 5&lt;br /&gt; 16 | codename FOR: 16&lt;br /&gt; 71 | codename FOR: 71&lt;br /&gt;(4 rows)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Но, никак нельзя добавить ничего в ORDER BY, чтобы получить их в порядке указанном в IN (...). Итак, что можно сделать. Один способ это использовать (доступные с 8.2) VALUES() следующим образом:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    t.*&lt;br /&gt;FROM&lt;br /&gt;    test_data t&lt;br /&gt;    JOIN (&lt;br /&gt;        VALUES&lt;br /&gt;            (1, 3),&lt;br /&gt;            (2, 71),&lt;br /&gt;            (3, 5),&lt;br /&gt;            (4, 16)&lt;br /&gt;        ) AS c (ordering, id) ON t.id = c.id&lt;br /&gt;ORDER BY&lt;br /&gt;    c.ordering;&lt;br /&gt; id |     codename     &lt;br /&gt;----+------------------&lt;br /&gt;  3 | codename FOR: 3&lt;br /&gt; 71 | codename FOR: 71&lt;br /&gt;  5 | codename FOR: 5&lt;br /&gt; 16 | codename FOR: 16&lt;br /&gt;(4 rows)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Всё очень хорошо, только надо указывать дополнительные данные, и их формат не очень хорошо выглядит. К счастью есть другой способ. С 8.4 у нас есть Window Functions и unnest(), т.ч. можно сделать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;WITH ordered_want AS (&lt;br /&gt;    SELECT&lt;br /&gt;        id,&lt;br /&gt;        row_number() over () AS ordering&lt;br /&gt;    FROM&lt;br /&gt;        unnest( '{3,71,5,16}'::INT4[] ) AS id&lt;br /&gt;)&lt;br /&gt;SELECT&lt;br /&gt;    t.*&lt;br /&gt;FROM&lt;br /&gt;    test_data t&lt;br /&gt;    JOIN ordered_want o ON t.id = o.id&lt;br /&gt;ORDER BY&lt;br /&gt;    o.ordering;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Уже лучше. В этом случае подстановка id-ков осуществляется намного проще - просто укажите массив целых и всё.&lt;br /&gt;&lt;br /&gt;Есть ещё один способ. Если не можете использовать Window Functions, то можно задействовать относительно старый трюк с упорядочиванием по position():&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    t.*&lt;br /&gt;FROM&lt;br /&gt;    test_data t&lt;br /&gt;WHERE&lt;br /&gt;    t.id IN (3,71,5,16)&lt;br /&gt;ORDER BY&lt;br /&gt;    position( ',' || t.id || ',' IN ',3,71,5,16,' );&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Тут не забудьте указать пердшествующую и последующую запятые и добавьте их также вокруг t.id в ORDER BY.&lt;br /&gt;&lt;br /&gt;Да, тут будут проблемы, если вы работаете с текстовыми id, но всёже один из вариантов.&lt;br /&gt;&lt;br /&gt;Комментарии:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;# AREK, 25 июня 2010&lt;br /&gt;&lt;br /&gt;Если поставить intarray, то можно упростить последний запрос следующим образом:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT *, idx(‘{3,71,5,16}’, id) AS rank&lt;br /&gt;FROM test_data&lt;br /&gt;WHERE id = ANY(‘{3,71,5,16}’)&lt;br /&gt;ORDER BY rank;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Заметьте также, что вместо IN тут используется = ANY(). Это может быть проблемой для кода приложения, если вы не пишите запросы сами, а просто подставляете значения.&lt;br /&gt;&lt;br /&gt;Что касается текстовых id, то можно написать функцию idx(text[], text) и использовать тот же запрос.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-1386630785662872087?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/taNI86obP40" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1386630785662872087/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/07/blog-post.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1386630785662872087?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1386630785662872087?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/taNI86obP40/blog-post.html" title="Как можно задать порядок результата" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/07/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EFRn4zfSp7ImA9Wx5TEU4.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-5688183735064677642</id><published>2010-07-26T12:59:00.003+04:00</published><updated>2010-07-26T13:13:37.085+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-26T13:13:37.085+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="David Fetter" /><category scheme="http://www.blogger.com/atom/ns#" term="backup" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>MVC бэкапы</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://people.planetpostgresql.org/dfetter/index.php?/archives/61-MVC-Backups.html"&gt;MVC Backups&lt;/a&gt; с &lt;a href="http://people.planetpostgresql.org/dfetter/"&gt;David Fetter's blog&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Цель - использовать паттерн Model-View-Controller для создания бэкапов на любой платформе, которую поддерживает PostgreSQL.&lt;br /&gt;&lt;br /&gt;Сначала создадим SQL файл, реализующий Model и View:&lt;br /&gt;&lt;br /&gt;backup.sql:&lt;br /&gt;&lt;code&gt;WITH t AS (                                -- Эта часть Model.&lt;br /&gt;    SELECT quote_ident(datname) AS d&lt;br /&gt;    FROM pg_database WHERE NOT datistemplate&lt;br /&gt;)&lt;br /&gt;SELECT&lt;br /&gt;    'pg_dump -U postgres -Fc --file=' || d ||   -- Эта часть View.&lt;br /&gt;     to_char(now(),'_YYYYMMDD') ||&lt;br /&gt;    '.pgbackup' || ' '|| d&lt;br /&gt;FROM t;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Затем реализуем Controller.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;psql -Atqf backup.sql | sh&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Заметьте, если вы на Windows, то можете подставить cmd.exe или command.com как sh.&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/193160215117996166-5688183735064677642?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/bH8fycvgxnc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/5688183735064677642/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/07/mvc.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/5688183735064677642?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/5688183735064677642?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/bH8fycvgxnc/mvc.html" title="MVC бэкапы" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/07/mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04NQno-cSp7ImA9Wx5TFE8.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-969143279086662812</id><published>2010-07-22T11:29:00.004+04:00</published><updated>2010-07-29T21:53:13.459+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-29T21:53:13.459+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="psql" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><category scheme="http://www.blogger.com/atom/ns#" term="conninfo" /><title>В ожидании 9.1 - \conninfo в psql</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/07/21/waiting-for-9-1-conninfo-in-psql/"&gt;Waiting for 9.1 – \conninfo in psql&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;20 июля Robert Haas применил патч, добавляющий ещё одну \* комманду в psql:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Добавляет команду \conninfo в psql, показывающую информацию о текущем соединении.&lt;br /&gt;&lt;br /&gt;David Christensen. Проверено Steve Singer. Некоторые изменения от меня.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Из сообщения всё предельно понятно, т.ч. просто посмотрим на это:&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;code&gt;$ \conninfo&lt;br /&gt;&lt;br /&gt;You are connected to database "depesz" via local socket at port "5900" as user "depesz".&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это полезно тем, кто работает с несколькими базами данных - просто для того чтобы по ошибке не запустить SQL не на той базе.&lt;br /&gt;&lt;br /&gt;Ранее подобный эффект можно было получить добавив следующее в $HOME/.psqlrc:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;\set PROMPT1 '(%n@%M:%&gt;) %`date +%H:%M:%S` [%/] \n%x$ '&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Благодаря этому моя подсказка выглядит так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(depesz@[local]:5900) 14:57:43 [depesz]&lt;br /&gt;$&lt;/code&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/193160215117996166-969143279086662812?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/PcwSgexYXAw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/969143279086662812/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/07/91-conninfo-psql.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/969143279086662812?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/969143279086662812?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/PcwSgexYXAw/91-conninfo-psql.html" title="В ожидании 9.1 - \conninfo в psql" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/07/91-conninfo-psql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcGR388cSp7ImA9Wx5TFE8.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-1659248567010570643</id><published>2010-07-22T10:42:00.007+04:00</published><updated>2010-07-29T21:53:46.179+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-29T21:53:46.179+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sql-standart" /><category scheme="http://www.blogger.com/atom/ns#" term="Hubert Lubaczewski" /><category scheme="http://www.blogger.com/atom/ns#" term="strings" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="pg91" /><title>В ожидании 9.1 - standard_conforming_strings = on</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://www.depesz.com/index.php/2010/07/21/waiting-for-9-1-standard_conforming_strings-on/"&gt;Waiting for 9.1 – standard_conforming_strings = on&lt;/a&gt; с &lt;a href="http://www.depesz.com/"&gt;select * from depesz;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;В основном я пишу о новых возможностях, но это изменение довольно таки важное.&lt;br /&gt;&lt;br /&gt;20 июля Robert Haas сделал следующие изменения:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Значение standard_conforming_strings по умолчанию теперь on.&lt;br /&gt;&lt;br /&gt;Это изменение должно быть доведено до сведения разработчиков драйверов и в &lt;br /&gt;замечаниях к релизу должно быть указанным как не совместимое с предыдущими &lt;br /&gt;релизами.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Что это и почему так важно?&lt;br /&gt;Допустим вы хотите выбрать какое-то значение содержащее символ ' (апостроф). Т.к. строки тоже определяются этим символом нам нужно замаскировать его.&lt;br /&gt;&lt;br /&gt;Долгое время можно было делать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT 'guns \'n roses';&lt;br /&gt;   ?COLUMN?    &lt;br /&gt;---------------&lt;br /&gt; guns 'n roses&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Это выглядит нормально для любого программиста, работающего на другом языке, но у нас есть небольшая проблема - SQL стандарт это не приемлет.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Некоторое время назад, не помню когда точно, да и это не так важно, PostgreSQL представил маскированые строковые константы, которые выглядят так: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT E'guns \'n roses';&lt;br /&gt;   ?COLUMN?    &lt;br /&gt;---------------&lt;br /&gt; guns 'n roses&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;И когда вы используете обычные строки с маскированием обратной косой чертой, он выдаёт предупреждение:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT 'guns \'n roses';&lt;br /&gt;WARNING:  nonstandard USE of \' in a string literal&lt;br /&gt;LINE 1: select 'guns \'n roses';&lt;br /&gt;               ^&lt;br /&gt;HINT:  USE '' TO WRITE quotes IN strings, OR USE the escape string syntax (E'...').&lt;br /&gt;   ?COLUMN?    &lt;br /&gt;---------------&lt;br /&gt; guns 'n roses&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Т.е. всё работает так же как и раньше, только добавилось это предупреждение. Конечно же оно (предупреждение) может быть отключено (escape_string_warning GUC), и вы можете запретить маскирование установив standard_conforming_strings в on.&lt;br /&gt;&lt;br /&gt;Теперь, в 9.1, standard_conforming_strings будет по умолчанию on. А это значит, что с нашим тестом случится следующее:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT 'guns \'n roses';&lt;br /&gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;PostgreSQL теперь трактует \ как обычный символ, и т.к. кол-во апострофов нечётное значит что одна из строк ещё не завержена и запрос ещё не готов.&lt;br /&gt;&lt;br /&gt;Простой пример:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT 'first line\nsecond line';&lt;br /&gt;  ?COLUMN?&lt;br /&gt;-------------&lt;br /&gt; first line +&lt;br /&gt; second line&lt;br /&gt;(1 row)&lt;br /&gt; &lt;br /&gt;$ SET standard_conforming_strings = ON;&lt;br /&gt;SET&lt;br /&gt; &lt;br /&gt;$ SELECT 'first line\nsecond line';&lt;br /&gt;        ?COLUMN?&lt;br /&gt;-------------------------&lt;br /&gt; first line\nsecond line&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Итак, как теперь писать запросы с апострофами и символами новой строки? Короткий ответ - делать это правильно. Пример:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ SELECT 'guns ''n roses';&lt;br /&gt;   ?COLUMN?&lt;br /&gt;---------------&lt;br /&gt; guns 'n roses&lt;br /&gt;(1 row)&lt;br /&gt; &lt;br /&gt;$ select E'first line\nsecond line';&lt;br /&gt;  ?column?&lt;br /&gt;-------------&lt;br /&gt; first line +&lt;br /&gt; second line&lt;br /&gt;(1 row)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Если вы пишите запросы сами, это не большая проблема, но если используете что-то что строит их за вас (ORM или что-то формирующее параметры) - это должно быть исправлено (если не было исправлено ранее). &lt;br /&gt;&lt;br /&gt;Конечно же можно изменить standard_conforming_strings обратно в off, но это не будет нормальным решением.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-1659248567010570643?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/9oL6M4sVb84" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/1659248567010570643/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/07/91-standardconformingstrings-on.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1659248567010570643?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/1659248567010570643?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/9oL6M4sVb84/91-standardconformingstrings-on.html" title="В ожидании 9.1 - standard_conforming_strings = on" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/07/91-standardconformingstrings-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8HSH4yfip7ImA9WxFaF0U.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-6462240913747863746</id><published>2010-06-07T14:27:00.006+04:00</published><updated>2010-07-22T10:40:39.096+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-22T10:40:39.096+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="emacs" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="dired" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><title>Скрываем dot-файлы в Dired (Emacs)</title><content type="html">Если пользуетесь Dired, то наверняка часто сталкивались с проблемой, когда, допустим, в вашем "хоуме" (~/) глаза разбегались от обилия dot-файлов (.filename). Действительно так очень неудобно, но есть решение - просто добавьте этот сниплет в конфигурацию:&lt;br /&gt;&lt;br /&gt;~/.emacs.d/general.el:&lt;br /&gt;&lt;code&gt;;; Dired Mode extra features&lt;br /&gt;(load "dired-x.el")&lt;br /&gt;(setq dired-omit-files&lt;br /&gt;      (concat dired-omit-files "\\|^\\..+$"))&lt;br /&gt;(dired-omit-mode 1)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;По умолчанию он выключает отображение dot-файлов. Чтобы переключать режим отображения используйте M-o.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-6462240913747863746?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/0i_ehJNnwbM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/6462240913747863746/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/06/dot-dired-emacs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/6462240913747863746?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/6462240913747863746?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/0i_ehJNnwbM/dot-dired-emacs.html" title="Скрываем dot-файлы в Dired (Emacs)" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/06/dot-dired-emacs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MFRXs5eSp7ImA9WxFRE0g.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-5071160137543355365</id><published>2010-04-27T03:51:00.010+04:00</published><updated>2010-04-27T12:03:34.521+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-27T12:03:34.521+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="londiste" /><category scheme="http://www.blogger.com/atom/ns#" term="pgq" /><category scheme="http://www.blogger.com/atom/ns#" term="skytools" /><category scheme="http://www.blogger.com/atom/ns#" term="replication" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Установка Londiste в подробностях</title><content type="html">Этот пост содержит подробное пошаговое описание процесса настройки репликации на основе Londiste, системы асинхронной мастер-слэйв репликации из пакета SkyTools от Skype.&lt;br /&gt;&lt;br /&gt;Допустим есть 2 сервера - host1 и host2. На host1 работает кластер с одной или несколькими базами, которые необходимо реплицировать на host2. Другими словами host1 будет мастером, а host2 слейвом.&lt;br /&gt;&lt;br /&gt;Прежде всего необходимо установить пакет SkyTools. Его исходники можно найти на &lt;a href="https://developer.skype.com/SkypeGarage/DbProjects/SkyTools"&gt;официальном сайте проекта&lt;/a&gt; или в &lt;a href="http://wiki.postgresql.org/wiki/Skytools"&gt;wiki&lt;/a&gt;. Там же найдёте всю документацию и ссылки на дополнительные материалы. Советую обращаться к ним если захотите узнать дополнительные подробности о вещах, которых я буду в данной статье касаться поверхностно.&lt;br /&gt;&lt;br /&gt;Итак, всё ПО необходимое для репликации установлено, но, прежде чем начать настройку, хочу рассказать о принципах работы Londiste в очень общих словах.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;Londiste базируется на механизме очередей PgQ, который тоже входит в пакет SkyTools. Информация об изменениях данных попадает в эти очереди из спец-триггеров, навешиваемых на реплицируемые таблицы. PgQ, в свою очередь, основывается на пакетной обработке и использует так называемый ticker, утилиту (демон), генерирующую события готовности пачек данных. Эти события слушает демон Londiste и по их наступлению переносит пачки с мастера на слейв.&lt;br /&gt;&lt;br /&gt;Репликация на базе Londiste может работать по схеме - один мастер на несколько слейвов. В связи с этим я буду делать пометки, различающие установку репликации первого слейва и последующих. Также я буду различать репликацию отдельной базы и кластера целиком.&lt;br /&gt;&lt;br /&gt;Описанный процесс не требует даунтайма.&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;В данном описании будут часто встречаются обобщения более узких ситуаций, которые не тестировались во всех возможных вариантах. Так что прежде чем внедрять её в продакшн, тщательно протестируйте ваш процесс. Если вы найдёте какую-нибудь ошибку или не рабочую ситуацию, буду благодарен если сообщите.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;1. Первым делом подготовим мастер-сервер&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Пропустите этот пункт если репликация мастер-сервера уже есть.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;1.1. Права на мастере&lt;br /&gt;&lt;br /&gt;В данном примере все утилиты будут работать под системным пользователем postgres. Операции с БД я доверю также пользователю postgres (который в базе). Но в реальности будет правильнее сделать отдельного пользователя для этих утилит, смотрите по вашей ситуации.&lt;br /&gt;&lt;br /&gt;Дадим пользователю postgres доверительный доступ (без пароля) к базам на мастере со слейва.&lt;br /&gt;&lt;br /&gt;/var/lib/postgres/8.4/data/pg_hba.conf:&lt;br /&gt;&lt;code&gt;...&lt;br /&gt;# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD&lt;br /&gt;                                # host2 IP&lt;br /&gt;host    db1         postgres    192.168.10.2/32       trust&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Если реплицируются конкретные базы, а не весь инстанс, то добавьте такие записи для каждой из них. В случае же репликации всего инстанса достаточно одной записи, где в колонке DATABASE указываем all. Не забудьте сделать reload серверу.&lt;br /&gt;&lt;br /&gt;1.2. Настрока ticker-а&lt;br /&gt;&lt;br /&gt;Далее создадим файл конфигурации ticker-а.&lt;br /&gt;&lt;br /&gt;/etc/skytools/db1-ticker.ini:&lt;br /&gt;&lt;code&gt;[pgqadm]&lt;br /&gt;job_name = db1-ticker&lt;br /&gt;db = dbname=db1&lt;br /&gt;&lt;br /&gt;# Задержка между запусками обслуживания (ротация очередей и т.п.) в секундах&lt;br /&gt;maint_delay = 600&lt;br /&gt;&lt;br /&gt;# Задержка между проверками наличия активности (новых пакетов данных) в секундах&lt;br /&gt;loop_delay = 0.1&lt;br /&gt;logfile = /var/log/skytools/%(job_name)s.log&lt;br /&gt;pidfile = /var/run/skytools/%(job_name)s.pid&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Создайте подобные конфигурации для каждой реплицируемой базы. &lt;br /&gt;&lt;br /&gt;1.3. Запускаем ticker&lt;br /&gt;&lt;br /&gt;Теперь необходимо инсталлировать служебный код (SQL) и запустить ticker как демона для каждой из баз. Делается это с помощью утилиты pgqadm.py следующими командами:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python pgqadm.py /etc/skytools/db1-ticker.ini install&lt;br /&gt;python pgqadm.py /etc/skytools/db1-ticker.ini ticker -d&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Проверим, что в логах (/var/log/skytools/db1-tickers.log) всё нормально. На данном этапе там должны быть редкие записи (раз в минуту).&lt;br /&gt;&lt;br /&gt;2. Далее настроим слейв&lt;br /&gt;&lt;br /&gt;2.1. Убедимся что Londiste остановлен&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Это действие необходимо если вы раньше работали с Londiste на этом слейве.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py -s /etc/skytools/db1-londiste.ini&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Повторите для всех реплицируемых баз.&lt;br /&gt;&lt;br /&gt;2.2. Востанавливаем схему базы&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;В данном примере подразумевается что целевой инстанс не содержит баз с такими же именами как у реплицируемых.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Если реплицируются отдельные базы, то прежде всего необходимо &lt;a href="http://www.postgresql.org/docs/8.4/interactive/sql-createrole.html"&gt;создать пользователей&lt;/a&gt;, идентичных тем, которые работали с ними на мастере. Далее переносим схемы этих баз на слейв (повторяем для каждой):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;pg_dump -s -C -h host1 -U postgres db1 | &lt;br /&gt;psql -U postgres 1&gt;db1-restore.stdout 2&gt;db2-restore.stderr&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Если реплицируем инстанс целиком, то достаточно один раз сделать так:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;pg_dumpall -s -h host1 -U postgres | &lt;br /&gt;psql -U postgres 1&gt;all-restore.stdout 2&gt;all-restore.stderr&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Убедимся, что в лог-файлах *-restore.stderr отсутствуют ошибки кроме "роль postgres уже существует" (ч.г. не могу понять для чего вообще pg_dumpall дампит эту роль). &lt;br /&gt;&lt;br /&gt;2.3. Создаём конфигурацию репликатора &lt;br /&gt;&lt;br /&gt;Для каждой из реплицируемых баз создадим конфигурационные файлы:&lt;br /&gt;&lt;br /&gt;/etc/skytools/db1-londiste.ini:&lt;br /&gt;&lt;code&gt;[londiste]&lt;br /&gt;job_name = db1-londiste&lt;br /&gt;&lt;br /&gt;provider_db   = dbname=db1 port=5432 host=host1&lt;br /&gt;subscriber_db = dbname=db1&lt;br /&gt;&lt;br /&gt;# Это будет использоваться в качестве SQL-идентификатора, т.ч. не используйте&lt;br /&gt;# точки и пробелы.&lt;br /&gt;# ВАЖНО! Если есть живая репликация на другой слейв, именуем очередь так-же&lt;br /&gt;pgq_queue_name = db1-londiste-queue&lt;br /&gt;&lt;br /&gt;logfile = /var/log/skytools/%(job_name)s.log&lt;br /&gt;pidfile = /var/run/skytools/%(job_name)s.pid&lt;br /&gt;&lt;br /&gt;log_size = 5242880&lt;br /&gt;log_count = 3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2.4. Устанавливаем Londiste в базы на мастере и слейве&lt;br /&gt;&lt;br /&gt;Теперь необходимо установить служебный SQL для каждой из созданных в предыдущем пункте конфигураций.&lt;br /&gt;&lt;br /&gt;Устанавливаем код на стороне мастера:&lt;br /&gt;&lt;br /&gt;Замечание: &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Если установка Londiste на эту базу мастера уже была то для него не делаем.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini provider install&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;и подобным образом на стороне слейва:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini subscriber install&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;После этого пункта на мастере будут созданы очереди для репликации. &lt;br /&gt;&lt;br /&gt;2.5. Запускаем процессы Londiste&lt;br /&gt;&lt;br /&gt;Для каждой реплицируемой базы делаем:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini replay -d&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Таким образом запустятся слушатели очередей репликации, но, т.к. мы ещё не указывали какие таблицы хотим реплицировать, они пока будут работать в холостую. &lt;br /&gt;&lt;br /&gt;Убедимся что в логах нет ошибок (/var/log/skytools/db1-londistes.log).&lt;br /&gt;&lt;br /&gt;2.6. Добавляем реплицируемые таблицы&lt;br /&gt;&lt;br /&gt;Для каждой конфигурации указываем что будем реплицировать с мастера:&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Если указывали эти таблицы на мастере для другой репликации, то на мастере не делать.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini provider add --all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;и что со слейва:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini subscriber add --all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;В данном примере я использую спец-параметр --all, который означает все таблицы, но вместо него вы можете перечислить список конкретных таблиц, если не хотите реплицировать все.&lt;br /&gt;&lt;br /&gt;2.7. Добавляем реплицируемые последовательности (sequence)&lt;br /&gt;&lt;br /&gt;Так же для всех конфигураций.&lt;br /&gt;&lt;br /&gt;Для мастера:&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Опять же, если они уже добавлены на мастере, то не добавляем их там.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini provider add-seq --all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Замечание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;В версиях SkyTools до 2.1.9 включительно был обнаружен баг при добавлением последовательностей на мастере используя параметр --all, т.ч. если у вас такая версия используйте следующий хак:&lt;br /&gt; &lt;br /&gt;&lt;code&gt;for seq in $(&lt;br /&gt;  psql -t -A -U postgres toozla -c "\ds" |&lt;br /&gt;  awk -F '|' '{ if ($1 != "pgq" &amp;&amp; $1 != "londiste") { print $1"."$2 } }'); &lt;br /&gt;do&lt;br /&gt;  python londiste.py /etc/skytools/db1-londiste.ini provider add-seq $seq; &lt;br /&gt;done&lt;/code&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Для слейва:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini subscriber add-seq --all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Точно также как и с таблицами можно указать конкретные последовательности вместо --all.&lt;br /&gt;&lt;br /&gt;2.8. Проверка&lt;br /&gt;&lt;br /&gt;Итак, всё что надо сделано. Теперь Londiste запустит так называемый bulk copy процесс, который массово (с помощью COPY) зальёт присутствующие на момент добавления таблиц данные на слейв, а затем перейдёт в состояние обычной репликации.&lt;br /&gt;&lt;br /&gt;Мониторим логи на предмет ошибок:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;less /var/log/skytools/db1-londiste.log&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Если всё хорошо, смотрим состояние репликации. Данные уже синхронизированы для тех таблиц, где статус отображается как "ok".&lt;br /&gt;&lt;br /&gt;&lt;code&gt;python londiste.py /etc/skytools/db1-londiste.ini subscriber tables&lt;br /&gt;&lt;br /&gt;Table                                           State&lt;br /&gt;public.table1                                      ok&lt;br /&gt;public.table2                                      ok&lt;br /&gt;public.table3                                 in-copy&lt;br /&gt;public.table4                                       -&lt;br /&gt;public.table5                                       -&lt;br /&gt;public.table6                                       -&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Для удобства представляю следующий трюк с уведомление в почту об окончании первоначального копирования (мыло поменять на своё ;):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(&lt;br /&gt;  while [ $(&lt;br /&gt;    python londiste.py /etc/skytools/db1-londiste.ini subscriber tables |&lt;br /&gt;    tail -n+2 | awk '{print $2}' | grep -v ok | wc -l) -ne 0 ];&lt;br /&gt;  do sleep 60; done; echo '' | mail -s 'Replication done EOM' user@domain.com&lt;br /&gt;) &amp;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ссылки на публикации, которые мне помогли в написании этой статьи:&lt;br /&gt;&lt;br /&gt;SkyTools - PostgreSQL Wiki&lt;br /&gt;&lt;a href="http://wiki.postgresql.org/wiki/Skytools"&gt;http://wiki.postgresql.org/wiki/Skytools&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SkyTools - Skype Developer Zone&lt;br /&gt;&lt;a href="https://developer.skype.com/SkypeGarage/DbProjects/SkyTools"&gt;https://developer.skype.com/SkypeGarage/DbProjects/SkyTools&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;PostgreSQL master slave(s) asynchronous replication - tail -f /dev/dim&lt;br /&gt;&lt;a href="http://tapoueh.org/skytools.html"&gt;http://tapoueh.org/skytools.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-5071160137543355365?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/XKHbusD6PKg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/5071160137543355365/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/londiste.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/5071160137543355365?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/5071160137543355365?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/XKHbusD6PKg/londiste.html" title="Установка Londiste в подробностях" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/londiste.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4GRn4_fyp7ImA9WxFSEko.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-3170484526922763840</id><published>2010-04-14T22:48:00.004+04:00</published><updated>2010-04-14T23:22:07.047+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-14T23:22:07.047+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="Bruce Momjian" /><category scheme="http://www.blogger.com/atom/ns#" term="nosql" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Перенимаем NoSQL</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://momjian.us/main/blogs/pgblog/2010.html#April_10_2010_2"&gt;Learning from NoSQL&lt;/a&gt; с &lt;a href="http://momjian.us/main/blogs/pgblog/2010.html"&gt;Bruce Momjian: Postgres Blog&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Я думаю, что первый урок, который PostgreSQL сообщество может вынести из NoSQL, в том, что не всем нужны все наши возможности, и, если это не будет сложно, нам необходимо дать пользователям возможность отказаться от некоторых из них, в пользу желаемых NoSQL преимуществ. В некоторых случаях мы уже можем это сделать:&lt;br /&gt;&lt;br /&gt;- Вы можете улучшить скорость за счёт откладывания или отказа от надежности (synchronous_commit, fsync)&lt;br /&gt;- Вы можете убрать затраты на целостность не устанавливая ограничения (constraints)&lt;br /&gt;- Можете использовать подготовленные (prepared) запросы для устранения затрат на парсера и оптимизатора&lt;br /&gt;- Массивы часто могут быть использованы для ухода от затрат на join&lt;br /&gt;- Можно хранить не структурированные данные в hstore&lt;br /&gt;- Устаревшие данные можно обслуживать с помощью асинхронной мульти-мастер репликации (Bucardo)&lt;br /&gt;&lt;br /&gt;Однако есть некоторые вещи, которые будет сложно осуществить:&lt;br /&gt;&lt;br /&gt;- Доступ к данным без SQL&lt;br /&gt;- Снижение затрат за счёт отказа от атомарности и изоляции&lt;br /&gt;&lt;br /&gt;Я думаю о новых опциональных возможностях, которые мы могли бы предоставлять потенциальным NoSQL пользователям, но тут надо всё хорошо продумывать.&lt;br /&gt;&lt;br /&gt;Дополнение: Один из пунктов в нашем TODO-листе, который может помочь потенциальным NoSQL пользователям, это реализация встроенного типа данных JSON. JSON используется в качестве формата хранилища во многих NoSQL базах.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-3170484526922763840?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/Rlgw6cIKyo0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/3170484526922763840/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/nosql_14.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/3170484526922763840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/3170484526922763840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/Rlgw6cIKyo0/nosql_14.html" title="Перенимаем NoSQL" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>2</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/nosql_14.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8BQHc8fyp7ImA9WxFSEko.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-9195796115899563255</id><published>2010-04-14T22:14:00.003+04:00</published><updated>2010-04-14T22:47:31.977+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-14T22:47:31.977+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Bruce Momjian" /><category scheme="http://www.blogger.com/atom/ns#" term="cassandra" /><category scheme="http://www.blogger.com/atom/ns#" term="nosql" /><category scheme="http://www.blogger.com/atom/ns#" term="mongodb" /><category scheme="http://www.blogger.com/atom/ns#" term="translation" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Несколько слов о NoSQL</title><content type="html">&lt;span style="font-style:italic;"&gt;Перевод &lt;a href="http://momjian.us/main/blogs/pgblog/2010.html#April_10_2010"&gt;Settling for NoSQL&lt;/a&gt; с &lt;a href="http://momjian.us/main/blogs/pgblog/2010.html"&gt;Bruce Momjian: Postgres Blog&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;В последнее время вокруг NoSQL баз данных довольно много шума, и, багодаря посещению конференции &lt;a href="http://phillyemergingtech.com/"&gt;Emerging Technologies for the Enterprise Conference&lt;/a&gt;, я узнал о них больше. Я прослушал рассказ о &lt;a href="https://docs.google.com/viewer?url=http://cbcg.net/talks/Cassandra-PL.pdf"&gt;Cassandra&lt;/a&gt;, и ещё один о &lt;a href="http://dirolf.com/2010/04/09/introduction-to-mongodb.html"&gt;MongoDB&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;NoSQL базы имеют несколько отличий от реляционных:&lt;br /&gt;&lt;br /&gt;- "голое" обращение к данным, другими словами отсутствие языка запросов (клиент делает большинство того, что обычно делается с помощью SQL)&lt;br /&gt;- отсутствие join-ов (данные должны соединяться на стороне клиента)&lt;br /&gt;- жертвуется ACID и транзакционные свойства ради скорости, отказоустойчивости, простоты добавления/выведения нод&lt;br /&gt;&lt;br /&gt;Кого-то может смутить отсутствие этих значительных возможностей реляционных баз, но, если нужный вам отклик и требования к инфраструктуре не вписываются в рамки реляционных баз, и вы можете принять такие ограничения (думаю социальные медиа или поисковые движки), тогда NoSQL вполне имеет смысл.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-9195796115899563255?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/Ch-8xZPm9uQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/9195796115899563255/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/nosql.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/9195796115899563255?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/9195796115899563255?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/Ch-8xZPm9uQ/nosql.html" title="Несколько слов о NoSQL" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/nosql.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEFSHszcCp7ImA9WxFSEEo.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-6826080981454490025</id><published>2010-04-12T10:33:00.005+04:00</published><updated>2010-04-12T17:06:59.588+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-12T17:06:59.588+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="rule" /><category scheme="http://www.blogger.com/atom/ns#" term="cursor" /><category scheme="http://www.blogger.com/atom/ns#" term="view" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><category scheme="http://www.blogger.com/atom/ns#" term="Vhubuo" /><title>Как передать NEW из правила в хранимую функцию.</title><content type="html">Всё началось на форуме &lt;a href="http://www.sql.ru/forum/actualtopics.aspx?bid=7"&gt;sql.ru - PostgreSQL&lt;/a&gt;. Вопрос был следующим:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://www.sql.ru/forum/actualthread.aspx?tid=749450"&gt;Как передать NEW из правила в хранимую функцию?&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Описание:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Есть много представлений, в которых в базу записывается, например, адрес. И это везде происходит одинаково. Хочется вынести этот процесс в отдельную процедуру.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.dimka.lv/programmirovanie/postgresql-kak-peredat-new-iz-pravila-v-funkciyu/"&gt;Интересное генерализирующее решение&lt;/a&gt; на основе курсоров сегодня в своём блоге опубликовал автор этого вопроса - Vhubuo. Очень не обычный подход.&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/193160215117996166-6826080981454490025?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/Ktpy8Dw8ISI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/6826080981454490025/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/new.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/6826080981454490025?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/6826080981454490025?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/Ktpy8Dw8ISI/new.html" title="Как передать NEW из правила в хранимую функцию." /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/new.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MNSXs6cSp7ImA9WxFTFkg.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-2934421338394571245</id><published>2010-04-07T20:09:00.006+04:00</published><updated>2010-04-07T20:58:18.519+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-07T20:58:18.519+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="pg_xlog" /><category scheme="http://www.blogger.com/atom/ns#" term="junction" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><category scheme="http://www.blogger.com/atom/ns#" term="postgresql" /><title>Переносим pg_xlog на другой диск под Windows</title><content type="html">На днях на форуме &lt;a href="http://www.sql.ru/forum/actualtopics.aspx?bid=7"&gt;sql.ru - PostgreSQL&lt;/a&gt; был задан вопрос &lt;a href="http://www.sql.ru/forum/actualthread.aspx?tid=748766"&gt;о переносе pg_xlog под Windows&lt;/a&gt;. Т.к. вопрос актуален для России - 1С, Windows сервера, и т.п., решил сделать этот пост.&lt;br /&gt;&lt;br /&gt;Собственно особенность прцедуры переноса лишь в одном - символические ссылки.&lt;br /&gt;&lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;В Linux это делается просто встроенной командой "ln -s ...", а под Windows для их создания будет нужна &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx"&gt;вот эта программа (Junction)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Итак, опишу сам процесс по шагам. Допустим директория pgdata на диске D, и необходимо вынести WAL (pg_xlog) на диск C.&lt;br /&gt;&lt;br /&gt;Для этого надо:&lt;br /&gt;&lt;br /&gt;1. Остановить postgres&lt;br /&gt;2. Сделать бэкап D:\pgdata\pg_xlog&lt;br /&gt;3. Скопировать D:\pgdata\pg_xlog в C:\pg_xlog и удалить D:\pgdata\pg_xlog&lt;br /&gt;4. Распаковать программу &lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx"&gt;junction&lt;/a&gt; в D:\pgdata&lt;br /&gt;5. Открыть окно cmd, перейти там в D:\pgdata и выполнить junction -s pg_xlog C:\pg_xlog&lt;br /&gt;6. Теперь кликаем правой кнопкой на папке C:\pg_xlog и устанавливаем права на неё  пользователю postgres&lt;br /&gt;7. Запускаем postgres&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/193160215117996166-2934421338394571245?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/A52-4chjmk0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/2934421338394571245/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/pgxlog-windows.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2934421338394571245?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2934421338394571245?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/A52-4chjmk0/pgxlog-windows.html" title="Переносим pg_xlog на другой диск под Windows" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>1</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/pgxlog-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUDRn4_fSp7ImA9WxFTFU0.&quot;"><id>tag:blogger.com,1999:blog-193160215117996166.post-2276414378120244389</id><published>2010-04-05T19:36:00.003+04:00</published><updated>2010-04-06T02:57:57.045+04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-06T02:57:57.045+04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="q and a" /><category scheme="http://www.blogger.com/atom/ns#" term="pg_buffercache" /><category scheme="http://www.blogger.com/atom/ns#" term="buffers" /><category scheme="http://www.blogger.com/atom/ns#" term="Sergey Konoplev" /><category scheme="http://www.blogger.com/atom/ns#" term="russian" /><title>Использование страниц разделяемой памяти</title><content type="html">&lt;i&gt;Требуется расширение pg_buffercache.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Запрос помогает понять как используется разделяемая память разными сущностями.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;SELECT&lt;br /&gt;    c.relname, -- отношение&lt;br /&gt;    count(*) AS pages, -- количество страниц&lt;br /&gt;    -- использование страниц&lt;br /&gt;    sum((usagecount = 0)::int4) as "0",&lt;br /&gt;    sum((usagecount = 1)::int4) as "1",&lt;br /&gt;    sum((usagecount = 2)::int4) as "2",&lt;br /&gt;    sum((usagecount = 3)::int4) as "3",&lt;br /&gt;    sum((usagecount = 4)::int4) as "4",&lt;br /&gt;    sum((usagecount = 5)::int4) as "5"&lt;br /&gt;FROM&lt;br /&gt;    pg_buffercache b&lt;br /&gt;    INNER JOIN pg_class c ON&lt;br /&gt;        b.relfilenode = c.relfilenode AND&lt;br /&gt;        b.reldatabase IN (&lt;br /&gt;            0, (SELECT oid FROM pg_database WHERE datname = current_database())&lt;br /&gt;        )&lt;br /&gt;GROUP BY c.relname&lt;br /&gt;ORDER BY 2 DESC&lt;br /&gt;LIMIT 10;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/193160215117996166-2276414378120244389?l=gray-hemp.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/gray-hemp/~4/ZRU_gqgU3Ns" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://gray-hemp.blogspot.com/feeds/2276414378120244389/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://gray-hemp.blogspot.com/2010/04/blog-post.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2276414378120244389?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/193160215117996166/posts/default/2276414378120244389?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/gray-hemp/~3/ZRU_gqgU3Ns/blog-post.html" title="Использование страниц разделяемой памяти" /><author><name>gray_hemp</name><uri>http://www.blogger.com/profile/10468769612315616319</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://2.bp.blogspot.com/_jLPKwKvtcTk/S5-vci0mafI/AAAAAAAABn0/vol64Ft6NAo/s1600-R/AIbEiAIAAABECNzsj5LQnJ_RkwEiC3ZjYXJkX3Bob3RvKigyM2E3NjQyZmRjYTA3ZGM3Y2M2NjVlOWQ0MDYzMWI0ZGMyYmZlNjcyMAHRW11EZGB6qf4Mu2b2zNgfQmqlWg" /></author><thr:total>0</thr:total><feedburner:origLink>http://gray-hemp.blogspot.com/2010/04/blog-post.html</feedburner:origLink></entry></feed>

