Seite wählen

NETWAYS Blog

Warum wir in den NETWAYS-PostgreSQL-Trainings eigentlich nur „psql“ nutzen

Wieder einmal PostgreSQL Schlung (Fundamentals und Advanced) durchgeführt.
Wieder einmal wurde nach GUIs gefragt.
Wieder einmal haben wir uns dann letztlich doch fast auf psql beschränkt.

Warum ist das so?

 

GUI vs. TUI – the eternal battle

GUIs werden i. A. als „benutzerfreundlicher“ dargestellt.

Ich persönlich wiederum finde es ganz schrecklich, dauernd zur Maus greifen zu müssen, um irgendeine Aktion auszulösen, für die die Entwickler keinen oder einen grauenhaften Shortcut konfiguriert haben… für mich sind GUIs also eher weniger benutzerfreundlich.

Mir ist auch klar, dass es beileibe nicht jedem Menschen so geht, und die Gewöhnung spielt dabei sicher auch eine enorme Rolle.

„The usual suspects“: die üblicherweise genannten Gründe pro GUI/TUI

GUI:

  • intuitiver zu bedienen
  • „gewohnte“ Optik
  • bessere Übersicht über Ergebnisse von Queries

TUI:

  • steht vom Funktionsumfang dem GUI kaum nach
  • funktioniert auch bei langsamer Verbindung („Zug“)
  • kann gescriptet werden

Es gibt aber einige durchaus schwerwiegende Gründe, warum ich bei Trainings so einen großen Wert auf psql lege.

„The killer arguments“: warum psql elementar ist

Die Lernschwelle ist bei GUIs unnötig hoch

  • Jedes GUI sieht letztlich (ein wenig) anders aus und es gibt einfach zu viele
  • Um eine erste Verbindung herzustellen, muss im GUI erst ein Server definiert werden, mit jeder Menge Parametern, u.a. einer Netzwerkverbindung
    • dafür muss aber erst ein Konfigurationsparameter (listen_addresses=) gesetzt werden, was wiederum erst deutlich nach dem ersten „Reinschnuppern“ behandelt wird…
    • Im Terminal hingegen (wo ich ja gerade den DB-Server installiert habe) komme ich per psql direkt an die DB (wenn ich der OS-User postgres bin…)
  • Objekte anschauen („Erste Schritte“):
    • TUI: nach Eingabe von psql kann ich einfach z.B. \dt eingeben und bekomme alle Tabellen gelistet, \d nachnamen zeigt mir instant die Tabellenstruktur, dazu Indexe, Primär-/Fremdschlüssel etc. an
    • in allen GUIs muss ich dafür erst durch einen Baum klicken, in pgAdmin4 z.B. Servergruppe -> Server -> Datenbank -> Schemas -> ‚public‘ -> Tabellen

Die (online-)Trainings-VMs sind nur per ssh und Webinterface erreichbar

  • um da per GUI dranzukommen, müssten also die Teilnehmer erstmal Software auf ihren (privaten oder dienstlichen) PCs installieren…

Viel entscheidender ist aber m.E.:

psql ist für den PostgreSQL-DBA, was vi für den U\*\*X-Admin ist:

  • auf jeder PostgreSQL-Maschine verfügbar
  • minimalistisch, aber gleichzeitig unglaublich leistungsfähig
  • ich muss das sowieso zu nennenswerten Teilen beherrschen, z.B.
    • für den Fall, dass mir die Firewall einen Streich spielt
    • wenn ich mal als Superuser in die DB will/muss (max_connections= ausgeschöpft)
    • um Dinge zu scripten

Wenn mir jemand erzählt, er oder sie sei UNIX-Admin, dann aber einen nano benutzt, bin ich sofort (zurückhaltend ausgedrückt) skeptisch.

Ähnlich ist es mit psql. Ich muss (als DBA) sowieso wissen, wie ich damit z.B. Objekte anzeigen, DDL einspielen, ggfs. mal eine Stored procedure umschreiben etc. pp. kann. Wenn ich die Software also sowieso (halbwegs) beherrschen muss, kann ich sie doch auch gleich benutzen? Ich sehe nur wenige Szenarien, in denen ein(e) DBA von einem GUI profitieren würde.

