MySQL Workbench 8

Kleines Ratespiel: Wurde für diese Meldung eine SQL-Datenbank benutzt oder nicht? 🙂 Wenig überraschend lautet die Antwort: „Ja“. Das könnte an der weiten Verbreitung und den vielfältigen Anwendungsmöglichkeiten liegen. Es folgt übrigens keine SQL Einführung oder gar ein SQL Lehrgang 😉

Desktop-App: MySQL Workbench 8

Wenn man mit einer SQL-Datenbank arbeiten möchte, braucht man i.d.R. drei Dinge: Einen SQL-Server, einen SQL-Clienten und ein Programm, daß mit den Daten in der SQL-Datenbank etwas machen möchte.

Der im FOSS vermutlich am häufigsten eingesetzt wird, ist MariaDB. Dieser Fork von MySQL entstand, weil Oracle, die die Firma hinter MySQL gekauft hatten, der Meinung war, mal die Regel zu ändern. Das hat einem Teil der Gemeinde, die bislang MySQL mit entwickelt hatten nicht gefallen und so zogen/forkten Sie in eine eigene Trägergesellschaft „The MariaDB Foundation“ um. Zu den größten Sponsoren zählen Booking.com ( die mit den dicken Spamproblem ), Alibaba Cloud und Microsoft (die mit dem eigenen Closed Source MSQL-Server {Wieso eigentlich Microsoft!?!?!?!}), aber auch WordPress Hersteller Automattic, IBM und ein paar Andere.

Bei MariaDB handelt es sich also um den Serverteil, der verschiedene Datenbank Engines unter ein Dach bringt, so daß man diese mit dem SQL-Clienten der Wahl ansprechen kann. Im MariaDB Paket ist ein einfacher Kommandozeilen Client namens „mysql“ mit dabei. Ja, der heißt nicht „mariadb“ sondern „mysql“, weil das ein Fork von MySQL ist, der eine möglichst große Rückwärtskompatibilität anstrebt. Mit anderen Worten, für den Endbenutzer sollte sich nichts ändern. Möglich ist das, weil MySQL eine FOSS Entwicklung ist, die jeder clonen und weiterentwicklen kann, solange er sich an die Lizenzregeln hält.

Jetzt mag nicht jeder in der Konsole rumschrauben, auch wenn das nicht wirklich schwierig ist, und möchte vielleicht eine Desktop-Anwendung benutzen. Hier kommt die MySQL Workbench ins Spiel:

man sieht ein Startfenster mit der Auswahl in welche Datenbank man einloggen möchte.Wenn man das Fedora Paket MariaDB-Server installiert ( dnf install mariadb-server mariadb ), dann kann man direkt mit der Workbench mit der Arbeit anfangen, da der ROOT Zugang zu dem Datenbankserver nicht beschränkt ist. Das ist natürlich auf Dauer eine völlig untragbare Situation, aber irgendwie muß man erstmal in den Datenbankserver rein kommen, um dann dort die Zugangsdaten für den Rootzugang zusetzen 🙂 In meinem Beispiel ist das erst einmal kein Problem, da die spätere App auf einem abgesicherten Server neu aufgesetzt wird. Aber sobald Eurer Server übers Netz erreichbar ist, ist ein Passwortschutz unumgänglich.

Mein drittes Problem, das welches mit den Daten arbeiten soll, gibts noch nicht, aber das wird dann in PHP oder JAVA geschrieben sein. Beide Sprachen bringen einen kompletten Support für MySQL(und Forks) Datenbankserver  mit.

Mit dem SQL-Clienten kann man jetzt die eigentlichen Datenbanken, Tabellen, Views, Indexe und in letzter Konsequenz auch die Datensätze anlegen und bearbeiten:

Im Beispiel oben die Datenbank namens „census“ und darin die Datenbanktabelle „users“.

Der eine oder andere könnte an der Tabellenbeschreibung erkennen, um was für ein Projekt es sich handelt, aber laßt Euch sagen, es funktioniert leider nicht sauber…{ PAM_MYSQL Frustanflug niederkämpf}.. Wie man hier sehen kann, ist die Ansicht der Datenzeile(n) reicht ansehnlich. Für einfache Bearbeitungen ist der Client gut zu benutzen, aber ehrlich gesagt ist PHPMyAdmin weitaus besser!

Also wenn Ihr mal ein Desktopprogramm sucht, mit dem Ihr in einer SQL Datenbank arbeiten könnte, das wäre ein brauchbares.

