PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL - wiederhergestellte Datenbank kleiner als das Original

Die kurze Antwort lautet, dass der Datenbankspeicher mehr auf Geschwindigkeit als auf Platz optimiert ist.

Wenn Sie beispielsweise 100 Zeilen in eine Tabelle eingefügt und dann jede Zeile mit einer ungeraden ID gelöscht haben, könnte das DBMS eine neue Tabelle mit nur 50 Zeilen schreiben, aber es ist effizienter, die gelöschten Zeilen einfach als freien Speicherplatz zu markieren und beim nächsten Einfügen einer Zeile wiederverwenden. Daher nimmt der Tisch doppelt so viel Platz ein, wie derzeit benötigt wird.

Die Verwendung von "MVCC" durch Postgres anstelle von Sperren für die Transaktionsverwaltung macht dies noch wahrscheinlicher, da ein UPDATE normalerweise das Schreiben einer neuen Zeile in den Speicher und das anschließende Markieren der alten Zeile als gelöscht beinhaltet, sobald keine Transaktionen darauf zugreifen.

Indem Sie die Datenbank sichern und wiederherstellen, erstellen Sie eine Datenbank ohne all diesen freien Speicherplatz neu. Dies ist im Wesentlichen das, was VACUUM FULL Befehl tut - er schreibt die aktuellen Daten in eine neue Datei um und löscht dann die alte Datei.

Es gibt eine Erweiterung, die mit Postgres namens pg_freespace vertrieben wird wodurch Sie einiges davon untersuchen können. z.B. Sie können die Haupttabellengröße (ohne Indizes und Spalten, die in separaten "TOAST"-Tabellen gespeichert sind) und den freien Speicherplatz, der von jeder Tabelle verwendet wird, mit dem Folgenden auflisten:

Select oid::regclass::varchar as table,
      pg_size_pretty(pg_relation_size(oid)/1024 * 1024) As size,
      pg_size_pretty(sum(free)) As free
 From (
   Select c.oid,
       (pg_freespace(c.oid)).avail As free
     From pg_class c
     Join pg_namespace n on n.oid = c.relnamespace
    Where c.relkind = 'r'
      And n.nspname Not In ('information_schema', 'pg_catalog')
 ) tbl
 Group By oid
 Order By pg_relation_size(oid) Desc, sum(free) Desc;