Global Browser

See what is actually stored beneath your tables

Walk the multidimensional globals under your SQL schema, drill into subscript levels and resolve $LISTBUILD values into readable fields.

Unique to SQL DATA LENS

  • Durch Subscript-Ebenen navigieren
  • $LISTBUILD-Werte in Felder aufgelöst
  • Von einer Ergebniszeile zum Global-Knoten springen
  • .gof-Export offline öffnen, Named User oder höher
  • Gemischte Subscript-Typen werden korrekt behandelt

Früher oder später kommt eine Frage, die SQL nicht beantworten kann. Eine Zeile existiert im Global, aber die Class Query liefert sie nicht zurück. Eine Property liest sich über die Objektschicht als null, während die Daten sichtbar da sind. Eine Legacy-Routine hat vor zwanzig Jahren direkt in den Storage geschrieben und niemand erinnert sich mehr an das Format. An diesem Punkt muss man den Global selbst ansehen, und die üblichen Optionen sind eine Terminal-Session mit ZWRITE oder jemanden mit Server-Zugriff zu bitten, das zu tun.

Global Browser mit einem IRIS-Global, der drei Subscript-Ebenen tief aufgeklappt ist, der Subscript-Pfad oben angezeigt und das Value-Panel rechts mit einem $LISTBUILD-Wert, der in nummerierte Einzelfelder aufgelöst wurde
Der Storage unterhalb einer Tabelle, navigierbar wie die Tabelle selbst.

Warum Globals wichtig sind, auch wenn man nur SQL schreibt

Jedes Datenelement in einer InterSystems IRIS Datenbank wird in einem effizienten, baumbasierten, dünn besetzten mehrdimensionalen Array gespeichert — einem Global. Globals bilden die Grundlage sowohl der Objekt- als auch der SQL-Schnittstelle der Plattform: ein Datenkatalog, erreichbar als Tabellen, als Objekte, als mehrdimensionale Arrays oder als Dokumente, alles ruhend auf demselben Storage. Man muss nie direkt mit ihnen arbeiten, aber das Verständnis, wie IRIS sie verwendet, verwandelt ein unerklärliches Ergebnis in eine Diagnose.

Daten können in einem Global unter beliebig vielen Subscripts gespeichert werden, und Subscripts sind typlos. Ein Subscript auf einer bestimmten Ebene könnte die Zahl 34 sein, während sein Nachbar auf derselben Ebene der String "LineItems" ist. Eine Lagerbestandsanwendung für Artikel, Größe, Farbe und Muster könnte so aufgebaut sein:

^Stock(item,size,color,pattern) = quantity

mit Daten wie:

^Stock("slip dress",4,"blue","floral") = 3

Diese Flexibilität ist genau der Grund, warum generische SQL-Clients hier nichts anzeigen können: Es gibt keine feste Zeilen- und Spaltenform zum Rendern. Der Global Browser rendert stattdessen den Baum.

Navigation durch den Baum

Globals in einem Namespace werden als Ordner im Server Navigator aufgeführt, mit genauer Item-Anzahl, und expandieren Ebene für Ebene. Man steigt ein Subscript nach dem anderen ab, sieht die Subscripts, die auf jeder Ebene tatsächlich existieren, anstatt einen Bereich zu erraten, und der Wert an jedem Knoten wird angezeigt, sobald man ihn auswählt. Der Subscript-Pfad wird in einer Form angezeigt, die man direkt in ein Terminal oder in ObjectScript kopieren kann, sodass das, was man im Browser gefunden hat, anderswo reproduzierbar ist.

Da Subscript-Ebenen Datentypen auf derselben Ebene mischen können, sortiert und zeigt der Browser numerische und String-Subscripts nebeneinander an, ohne das eine in das andere zu kollabieren — ein Fall, der früher falsch behandelt wurde und jetzt explizit ist.

$LISTBUILD-Werte, aufgelöst

