Smartblobs externos fáciles de usar mediante un directorio sombra
Mary Schulte
16 de diciembre de 2024

Estoy muy entusiasmado con la función de smartblob externo de HCL Informix® 15.
Si no está familiarizado con ellos, los smartblobs externos permiten al usuario almacenar datos reales Binary Large Object (blob) y Character Large Object (clob) externos a la base de datos. métadonnées sobre ese almacenamiento externo es mantenido por la base de datos.
Notas: Este artículo NO discute los detalles de la característica smartblobs en sí, sino que propone una solución para hacer la funcionalidad más fácil de usar. Para más detalles sobre el comportamiento, la configuración y las nuevas funciones, consulte la documentación.
Al escribir este blog, v15.0 no tiene definida la función ifx_lo_path, como se requiere a continuación. Esto ha sido reportado a ingeniería. La solución es crearla usted mismo con el siguiente comando:
create dba function ifx_lo_path(blob) devuelve lvarchar nombre externo '(sq_lo_path)' lenguaje C;
Este artículo tampoco trata los detalles de la programación cliente necesaria para INSERTAR blobs y clobs en la base de datos.
La función de smartblob externo se creó por dos razones principales:
1. Tamaño de la copia de seguridad
Almacenar blobs en la propia base de datos puede hacer que ésta se vuelva extremadamente grande. Por lo tanto, realizar copias de seguridad de la base de datos lleva mucho tiempo y las copias de seguridad de nivel 0 pueden resultar imposibles. La descarga del contenido real de los blobs a un sistema de archivos externo puede reducir la carga de las copias de seguridad de HCL Informix al colocar los datos de los blobs en otro lugar. La base de datos sigue controlando el almacenamiento y el acceso al blob, pero el blob físico se aloja en otro lugar o de forma externa.
2. Fácil acceso a las manchas
A los usuarios les gustaría acceder fácilmente a los datos blob, con herramientas conocidas, sin tener que pasar por la base de datos.
Uso de Smartblobs externos en HCL Informix 15
HCL Informix 15 introduce smartblobs externos. Cuando se define un espacio smartblob externo, se especifica la ubicación del directorio externo (fuera de la base de datos) donde se almacenarán los datos blob reales. A continuación, al crear una tabla (CREATE TABLE), se asignan columnas blob a ese espacio smartblob externo. Cuando se inserta una fila, HCL Informix almacena los datos blob en el directorio definido utilizando un identificador interno para el nombre de archivo.
Este es un ejemplo de una tabla de formularios de clientes: custforms (desnormalizada y codificada para simplificar). Mi directorio externo sbspace es /home/informix/blog/resources/esbsp_dir1.
CREAR TABLA custforms(formid SERIAL, company CHAR(20), year INT, lname CHAR(20), formname CHAR(50), form CLOB) PUT form IN (esbsp);
Aquí, INSERTO un documento 2023 TaxForm123 desde un programa Java para una mujer llamada Sánchez, que trabaja para 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(); }
Después de que INSERTAR esta fila, mi directorio externo y el archivo se vería así:
[informix@schma01-rhvm03 recursos]$ pwd /home/informix/blog/recursos [informix@schma01-rhvm03 resources]$ ls -l esbsp* -rw-rw---- 1 informix informix 10240000 17 oct 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]
Donde LO[2,2,1(0x102),1729188125]es un fichero real que contiene los datos a los que podría acceder directamente. El problema es que si quiero acceder directamente a este fichero de la Sra. Sánchez, primero tendría que averiguar que este fichero le pertenece y es el documento fiscal que quiero. ¡Es muy críptico!
Una solución Smartblob fácil de usar
Al hablar con los clientes de Informix, les encanta la nueva función de smartblobs externos, pero desearían que fuera un poco más fácil de usar.
Como en el ejemplo anterior, en lugar de poner el 2023 TaxForm123 de Sánchez en un directorio general llamado IFMXSB0 en un archivo llamado LO[2,2,1(0x102),1729188125, que juntos no tienen sentido para un usuario final, ¿no estaría bien que el archivo se ubicara en un lugar intuitivo como /home/forms/Actian/2024/TaxForm123/Sanchez.xml o algo similar...algo significativo...como USTED lo quiere organizado?
Conseguir que HCL Informix lo haga automáticamente es un poco más fácil de decir que de hacer, sobre todo porque la base de datos no sabría intuitivamente cómo querría organizar sus blobs un cliente concreto. ¿Qué subestructura de directorio exacta? ¿A partir de qué columna o columnas se forman los nombres de los archivos? ¿En qué orden? Todos los casos de uso serían diferentes.
Aprovechar un directorio en la sombra fácil de usar
La siguiente solución muestra cómo puede crear sus propias ubicaciones lógicas de fácil uso para sus smartblobs externos manteniendo automáticamente una estructura ligera de directorios sombra que se corresponda con las ubicaciones de almacenamiento reales. Para ello, la solución utiliza un sistema muy sencillo de triggers y procedimientos almacenados.
Nota: Los ejemplos se muestran en Linux, pero otros sistemas UNIX también deberían funcionar.
Cómo instalarse en 4 pasos
Para cada columna smartblob en cuestión
PASO 1: Decide cómo quieres organizar el acceso a tus archivos.
Decide cuál quieres que sea la base de tu directorio sombra y créalo. En mi caso para este blog, es: /home/informix/blog/resources/user-friendly. Probablemente podrías implementar esta solución sin un directorio base establecido (como se ve en los ejemplos), pero puede que no sea una buena idea porque los usuarios, sin saberlo, empezarían a crear directorios por todas partes.
PASO 2: Cree un procedimiento almacenado create_link y el trigger correspondiente para INSERTs.
Este procedimiento se asegura de que existe la estructura de subdirectorio deseada a partir de la base (mkdir -p) y, a continuación, forma un enlace lógico fácil de usar con el archivo smartblob de Informix. Debe pasar a este procedimiento todas las columnas a partir de las cuales desea formar la estructura de directorios y el nombre de archivo desde el disparador.
CREAR PROCEDIMIENTO
CREAR PROCEDIMIENTO 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);
-- establecer el directorio base LET v_basedir = '/home/informix/blog/resources/user-friendly';
-- asegúrese de que el árbol de directorios existe LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year); SYSTEM v_oscommand; -- formar nombre de enlace completo LET v_custlinkname = TRIM(v_basedir) || '/' | TRIM(p_company) || '/' | TO_CHAR(p_year) || '/' || TRIM(p_lname) || '.' || TRIM(p_formname) || '.' || TO_CHAR(p_formid); -- obtener la ubicación real SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid; -- crear el enlace os LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) | '''' || ' ' || v_custlinkname; SYSTEM v_oscommand; FIN DEL PROCEDIMIENTO
CREAR 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));
PASO 3: Cree un procedimiento almacenado delete_link y el trigger correspondiente para DELETEs.
Este procedimiento borrará el enlace de directorio sombra si se borra la fila.
CREAR PROCEDIMIENTO
CREAR PROCEDIMIENTO 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);
-- establecer el directorio base LET v_basedir = '/home/informix/blog/resources/user-friendly';
-- nombre completo del enlace LET v_custlinkname = TRIM(v_basedir) || '/' || TRIM(p_company) || '/' || TO_CHAR(p_year) || '/' || TRIM(p_lname) || '.' || TRIM(p_formname) || '.' || TO_CHAR(p_formid);
-- eliminar el enlace LET v_oscommand = 'rm -f -d ' || v_custlinkname; SYSTEM v_oscommand; FIN DEL PROCEDIMIENTO
CREAR TRIGGER
CREATE TRIGGER del_tr DELETE ON custforms REFERENCING old AS pre FOR EACH ROW (EJECUTAR PROCEDIMIENTO delete_link (pre.formid, pre.company, pre.year, pre.lname, pre.formname));
PASO 4: Cree un procedimiento almacenado change_link y el trigger correspondiente para UPDATEs, si lo desea. En mi ejemplo, la Sra. Sánchez podría casarse con el Sr. Simón y ocurrir un UPDATE a su apellido en la base de datos. A continuación, puede que desee cambiar todos mis nombres fáciles de usar de Sánchez a Simón. Este procedimiento borra el enlace antiguo y crea uno nuevo.
Observe que el disparador de actualización sólo debe dispararse en las columnas que forman su estructura de directorios y nombres de archivo.
CREAR PROCEDIMIENTO
CREAR PROCEDIMIENTO 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); -- establecer el directorio base LET v_basedir = '/home/informix/blog/resources/user-friendly'; -- deshacerse de lo viejo -- formar antiguo nombre de enlace completo 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) ; -- eliminar el enlace y los directorios vacíos LET v_oscommand = 'rm -f -d ' | v_custlinkname; SYSTEM v_oscommand; -- formar el nuevo -- asegúrese de que el árbol de directorios existe LET v_oscommand = 'mkdir -p ' || TRIM(v_basedir) || '/' || TRIM(p_post_company) || '/' || TO_CHAR(p_post_año); SYSTEM v_oscommand; -- nombre completo del enlace 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) ; -- obtener la ubicación actual -- esto es lo mismo que antes ya que el id no ha cambiado SELECT IFX_LO_PATH(form::LVARCHAR) INTO v_ifmxname FROM custforms WHERE formid = p_formid; -- crear el enlace os LET v_oscommand = 'ln -s -f ' || '''' || TRIM(v_ifmxname) | '''' || ' ' || v_custlinkname; SYSTEM v_oscommand; FIN DEL PROCEDIMIENTO
CREAR 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));
Ejemplo de resultados
Volvamos a nuestro ejemplo.
Con esta infraestructura, además del archivo con el nombre de Informix, dispondré de enlaces fáciles de usar en mi sistema de archivos que podré localizar e identificar fácilmente.
INSERTAR
[informix@schma01-rhvm03 2023]$ pwd
/home/informix/blog/recursos/fácil de usar/Actian/2023 [informix@schma01-rhvm03 2023]
$ ls Sanchez.TaxForm123.2
Si hago un ls -l, verás que es un enlace al archivo blob de Informix.
[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]
ACTUALIZACIÓN
Si luego actualizo su apellido con UPDATE custforms SET lname = 'Simon' where formid=2,mi sistema de archivos ahora tiene este aspecto:
[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]
BORRAR
Si luego voy y BORRO este formulario con DELETE FROM custforms where formid=2, mi estructura de directorios se ve así:
[informix@schma01-rhvm03 2023]$ pwd /home/informix/blog/recursos/usuario-amigable/Actian/2023 [informix@schma01-rhvm03 2023]$ ls [informix@schma01-rhvm03 2023]$
Agradecemos sus comentarios
Disfrute de la nueva función smartblob externa de HCL Informix15.
Espero que esta idea pueda facilitarte el uso de smartblobs externos. Si tienes algún comentario sobre la idea, especialmente sobre mejoras o experiencia en producción, no dudes en ponerte en contacto conmigo en mary.schulte@hcl-software.com. Estaré encantado de recibir tus comentarios.
Obtenga más información sobre el lanzamiento de HCL Informix 15.
Notas
1. Permisos de directorio en la sombra. Al crear este ejemplo, no exploré los permisos de directorios y archivos, sino que me limité a utilizar la configuración general de permisos en mi servidor sandbox. Probablemente, querrás controlar los permisos para evitar algunas de las anomalías que comento a continuación.
2. Eliminación manual del archivo blob. Con los smartblobs externos, si no se controlan los permisos, es posible que un usuario elimine de algún modo el propio archivo smartblob físico de su directorio. HCL Informix no puede controlar que esto ocurra. En caso de que ocurra, HCL Informix NO eliminará la fila correspondiente; el archivo blob simplemente desaparecerá. Es posible que haya aspectos de los enlaces que puedan gestionar esto automáticamente, pero no los he investigado para este blog.
3. Eliminación de enlaces en el directorio sombra. Si no se controlan los permisos, es posible que un usuario borre un enlace lógico formado por esta infraestructura. Esta solución no lo detecta. Si esto es un problema, yo sugeriría un trabajo de mantenimiento periódico que haga referencias cruzadas entre los enlaces del directorio sombra y los archivos blob para detectar los enlaces que faltan. Para aquellos blobs con enlaces perdidos, escriba un programa de base de datos que busque la ubicación de la fila con la función IFX_LO_PATH, y reforme el enlace perdido.
4. Identificadores únicos. Recomiendo encarecidamente el uso de identificadores únicos en esta solución. En este sencillo ejemplo, he utilizado formid. Usted no quiere desordenar las cosas, por supuesto, pero dependiendo de cómo estructurar su sombra directorios y nombres de archivo, puede que tenga que incluir más identificadores únicos para evitar la duplicación de nombres de directorio y enlace.
5. Directorios vacíos. No he investigado si existen opciones a rm en el procedimiento almacenado de borrado para limpiar directorios vacíos que puedan quedar si se borra un último elemento.
6. Sobrecarga de producción. Se sabe que un exceso de triggers y procedimientos almacenados puede añadir sobrecarga a un entorno de producción. Para este blog, se asume que la actividad OLTP en blobs no es excesiva, por lo que la sobrecarga de producción no debería ser un problema. Dicho esto, esta solución NO ha sido probada a escala.
7. Valores NULL. Asegúrese de tener en cuenta la presencia y el impacto de los valores NULL en las columnas utilizadas en esta solución. Por simplicidad, no los he tratado aquí.
Informix es una marca comercial de IBM Corporation en al menos una jurisdicción y se emplea bajo licencia.
Suscríbase al blog de Actian
Suscríbase al blog de Actian para recibir información sobre datos directamente en su correo electrónico.
- Manténgase informado: reciba lo último en análisis de datos directamente en su bandeja de entrada.
- No se pierda ni una publicación: recibirá actualizaciones automáticas por correo electrónico que le avisarán cuando se publiquen nuevas publicaciones.
- Todo depende de usted: cambie sus preferencias de entrega para adaptarlas a sus necesidades.