pgio ist ein von Kevin Closson, Autor von SLOB für Oracle Datenbanken, implementiertes und unter der Apache 2.0 Lizenz auf Github veröffentlichtes Tool zum Testen der I/O Performance einer Plattform mit installiertem PostgreSQL.

Als Demo-Umgebung steht eine per Vagrant angelegte CentOS 7(.4) VM mit installiertem EnterpriseDB Advanced Server 10 zur Verfügung. In der postgresql.conf ist der Parameter shared_buffers = 512MB angepasst. Ansonsten ist die Konfiguration nach Installation nicht verändert worden.

Zusätzlich wurde noch das sysstat Paket installiert.

Copy to Clipboard

Installation

Die Installation und die nachfolgende Demo wird als User enterprisedb ausgeführt.

Copy to Clipboard

Nun geht die Installation von pgio schnell, da das Release 1.0 nur von Github heruntergeladen und extrahiert werden muss.

Copy to Clipboard

Die Shellskripte im pgio Verzeichnis werden ausführbar gemacht.

Copy to Clipboard

Konfiguration

Die Konfiguration von pgio erfolgt über die Konfigurationsdatei pgio.conf. In dieser Datei sind die folgenden Parameter enthalten, die das Anpassen des Workloads an die Postgres Instanz und Plattform ermöglichen.

Copy to Clipboard
PARAMETER BEDEUTUNG
UPDATE_PCT Anteil an SQL Update Statements
RUN_TIME Ausführungsdauer des runit.sh Skripts in Sekunden
NUM_SCHEMAS Alle durch das setup.sh Skript generierten Daten liegen entweder in einem einzigen Schema oder aber werden mit diesem Parameter in n Schemas angelegt; VORSICHT: Mit Schema wird in der Dokumentation Tabelle gemeint!

| NUM_THREADS |

setup.sh nutzt n parallele Ladeprozesse

runit.sh nutzt n parallele Sessions pro Schema während der Workload Generation

| WORK_UNIT | Setzt das Limit des BETWEEN im Select Statement, so dass n zufällig gewählte Blöcke ausgewählt werden; bei einem kleineren Wert als 255 sind mehr Select Statements notwendig, um den gleichen IOPS zu erreichen | | UPDATE_WORK_UNIT | Definiert die logische Abfolge des Workloads der Select/Update Statements, wobei die Select Statements mehr Blöcke als die Updates nutzen | | SCALE | Menge an initial generierten Daten pro Schema durch setup.sh entweder als

n multipliziert mit 8 Kilobyte

nM für Größe in Megabyte

nG für Größe in Gigabyte

| | DBNAME | Datenbank in der alle Objekte für den Test erzeugt werden | | CONNECT_STRING | Parameter zur Übergabe an psql, wobei Umgebungsvariablen, .pgpass Datei und die Authentifikation bereits konfiguriert sind | | CREATE_BASE_TABLE | setup.sh erzeugt beim ersten Start eine Quelltabelle um alle weiteren Tabellen zu beladen; bei dem Wert true wird diese Quelltabelle bei erneuten Ausführungen nicht erneut erzeugt |

Demo

Für die Demo wird die pgio.conf angepasst:

Copy to Clipboard

Es wird für 2 Minuten mit einem 15%igen Update-Anteil, verteilt über 4 Tabellen, mit jeweils 2 Sessions (insgesamt also 8) gearbeitet. Die Skalierung auf 1 GB erwirkt dabei, dass Postgres nicht nur die Pages in den Shared Buffers nutzt, sondern auch Pages aus dem Filesystem nachgeladen werden.

Bevor jedoch das setup.sh Skript gestartet werden kann, wird die die Datenbank für den Test angelegt.

Copy to Clipboard

Nun erzeugt das setup.sh Skript die Tabellen und Daten.

Copy to Clipboard

Die Quelltabelle und die 4 konfigurierten Tabellen sind jetzt im Schema public zu sehen.

Copy to Clipboard

Nun kann das runit.sh Skript ausgeführt werden und ein erstes Ergebnis liefern.

Copy to Clipboard

Interessant bei dem Ergebnis sind die Spalten tup_fetched und tup_updated, da sie die geladenen und aktualisierten Zeilen während dem Test darstellen. Je höher die Werte sind, desto besser. Mit dem in der letzten Zeile dargestellten Wert für Read IOPS (RIOPS) kann geprüft werden, ob die Plattform den “versprochenen” IOPS Wert liefert.

Buffered I/O vs. Direct I/O

Es ist wichtig zu verstehen, dass pgio RIOPS und nicht Read Physical IOPS (RPIOPS) anzeigt. Das kommt daher, dass Postgres Dateien nicht mit dem O_Direct Flag öffnet, was bedeutet, dass es “buffered” I/O ist. Das “buffering” wird über physikalischen Hauptspeicher des Linux Page Caches abgewickelt. Dies fällt beim Vergleich der I/O Werte mit iostat auf und wurde in einem Beitrag von Kevin Closson inklusive der Möglichkeit dies zu umgehen beschrieben. Dies ist auch einer der Gründe, warum das runit.sh Skript iostat während dem Test mitlaufen lässt.

pgio bietet mit dem Shellskript pgio_reduce_free_memory.sh die Möglichkeit, den freien Hauptspeicher zu beschränken und das Page Caching zu auszuschalten. Dabei übergibt man dem Shellskript den frei zu bleibenden Wert in Gigabyte. In diesem Beispiel wird der freie Hauptspeicher auf 1 GB beschränkt. Das Skript muss als User root ausgeführt werden.

Copy to Clipboard

Ein Blick mit free zeigt, dass nur noch 1 GB freier Hauptspeicher vorhanden ist.

Copy to Clipboard

Jetzt wird pgio als User enterprisedb erneut mit runit.sh ausgeführt.

Copy to Clipboard

Der nun erreichte RIOPS Wert von 5032 wird jetzt mit den Disk-Statistiken verglichen. Es ist ersichtlich, dass die Werte sich nun annähern.

Das wird zusätzlich durch einen Vergleich des RIOP-Wertes mit den iostat-Daten bestätigt.

Copy to Clipboard

Aufräumen

Im Hintergrund hat pgio beim Ausführen von runit.sh iostat, vmstat und mpstat mitlaufen lassen. Dabei wird pro Befehl eine Ausgabedatei erzeugt.

  • iostat.out
  • vmstat.out
  • mpstat.out
  • pgio_diskstats.out
  • pgio_objects_creation.out
  • pgio_session_detail.out

Werden die Daten nicht weiter benötigt, können sie wieder gelöscht werden, da sie je nach Testlänge recht beachtliche Größen erreichen können.

Copy to Clipboard

Fazit

pgio bietet die komfortable Möglichkeit mit PostgreSQL die I/O Performance der darunter liegenden Plattform zu testen. Dabei ist die Installation und Konfiguration leicht und verständlich durchzuführen. Das Nutzen von pgio ist einerseits besonders zu empfehlen, wenn (Cloud) Service Provider auf die zugesicherten Rahmenbedinungen hin gestest werden sollen. Andererseits lässt sich vor Inbetriebnahme einer Datenbank testen, welches Filesystem (z.B. xfs oder ext4) mit welchen Mount Optionen (z.B. sync) Sinn macht.