Ein(e) AnalystIn hingegen wird die DB wahrscheinlich eher direkt an ein Reporting-Tool oder M$ Excel anbinden wollen.

Bleibt der/die (SQL-) EntwicklerIn. Ja, fair enough, da sehe auch ich gewissen Charme (üblicherweise F5 drücken, um das SQL im Fenster (erneut) laufen zu lassen). Auf der anderen Seite ist derselbe Effekt in psql durch Eingabe von \e zu erreichen, und da kommt ein vi. Der ist ja bekanntlich minimalistisch, aber… 😉

Und ob man DDL jetzt per GUI erzeugen sollte, darüber scheiden sich ja auch die Geister… IMHO eher nicht.

Fazit:

„I never leave the house without it!“

psql ist der vi(m) der PostgreSQL-Welt. Unfassbar flexibel und leistungsfähig, immer verfügbar und dadurch absolutes „Pflichtprogramm“.

P.S.

Ich habe mal jemanden kennengelernt, der eine U\*\*X-Consulting-Firma betrieb und lt. eigener Aussage nur Menschen anstellte, die den ed beherrschen. So weit würde ich dann auch nicht gehen… 😉

P.P.S.

Vielleicht hat die Abneigung gegen TUIs was mit Oracles SQL*Plus (TM) zu tun? Wäre absolut nachvollziehbar, das fasse ich auch nur mit der Kneifzange an…

 

Über den Author:

Gunnar “Nick” Bluth hat seine Liebe zu relationalen Datenbanken Ende des letzten Jahrtausends entdeckt. Über MS Access und MySQL 3.x landete er sehr schnell bei PostgreSQL und hat nie zurückgeschaut, zumindest nie ohne Schmerzen. Er verdient seine Brötchen seit beinahe 20 Jahren mit FOSS (Administration, Schulungen, Linux, PostgreSQL). Gelegentlich taucht er auch tiefer in die Programmierung ein, so als SQL-Programmierer bei der Commerzbank oder in App-Nebenprojekten.

Ansible, so einfach!

Konfigurationsmanagement in Rechenzentren ist aus der modernen „DevOps“ IT nicht mehr wegzudenken. Puppet, Chef, Salt oder Ansible automatisieren Umgebungen von mittelständischen Unternehmen bis hin zu Weltkonzernen.
Wenn wir die verschiedenen Lösungen betrachten, bedienen sie sich alle einer eigenen Sprache, diese soll möglichst einfach unsere Infrastruktur abbilden. („infrastructure as a code“)
Da nicht jeder Admin im Tagesgeschäft programmiert, kann so eine Sprache ein Hindernis werden und Arbeitsschritte vielleicht verkomplizieren.
Seit einiger Zeit beschäftige ich mit Ansible, ein Tool welches ohne vorinstallierte Clients arbeitet und eine Konfiurationsprache basierend auf YAML nutzt.
Um Ansible zu nutzen muss lediglich eine SSH Verbindung, ein Benutzer mit Rootrechten und ein Inventarfile bestehen.
Das Sprache im YAML Format ist für jeden leicht lesbar und sofort verständlich.
Ansible kann entweder lokal auf dem Arbeitsrechner oder auf einem sogenannten „Managementnode“ über bereitgestellte Pakete installiert werden.
Unter „/etc/ansible/“ legen wir nach der Installation zusätzlich ein Inventar an.

$ cat /etc/ansible/hosts
host01.localdomain ansible_ssh_host=10.10.10.11
host02.localdomain ansible_ssh_host=10.10.10.12</pre lang="bash">

Wenn Ansible installiert und ein Inventarfile erstellt wurde, kann die Verbindung zum Server mit dem Modul „ping“ getestet werden. Hierbei versucht Ansible den Server per SSH zu erreichen und einzuloggen.

$ ansible host01.localdomain -m ping
host01.localdomain | success >> {
"changed": false,
"ping": "pong"
}</pre lang="bash">

