Nutzer externe Smartblobs mit einem Schattenverzeichnis
Maria Schulte
16. Dezember 2024

Ich bin sehr begeistert von der externen Smartblob-Funktion von HCL Informix® 15.
Externe Smartblobs ermöglichen es dem Nutzer , Binary Large Object (blob) und Character Large Object (clob) Daten extern in der Datenbank zu speichern, falls Sie damit nicht vertraut sind. Die Metadaten über diesen externen Speicher werden von der Datenbank verwaltet.
Anmerkungen: Dieser Artikel befasst sich NICHT mit den Details der Smartblobs-Funktion selbst, sondern schlägt eine Lösung vor, um die Funktionalität Nutzer zu gestalten. Details zum Verhalten der Funktion, zur Einrichtung und zu den neuen Funktionen finden Sie in der Dokumentation.
Zum Zeitpunkt der Erstellung dieses Blogs ist in v15.0 die Funktion ifx_lo_path nicht definiert, wie unten gefordert. Dies wurde der Technik gemeldet. Die Umgehung besteht darin, sie mit dem folgenden Befehl selbst zu erstellen:
dba-Funktion ifx_lo_path(blob) erstellen gibt lvarchar zurück externer Name '(sq_lo_path)' Sprache C;
In diesem Artikel wird auch nicht auf Einzelheiten der Client-Programmierung eingegangen, die für das INSERT von Blobs und Clobs in die Datenbank erforderlich ist.
Die externe Smartblob-Funktion wurde vor allem aus zwei Gründen entwickelt:
1. Größe der Backup
Die Speicherung von Blobs in der Datenbank selbst kann dazu führen, dass die Datenbank extrem groß wird. Daher nimmt die Durchführung von Sicherungen der Datenbank unangemessen viel Zeit in Anspruch, und Sicherungen auf 0-Ebene können unmöglich sein. Das Auslagern der eigentlichen Blob-Inhalte in ein externes Dateisystem kann die backup verringern, indem die Blob-Daten woanders abgelegt werden. Die Datenbank verwaltet nach wie vor die Speicherung und den Zugriff auf den Blob, aber der physische Blob ist an einem anderen Ort/extern untergebracht.
2. Einfacher Zugang zu Blobs
Die Nutzer wünschen sich einen einfachen Zugriff auf Blob-Daten mit vertrauten Werkzeugen, ohne die Datenbank durchforsten zu müssen.
Verwendung externer Smartblobs in HCL Informix 15
Mit HCL Informix 15 werden externe Smartblobs eingeführt. Wenn Sie einen externen Smartblobspace definieren, geben Sie den externen Verzeichnisspeicherort (außerhalb der Datenbank) an, in dem die eigentlichen Blobdaten gespeichert werden sollen. Dann weisen Sie beim CREATE TABLE diesem externen Smartblobspeicher Blobspalte(n) zu. Wenn eine Zeile EINGESETZT wird, speichert HCL Informix die Blobdaten in dem definierten Verzeichnis unter Verwendung eines internen Bezeichners für den Dateinamen.
Hier ist ein Beispiel für eine Tabelle mit Kundenformularen: custforms (der Einfachheit halber denormalisiert und hartkodiert). Mein externes sbspace-Verzeichnis ist /home/informix/blog/resources/esbsp_dir1.
CREATE TABLE custforms(formid SERIAL, company CHAR(20), year INT, lname CHAR(20), formname CHAR(50), form CLOB) PUT form IN (esbsp);
Hier füge ich ein 2023 TaxForm123-Dokument aus einem Java für eine Frau namens Sanchez ein, die für Actian arbeitet:
try(PreparedStatement p = c.prepareStatement("INSERT INTO custforms (company, year, lname, formname, form) values(?,?,?,?,?)"); FileInputStream is = new FileInputStream("file.xml")) { p.setString(1, "Actian"); p.setString(2, "2023"); p.setString(3, "Sanchez"); p.setString(4, "TaxForm123"); p.setBinaryStream(5, is); p.executeUpdate(); }
Nachdem ich diese Zeile eingefügt habe, würden mein externes Verzeichnis und meine Datei wie folgt aussehen:
[informix@schma01-rhvm03 resources]$ pwd /home/informix/blog/resources [informix@schma01-rhvm03 resources]$ ls -l esbsp* -rw-rw---- 1 informix informix 10240000 Oct 17 13:22 esbsp_chunk1 esbsp_dir1: gesamt 0 drwxrwx--- 2 informix informix 41 Okt 17 13:19 IFMXSB0 [informix@schma01-rhvm03 resources]$ ls esbsp_dir1/IFMXSB0 LO[2,2,1(0x102),1729188125]
Dabei ist LO[2,2,1(0x102),1729188125]eine tatsächliche Datei, die die Daten enthält, auf die ich direkt zugreifen könnte. Das Problem ist, dass ich, wenn ich direkt auf diese Datei für Frau Sanchez zugreifen möchte, erst herausfinden müsste, dass diese Datei ihr gehört und das gewünschte Steuerdokument ist. Das ist sehr kryptisch!
Eine Nutzer Smartblob-Lösung
Wenn ich mit Informix-Kunden spreche, lieben sie die neue Funktion der externen Smartblobs, aber sie wünschen sich, dass sie etwas Nutzer sein könnte.
Anstatt, wie im obigen Beispiel, Sanchez' 2023 TaxForm123 in ein allgemeines Verzeichnis mit dem Namen IFMXSB0 in eine Datei mit dem Namen LO[2,2,1(0x102),1729188125 zu legen, die zusammen für einen Nutzer bedeutungslos sind, wäre es nicht schön, wenn sich die Datei an einem intuitiven Ort wie /home/forms/Actian/2024/TaxForm123/Sanchez.xml oder etwas Ähnlichem befinden würde... etwas Sinnvolles... wie SIE es haben wollen?
Dass HCL Informix dies automatisch tut, ist leichter gesagt als getan, vor allem weil die Datenbank nicht intuitiv weiß, wie ein Kunde seine Blobs organisieren möchte. Welche genaue Verzeichnisunterstruktur? Aus welcher Spalte oder welchen Spalten werden die Dateinamen gebildet? In welcher Reihenfolge? Jeder Anwendungsfall wäre anders.
Nutzung eines Nutzer Schattenverzeichnisses
Die folgende Lösung zeigt, wie Sie Ihre eigenen Nutzer logischen Speicherorte für Ihre externen Smartblobs erstellen können, indem Sie automatisch eine leichtgewichtige Schattenverzeichnisstruktur pflegen, die den tatsächlichen Speicherorten entspricht. Die Lösung verwendet ein sehr einfaches System von Triggern und gespeicherten Prozeduren, um dies zu erreichen.
Hinweis: Die Beispiele werden unter Linux gezeigt, aber andere UNIX-Varianten sollten auch funktionieren.
Einrichten in 4 Schritten
Für jede betreffende Smartblob-Spalte
SCHRITT 1: Entscheiden Sie, wie Sie den Zugriff auf Ihre Dateien organisieren wollen.
Entscheiden Sie, was die Basis Ihres Schattenverzeichnisses sein soll, und erstellen Sie es. In meinem Fall für dieses Blog ist es: Nutzer. Sie könnten diese Lösung wahrscheinlich auch ohne ein festgelegtes Basisverzeichnis implementieren (wie in den Beispielen zu sehen), aber das ist möglicherweise keine gute Idee, weil die Benutzer unwissentlich überall Verzeichnisse anlegen würden.
SCHRITT 2: Erstellen Sie eine gespeicherte Prozedur create_link und einen entsprechenden Trigger für INSERTs.
Diese Prozedur stellt sicher, dass die gewünschte data driven Unterverzeichnisstruktur von der Basis aus existiert (mkdir -p), und bildet dann eine Nutzer logische Verknüpfung mit der Informix-Smartblob-Datei. Sie müssen dieser Prozedur alle Spalten übergeben, aus denen Sie die Verzeichnisstruktur und den Dateinamen aus dem Trigger bilden wollen.
VERFAHREN ERSTELLEN
CREATE PROCEDURE create_link (p_formid INT, p_company CHAR(20), p_year INT, p_lname CHAR(20), p_formname CHAR(50))
DEFINE v_oscommand CHAR(500); DEFINE v_custlinkname CHAR(500); DEFINE v_ifmxname CHAR(500); DEFINE v_basedir CHAR(100);
-- das Basisverzeichnis festlegen LET v_basedir = '/home/informix/blog/Nutzer";
-- Sicherstellen, dass der Verzeichnisbaum existiert LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year); SYSTEM v_oscommand; -- vollständigen Link-Namen bilden LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year) || '/' || TRIM(p_lname) || '.' || TRIM(p_formname) || '.' || TO_CHAR(p_formid); -- Ermitteln des tatsächlichen Speicherorts SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid; -- Erstellen des os-Links LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) || '''' || ' ' || v_custlinkname; SYSTEM v_oscommand; END PROCEDURE
TRIGGER ERZEUGEN
CREATE TRIGGER ins_tr INSERT ON custforms REFERENCING new AS post FOR EACH ROW(EXECUTE PROCEDURE create_link (post.formid, post.company, post.year, post.lname, post.formname));
SCHRITT 3: Erstellen Sie eine delete_link Stored Procedure und einen entsprechenden Trigger für DELETEs.
Bei diesem Verfahren wird die Schattenverzeichnisverknüpfung gelöscht, wenn die Zeile gelöscht wird.
VERFAHREN ERSTELLEN
CREATE PROCEDURE delete_link (p_formid INT, p_company CHAR(20), p_year INT, p_lname CHAR(20), p_formname CHAR(50))
DEFINE v_oscommand CHAR(500); DEFINE v_custlinkname CHAR(500);; DEFINE v_basedir CHAR(100);
-- das Basisverzeichnis festlegen LET v_basedir = '/home/informix/blog/Nutzer";
-- vollständigen Link-Namen bilden LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year) || '/' || TRIM(p_lname) || '.' || TRIM(p_formname) || '.' || TO_CHAR(p_formid);
-- den Link entfernen LET v_oscommand = 'rm -f -d ' || v_custlinkname; SYSTEM v_oscommand; END PROCEDURE
TRIGGER ERZEUGEN
CREATE TRIGGER del_tr DELETE ON custforms REFERENCING old AS pre FOR EACH ROW (EXECUTE PROCEDURE delete_link (pre.formid, pre.company, pre.year, pre.lname, pre.formname));
SCHRITT 4: Erstellen Sie eine change_link Stored Procedure und einen entsprechenden Trigger für UPDATEs, falls gewünscht. In meinem Beispiel könnte Frau Sanchez Herrn Simon heiraten und es erfolgt ein UPDATE ihres Nachnamens in der Datenbank. Ich möchte dann vielleicht alle Nutzer Namen von Sanchez in Simon ändern. Dieses Verfahren löscht die alte Verknüpfung und erstellt eine neue.
Beachten Sie, dass der Aktualisierungs-Trigger nur auf die Spalten wirken muss, die Ihre Verzeichnisstruktur und Dateinamen bilden.
VERFAHREN ERSTELLEN
CREATE PROCEDURE change_link (p_formid INT, p_pre_company CHAR(20), p_pre_year INT, p_pre_lname CHAR(20), p_pre_formname CHAR(50), p_post_company CHAR(20), p_post_year INT, p_post_lname CHAR(20), p_post_formname CHAR(50)) DEFINE v_oscommand CHAR(500); DEFINE v_custlinkname CHAR(500); DEFINE v_ifmxname CHAR(500); DEFINE v_basedir CHAR(100); -- Festlegen des Basisverzeichnisses LET v_basedir = 'Nutzer'; -- altes Verzeichnis loswerden -- alten vollständigen Linknamen bilden LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_pre_company) || '/' || TO_CHAR(p_pre_year) || '/' || TRIM(p_pre_lname) || '.' || TRIM(p_pre_formname) || '.' || TO_CHAR(p_formid) ; -- Entfernen des Links und der leeren Verzeichnisse LET v_oscommand = 'rm -f -d ' || v_custlinkname; SYSTEM v_oscommand; -- bilden Sie den neuen -- Sicherstellen, dass der Verzeichnisbaum existiert LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_post_company) || '/' || TO_CHAR(p_post_year); SYSTEM v_oscommand; -- vollständigen Link-Namen bilden LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_post_company) || '/' || TO_CHAR(p_post_year) || '/' || TRIM(p_post_lname) || '.' || TRIM(p_post_formname) || '.' || TO_CHAR(p_formid) ; -- Ermittelt den tatsächlichen Ort -- dies ist derselbe wie zuvor, da sich die id nicht geändert hat SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid; -- Erstellen des os-Links LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) || '''' || ' ' || v_custlinkname; SYSTEM v_oscommand; END PROCEDURE
TRIGGER ERZEUGEN
CREATE TRIGGER upd_tr UPDATE OF formid, company, year, lname, formname ON custforms REFERENCING OLD AS pre NEW as post FOR EACH ROW(EXECUTE PROCEDURE change_link (pre.formid, pre.company, pre.year, pre.lname, pre.formname, post.company, post.year, post.lname, post.formname));
Ergebnisse Beispiel
Zurück zu unserem Beispiel.
Mit dieser Infrastruktur hätte ich nun zusätzlich zu der Informix-benannten Datei diese Nutzer Links in meinem Dateisystem, die ich leicht auffinden und identifizieren kann.
INSERT
[informix@schma01-rhvm03 2023]$ pwd
/home/informix/blog/resources/Nutzer [informix@schma01-rhvm03 2023]
$ ls Sanchez.TaxForm123.2
Wenn ich ls -l ausführe, sehen Sie, dass es sich um einen Link auf die Informix-Blob-Datei handelt.
[informix@schma01-rhvm03 2023]$ ls -l gesamt 0 lrwxrwxrwx 1 informix informix 76 Oct 17 14:20 Sanchez.TaxForm123.2 -> /home/informix/blog/resources/esbsp_dir1/IFMXSB0/LO[2,2,1(0x102),1729188126]
UPDATE
Wenn ich dann ihren Nachnamen mit UPDATE custforms SET lname = 'Simon' where formid=2 aktualisiere, sieht mein Dateisystem jetzt so aus:
[informix@schma01-rhvm03 2023]$ ls -l lrwxrwxrwx 1 informix informix 76 Oct 17 14:25 Simon.TaxForm123.2 -> /home/informix/blog/resources/esbsp_dir1/IFMXSB0/LO[2,2,1(0x102),1729188126]
DELETE
Wenn ich dann dieses Formular mit DELETE FROM custforms where formid=2 lösche, sieht meine Verzeichnisstruktur wie folgt aus:
[informix@schma01-rhvm03 2023]$ pwd Nutzer [informix@schma01-rhvm03 2023]$ ls [informix@schma01-rhvm03 2023]$
Wir begrüßen Ihr Feedback
Wir wünschen Ihnen viel Spaß mit der neuen externen Smartblob-Funktion von HCL Informix15.
Ich hoffe, dass diese Idee die Verwendung externer Smartblobs für Sie einfacher machen kann. Wenn Sie Feedback zu dieser Idee haben, insbesondere zu Verbesserungen oder Erfahrungen in der Produktion, können Sie mich gerne unter mary.schulte@hcl-software.com kontaktieren . Ich freue mich darauf, von Ihnen zu hören!
Erfahren Sie mehr über die Einführung von HCL Informix 15.
Anmerkungen
1. Schattenverzeichnis-Berechtigungen. Bei der Erstellung dieses Beispiels habe ich keine Verzeichnis- und Dateiberechtigungen kennenlernen , sondern nur allgemeine Berechtigungseinstellungen auf meinem Sandbox-Server verwendet. Wahrscheinlich werden Sie die Berechtigungen kontrollieren wollen, um einige der Anomalien zu vermeiden, die ich unten bespreche.
2. Manuelles Löschen der Blobdatei. Bei externen Smartblobs ist es möglich, dass ein Nutzer die physische Smartblob-Datei selbst aus ihrem Verzeichnis löscht, wenn die Berechtigungen nicht kontrolliert werden. HCL Informix selbst kann dies nicht verhindern. In diesem Fall löscht HCL Informix die entsprechende Zeile NICHT; die Blob-Datei ist dann einfach nicht mehr vorhanden. Es mag Aspekte von Links geben, die dies automatisch handhaben können, aber ich habe sie für diesen Blog nicht untersucht.
3. Löschung von Links im Schattenverzeichnis. Wenn die Berechtigungen nicht kontrolliert werden, ist es möglich, dass ein Nutzer eine logische Verknüpfung löscht, die durch diese Infrastruktur gebildet wird. Diese Lösung erkennt dies nicht. Wenn dies ein Problem ist, würde ich einen regelmäßigen Wartungsjob vorschlagen, der die Links des Schattenverzeichnisses mit den Blobs abgleicht, um fehlende Links zu erkennen. Für die Blobs mit fehlenden Links sollte ein Datenbankprogramm geschrieben werden, das mit der Funktion IFX_LO_PATH den Standort der Zeile ermittelt und den fehlenden Link neu erstellt.
4. Eindeutige Bezeichner. Ich empfehle dringend die Verwendung eindeutiger Bezeichner in dieser Lösung. In diesem einfachen Beispiel habe ich formid verwendet. Sie wollen natürlich nicht alles durcheinander bringen, aber je nachdem, wie Sie Ihre Schattenverzeichnisse und Dateinamen strukturieren, müssen Sie möglicherweise mehr eindeutige Bezeichner verwenden, um die Duplizierung von Verzeichnis- und Linknamen zu vermeiden.
5. Leere Verzeichnisse. Ich habe nicht untersucht, ob es in der gespeicherten Prozedur "delete" Optionen für "rm" gibt, um leere Verzeichnisse zu bereinigen, die zurückbleiben könnten, wenn ein letztes Element gelöscht wird.
6. Produktions-Overhead. Es ist bekannt, dass exzessive Trigger und gespeicherte Prozeduren in einer Produktionsumgebung einen Overhead verursachen können. In diesem Blog wird davon ausgegangen, dass die OLTP-Aktivität auf Blobs nicht übermäßig hoch ist, so dass der Produktions-Overhead kein Problem darstellen sollte. Allerdings wurde diese Lösung NICHT im großen Maßstab getestet.
7. NULL-Werte. Beachten Sie unbedingt das Vorhandensein und die Auswirkungen von NULL-Werten in den in dieser Lösung verwendeten Spalten. Der Einfachheit halber habe ich sie hier nicht behandelt.
Informix ist eine Marke der IBM Corporation in mindestens einer Gerichtsbarkeit und wird unter Lizenz verwendet.
Abonnieren Sie den Actian Blog
Abonnieren Sie den Blog von Actian, um direkt Dateneinblicke zu erhalten.
- Bleiben Sie auf dem Laufenden: Holen Sie sich die neuesten Informationen zu Data Analytics direkt in Ihren Posteingang.
- Verpassen Sie keinen Beitrag: Sie erhalten automatische E-Mail-Updates, die Sie informieren, wenn neue Beiträge veröffentlicht werden.
- Ganz wie sie wollen: Ändern Sie Ihre Lieferpräferenzen nach Ihren Bedürfnissen.