Bases de données

Smartblobs externes utilisateur utilisant un Shadow Directory

Mary Schulte

16 décembre 2024

smartblobs utilise un répertoire fantôme

Je suis très enthousiaste à propos de la fonction smartblob externe de HCL Informix® 15.

Si vous ne les connaissez pas, les smartblobs externes permettent à l'utilisateur de stocker des données Binary Large Object (blob) et Character Large Object (clob) en dehors de la base de données. Les métadonnées relatives à ce stockage externe sont gérées par la base de données.

Notes : Cet article ne discute PAS des détails de la fonctionnalité smartblobs elle-même, mais propose plutôt une solution pour rendre la fonctionnalité plus utilisateur. Pour plus de détails sur le comportement de la fonctionnalité, la configuration et les nouvelles fonctions, voir la documentation.

Au moment de la rédaction de ce blog, la v15.0 n'a pas la fonction ifx_lo_path définie, comme requis ci-dessous. Ce problème a été signalé à l'ingénierie. La solution consiste à la créer soi-même à l'aide de la commande suivante :

create dba function ifx_lo_path(blob)
  renvoie lvarchar
  nom externe '(sq_lo_path)'
  langage C ;

Cet article n'aborde pas non plus les détails de la programmation client nécessaire pour INSÉRER des blobs et des clobs dans la base de données.

La fonction smartblob externe a été créée pour deux raisons principales :

1. Taille de la sauvegarde

Le stockage des blobs dans la base de données elle-même peut rendre la base de données extrêmement volumineuse. Les sauvegardes de la base de données prennent alors un temps considérable et les sauvegardes de niveau 0 peuvent s'avérer impossibles. Le fait de décharger le contenu réel des blobs vers un système de fichiers externe peut alléger la charge de sauvegarde de HCL Informix en plaçant les données des blobs à un autre endroit. La base de données régit toujours le stockage et l'accès au blob, mais le blob physique est hébergé ailleurs/à l'extérieur.

2. Accès facile aux blobs

Les utilisateurs aimeraient accéder facilement aux données blob, avec des outils familiers, sans avoir à passer par la base de données.

Utilisation de Smartblobs externes dans HCL Informix 15

HCL Informix 15 introduit les smartblobs externes. Lorsque vous définissez un espace smartblob externe, vous spécifiez l'emplacement du répertoire externe (en dehors de la base de données) où vous souhaitez que les données blob soient stockées. Vous affectez ensuite une ou plusieurs colonnes de blob à cet espace smartblob externe lorsque vous créez une table. Lorsqu'une ligne est insérée, HCL Informix stocke les données blob dans le répertoire défini en utilisant un identifiant interne pour le nom de fichier.

Voici un exemple de table de formulaires clients : custforms (dénormalisé et codé en dur pour plus de simplicité). Mon répertoire sbspace externe est /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) ;

Ici, j'INSÈRE un document TaxForm123 2023 à partir d'un programme Java pour une femme nommée Sanchez, qui travaille pour Actian :

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();
}

Après avoir INSÉRÉ cette ligne, mon répertoire et mon fichier externes ressembleront à ceci :