Alternativ kann statt dem Hostalias auch „all“ gesetzt werden um alle Hosts aus dem Inventar zu prüfen.

$ ansible all -m ping</pre lang="bash">

Ansible bietet zahlreiche Module mit denen Pakete installiert, Dateien kopiert oder bearbeitet werden können. Hier findet ihr eine Übersicht aller Module
Tasks verwenden diese Module um die Arbeitsschritte in Playbooks oder Rollen auszuführen.
Beispiel eines Playbooks:

$ cat ansible_starter.yml
---
- hosts: all <- Führe die Tasks auf allen Hosts aus
  tasks:
    - name: say hello to everyone <- Name des Tasks
      debug:                      <- Name des Moduls
        msg: "Hello World"        <- Parameter des Moduls

– name: install ntp
yum:
name: ntp
state: installed
</pre lang=“yaml“>

$ ansible-playbook -s ansible_starter.yml
</pre lang="bash">
Diese Task werden der Reihenfolge nach auf dem Zielhost ausgeführt und damit haben wir schon eine kleine Automation geschaffen. Probiert's aus!

Da Ansible im Sturm mein Automationsherz erobern konnte war ich mit meinem Kollegen dieses Jahr auf dem Ansible Fest in London, einen Erfahrungsbericht der Veranstaltung findet ihr hier.

Thilo Wening
Thilo Wening
Manager Consulting

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Drei Wege um virtuelle Maschinen zu migrieren

OpenNebulaConf Grafiken 09Neue Storage-Lösungen sprießen wie Tulpen im Frühling aus dem Boden. Jede einzelne ist flexibler, schlanker und hochverfügbarer.
Da kommt meine Cloud ins Spiel, die eigentlich gut läuft aber so ein schnelleres Storage ist eine willkommene Abwechslung.
So ein neues Storage ist schnell aufgesetzt, was uns dann aber vor eine neue Aufgabe stellt,
denn unsere VMs laufen… nur nicht auf unserem hippen Storage.
Nun gibt es diverse Methoden um eine virtuelle Maschine in ein neues Image bzw. neues Storage zu transferieren.
Da haben wir zum einen die altbewährte Methode, mit dem Urgestein aller blockorientierten Kopiervorgänge dd.
Dazu muss die virtuelle Maschine komplett ausgeschaltet sein. Da sich der Zustand der VMs nicht mehr ändert, kann man beruhigt die VM kopieren.
dd if=/path/to/input/file of=/path/to/output/file bs=4096
Zum anderen die Methode ein qcow2 Image in ein Blockdevice zu schreiben.
In Worten gesagt: das Image wird mit „qemu-img convert“ in Raw umgewandelt und danach mit dd auf das neue Blockdevice kopiert. (Auch hier sollte die VM nicht mehr laufen!)
qemu-img convert -p -f qcow2 -O raw /path/to/input/file /path/to/outputfile.raw && dd if=/path/to/outputfile.raw of=/path/of/device bs=4M
Da die beiden genannten Arten eine lange Downtime benötigen, sind sie nur für VMs geeignet die nicht zeitkritisch sind.
Ein UNIX System kann mit guten Kenntnissen, mit relativ kurzer Ausfallszeit migriert werden. Ein hilfreiches Werkzeug dabei ist Rsync.
Leider kann ich hierzu kein fixes Beispiel vorzeigen, da die einzelnen Schritte von System zu System unterschiedlich ausfallen.
Die essentiellen Schritte sind:
1. Neues Device in der VM mounten und das gewünschte Filesystem erstellen.
2. Systemverzeichnisse auf dem neuen Device erstellen.
3. Das komplette System mit Rsync auf das neue Device kopieren. Hier muss man natürlich etwas aufpassen und Verzeichnisse wie /proc oder ggf. /mnt exkludieren. Auch auf bind Mounts sollte man achten, damit man Daten nicht ausversehen doppelt kopiert.
4. Die grub.cfg natürlich im neuen /boot Pfad aktualisieren. (grub-install und update-grub sind hierfür hilfreich)
5. Das „alte Device“ als read-only einbinden und die neue fstab anpassen.
6. Und last but not least, einen weiteren Rsync in dem die restlichen Files auf das neue Image übertragen werden. (auch hier bitte das Exkludieren von wichtigen Pfaden nicht vergessen. z.B.: /etc/fstab oder auch /boot !!)
Der Vorteil hierbei ist: die Downtime erstreckt sich dabei nur über den zweiten Rsync, bei dem die Festplatte im „read-only“ Modus ist.
Habt Ihr weitere coole Möglichkeiten einen VM zu migrieren?
Dann dürft ihr euch in den Kommentaren dazu äußern.
Oder seid Ihr interessiert an dem Thema Cloud und alles was damit zu tun hat? Dann besucht uns einfach auf der OpenNebula Conf 2014

