2014-04-16 10 views
7

Mam tabelę, która zawiera dwa pola tekstowe, które zawierają dużo tekstu. Z jakiegoś powodu nasz stół zaczął rosnąć wykładniczo. Podejrzewam, że TOAST (kompresja dla pól tekstowych w postgresie) nie działa automatycznie. W naszej definicji tabeli nie zdefiniowaliśmy żadnej klauzuli wymuszającej kompresję tych pól. Czy istnieje sposób sprawdzenia, czy kompresja działa na tym stole, czy nie?Jak sprawdzić, czy TOAST działa na konkretnej tabeli w postgresie

+0

Czy odkurzasz regularnie? – SingleNegationElimination

+0

Tak auto próżnia działa regularnie. Ale stół nadął się od 80G do 165G w ciągu 5 dni, a następnie uruchomiliśmy pełną próżnię, a rozmiar tego stołu zmniejszył się do 19G. Ale znowu jego nadęty z wykładniczą prędkością. – jindal

Odpowiedz

7

From the docs. . .

Jeżeli którykolwiek z kolumn tabeli są TOAST-stanie, tabela będzie miała skojarzony stołowego tosty, którego OID jest przechowywany w tabeli za pg_class.reltoastrelid wpisu. Wartości TOASTed w trybie out-line są przechowywane w tabeli TOAST , jak opisano bardziej szczegółowo poniżej.

Dzięki temu można ustalić, czy istnieje tabela TOAST, wysyłając zapytanie do pg_class system catalog. To powinno zbliżyć Cię do tego, czego szukasz.

select t1.oid, t1.relname, t1.relkind, t2.relkind, t2.relpages, t2.reltuples 
from pg_class t1 
inner join pg_class t2 
on t1.reltoastrelid = t2.oid 
where t1.relkind = 'r' 
    and t2.relkind = 't'; 

W psql można użyć \d+. Użyję katalogu systemowego pg_class jako przykładu; użyjesz własnej nazwy tabeli.

sandbox=# \d+ pg_class 
    Column  | Type | Modifiers | Storage | Stats target | Description 
----------------+-----------+-----------+----------+--------------+------------- 
relname  | name  | not null | plain |    | 
relnamespace | oid  | not null | plain |    | 
[snip] 
relacl   | aclitem[] |   | extended |    | 
reloptions  | text[] |   | extended |    | 

Gdzie Storage „rozszerzony”, PostgreSQL będzie próbował zmniejszyć rozmiar wiersza poprzez kompresję, następnie przechowując dane z linii. Tam, gdzie Storage jest "głównym" (nie pokazano), PostgreSQL spróbuje skompresować.

W danym przypadku przydatnym może okazać się monitorowanie zmian w czasie. Możesz użyć tego zapytania i zapisać wyniki do późniejszej analizy.

select table_catalog, table_schema, table_name, 
     pg_total_relation_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_total_relation_size, 
     pg_relation_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_relation_size, 
     pg_table_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_table_size 
from information_schema.tables 

PostgreSQL admin functions zawiera informacje o tym, co każda funkcja zawiera w swoich obliczeniach.

0

Jeśli odkurzanie rhe table obnaża go do 19 GB z 80 GB, prawdopodobnie widzisz w pracy MVCC: martwe rzędy zajmują miejsce do odkurzania lub ponownego użycia.

http://wiki.postgresql.org/wiki/MVCC

+0

System ten działał dobrze przez długi czas. Nagle zaczęło się to wydarzenie. – jindal

+0

Być może ostatnio miałeś niezwykłe ilości wpisów db? Vacuum i TOAST "working" są, według mojej najlepszej wiedzy, w żaden sposób nie skorelowane. Jedynym realistycznym wytłumaczeniem, jakie mogę sobie wyobrazić, jest pięciokrotny wzrost rozmiaru bazy danych: MVCC i martwe rzędy odkurzane, które leżą po rozdawaniu stron (zobacz dokumentację PG na temat tworzenia współczynnika wypełnienia). –

+0

