<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>pastbedti.me &#187; Databases</title>
	<atom:link href="http://www.pastbedti.me/category/databases/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pastbedti.me</link>
	<description>About ruby, rails, postgresql and stuff....</description>
	<lastBuildDate>Fri, 02 Apr 2010 20:12:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Grouping a timestamp field by date in Ruby On Rails / PostgreSQL</title>
		<link>http://www.pastbedti.me/2009/11/grouping-a-timestamp-field-by-date-in-ruby-on-rails-postgresql/</link>
		<comments>http://www.pastbedti.me/2009/11/grouping-a-timestamp-field-by-date-in-ruby-on-rails-postgresql/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 00:55:09 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[timestamp]]></category>

		<guid isPermaLink="false">http://www.pastbedti.me/?p=563</guid>
		<description><![CDATA[Recently I&#8217;ve been working a lot with dates and tonight I had a hard time finding information about how to group a model by date when the model only have a timestamp column. 
Lets pretend we have a user model with a created_at attribute which is stored as a timestamp.
If we want to plot a [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been working a lot with dates and tonight I had a hard time finding information about how to group a model by date when the model only have a timestamp column. </p>
<p>Lets pretend we have a user model with a created_at attribute which is stored as a timestamp.</p>
<p>If we want to plot a simple graph showing signups per date this is the way to extract them:</p>
<p>[cc lang="ruby"]<br />
User.count(:group => &#8220;DATE(created_at)&#8221;)<br />
[/cc]</p>
<p>Thats all there is to it. From this you will get an OrderedHash containing the date and count of users for each date. </p>
<p>One small thing to remember if you are using PostgreSQL. You will need the DATE() function in any ORDER/SELECT statements because PostgreSQL will only select/order by fields thats in the GROUP BY statement and this is a  pretty healthy behavior that many databases (no names here) don&#8217;t care about. Think about it. If you are grouping all users by date and use * as selector how would the database know which username or email address to display?</p>
<p>This is what happens if you try to group by created_at without DATE() -></p>
<p>[cc lang="ruby"]<br />
>> User.count(:order => &#8216;created_at DESC&#8217;, :group => ["DATE(created_at)"])<br />
ActiveRecord::StatementInvalid: PGError: ERROR:  column &#8220;users.created_at&#8221; must appear in the GROUP BY clause or be used in an aggregate function<br />
: SELECT count(*) AS count_all, DATE(created_at) AS date_created_at FROM &#8220;users&#8221;  GROUP BY DATE(created_at)  ORDER BY created_at DESC<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:507:in `execute&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:985:in `select_raw&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb:972:in `select&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:255:in `execute_grouped_calculation&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:132:in `calculate&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:130:in `catch&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:130:in `calculate&#8217;<br />
        from /tmp/app/vendor/rails/activerecord/lib/active_record/calculations.rb:48:in `count&#8217;<br />
        from (irb):18<br />
[/cc]</p>
<p>And this is the right way to do it:</p>
<p>[cc lang="ruby"]<br />
>> User.count(:order => &#8216;DATE(created_at) DESC&#8217;, :group => ["DATE(created_at)"])<br />
=> #<OrderedHash {"2009-10-14"=>22, &#8220;2009-10-25&#8243;=>4, &#8220;2009-11-04&#8243;=>8, &#8220;2009-10-15&#8243;=>9, &#8220;2009-10-26&#8243;=>16, &#8220;2009-11-05&#8243;=>9, &#8220;2009-10-16&#8243;=>193, &#8220;2009-10-27&#8243;=>14, &#8220;2009-11-06&#8243;=>9, &#8220;2009-10-17&#8243;=>49, &#8220;2009-10-28&#8243;=>15, &#8220;2009-11-07&#8243;=>6, &#8220;2009-10-18&#8243;=>36, &#8220;2009-10-29&#8243;=>8, &#8220;2009-10-19&#8243;=>116, &#8220;2009-10-30&#8243;=>15>[/cc]</p>
<p>As you may notice the Hash does not look ordered. But if you loop over it you will get them in order:</p>
<p>[cc lang='ruby']<br />
>> User.count(:order => &#8216;DATE(created_at) DESC&#8217;, :group => ["DATE(created_at)"]).each {|u| puts &#8220;#{u[0]} -> #{u[1]}&#8221; }<br />
2009-11-07 -> 6<br />
2009-11-06 -> 9<br />
2009-11-05 -> 9<br />
2009-11-04 -> 8<br />
2009-11-03 -> 14<br />
2009-11-02 -> 20<br />
2009-11-01 -> 10<br />
2009-10-31 -> 6<br />
2009-10-30 -> 15<br />
2009-10-29 -> 8<br />
..<br />
[/cc]</p>
<p>And thats how you group a timestamp field with just its date part.</p>
<p>Cheers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2009/11/grouping-a-timestamp-field-by-date-in-ruby-on-rails-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running couchdb under an unprivileged user account.</title>
		<link>http://www.pastbedti.me/2009/04/running-couchdb-under-an-unprivileged-user-account/</link>
		<comments>http://www.pastbedti.me/2009/04/running-couchdb-under-an-unprivileged-user-account/#comments</comments>
		<pubDate>Fri, 10 Apr 2009 18:23:55 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[couchdb]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[unprivileged]]></category>

		<guid isPermaLink="false">http://www.pastbedti.me/?p=423</guid>
		<description><![CDATA[When helping a friend last night with couchdb a got stuck when trying to start it as an unprivileged user. The error messages you get from couchdb is far from easy to understand. 
This is my way of solving it.

[cc console]
$ couchdb
kernel-poll not supported; &#8220;K&#8221; parameter ignored
Apache CouchDB 0.9.0 (LogLevel=info) is starting.
{&#8220;init terminating in do_boot&#8221;,{{badmatch,{error,shutdown}},[{couch_server_sup,start_server,1},{erl_eval,do_apply,5},{erl_eval,exprs,5},{init,start_it,1},{init,start_em,1}]}}
Crash [...]]]></description>
			<content:encoded><![CDATA[<p>When helping a friend last night with couchdb a got stuck when trying to start it as an unprivileged user. The error messages you get from couchdb is far from easy to understand. </p>
<p>This is my way of solving it.<br />
<span id="more-423"></span></p>
<p>[cc console]<br />
$ couchdb<br />
kernel-poll not supported; &#8220;K&#8221; parameter ignored<br />
Apache CouchDB 0.9.0 (LogLevel=info) is starting.<br />
{&#8220;init terminating in do_boot&#8221;,{{badmatch,{error,shutdown}},[{couch_server_sup,start_server,1},{erl_eval,do_apply,5},{erl_eval,exprs,5},{init,start_it,1},{init,start_em,1}]}}</p>
<p>Crash dump was written to: erl_crash.dump<br />
init terminating in do_boot ()<br />
[/cc]</p>
<p>Even with debug turned on it&#8217;s pretty hard to understand.</p>
<p>[cc console]<br />
kernel-poll not supported; &#8220;K&#8221; parameter ignored<br />
Apache CouchDB 0.9.0 (LogLevel=debug) is starting.<br />
Configuration Settings ["./couchdb/local.ini"]:<br />
  [Couch] BindAddress=&#8221;127.0.0.1&#8243;<br />
  [Couch] ConsoleStartupMsg=&#8221;Apache CouchDB is starting.&#8221;<br />
  [Couch] DbRootDir=&#8221;/home/mathias/couchdb&#8221;<br />
  [Couch] DocumentRoot=&#8221;/home/mathias/couchdb/www&#8221;<br />
  [Couch] LogFile=&#8221;/home/mathias/couchdb/couch.log&#8221;<br />
  [Couch] LogLevel=&#8221;debug&#8221;<br />
  [Couch] Port=&#8221;5984&#8243;<br />
  [Couch] UtilDriverDir=&#8221;/usr/local/lib/couchdb/erlang/lib/couch-0.8.1-incubating/priv/lib&#8221;<br />
  [Couch Query Servers] javascript=&#8221;/usr/local/bin/couchjs /usr/local/share/couchdb/server/main.js&#8221;<br />
  [couchdb] database_dir=&#8221;/home/mathias/couchdb&#8221;<br />
  [couchdb] view_index_dir=&#8221;/home/mathias/couchdb&#8221;<br />
  [httpd] bind_address=&#8221;127.0.0.1&#8243;<br />
  [httpd] port=&#8221;5984&#8243;<br />
  [log] level=&#8221;debug&#8221;<br />
[error] [<0.41.0>] {error_report,<0.21.0>,<br />
    {<0.41.0>,crash_report,<br />
     [[{pid,<0.41.0>},<br />
       {registered_name,couch_server},<br />
       {error_info,<br />
           {exit,<br />
               {badarg,<br />
                   [{erlang,list_to_integer,[undefined]},<br />
                    {couch_server,init,1},<br />
                    {gen_server,init_it,6},<br />
                    {proc_lib,init_p_do_apply,3}]},<br />
               [{gen_server,init_it,6},{proc_lib,init_p_do_apply,3}]}},<br />
       {initial_call,{couch_server,init,['Argument__1']}},<br />
       {ancestors,[couch_primary_services,couch_server_sup,<0.1.0>]},<br />
       {messages,[]},<br />
       {links,[<0.36.0>]},<br />
       {dictionary,[]},<br />
       {trap_exit,false},<br />
       {status,running},<br />
       {heap_size,233},<br />
       {stack_size,23},<br />
       {reductions,113}],<br />
      []]}}<br />
{&#8220;init terminating in do_boot&#8221;,{{badmatch,{error,shutdown}},[{couch_server_sup,start_server,1},{erl_eval,do_apply,5},{erl_eval,exprs,5},{init,start_it,1},{init,start_em,1}]}}</p>
<p>Crash dump was written to: erl_crash.dump<br />
init terminating in do_boot ()<br />
[/cc]</p>
<p>When running things as unprivileged users the usual problems are that you do not have access to read/write files or binding to the lower ports A.K.A. &#8220;well known ports&#8221;.  With that in mind I located the original config files for couchdb with the plan of copying or overriding them. </p>
<p>My config files where located under <strong>/usr/local/etc/couchdb/</strong></p>
<p>[cc console]<br />
$ ls -lsa /usr/local/etc/couchdb/<br />
4 -rw-r&#8211;r&#8211; 1 root root 2626 2009-04-10 11:58 default.ini<br />
4 -rw-r&#8211;r&#8211; 1 root root  847 2009-04-10 14:17 local.ini<br />
[/cc]</p>
<p>Reading the documentation I found out that local.ini is just for overriding stuff and local.ini will never be overwritten by any upgrades. The config files contain lots of settings, but my aim is just to get it to start so I focus on the things that I think is the problem and thats all the PATH settings. </p>
<p>In my  unprivileged users home folder I created a folder named couchdb to hold my config and datafiles. I also created a www folder inside it. </p>
<p>After that I create my local.ini to override my settings:</p>
<p>[cc console]<br />
$ cat couchdb/local.ini </p>
<p>[couchdb]<br />
database_dir = ./couchdb<br />
view_index_dir = ./couchdb</p>
<p>[httpd]<br />
port = 5984<br />
bind_address = 127.0.0.1</p>
<p>[log]<br />
level = info<br />
file=./couchdb/couch.log<br />
[/cc]</p>
<p>When our new config is in place we can try to start couchdb again. </p>
<p>[cc console]<br />
$ couchdb -C ./couchdb/local.ini -p ./couchdb/couch.pid -b<br />
Apache CouchDB has started, time to relax.<br />
[/cc]</p>
<p><strong>-C</strong> means use configuration FILE (chainable, does not reset system default). If we do not want to use the system config at all we can use a lowercase -c but we want to keep our overridden config as small as possible right now.</p>
<p><strong>-p</strong> is the path to our pid file and <strong>-b</strong> tells couchdb to spawn in the background.</p>
<p>If you are on your local machine you can just launch your browser and point it to <a href="http://127.0.0.1:5984/">http://127.0.0.1:5984/</a></p>
<p>[cc json]<br />
{&#8220;couchdb&#8221;:&#8221;Welcome&#8221;,&#8221;version&#8221;:&#8221;0.9.0&#8243;}<br />
[/cc]</p>
<p>or you can access the admin gui trough: <a href="http://127.0.0.1:5984/_utils/index.html">http://127.0.0.1:5984/_utils/index.html</a>.</p>
<p>After I started to write this blogpost I did found a page on the Couchdb wiki that explains Error messages and solutions and here it is: <a href="http://wiki.apache.org/couchdb/Error_messages">http://wiki.apache.org/couchdb/Error_messages</a>.</p>
<p>Happy haxxing! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2009/04/running-couchdb-under-an-unprivileged-user-account/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PostgreSQL logging with syslog-ng</title>
		<link>http://www.pastbedti.me/2008/12/postgresql-logging-with-syslog-ng/</link>
		<comments>http://www.pastbedti.me/2008/12/postgresql-logging-with-syslog-ng/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 22:25:16 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[pgFouine]]></category>
		<category><![CDATA[syslog ng]]></category>

		<guid isPermaLink="false">http://www.pastbedti.me/?p=293</guid>
		<description><![CDATA[Today I where about to analyze a PostgreSQL database with the wonderful pgFouine. On the machine syslog-ng where  installed as logging daemon and I have never worked with PostgreSQL logging and syslog-ng. This post is about how to get them to work together. 

pgFouine is pretty simple to setup and the process is where [...]]]></description>
			<content:encoded><![CDATA[<p>Today I where about to analyze a PostgreSQL database with the wonderful <a href="http://pgfouine.projects.postgresql.org/">pgFouine</a>. On the machine syslog-ng where  installed as logging daemon and I have never worked with PostgreSQL logging and syslog-ng. This post is about how to get them to work together. </p>
<p><span id="more-293"></span></p>
<p>pgFouine is pretty simple to setup and the process is where well documented at their website (<a href="http://pgfouine.projects.postgresql.org/tutorial.html">http://pgfouine.projects.postgresql.org/tutorial.html</a>).</p>
<p>However syslog-ng is very different if you are used to &#8220;normal&#8221; syslog daemon. </p>
<p>The first thing you have to do is setup PostgreSQL as the instructions says on the website. The next step is to tell syslog-ng to log you postgres data to a separate file.</p>
<p>The first thing to create in syslog-ng.conf is a destination. Destination blocks is used to send logs somewhere.</p>
<p>By adding the following row we tell syslog-ng that there is a destination called postgres and that we want this data in /var/log/pgsql.</p>
<p>[cc lang="bash"]<br />
destination postgres { file(&#8220;/var/log/pgsql&#8221;); };<br />
[/cc]</p>
<p>Now we are ready to add a filter to caputre our PostgreSQL data. Filters can both be used to include or exclude data from you logs. The following row in your syslog-conf captures all data sent to local0 or whatever you called it in postgresql.conf <img src='http://www.pastbedti.me/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>[cc lang="bash"]<br />
filter f_postgres { facility(local0); };<br />
[/cc]</p>
<p>It&#8217;s time to join our destination with our filter and the following line tells syslog-ng to join our source, destination and filter together.</p>
<p>[cc lang="bash]<br />
log { source(src); filter(f_postgres); destination(postgres); };<br />
[/cc]</p>
<p>Put these lines in your syslog-ng.conf and restart syslog-ng and also PostgreSQL and you will have logging in a separate file! </p>
<p>Next step is to write a little guide to pgFouine <img src='http://www.pastbedti.me/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Cheers! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2008/12/postgresql-logging-with-syslog-ng/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reset/recover MySQL root password in freebsd</title>
		<link>http://www.pastbedti.me/2008/11/resetrecover-mysql-root-password-in-freebsd/</link>
		<comments>http://www.pastbedti.me/2008/11/resetrecover-mysql-root-password-in-freebsd/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 14:49:16 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[passwords]]></category>

		<guid isPermaLink="false">http://www.pastbedti.me/?p=219</guid>
		<description><![CDATA[This is a little memory note for my self and hopefully it can help someone else how to reset MySQL root password. 
It happens that we are asked to do some work on our customers dedicated servers and when that happens it&#8217;s not that uncommon that there is not a single person alive that has [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a little memory note for my self and hopefully it can help someone else how to reset MySQL root password.</em> </p>
<p>It happens that we are asked to do some work on our customers dedicated servers and when that happens it&#8217;s not that uncommon that there is not a single person alive that has the root password for the MySQL server. When that happen it&#8217;s good to know how to reset it <img src='http://www.pastbedti.me/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>This post is about how simple it&#8217;s to reset MySQL&#8217;s root password under FreeBSD.<br />
<span id="more-219"></span></p>
<p>The first step is to start MySQL without it&#8217;s grant tables.</p>
<p>Under FreeBSD you pass your mysql startup parameters in /etc/rc.conf</p>
<p>Add the following to /etc/rc.conf. We add &#8211;skip-networking to because we do not want someone from the outside to connect without passwords to our server.</p>
<p>[cc lang="bash"]<br />
mysql_enable=&#8221;YES&#8221;<br />
mysql_args=&#8221;&#8211;skip-grant-tables &#8211;skip-networking&#8221;<br />
[/cc]</p>
<p>And then restart MySQL with the following command.</p>
<p>[cc lang="bash"]<br />
> /usr/local/etc/rc.d/mysql-server restart<br />
[/cc]</p>
<p>When MySQL comes back online it&#8217;s running without grant tables which means that you do not have to use a password to connect to it (no one has to).</p>
<p>Simply connect as root (without password) and issue the following SQL query.</p>
<p>[cc lang="sql"]<br />
> mysql -u root mysql</p>
<p>mysql> UPDATE mysql.user SET Password=PASSWORD(&#8216;<Your new password>&#8216;) WHERE User=&#8217;root&#8217;;<br />
[/cc]</p>
<p>Now we are almost done. Just comment the skip-grant-tables line from rc.conf and restart MySQL and you should have a brand new root password. </p>
<p>For for other *nix users the process is the same except from how you pass your MySQL params to MySQL at startup. You can also start MySQL manually with something like this.</p>
<p>[cc lang="bash"]</p>
<path to safe_mysqld>/safe_mysqld &#8211;user=mysql &#8211;skip-grant-tables &#8211;skip-networking &#038;<br />
[/cc]</p>
<p>Cheers! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2008/11/resetrecover-mysql-root-password-in-freebsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interesting use of SSD drives with PostgreSQL</title>
		<link>http://www.pastbedti.me/2008/08/interesting-use-of-ssd-drives-with-postgresql/</link>
		<comments>http://www.pastbedti.me/2008/08/interesting-use-of-ssd-drives-with-postgresql/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 10:47:19 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[links]]></category>

		<guid isPermaLink="false">http://www.pastbedti.me/?p=106</guid>
		<description><![CDATA[These are two interesting articles/benchmarks about how you can use SSD drives for storing postgres indexes on them.

SSD vs. SATA RAID: A performance benchmark
SSD vs. SATA benchmarks, round 2: Server applications

The low low seek times on a SSD drives make it a perfect candidate for the indexes.
 
]]></description>
			<content:encoded><![CDATA[<p>These are two interesting articles/benchmarks about how you can use SSD drives for storing postgres indexes on them.</p>
<ul>
<li><a href="http://www.linux.com/feature/142657" target="_blank">SSD vs. SATA RAID: A performance benchmark</a></li>
<li><a href="http://www.linux.com/feature/142658" target="_blank">SSD vs. SATA benchmarks, round 2: Server applications</a></li>
</ul>
<div>The low low seek times on a SSD drives make it a perfect candidate for the indexes.</div>
<div> </div>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2008/08/interesting-use-of-ssd-drives-with-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Postgresql table sizes</title>
		<link>http://www.pastbedti.me/2008/03/postgresql-table-sizes/</link>
		<comments>http://www.pastbedti.me/2008/03/postgresql-table-sizes/#comments</comments>
		<pubDate>Sun, 16 Mar 2008 18:40:10 +0000</pubDate>
		<dc:creator>Mathias Stjernström</dc:creator>
				<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://stjernstromblog.cust.globalinn.com/?p=7</guid>
		<description><![CDATA[PostgreSQL has lots and lots of sweet internals but its not always easy to know how to find them.  Here is an simple way of getting the disk size of a PostgreSQL table.

From within the database of choice.
Run the following query to get some useful table statistics.
[cc lang="html"]
SELECT relname, reltuples, relpages * 8 / [...]]]></description>
			<content:encoded><![CDATA[<p>PostgreSQL has lots and lots of sweet internals but its not always easy to know how to find them.  Here is an simple way of getting the disk size of a PostgreSQL table.</p>
<p><span id="more-7"></span></p>
<p>From within the database of choice.</p>
<p>Run the following query to get some useful table statistics.<br />
[cc lang="html"]<br />
SELECT relname, reltuples, relpages * 8 / 1024 AS &#8220;MB&#8221; FROM pg_class ORDER BY relpages DESC;<br />
[/cc]</p>
<h2>Block size</h2>
<p>If you use another block size than 8kb you have do multiply relpages with your own block size. To find your block size you can use <strong>pg_controldata</strong> which is a command-line utility to display control information of a PostgreSQL database cluster.</p>
<p>Run it with your datadir as first parameter <strong>pg_controldata ./data/</strong> and look for <strong>Database block size</strong> in the output.</p>
<p>Database query result</p>
<p>The outout gives you:</p>
<ol>
<li>relname: The name of the table.</li>
<li>reltuples: Estimated numbers of rows.</li>
<li>MB: Table size in Mbytes.</li>
</ol>
<p>[cc lang="html"]<br />
relname              |  reltuples  |  MB<br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;-+&#8212;&#8212;-<br />
history_uint                      |   1.685e+08 | 15396<br />
history_uint_1                    |   1.685e+08 | 12279<br />
history                           | 1.40719e+08 |  8405<br />
history_1                         | 1.40719e+08 |  7153<br />
trends                            | 1.03077e+07 |   929<br />
trends_pkey                       | 1.03077e+07 |   423<br />
items                             |        4698 |    83<br />
history_str                       |      536599 |    53<br />
history_str_1                     |      536599 |    27<br />
events                            |      166602 |    15<br />
[/cc]</p>
<p>We can now see that history_uint is the biggest table and holds an estimate of 168,572,082 rows and takes about 15GB on disk.</p>
<p><strong>Be aware that these numbers only gets updated when you run vacuum.</strong></p>
<p>I have more PostgreSQL internals to come!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pastbedti.me/2008/03/postgresql-table-sizes/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