Thilo Wening
Thilo Wening
Manager Consulting

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Wenn das MacBook zu heiß ist – cpulimit.sh

Ich mag laute Hardware nicht. Und ich fand es gut, dass mein iBook mit 600MHz PowerPC G3 Prozessor aus dem Jahr 2001 nur im absoluten Notfall den Lüfter eingeschaltet hat. Auch mein MacBook Pro mit 2,4GHz Intel Core 2 Duo Prozessor war im Normalfall nicht zu hören.
Aber mein neues MacBook Pro mit 2,2GHz Intel Core i7 erdreistet sich, bei verschiedenen Gelegenheiten, in den „Jet-mode“ zu gehen. Die Ursache ist dann gern mal der Indexer für Spotlight (metadata server – mds) oder ein Video Player (video lan client – vlc). Beide brauchen eigentlich nicht mit voller Power zu laufen um meinen Ansprüchen gerecht zu werden. Ausserdem braucht man meist auch die dedizierte Grafikkarte nicht. Die kann man aber Dank gfxCardStatus einfach abschalten. Achtung, nicht vergessen wieder anzuschalten, wenn man den Beamer dranhängt!
Apple hat leider keine Möglichkeit vorgesehen die CPU zu drosseln um weniger Strom zu verbrauchen und somit den Akku und das Gehör zu schonen. Todtraurig!
Nice ist auch keine Lösung, weil ja dennoch die Power genutzt wird die zur Verfügung steht.
Aber ich habe etwas gefunden was an dieser Stelle weiterhelfen kann: cpulimit. Das ließ sich aber unter Lion nicht compilieren. Es gibt da aber noch diese Variation davon.
An der Shell Variante habe ich ein wenig gefeilt. Nun bekommt man eine Liste der CPU hungrigen Prozesse zur Auswahl und den Erstplatzierten als Vorauswahl.
Das Ergebnis sieht dann so aus:

$ sudo ~/bin/cpulimit.sh
Password:
  This script will throttle a chosen process as you like it.
  Therefore your cpu runs cooler - hopefully.
Chose which process to throttle:
 PPID   PID USER            %CPU %MEM STARTED      TIME     STIME COMMAND
    1    66 root            25,5  5,1 Do08am   73:25.42  32:24.31 mds
  273   436 bschmidt        23,1  0,1 Do08am    1:20.18   0:13.72 Folder Actions Dispatcher
    1 19304 root            15,3  0,1 Sa03pm   62:40.11  51:14.03 activitymonitord
  273 91519 bschmidt        14,6  0,3  7:57pm   0:06.47   0:02.17 mdworker
    1    12 _mdnsresponder  12,6  0,0 Do08am   26:20.00  19:02.96 mDNSResponder
  273 91189 bschmidt        11,6  0,4  7:55pm   0:06.54   0:02.21 mdworker
  273 91520 bschmidt        11,3  0,3  7:57pm   0:06.48   0:02.17 mdworker
  273 91518 bschmidt         9,2  0,3  7:57pm   0:06.36   0:02.14 mdworker
  273 13471 bschmidt         8,7  3,6 Fr02pm  101:01.25  22:25.71 Google Chrome
Which process ID (PID) [guess: 66]?
Chosen:
  PID USER  %CPU %MEM STARTED      TIME COMMAND
   66 root  21,9  5,1 Do08am   73:26.43 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds
Sleep time in seconds (e.g 0.5 or 1 …) [default: 0.5]?
Run time in seconds (e.g 0.5 or 1 …) or percent [default: .5000 = 50%]?
OK. I will throttle PID 66 now and dislay processinfo every 20 seconds …
  PID USER  %CPU %MEM STARTED      TIME COMMAND
   66 root  40,5  4,7 Do08am   73:34.02 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds
  PID USER  %CPU %MEM STARTED      TIME COMMAND
   66 root  32,7  4,8 Do08am   73:34.91 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds
  PID USER  %CPU %MEM STARTED      TIME COMMAND
   66 root   0,0  4,8 Do08am   73:35.15 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Support/mds
^C
*** Ouch! Stop throtteling of PID 66. Exiting ***

Mit diesem Script ist es ein Leichtes, Prozesse ausser Rand und Band wieder einzufangen. Erstaunlicher Weise sogar den Video Player, wenn man nur die sleep time kurz genug wählt.
Da das Script nicht lang ist, stell ich es hier einfach mal rein:

#! /bin/bash
# Description:
#
# If you want to decrease the CPU demands for an application
# you can use this very simple and ugly "hack".
# I use it when I convert videos on my MacBook Pro
# to prevent it from getting to warm. Even if the CPU is IDLE this hack
# will prevent the application to use the CPU during Sleep Time
# (in contrast to renice/nice commands which will take all IDLE time).
# This means the conversions will take longer time, but I
# don't care because I run it at night.
#
# There is similar c program for Linux called cpulimit, but it wont
# compile on my Mac.
#
# Usage:  sudo ./cpulimit.sh
#
#################################
# config
sleeptime_default=0.5   # in seconds
runtimep_default=50     # in percent (50 = same as sleeptime)
reporttime=30           # report every x seconds while running
# PROCESSLISTformat: pid has to be on the second position
PROCESSLISTformat="ppid,pid,user,%cpu,%mem,start,cputime,stime,command"
#PROCESSLISTformat="ppid,pid,user,%cpu,%mem,start,cputime,stime,rss,vsz,cpu,re,wq,wqr,stat,nsigs,command"
#################################
# dont change anything below here
pid=""
scriptuser=$(id -u)
# run if user hits control-c
control_c()
{
  echo ""
  if [ "$pid" != "" ]; then
    echo -en "\n*** Ouch! Stop throtteling of PID $pid. Exiting ***\n"
    kill -SIGCONT $pid
  fi
  echo ""
  exit $?
}
# trap keyboard interrupt (control-c)
trap control_c SIGINT
pidstring()
{
  # takes pid as argument
  ps -p $1 -w -o pid,user,%cpu,%mem,start,cputime,command 2>/dev/null
}
isnumber()
{
  if [[ "$1" =~ ^[0-9]*([.][0-9]+)?$ ]] ; then
    return 0
  else
    return 1
  fi
}
#################################
# main
cat << EOF
  This script will throttle a chosen process as you like it.
  Therefore your cpu runs cooler - hopefully.
EOF
if [ "$scriptuser" != "0" ]; then
cat << EOF
  You're not root!
  If you want to controll processes that you dont own,
  please run via sudo.
EOF
fi
PIDSTRING=""
until [ "$PIDSTRING" != "" ]; do
  #PROCESSLIST=$(ps -r -A -f -S | head)
  if [ "$scriptuser" != "0" ]; then
    PROCESSLIST=$(ps -r -u $scriptuser -S -c -o $PROCESSLISTformat 2>/dev/null)
  else
    PROCESSLIST=$(ps -r -A -S -c -o $PROCESSLISTformat 2>/dev/null)
  fi
  if [ "$PROCESSLIST" = "" ]; then
    echo -en "\n*** Sorry, ps dont work as expected on $(uname). Exiting ***\n\n"
    exit 1
  else
    PROCESSLIST=$(echo "$PROCESSLIST" | head)
  fi
  echo -en "\nChose which process to throttle:\n$PROCESSLIST\n"
  PID_GUESS=$(echo "$PROCESSLIST" | head -2 | tail -1 | awk '{print $2}')
  echo -n "Which process ID (PID) [guess: $PID_GUESS]? "
  read pid
  if [ "$pid" = "" ]; then
      pid=$PID_GUESS
  fi
  # test if $pid is valid
  PIDSTRING=$(pidstring $pid)
  if [ "$?" -eq "0"  ]; then
    echo -en "\nChosen:\n$PIDSTRING\n"
  else
    echo -en "\n$pid is not a valid PID for a running process.\n"
    pid=""
  fi
  echo -en "\n"