Für Fedora herunterladen könnt Ihr das hier: https://dev.mysql.com/downloads/workbench/#downloads Ihr müßt aber erstmal das passende OS ( hier Fedora ) auswählen, damit Euch die Downloadlinks angeboten werden. Das klappt sogar erfreulicherweise ohne Javascript 🙂 Die Fedora RPM-Pakete gibt es nur für 64Bit Versionen, aber das dürfte einen heutzutage nicht mehr wirklich stören.

 

XRDP und der schwarze Bildschirm

Die Leser von RemoteDesktop mit XRDP & XFreeRDP haben vielleicht noch im Kopf, daß RDP mit Linux mit Cinnamon einen schwarzen Bildschirm produziert hat, weil Cinnamon scheinbar viel mit Hardwarebeschleunigung arbeitet. Darum geht es heute nicht 😀

XRDP und der schwarze Bildschirm

Ein Phänomen beim Ausprobieren von RDP mit Linux war, daß auf einem Linuxrechner die Desktopsession nicht zwangsläufig weiter lief, wenn die Verbindung vom Clienten gekappt wurde. Wenn man mit RDP arbeitet, gibt es vier Gründe wieso eine Sitzung getrennt wird:

Netzwerkausfall: Verbindung unterbrochen
Sitzungsende: Benutzer loggt aus
Updates: Windows rebootet
WTF!: Der Benutzer fährt den RemotePC runter, statt sich abzumelden.

In den Fällen, wo die Verbindung gekappt wird, kann man normal weiter arbeiten, wenn man die Verbindung durch einen Reconnect wieder herstellt. Bei Windows klappt das bis lang ohne Probleme, weswegen sich viele einfach gar nicht „abmelden“ sondern einfach den RDP Clienten beenden, ohne sich auszuloggen.

Jetzt versucht das Kunststück mal bei einem XRDP Server 🙂 Das kann funktionieren, habe ich heute erst erlebt, aber meistens geht es nicht. Man sieht nur einen schwarzen Bildschirm, wenn es überhaupt funktioniert mit der erneuten Verbindung.

Nicht Remote, Nicht Lokal

Jetzt haben wir die kuriose Situation, daß wir per Remote nicht mehr in den PC kommen, und sich am Bildschirm einloggen als der Benutzer geht auch nicht. Zumindest ich habe keinen gleichzeitig lokalen wie remote Login geschafft, wenn man von SSH absieht.

Was macht man jetzt?

Es bleibt leider nur eins zu tun: per SSH einloggen und alles terminieren, was nicht im Screen läuft. Letzteres werde ich bei den jetzt folgenden Anweisungen nicht beachten, weil das ein von Euch selbst verursachter Spezialfall ist 😉

Erstmal sondieren:

{benutzername}“ bitte als ganzes mit Euren Benutzernamen austauschen, die {} gehören zum Platzhalter.

sudo ps auxf | grep ^{benutzername} | awk ‚{print „kill -9 „$2“;# „$0;}‘

Das sieht erst einmal wüst aus, ist aber nur die normale Ausgabe aller Prozesse die vom Benutzer gestartet wurden. Das Kill vorne ist schon für die nächste Aktion vorbereitet und Ihr sollt eigentlich nur kurz prüfen, ob da a) auch immer eine PID steht (Prozess-ID) b) was alles gekillt würde.

kill kann einem Prozess sagen, daß er sich selbst beenden soll, daß er sich neustarten sollen oder wenn der Prozess unreaktiv aka. tod ist, diesen hart beenden (-9 Option).

Wenn Ihr das geprüft habt, dann könnt Ihr loslegen:

sudo ps auxf | grep ^{benutzername} | awk ‚{print „kill -9 „$2;}‘| bash

Ihr dürft natürlich gern darauf vertrauen, daß es schon alles richtig ist und es gleich beenden, aber wenn was schief geht, nicht im Kommentarblock ausheulen 😉

Bitte beachten:

Wenn man per SSH als der besagte Benutzer eingeloggt ist um sich seine Desktopsession zu terminieren, die Befehle oben betreffen auch die SSH Session! d.h. Ihr kickt Euch selbst dabei raus. Nicht wundern, das ist völlig normal. Daher ggf. noch mal einloggen und prüfen, ob auch wirklich alles weg ist, was weg sein sollte.