[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 :
total 0
drwxrwx--- 2 informix informix 41 Oct 17 13:19 IFMXSB0
[informix@schma01-rhvm03 resources]$ ls esbsp_dir1/IFMXSB0
LO[2,2,1(0x102),1729188125]

Où LO[2,2,1(0x102),1729188125]est un fichier réel qui contient les données auxquelles je pourrais accéder directement. Le problème est que si je veux accéder directement à ce fichier pour Mme Sanchez, je dois d'abord m'assurer que ce fichier lui appartient et qu'il s'agit du document fiscal que je veux. C'est très énigmatique !

Une solution Smartblob utilisateur

Les clients d'Informix apprécient la nouvelle fonction "smartblobs" externe, mais souhaiteraient qu'elle soit un peu plus utilisateur.

Comme dans l'exemple ci-dessus, au lieu de placer la TaxForm123 2023 de Sanchez dans un répertoire général appelé IFMXSB0 dans un fichier appelé LO[2,2,1(0x102),1729188125, qui ensemble n'ont pas de sens pour un utilisateur utilisateur, ne serait-il pas préférable que le fichier soit situé dans un endroit intuitif comme /home/forms/Actian/2024/TaxForm123/Sanchez.xml ou quelque chose de similaire... quelque chose de significatif... comme VOUS voulez qu'il soit organisé ?

Faire en sorte que HCL Informix le fasse automatiquement est un peu plus facile à dire qu'à faire, principalement parce que la base de données ne saurait pas intuitivement comment un client donné souhaiterait organiser ses blobs. Quelle est la sous-structure exacte du répertoire ? À partir de quelle(s) colonne(s) dois-je former les noms de fichiers ? Dans quel ordre ? Tous les cas d'utilisation seraient différents.

Tirer parti d'un répertoire fantôme utilisateur

La solution suivante montre comment vous pouvez créer vos propres emplacements logiques utilisateur vos smartblobs externes en maintenant automatiquement une structure de répertoire fantôme légère correspondant aux emplacements de stockage réels. La solution utilise un système très simple de déclencheurs et de procédures stockées pour y parvenir.

Remarque : les exemples sont présentés ici sous Linux, mais d'autres variantes d'UNIX devraient également fonctionner.

Comment s'installer en 4 étapes

Pour chaque colonne smartblob en question

ÉTAPE 1 : Décidez de la manière dont vous souhaitez organiser l'accès à vos fichiers.

Décidez de la base de votre répertoire fantôme et créez-la. Dans mon cas, pour ce blog, il s'agit de /home/informix/blog/resources/utilisateur-friendly : utilisateur. Vous pourriez probablement mettre en œuvre cette solution sans définir de répertoire de base (comme dans les exemples), mais ce n'est peut-être pas une bonne idée car les utilisateurs commenceraient à créer des répertoires partout sans le savoir.

ÉTAPE 2 : Créer une procédure stockée create_link et un déclencheur correspondant pour les INSERT.

Cette procédure s'assure que la structure de sous-répertoire pilotée par les données souhaitée existe à partir de la base (mkdir -p), puis établit un lien logique utilisateur avec le fichier Informix smartblob. Vous devez transmettre à cette procédure toutes les colonnes à partir desquelles vous souhaitez créer la structure de répertoire et le nom de fichier à partir du déclencheur.

CRÉER UNE PROCÉDURE

CREATE PROCEDURE create_link (p_formid INT, p_company CHAR(20), p_year INT,
p_nom CHAR(20), p_nom de la forme CHAR(50))
DEFINE v_oscommand CHAR(500) ;
DEFINE v_custlinkname CHAR(500) ;
DEFINE v_ifmxname CHAR(500) ;
DEFINE v_basedir CHAR(100) ;
-- définir le répertoire de base
LET v_basedir = '/home/informix/blog/'.utilisateur" ;
-- s'assurer que l'arborescence des répertoires existe
LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || 
TO_CHAR(p_year) ;
SYSTEM v_oscommand ; 

-- former le nom complet du lien 
LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year) 
|| '/' || TRIM(p_lname) || '. || TRIM(p_formname) || '.' | TO_CHAR(p_formid) ;

-- obtenir l'emplacement réel 
SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid ; 

