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.
Installation
Die Installation und die nachfolgende Demo wird als User enterprisedb ausgeführt.
Nun geht die Installation von pgio schnell, da das Release 1.0 nur von Github heruntergeladen und extrahiert werden muss.
Die Shellskripte im pgio Verzeichnis werden ausführbar gemacht.
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.
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:
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.
Nun erzeugt das setup.sh Skript die Tabellen und Daten.
Die Quelltabelle und die 4 konfigurierten Tabellen sind jetzt im Schema public zu sehen.
Nun kann das runit.sh Skript ausgeführt werden und ein erstes Ergebnis liefern.
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.
Ein Blick mit free zeigt, dass nur noch 1 GB freier Hauptspeicher vorhanden ist.
Jetzt wird pgio als User enterprisedb erneut mit runit.sh ausgeführt.
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.
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.
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.