Das Problem läßt sich elegant durch einen ROOT Login vermeiden, weil wenn der das macht, trifft es ihn nicht. Aber da root auch Prozesse von sich selbst wegkillen könnte, müßt Ihr gerade bei so brutalen Kommandos die in der Shell zusammengestrickt sind extrem sorgsam sein.

Die Erklär-Sektion

farblich nochmal genau aufgeschlüsselt, was da gemacht wird:

sudo ps auxf | grep ^{benutzername} | awk{print „kill -9 „$2;}‚| bash

sudo                  führt ps als Root aus, was Begrenzungen aller Art bei der Ausgabe verhindert.
                      Kann aber weg gelassen werden.
ps                    "Prozesslist"
auxf                  listet alle Prozesse mit PID Username und Kommando auf.
grep                  filter die Ausgabe von ps nach...
^benutzername         allen Zeilen die mit dem Benutzernamen beginnen, das ^ ist wichtig dabei.
awk                   zerlegt die gefilterten Ausgaben in einzelne Spalten und ordnet die neu an.
{print "kill -9 "$2;} die neue Anordnung des Inhalts von Spalte 2 ( der PID )
bash                  führt die mit print zusammengebaute neue Anweisung "kill -9 PID" aus, 
                      wobei PID dann der Inhalt von Spalte 2 der Prozessliste ist.

Man erwischt so alle laufenden Prozesse des Users, egal wann, egal wieviele es sind.

XRDP und das screen-Tool

Ihr wisst noch, daß man nicht so genau hinsehen sollte, wenn man mehr Freizeit haben will? 😉 Den Grundsatz habe ich mal wieder bei RDP ignoriert und bin prompt in die Falle getappt.

XRDP, die Session und das screen-Tool

Wer von Euch weiß, was PID 1 ist? Ok, eine rhetorische Frage, jeder weiß das. Für die, die das vergessen haben, kleine Auffrischung:

Der erste Prozess, der beim Start des PCs erstellt wird, hat die Process-ID 1 ( PID ). Jeder andere Prozess danach, ist ein Kind(Child) vom Prozess mit PID 1. Der Prozess ist also das Elternteil(Parent) von dem gestarteten Prozess. Beim Systemd-Init-System heißt der PID 1 Prozess sinnigerweise „systemd“, beim Vorgänger System-V  wars noch „init“.

Beispiel:

systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352)
           |                    `-{ModemManager}(1354)
           |-NetworkManager(1319)-+-{NetworkManager}(1360)
           |                      `-{NetworkManager}(1362)

Hier im Beispiel, ist systemd(1) der Eltern-Prozess und ModemManager(1300) und NetworkManager(1319) sind die Kinder-Prozesse. Wenn der Rechner runtergefahren wird, terminiert der PID1 Prozess alle seine Kinder-Prozesse und wenn keins mehr da ist, beendet er sich selbst, in dem er der HW das Strom-Aus-Kommando sendet.

Merke: Alle Prozesse sind Kinder oder Kinds-Kinder von PID1, weil das eine baumartige Struktur ist.

Wer sich das mal selbst ansehen will: einfach „pstree -up | less“ in ein Terminalfenster eingeben.

Was passiert, wenn der Elternprozess eines Kindes terminiert wird und dieser Elternprozess nicht PID1 ist?

Im Beispiel oben, terminieren wir mal gedanklich den NetworkManager(1319) der ja 1360 und 1362 als Kinder hat. Was jetzt passiert ist, daß die Kinder-Prozesse als Waisen dem PID1 übertragen werden. Sie bekommen also einen neuen Eltern-Prozess, aber sonst ändert sich nichts: Sie laufen i.d.R. weiter.

Es gibt auch Situationen, wo das nicht der Fall ist, aber die lassen wir mal aus.

Ich merke gerade ich muß weiter ausholen, sonst verstehen das nicht alle Leser, daher nicht wundern, wenn alles etwas schlicht gehalten ist und es einem trotzdem wie eine Wüstenwanderung ohne Wasser vorkommt.

Der Benutzer meldet sich an

Stellen wir uns vor, Systemd hat das System(PC) soweit hochgefahren, daß uns am Monitor eine Anmeldemaske(Login-Dialog) begrüßt. Wenn der Benutzer einloggt(sich anmeldet), wird die Desktop-Session gestartet, das kann z.b. Gnome, Cinnamon oder sonst eine andere Deskopumgebung sein. Die Startet dann wieder Programme bis so eine Arbeitsoberfläche entstanden ist, wie man die von Fotos kennt:

Ein GNOME Remotearbeitsplatz mit laufendem VideoEs laufen jetzt rudelweise Prozesse im Namen des Benutzers:

systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352)
          ...
           |-csd-printer(2448,marius)-+-{csd-printer}(2449)
           |                          `-{csd-printer}(2450)
           |-cupsd(1364)
           |-dbus-broker-lau(1276,dbus)---dbus-broker(1277)
           |-dbus-daemon(5007,marius)---{dbus-daemon}(5011)
           |-dbus-daemon(5153,marius)---{dbus-daemon}(5154)
           |-dbus-daemon(5282,marius)---{dbus-daemon}(5283)
           |-dbus-daemon(5868,marius)---{dbus-daemon}(5869)
           |-dbus-daemon(8160,marius)---{dbus-daemon}(8161)
           |-dbus-daemon(12280,marius)---{dbus-daemon}(12281)
           |-dbus-daemon(27861,marius)---{dbus-daemon}(27862)
           |-dconf-service(5201,marius)-+-{dconf-service}(5202)
           |                            `-{dconf-service}(5203)
           |-dconf-service(5330,marius)-+-{dconf-service}(5331)
           |                            `-{dconf-service}(5332)
           |-dconf-service(5372,marius)-+-{dconf-service}(5378)
           |                            `-{dconf-service}(5379)
           |-dconf-service(5924,marius)-+-{dconf-service}(5925)
           |                            `-{dconf-service}(5926)
           |-dconf-service(12329,marius)-+-{dconf-service}(12330)
           |                             `-{dconf-service}(12331)
           |-dconf-service(28004,marius)-+-{dconf-service}(28007)
           |                             `-{dconf-service}(28008)
          ...

und die sind, wie man oben sehen kann, Kinder vom PID1. Die „Ausreißer“-Prozesse die auch laufen, wenn sich kein Benutzer anmeldet, habe ich mal rot markiert. Die gehören i.d.R. root oder einem Servicebenutzer „nobody“,“www-data“,“mysql“ so in der Art. Die werden gleich wichtig.

Wenn der Benutzer sich ausloggt

Kommen wir zu dem Punkt, wo sich der Benutzer aus dem PC ausloggt. Der Abmelden-Vorgang(Logout) stößt eine Kaskade an, die alle Benutzerprozesse terminiert. Wenn keine anderen Prozesse mehr laufen, dann terminiert sich der PID1 auch. I.d.R. ist das aber nicht der Fall, weil Root ja auch ein ganzes Rudel an Diensten gestartet hat, die alle Kind von PID1 sind.

Screen

Wenn man auf verschiedenen Servern zu tun hat, kommt man unweigerlich an den Punkt, wo man Programme laufen lassen muß die tage- oder wochenlang laufen müssen (ggf. auch ewig) oder man muß einfach zwischenzeitlich mal weg und will den Arbeitsstand den man erreicht hat nicht verlieren.

Einen Desktop-PC würde man einfach nicht abschalten und als Benutzer nur den Bildschirm sperren. Wenn man sich aber doch mal als anderer Benutzer an dem PC anmelden muß, und die Programme trotzdem nicht beendet werden sollen, kommt „screen“ ins Spiel.

Dies startet man in einer Konsole bevor man mit der Arbeit anfängt. Wenn man sich auf einem entfernten Server per SSH anmeldet, ist es oft der einzige Weg, wie man sicherstellen kann, daß ein Verbindungsverlust nicht im Desaster endet. Screen kann man aber natürlich auch in einem Desktop-Terminal starten.

Ich kann also als Benutzer meinem PC auch in einer Screensitzung längerfristig mit Aufgaben versorgen, mich dann ausloggen oder Bildschirm sperren und per SSH von Zuhause aus nachsehen, ob die Prozesse noch laufen oder schon fertig sind. Da jeder mit der richtigen Berechtigung eine Screensitzung betreten kann, kann ich dann also auch von Zuhause aus an der Stelle weiter machen, wo ich aufgehört habe.

Wenn ich das nur in einem Terminalfenster als eingeloggter Desktopbenutzer mache, kann ich das nicht tun, da man das Terminal nicht von außen betreten kann.

Damit dürfte die Idee hinter Screen klar sein:

Screen starten, Programme arbeiten lassen, die Benutzersitzung am Desktop oder per SSH beenden und dann später von irgendwo anders fortsetzen.

Jetzt kommt XRDP ins Spiel

Nun hatte ich einen PC bei einer Firma, den ich per getunneltem RDP von außen mit einer Desktop-Session benutzt habe und wollte die stundenlange Kopieraktion in einer Screensitzung laufen lassen und mich dann ausloggen. RDP hat das Problem, daß man nicht gleichzeitig per RDP und am Bildschirm eingeloggt sein kann.

Also muß man die Remote-RDP-Sitzung beenden, falls man am Bildschirm einloggen muß, weil der Job so lange lief, daß man schon wieder im Büro ist.  Das passiert öfters als man glauben mag.

Wenn man das tut, vertraut man darauf, daß man ja screen gestartet hatte und der Prozess noch da ist, wenn man wieder ins Büro kommt. War er aber nicht.

Ta Ta Daaaaaaa !!!

Eine per XRDP gestartete Desktop-Session bekommt nämlich einen eigenen systemd Prozess als Startprozess, genau wie der PC beim hochfahren auch, nur das dieser systemd Prozess keine anderen Dienste gestartet hat und daher alle seine Kinderprozesse terminiert, wenn die Sitzung endet… auch Screen!

Beispiel:

systemd(1)-+-ModemManager(1300)-+-{ModemManager}(1352)
           |                    `-{ModemManager}(1354)
           |-NetworkManager(1319)-+-{NetworkManager}(1360)
           |                      `-{NetworkManager}(1362)
	  ...
           |-gnome-terminal-(5111,marius)-+-bash(5412)---screen(13881)---screen(13882)---bash(13883)-+-less(14632)
           |                              |                                                          `-pstree(14631)
          ...
           |-systemd(5996,remote)-+-(sd-pam)(6006)
           |                             |-abrt-applet(6657)-+-{abrt-applet}(6671)
           |                             |                   |-{abrt-applet}(6672)
          ...
           |                             |                       `-{evolution-calen}(7037)
           |                             |-evolution-sourc(6381)-+-{evolution-sourc}(6383)
           |                             |                       |-{evolution-sourc}(6384)
           |                             |                       `-{evolution-sourc}(6385)
           |                             |-gnome-shell-cal(6374)-+-{gnome-shell-cal}(6378)
           |                             |                       |-{gnome-shell-cal}(6380)
           |                             |                       |-{gnome-shell-cal}(6432)
           |                             |                       |-{gnome-shell-cal}(6433)
           |                             |                       `-{gnome-shell-cal}(7050)
           |                             |-gnome-terminal-(11250)-+-bash(11424)---screen(21255)---screen(21326)---bash(21331)---les+
           |                             |                        |-{gnome-terminal-}(11277)
           |                             |                        |-{gnome-terminal-}(11278)
           |                             |                        `-{gnome-terminal-}(11310)
          ...