-- créer le lien os 
LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) || '''' || ' ' || v_custlinkname ; 
SYSTEM v_oscommand ;

FIN DE LA PROCÉDURE

CREATE TRIGGER

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)) ;

ÉTAPE 3 : Créer une procédure stockée delete_link et un déclencheur correspondant pour les DELETEs.

Cette procédure supprime le lien avec le répertoire fantôme si la ligne est supprimée.

CRÉER UNE PROCÉDURE

CREATE PROCEDURE delete_link (p_formid INT, p_company CHAR(20), p_year INT,
p_nom CHAR(20), p_nom du formulaire CHAR(50))
DEFINE v_oscommand CHAR(500) ;
DEFINE v_custlinkname CHAR(500) ; 
DEFINE v_basedir CHAR(100) ;
-- définir le répertoire de base
LET v_basedir = '/home/informix/blog/'.utilisateur" ;
-- former le nom complet du lien
LET v_custlinkname = TRIM(v_basedir) || '/' ||
TRIM(p_company) || '/' || TO_CHAR(p_year) || '/' || TRIM(p_lname) || '.
|| TRIM(p_formname) || '.' | TO_CHAR(p_formid) ;
-- supprimer le lien
LET v_oscommand = 'rm -f -d ' || v_custlinkname ;
SYSTEM v_oscommand ;

FIN DE LA PROCÉDURE

CREATE TRIGGER

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)) ;

ÉTAPE 4 : créer une procédure stockée change_link et un déclencheur correspondant pour les mises à jour, si nécessaire. Dans mon exemple, Mme Sanchez pourrait se marier avec M. Simon et une mise à jour de son nom de famille dans la base de données se produirait. Je peux alors vouloir changer tous mes noms utilisateur de Sanchez en Simon. Cette procédure supprime l'ancien lien et en crée un nouveau.

Notez que le déclencheur de mise à jour ne doit être déclenché que sur les colonnes qui forment la structure de votre répertoire et les noms de fichiers.

CRÉER UNE PROCÉDURE

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) ;
-- définit le répertoire de base
LET v_basedir = 'utilisateur' ;

-- se débarrasser de l'ancien

-- former l'ancien nom de lien complet
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) ;

-- supprimer le lien et les répertoires vides
LET v_oscommand = 'rm -f -d ' || v_custlinkname ;
SYSTEM v_oscommand ;

-- former le nouveau
-- s'assurer que l'arborescence des répertoires existe
LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_post_company) || '/' || 
TO_CHAR(p_post_year) ;
SYSTEM v_oscommand ;

-- former le nom complet du lien
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) ;

-- obtient l'emplacement actuel
-- c'est la même chose que précédemment puisque l'identifiant n'a pas changé
SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid ;

-- créer le lien os
LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) || '''' || ' ' || v_custlinkname ;
SYSTEM v_oscommand ;

FIN DE LA PROCÉDURE

CREATE TRIGGER

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)) ;

Exemple de résultats

Revenons à notre exemple.

Avec cette infrastructure en place, en plus du fichier nommé Informix, je disposerais de ces liens utilisateur sur mon système de fichiers que je pourrais facilement localiser et identifier.

INSÉRER

[informix@schma01-rhvm03 2023]$ pwd
/home/informix/blog/resources/utilisateur
[informix@schma01-rhvm03 2023]
$ ls Sanchez.TaxForm123.2

Si je fais un ls -l, vous verrez qu'il s'agit d'un lien vers le fichier Informix blob.

[informix@schma01-rhvm03 2023]$ ls -l
total 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]

MISE À JOUR

Si je mets à jour son nom de famille avec UPDATE custforms SET lname = 'Simon' where formid=2, mon système de fichiers ressemble maintenant à ceci :