IRIS und Caché speichern die Properties eines Objekts in einer kompakten binären Darstellung, die mit $LISTBUILD gebaut wird, sodass ein einzelner Global-Knoten typischerweise eine ganze Zeile enthält. Roh ausgegeben ist dieser Knoten eine Folge nicht druckbarer Bytes mit gelegentlich erkennbaren Strings darin. Der Global Browser dekodiert die Liste und zeigt die Elemente als einzelne, nummerierte Felder, die man dann mit der Storage-Definition der Klasse abgleichen kann, um zu sehen, welche Property in welcher Position sitzt.

Das ist das Nützlichste, was das Tool mit Globals macht. So bestätigt man, dass der Wert tatsächlich in Slot 7 steht, die Klasse ihn aber in Slot 8 erwartet, oder dass eine Property als String geschrieben wurde, wo die Storage-Definition Integer sagt.

Global Browser mit der Knotenliste eines Globals in der Mitte, jede Zeile zeigt den roh gespeicherten $LISTBUILD-Wert, und rechts das Decoder-Panel, das den ausgewählten Knoten in nummerierte Positionen mit je einem Feldwert pro Zeile zerlegt
Ein Knoten, zwei Lesarten: der Rohwert und die dekodierte Feldliste.

Wenn die Daten nicht sind, was sie vorgeben zu sein

Legacy-Systeme, die die SQL- und Objektschichten umgehen, führen zu Fehlern, die von oben schwer zu sehen sind: Werte, die überhaupt nicht gelesen werden können, Werte, die gültig aussehen, aber nicht den Metadaten entsprechen, und Werte, die stillschweigend angepasst werden, um einem erwarteten Typ zu entsprechen. Der Global Browser ist darüber absichtlich ehrlich. Wenn man ihn bittet, einen Knoten als $LISTBUILD zu interpretieren, und der Knoten nicht in diesem Format vorliegt, sagt er, dass das Format ungültig ist, und zeigt, was tatsächlich dort ist, anstatt plausiblen Unsinn zu rendern oder mit einem Stack Trace zu versagen.

Dieses Verhalten passt zur Fehlerbehandlung beim Lesen im SQL-Editor: Der Editor findet die Zeile und Spalte eines Werts, der nicht seinen Metadaten entspricht, und der Global Browser sagt, was dort gespeichert ist.

Von der Tabelle zum Storage und zurück

Der Weg zu einem Global beginnt meist bei einer Tabelle. Die IRIS-Storage- und Index-Tabs des Table Viewer nennen die Globals, in denen eine Tabelle und ihre Indizes tatsächlich leben, zusammen mit ihren Größen, sodass man von „diese Tabelle ist 14 GB" zum spezifischen Global, der sie hält, gehen kann, und dann hier in diesen Global einsteigen. In die andere Richtung zu arbeiten ist genauso üblich: einen verwaisten Subscript im Browser finden, dann zurück zu SQL gehen, um herauszufinden, welche Anwendung ihn geschrieben hat.

Größen sind auf diesem Weg beachtenswert. Eine Tabelle, deren Index-Globals größer geworden sind als ihr Daten-Global, ist meist eine Geschichte über einen redundanten Index, und das ist eine Frage für die Performance-Tools.

Es gibt eine dritte Richtung, und sie beantwortet die Frage „darf ich das anfassen?". Klicken Sie einen Global mit der rechten Maustaste an und wählen Sie Where is this used?: Der Global-Name wandert — ohne führendes ^ und ohne Subscripts — direkt in eine serverseitige Suche über alle Klassen und Routinen des Namespace. Zum Durchsuchen wird nichts heruntergeladen, und die Antwort kommt in wenigen Sekunden. Siehe Suche.

Von der Ergebniszeile direkt zum Global-Knoten

Seit 4.02 genügt ein Rechtsklick auf eine Zeile in einem Abfrageergebnis gegen IRIS oder Caché und Show in Global Browser..., um genau den Subscript zu öffnen, an dem diese Zeile liegt — nicht nur der Global-Name, sondern die echten Subscript-Werte dieser Zeile, egal ob der Schlüssel eine einzelne Zahl oder mehrere Spalten zusammen ist. Wählen Sie mehrere Zeilen aus, bekommen Sie stattdessen eine Auswahlliste, einen Eintrag pro Zeile.