Na wszelki wypadek, gdy nie było to wystarczająco jasne: mam na myśli to, że to, co widzisz, może być normalne *: rozmiar bazy danych powinien ustabilizować się (oczywiście nowe wpisy), w dłuższej perspektywie; możesz zauważyć dzikie huśtawki, ponieważ zrobiłaś próżnię pełną i zacząłeś stamtąd monitorować, zamiast ustawiać kij stoczni po kilku dniach lub tygodniach pracy. –

0

To jest stare, ale ostatnio miałem powodzenie z podobnym problemem. ANALYZE VERBOSE ujawniło, że kilka naszych stołów urosło do> 1 strony dysku na krotkę, a EXPLAIN ANALYZE ujawniło, że sekwencyjne skanowanie trwało do 30 sekund na stole o rzędach 27K. Szacunki liczby aktywnych wierszy zaczęły się coraz bardziej zmniejszać.

Po wielu poszukiwaniach dowiedziałem się, że wiersze można odkurzać tylko wtedy, gdy nie ma transakcji, która została otwarta od czasu ich aktualizacji. Ta tabela była przepisywana co 3 minuty, a było połączenie, które było "bezczynne w transakcji", które miało 3 dni. Możesz zrobić matematykę.

W tym przypadku mieliśmy do

  1. zabić połączenia z otwartej transakcji
  2. ponownego podłączenia do bazy danych. Niestety, maksymalny identyfikator transakcji dla wierszy, które można odkurzyć, jest obecnie (jak 9.3) zapisany w połączeniu, więc próżnia pełna nie zadziała.
  3. VACUUUM PEŁNY swój stół (to spowoduje wyjęcie blokady dostępu, która zablokuje wszystko, w tym odczyty.Możesz chcieć uruchomić VACUUM pierwszy (bez blokowania), aby przyspieszyć czas VACUUM FULL bierze).

To nie mógł być twój problem, ale jeśli chciałbyś sprawdzić, czy tabele mają wpływ na twoją własną bazę danych, napisałem zapytanie, by uporządkować tabele według średniej liczby krotek zapisanych na stronie dysku. Tabele z dużymi rzędami powinny znajdować się na górze - ANALYZE VERBOSE powinno dać ci pojęcie stosunku kumulacji martwych do żywych w tych tabelach. Ważny do 9,3 - to prawdopodobnie będzie wymagało kilku drobnych poprawek dla innych wersjach:

SELECT rolname AS owner, 
     nspname AS schemaname 
    , relname AS tablename 
    , relpages, reltuples, (reltuples::FLOAT/relpages::FLOAT) AS tuples_per_page 
FROM pg_class 
JOIN pg_namespace ON relnamespace = pg_namespace.oid 
JOIN pg_roles  ON relowner  = pg_roles.oid 
WHERE relkind = 'r' AND relpages > 20 AND reltuples > 1000 
    AND nspname != 'pg_catalog' 
ORDER BY tuples_per_page; 
1

można zobaczyć, jakie kwerendy działa PSQL uruchamiając go z parametrem -E, to działa normalne polecenia:

w tym Przykładowo, który zstąpił na to, po pierwsze, wyszukiwanie stolika za oid:

SELECT c.oid, 
    n.nspname, 
    c.relname 
FROM pg_catalog.pg_class c 
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
WHERE c.relname ~ '^(YOUR_TABLE_NAME_HERE)$' 
    AND pg_catalog.pg_table_is_visible(c.oid) 
ORDER BY 2, 3; 

to wykonuje to do wyszukiwania więcej statystyk o tym:

SELECT a.attname,                                   pg_catalog.format_type(a.atttypid, a.atttypmod), 
    (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) 
    FROM pg_catalog.pg_attrdef d 
    WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), 
    a.attnotnull, a.attnum, 
    (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t 
    WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation, 
    NULL AS indexdef, 
    NULL AS attfdwoptions, 
    a.attstorage, 
    CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget, pg_catalog.col_description(a.attrelid, a.attnum) 
FROM pg_catalog.pg_attribute a 
WHERE a.attrelid = '57692' AND a.attnum > 0 AND NOT a.attisdropped 
ORDER BY a.attnum; 

x.attrstorage jest tym, co Cię interesuje, p jest ZWYKŁA, x jest PRZEDŁUŻONYM Idę o zakład.

Powiązane problemy