2011-01-21 50 views
7

哈羅所有的計算總和,PostgreSQL數據庫的大小(表空間大小)更大然後關係

我看到實際的數據庫大小之間存在非常大的差異(在硬盤上,並通過pg_database_size()來電顯示)和大小,通過總結由pg_total_relation_size()檢索的總關係大小來計算。

首先是62G,最後是16G(右從最大的表中刪除的數據的差)

下面是一個簡單的查詢,可以顯示我的系統上的區別:

select current_database(), 
     pg_size_pretty(sum(total_relation_raw_size)::bigint) as calculated_database_size, 
     pg_size_pretty(pg_database_size(current_database())) as database_size 
    from (select pg_total_relation_size(relid) as total_relation_raw_size 
      from pg_stat_all_tables -- this includes also system tables shared between databases 
     where schemaname != 'pg_toast' 
     ) as stats; 

看來這裏有一些懸而未決的數據。出現這種情況後,我們傾倒並徹底清除了該數據庫中大量未使用的數據。

PS:我想,這是某種形式的數據庫損壞......從這種情況下恢復的唯一辦法是切換到熱備用數據庫...

+0

你能舉一個大小和差異的例子嗎?哪一個更大? – 2011-01-21 21:44:43

+0

O,對不起,我忘了提及實數: 62G用於`pg_database_size()`顯示的數據庫大小; 17G用於關係大小的總和 – valgog 2011-01-23 10:08:14

回答

1

你有閒置的LOB ?

如果你有這樣的事情:在數據庫中

\lo_import '/tmp/bigfile' 
11357 
INSERT INTO bigobjects VALUES (1, 'bigfile', 11357); 
TRUNCATE TABLE bigobjects; 

你仍然有LOB(ID 11357):

CREATE TABLE bigobjects (
    id BIGINT NOT NULL PRIMARY KEY, 
    filename VARCHAR(255) NOT NULL, 
    filecontents OID NOT NULL 
); 

其次。

您可以檢查所有的大型物體的pg_catalog.pg_largeobject系統目錄表在數據庫中(建議除非你想看到你的所有LOB數據作爲八進制SELECT DISTINCT霧狀FROM pg_catalog.pg_largeobject。)

如果您清理所有未使用的LOB並做一個VACUUM FULL,你應該看到存儲量的巨大減少。我剛剛在我一直使用的個人開發數據庫上嘗試過這種方法,並且發現其大小從200MB降低到10MB(由pg_database_size(current_database())報告。)

+0

由於`pg_largeobject`出現在`pg_stat_all_tables`中,因此大對象仍然會在問題的查詢中計數。 – 2011-01-21 21:40:40

+0

您可以通過執行此查詢來驗證Peter所說的內容:`SELECT relname,PG_SIZE_PRETTY(PG_TOTAL_RELATION_SIZE(relid))FROM pg_stat_all_tables WHERE schemaname!='pg_toast'AND relname LIKE'pg_%'ORDER BY PG_TOTAL_RELATION_SIZE(relid)DESC;`pg_largeobject shows bigobjects表(和其他BLOB)的總BLOB大小。 – jmz 2011-02-23 09:18:40

0

您的查詢是專門篩選出pg_toast表,這可能很大。看看是否擺脫那個schemaname != 'pg_toast'讓你更準確的答案。

1

當這種情況出現後,我們傾倒並完全清除了該數據庫中大量未使用的數據。

我有類似的經驗:3GB的數據庫,有大量的動態數據,一個月左右時間達到了20GB。 手動刪除/真空的問題表不縫有效果.. 然後,我們只是做了最後

VACUUM FULL ANALYZE 

對整個數據庫...它下降一半大小。

花了4小時,所以要小心。

2

當BobG寫入時,LOB是非常有效的問題,因爲當您的應用程序表(包含OID)的行被刪除時,它們不會被刪除。

這些不會被VACUUM過程自動刪除,只有你已經對它們運行了VACUUMLO。

Vacuumlo將從數據庫中刪除所有未引用的LOB。

調用示例:

vacuumlo -U postgres -W -v <database_name> 

(我只包括了-v使vacuumlo一點更詳細的讓你看它有多少的LOB刪除)

vacuumlo已經刪除了的LOB,你以後可以運行VACUUM FULL(或讓自動真空過程運行)。