done
sleeptime=""
until [ "$sleeptime" != "" ]; do
  echo -n "Sleep time in seconds (e.g 0.5 or 1 …) [default: $sleeptime_default]? "
  read sleeptime
  if [ "$sleeptime" = "" ]; then
    sleeptime=$sleeptime_default
  fi
  isnumber $sleeptime || sleeptime=""
done
#echo "sleeptime $sleeptime"
runtime=""
until [ "$runtime" != "" ]; do
  runtime_default=$(echo "scale=4;$sleeptime*$runtimep_default/(100-$runtimep_default)"|bc)
  echo -n "Run time in seconds (e.g 0.5 or 1 …) or percent [default: $runtime_default = $runtimep_default%]? "
  read runtime
  if [[ "$runtime" =~ ^([0-9]*([.][0-9]+)?)%$ ]] ; then
    runtimep_default=${BASH_REMATCH[1]}
  fi
  if [ "$runtime" = "" ]; then
    runtime=$runtime_default
  fi
  isnumber $runtime || runtime=""
done
#echo "runtime $runtime"
# now begin throttle
throttletime=1000000
looptime=$(awk "BEGIN { printf \"%.0f\\n\", ($sleeptime+$runtime)*100 }")
echo "OK. I will throttle PID $pid now and dislay processinfo every $reporttime seconds … "
((reporttime=$reporttime*100))
while true
do
  if [ $throttletime -ge 500 ]; then
    throttletime=0
    PIDSTRING=$(pidstring $pid)
    echo "$PIDSTRING"
  fi
  kill -SIGSTOP $pid || control_c
  sleep $sleeptime
  kill -SIGCONT $pid || control_c
  sleep $runtime
  throttletime=$(($looptime+$throttletime))
done

Unix Cheatsheets

Selbst der erfahrene Unix System Administrator muss hin und wieder mal was nachsehen. Normalerweise bieten sich da die entsprechenden Man Pages oder Google an. Aber was macht man, wenn man gar nicht weiss nach welchem Kommando man eigentlich suchen soll? Die Unix Toolbox ist eine sehr umfangreiche Referenz, die alle wichtigen Kommandos auflistet. Ohne lange Erklärungen, denn die Optionen jeden Befehls kann man ja dann später in den Man Pages nachlesen. Ein interessantes Konzept verfolgt Rosetta Stone for Unix. Auf dieser Website kann man sich die Befehle für verschiedene Unix Varianten „übersetzten“ lassen. Zur Auswahl stehen: AIX, A/UX, DG/UX, FreeBSD, HP-UX, IRIX, Linux, Mac OS X, NCR Unix, NetBSD, OpenBSD, Reliant, SCO OpenServer, Solaris, SunOS 4, Tru64, Ultrix und UNICOS. Das könnte helfen, wenn man sich mal auf einer weniger verbreiteten Plattform bewegen muss.

Julian Hein
Julian Hein
Executive Chairman

Julian ist Gründer und Eigentümer der NETWAYS Gruppe und kümmert sich um die strategische Ausrichtung des Unternehmens. Neben seinem technischen und betriebswirtschaftlichen Background ist Julian häufig auch kreativer Kopf und Namensgeber, beispielsweise auch für Icinga. Darüber hinaus ist er als CPO (Chief Plugin Officer) auch für die konzernweite Pluginstrategie verantwortlich und stösst regelmässig auf technische Herausforderungen, die sonst noch kein Mensch zuvor gesehen hat.