Das funktioniert nur, wenn sich die Tabelle der Zeile eindeutig auf eine einzelne, gewöhnliche persistente Klasse auflösen lässt — nicht bei einem Join oder einer View, und nicht bei einer Tabelle mit angepasstem Storage —, denn nur dann kann SQL DATA LENS sicher sein, welchen Global und welche Subscripts Sie meinen. Geht das nicht, nennt die Statusleiste, welche der beiden Bedingungen fehlgeschlagen ist, statt zu raten. Das steht in jeder Edition zur Verfügung, genau wie das Browsen eines Live-Globals.

Einen .gof-Export ganz ohne Server öffnen

Eine .gof-Datei ist ein InterSystems-Global-Export im Blockformat (%GOF, OutputFormat 7 von %Library.Global bzw. dem „Export Globals" des Management Portal mit „block format"). Seit 4.02 öffnet File > Open .gof File... eine solche Datei direkt und zeigt sie wie einen Live-Global — ohne Verbindung zurück zu dem Server, von dem sie stammt, sodass sich ein Dump von einem Kundensystem oder aus einem Incident auf einem Notebook ansehen lässt, das dieses Netz nie gesehen hat.

Der Header nennt Formatversion, Exportzeitpunkt und den Namespace, aus dem der Export stammt; die Globalliste links zeigt Node- und Byte-Zahlen je Global, und der Subscript-Baum darunter klappt Ebene für Ebene auf, genau wie der Live-Browser — ein Export von mehreren Gigabyte mit Millionen Nodes bleibt so navigierbar, statt auf einmal geladen zu werden. Das Value-Panel zeigt einen Knoten als Text, als Hex-Dump oder dekodiert als $LIST-Elemente, und sagt ausdrücklich, wenn ein Wert nicht dekodiert werden kann, statt etwas plausibel Aussehendes zu zeigen. Filtern Sie die Globalliste nach Name oder Muster, springen Sie mit Go to direkt zu einem Knoten (zum Beispiel ^Global(1,"x")), und exportieren oder kopieren Sie eine Auswahl als ZWRITE-Text oder CSV.

Zwei Grenzen, die Sie kennen sollten, bevor Sie sich darauf verlassen: Nur 8-KB-Datenbanken im Little-Endian-Blockformat, wie es aktuelles IRIS und Caché 2017.1+ schreiben, werden unterstützt — eine 2-KB-Datenbank oder eine Big-Endian-Datei wird mit einer Meldung abgelehnt, die nennt, was gefunden wurde —, und bei einem Mehrvolumen-Export wird nur das geöffnete Volume gelesen, sodass auf einem anderen Volume fortgesetzte Globals unvollständig zurückkommen. Das Öffnen einer .gof-Datei braucht Named User oder höher; die Free Edition zeigt den Menüeintrag ausgegraut mit dem Grund dabei, statt ihn zu verstecken.

Die Fähigkeit, den eigenen Storage lesen zu können, verändert, wie schnell seltsame Daten erklärt werden — ein zehnminütiger Blick statt eines Tickets an denjenigen, der Terminal-Zugriff hat. Das Browsen eines Live-Globals und der Sprung aus einer Ergebniszeile stehen in jeder Edition zur Verfügung, auch in der Free Edition; das Öffnen einer .gof-Datei offline ist der einzige Teil dieser Seite, der Named User oder höher braucht, weil er ganz ohne Serververbindung auskommt und die Edition dann das einzig verbleibende Kriterium ist. SQL DATA LENS herunterladen und einen Global auf einem Test-Namespace öffnen, um zu sehen, wie Ihre Tabellen darunter wirklich aussehen.

Explore your IRIS data from SQL down to globals

Download, unzip, connect. Your first namespace is on screen in about three minutes.

Windows 10, 11 and Windows Server (64-bit) · ~130 MB · version 4.02 · full 30-day Pro trial included