In dem Auszug oben seht Ihr den Unterschied:

systemd(1) -> systemd(????) -> gnome-terminal -> bash -> screen

statt:

systemd(1) -> gnome-terminal -> bash -> screen

Da systemd(????) (die ???? stehen für eine beliebige PID) nach dem Logout keine Prozesse von „anderen“ Benutzer gestartet hat, terminiert er sich auch selbst, was dann in Folge auch das Screen noch terminiert.

In der Desktopkette (in grün) bleibt der systemd (1) Prozess stehen, weil noch andere Prozesse von anderen Benutzern laufen (inkl. root), deswegen wird Screen dann nicht terminiert und läuft weiter.(denkt dran, einfache Darstellung 🙂 )

Am Beispiel von SSH schön zu sehen:

|-sshd(20153)-+-sshd(21640)—sshd(21661)—bash(21671)—screen(22867)—screen(22881)—bash(22882)

wird zu

|-screen(22881)—bash(22882)

Merke:

Wenn Du per XRDP eingeloggt bist und screen benutzen willst, melde Dich lokal per SSH an, starte dann screen und arbeite damit.

Es klingt bescheuert, weil man von Screen genau erwarten würde, daß es weiterläuft, aber es passiert halt nicht, weil der das screen in der Konsequenz startende Prozess ( systemd(????) ), alles terminert, weil er selbst terminieren will/muß.

Ich befürchte wir bekommen Pöttering nicht dazu, dafür eine Ausnahme in systemd einzubauen und müssen damit leben.