[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

Si je supprime ensuite ce formulaire avec DELETE FROM custforms where formid=2, la structure de mon répertoire ressemble à ceci :

[informix@schma01-rhvm03 2023]$ pwd
utilisateur
[informix@schma01-rhvm03 2023]$ ls
[informix@schma01-rhvm03 2023]$

Nous vous invitons à nous faire part de vos commentaires

Profitez de la nouvelle fonction smartblob externe de HCL Informix15.

J'espère que cette idée vous permettra d'utiliser plus facilement les smartblobs externes. Si vous avez des commentaires sur cette idée, en particulier sur les améliorations ou l'expérience en production, n'hésitez pas à me contacter à l'adresse mary.schulte@hcl-software.com. J'attends vos commentaires avec impatience !

En savoir plus sur le lancement de HCL Informix 15.

Notes

1. Permissions des répertoires fantômes. Lors de la création de cet exemple, je n'ai pas exploré les autorisations de répertoire et de fichier, mais je me suis contenté d'utiliser les paramètres généraux d'autorisation sur mon serveur bac à sable. Il est probable que vous souhaitiez contrôler les autorisations afin d'éviter certaines des anomalies décrites ci-dessous.

2. Suppression manuelle du fichier blob. Avec les smartblobs externes, si les autorisations ne sont pas contrôlées, il est possible qu'un utilisateur supprime d'une manière ou d'une autre le fichier smartblob physique lui-même de son répertoire. HCL Informix ne peut pas contrôler ce phénomène. Dans ce cas, HCL Informix ne supprime PAS la ligne correspondante ; le fichier blob est simplement manquant. Il est possible que certains aspects des liens puissent gérer automatiquement ce problème, mais je ne les ai pas étudiés dans le cadre de ce blog.

3. Suppression de liens dans le répertoire fantôme. Si les permissions ne sont pas contrôlées, il est possible qu'un utilisateur supprime un lien logique formé par cette infrastructure. Cette solution ne détecte pas ce phénomène. Si c'est un problème, je suggérerais un travail de maintenance périodique qui croise les liens du répertoire shadow avec les fichiers blob pour détecter les liens manquants. Pour les blobs dont les liens sont manquants, il faut écrire un programme de base de données qui recherche l'emplacement de la ligne à l'aide de la fonction IFX_LO_PATH et qui réforme le lien manquant.

4. Identifiants uniques. Je recommande vivement l'utilisation d'identifiants uniques dans cette solution. Dans cet exemple simple, j'ai utilisé formid. Vous ne voulez pas encombrer les choses, bien sûr, mais selon la façon dont vous structurez vos répertoires et noms de fichiers fantômes, vous pouvez avoir besoin d'inclure plus d'identificateurs uniques pour éviter la duplication des noms de répertoires et de liens.

5. Répertoires vides. Je n'ai pas cherché à savoir s'il existait des options à rm dans la procédure stockée de suppression pour nettoyer les répertoires vides qui pourraient subsister après la suppression d'un dernier élément.

6. Frais généraux de production. On sait qu'un nombre excessif de déclencheurs et de procédures stockées peut alourdir la charge de travail d'un environnement de production. Pour ce blog, on suppose que l'activité OLTP sur les blobs n'est pas excessive, et que la surcharge de production ne devrait donc pas être un problème. Ceci étant dit, cette solution n'a PAS été testée à grande échelle.

7. Valeurs NULL. Veillez à prendre en compte la présence et l'impact des valeurs NULL dans les colonnes utilisées dans cette solution. Par souci de simplicité, je ne les ai pas traitées ici.

Informix est une marque déposée d'IBM Corporation dans au moins une juridiction et est utilisée sous licence.

 

photo de mary schulte

À propos de Mary Schulte

Mary Schulte est ingénieur commercial principal chez Actian. Elle s'appuie sur des décennies d'expérience avec des fournisseurs de bases de données de premier plan tels qu'Informix et Netezza. Elle a écrit des milliers de lignes d'Informix 4GL et ESQL/C pour des clients internationaux, y compris la mise en œuvre révolutionnaire de la datablade d'American Airlines. Mary a animé d'innombrables sessions d'apprentissage , aidant les organisations à optimiser leurs environnements de bases de données. Ses articles sur le blogue d'Actian portent sur les performances des requête , les bases de données analytiques comme Vector et les conseils pratiques pour tirer parti d'Informix. Consultez ses articles pour obtenir des conseils d'experts.