Uso de mensajes persistentes con mensajes almacenados en el almacén de objetos en la nube
El paquete DBMS_PIPE tiene una funcionalidad ampliada en la base de datos de IA autónoma para admitir la mensajería persistente, donde los mensajes se almacenan en Cloud Object Store.
Acerca de la mensajería persistente con DBMS_PIPE
Los mensajes persistentes con DBMS_PIPE permiten que una o más sesiones de base de datos se comuniquen en la misma región o entre regiones con mensajes almacenados en el almacén de objetos en la nube.
Mensajes persistentes en DBMS_PIPE:
-
Permite enviar y recuperar mensajes muy grandes.
-
Admite el envío de un gran número de mensajes de conducción.
-
Soporte para enviar y recibir mensajes en una única base de datos, en varias bases de datos y en distintas regiones.
-
Soporta varios pipes con el mismo URI de ubicación de almacenamiento de objetos en la nube.
Los canales de mensajes persistentes se pueden crear en cualquiera de los tipos de DBMS_PIPE soportados:
-
Conducto implícito: se crea automáticamente cuando se envía un mensaje con un nombre de conducto desconocido mediante la función
DBMS_PIPE.SEND_MESSAGE. -
Conducto explícito: creado mediante la función
DBMS_PIPE.CREATE_PIPEcon un nombre de conducto especificado por el usuario. -
Pipa pública: accesible para cualquier usuario con permiso
EXECUTEen el paqueteDBMS_PIPE. -
Pipa privada: accesible por sesiones con el mismo usuario que el creador del pipeline.
Nota: Oracle recomienda crear un canal explícito antes de enviar o recibir mensajes con mensajes persistentes. La creación de un conducto explícito con DBMS_PIPE.CREATE_PIPE garantiza que el conducto se cree con los permisos de acceso que desee, ya sean públicos o privados (mediante la definición del parámetro private).
A continuación se muestra el flujo de trabajo general para DBMS_PIPE con mensajes persistentes:
Descripción de la ilustración database-pipe-persistent-messaging.svg
Las aplicaciones existentes que utilizan DBMS_PIPE pueden seguir funcionando con cambios mínimos. Puede configurar aplicaciones existentes que utilicen DBMS_PIPE con un URI de ubicación y objeto de credencial mediante un disparador de conexión o mediante alguna otra rutina de inicialización. Después de definir el URI de ubicación y credencial DBMS_PIPE, no se necesitan otros cambios para utilizar mensajes persistentes. El uso posterior del canal almacena los mensajes en el almacén de objetos en la nube en lugar de en la memoria de la base de datos. Esto le permite cambiar el método de almacenamiento para mensajes de Cloud Object Storage en memoria a persistente, con cambios mínimos.
Visión General y Funciones de Mensajería Persistente
Funciones de DBMS_PIPE mediante mensajes persistentes:
-
Los mensajes se pueden enviar y recuperar en varias instancias de base de datos de IA autónoma en la misma región o entre regiones.
-
Se garantiza que los mensajes persistentes se escriban o lean exactamente mediante un proceso. Esto evita la inconsistencia del contenido del mensaje debido a lecturas y escrituras simultáneas.
DBMS_PIPEsolo permite una operación, el envío de un mensaje o la recepción de un mensaje están activos en un momento determinado y estas operaciones están protegidas por un mecanismo de bloqueo. Sin embargo, si no se puede realizar una operación debido a una operación en curso, el proceso se reintenta periódicamente hasta que se alcanza el valortimeout. -
DBMS_PIPEutilizaDBMS_CLOUDpara acceder al almacén de objetos en la nube. Los mensajes se pueden almacenar en cualquiera de los almacenes de objetos en la nube soportados. Consulte Formatos de URI de almacenamiento de objetos en la nube para obtener más información. -
DBMS_PIPEutilizaDBMS_CLOUDpara acceder al almacén de objetos en la nube y todos los tipos de credenciales soportados están disponibles:DBMS_CLOUD.CREATE_CREDENTIAL: consulte el procedimiento CREATE_CREDENTIAL para obtener más información.
Autorización y seguridad de privilegios DBMS_PIPE
Los procedimientos DBMS_PIPE se ejecutan con derechos del invocador. Los canales privados son propiedad del usuario actual y un canal privado que crea un usuario solo puede ser utilizado por el mismo usuario. Esto se aplica tanto a los canales en memoria como a los persistentes donde los mensajes se almacenan en el almacén de objetos en la nube. Los mensajes de envío y recepción se ejecutan en el esquema del invocador.
Mediante canalizaciones privadas, donde los mensajes se almacenan en el almacén de objetos en la nube, se necesita un objeto de credencial para la autenticación con el almacén de objetos en la nube identificado por el parámetro location_uri. El usuario que llama debe tener el privilegio EXECUTE en el objeto de credencial especificado con el parámetro credential_name que se utiliza para acceder al almacén de objetos.
Para utilizar un conducto público, el usuario, la sesión de base de datos, debe tener el privilegio de ejecución en DBMS_PIPE. Para un conducto público que utiliza mensajes persistentes y almacena mensajes en el almacén de objetos en la nube, el usuario, la sesión de base de datos, debe tener el privilegio de ejecución en DBMS_CLOUD y el privilegio de ejecución en el objeto de credencial (o puede crear un objeto de credencial que tenga permiso para acceder al URI de ubicación que contiene el mensaje).
Limitación DBMS_PIPE
El paquete DBMS_PIPE no soporta el envío de mensajes entre bases de datos que utilizan diferentes juegos de caracteres. Por ejemplo, si tiene una instancia de base de datos de IA autónoma que utiliza AL32UTF8 y otra instancia que utiliza WE8MSWIN1252, no puede enviar mensajes con DBMS_PIPE entre estas dos bases de datos. En este caso, el sistema emitirá el error ORA-12704 si intenta enviar mensajes con DBMS_PIPE entre estas dos bases de datos.
Consulte Selección de juego de caracteres para la base de datos de IA autónoma para obtener más información.
Creación de un Tubo Persistente Explícito y Envío de un Mensaje
Describe los pasos para crear un conducto persistente con un nombre de conducto especificado (tubo explícito).
-
Almacene las credenciales del almacén de objetos mediante el procedimiento
DBMS_CLOUD.CREATE_CREDENTIAL. Por ejemplo:BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'my_persistent_pipe_cred', username => 'adb_user@example.com', password => 'password' ); END; /Esta operación almacena las credenciales en la base de datos en un formato cifrado. Puede utilizar cualquier nombre para el nombre de credencial. Tenga en cuenta que este paso solo es necesario una vez, a menos que cambien las credenciales del almacén de objetos. Después de almacenar las credenciales, puede utilizar el mismo nombre de credencial para acceder al almacén de objetos en la nube y enviar y recibir mensajes con
DBMS_PIPE.Para obtener información detallada sobre los parámetros, consulte Procedimiento CREATE_CREDENTIAL. Para Oracle Cloud Infrastructure Object Storage, es necesario que la credencial utilice la autenticación nativa de Oracle Cloud Infrastructure.
Nota: Algunas herramientas como SQL*Plus y SQL Developer utilizan el carácter de ampersand (
&) como carácter especial. Si tiene el carácter ampersand en la contraseña, utilice el comandoSET DEFINE OFFen esas herramientas, como se muestra en el ejemplo, para desactivar el carácter especial y obtener la credencial creada correctamente. -
Cree un conducto explícito para enviar y recuperar mensajes. Por ejemplo, cree un conducto denominado
ORDER_PIPE.DECLARE r_status INTEGER; BEGIN r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE'); END; /Consulte Función CREATE_PIPE para obtener más información.
-
Verifique que se haya creado la conducción.
SELECT ownerid, name, type FROM v$db_pipes WHERE name = 'ORDER_PIPE';OWNERID NAME TYPE ------- ---------- ------- 80 ORDER_PIPE PRIVATE -
Utilice los procedimientos
DBMS_PIPEpara definir el URI de ubicación y la credencial de acceso por defecto para almacenar mensajes persistentes en el almacén de objetos en la nube.BEGIN DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred'); DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); END; /Estos procedimientos definen el nombre de credencial por defecto y el URI de ubicación por defecto para su uso con procedimientos
DBMS_PIPE.Si utiliza Oracle Cloud Infrastructure Object Storage para almacenar mensajes, puede utilizar los URI nativos de Oracle Cloud Infrastructure o los URI de Swift. Sin embargo, el URI de ubicación y la credencial deben coincidir en el tipo de la siguiente manera:
-
Si utiliza un formato de URI nativo para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar la autenticación de claves de firma nativas de Oracle Cloud Infrastructure en el objeto de credencial.
-
Si utiliza el formato URI de Swift para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar una autenticación de token de autenticación en el objeto de credencial.
Consulte Procedimiento SET_CREDENTIAL_NAME y Función GET_LOCATION_URI para obtener más información.
-
-
Empaquetar y enviar un mensaje en el conducto.
DECLARE l_result INTEGER; l_date DATE; BEGIN l_date := sysdate; DBMS_PIPE.PACK_MESSAGE(l_date); -- date of order DBMS_PIPE.PACK_MESSAGE('C123'); -- order number DBMS_PIPE.PACK_MESSAGE(5); -- number of items in order DBMS_PIPE.PACK_MESSAGE('Printers'); -- type of item in order l_result := DBMS_PIPE.SEND_MESSAGE( pipename => 'ORDER_PIPE', credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME, location_uri => DBMS_PIPE.GET_LOCATION_URI); IF l_result = 0 THEN DBMS_OUTPUT.put_line('DBMS_PIPE sent order successfully'); END IF; END; /Consulte Procedimientos PACK_MESSAGE en Referencia de tipos y paquetes PL/SQL de Oracle Database 19c o Referencia de tipos y paquetes PL/SQL de Oracle Database 26ai y Función SEND_MESSAGE para más información.
Recuperar un mensaje persistente en la misma base de datos
Describe los pasos para recuperar un mensaje persistente de un conducto explícito en la misma instancia de base de datos de IA autónoma (la instancia a la que se envió el mensaje).
En una instancia de base de datos de IA autónoma, puede recibir mensajes enviados a un canal desde una sesión diferente. Los procedimientos DBMS_PIPE son procedimientos de derechos del invocador y se ejecutan como el usuario invocado actual.
Las tuberías privadas son propiedad del usuario actual que crea la tubería. Solo puede acceder a las tuberías privadas el mismo usuario que creó la tubería. Esto se aplica a los pipes que utilizan mensajes en memoria y a los pipes que utilizan mensajes persistentes con mensajes almacenados en el almacén de objetos en la nube.
Cualquier sesión de base de datos que tenga privilegios de ejecución en DBMS_PIPE puede acceder a los canales públicos. Esto se aplica a los pipes que utilizan mensajes en memoria y a los pipes que utilizan mensajes persistentes con mensajes almacenados en el almacén de objetos en la nube.
-
Verifique que se haya creado la conducción.
SELECT ownerid, name, type FROM v$db_pipes WHERE name = 'ORDER_PIPE';OWNERID NAME TYPE ------- ---------- ------- 80 ORDER_PIPE PRIVATECuando se encuentra en la misma instancia de base de datos de IA autónoma y existe el canal, no es necesario que ejecute
DBMS_PIPE.CREATE_PIPEantes de recibir un mensaje. Esto se aplica cuando la conducción se creó en la misma instancia, como se muestra en Create an Explicit Persistent Pipe and Send a Message. -
Recibir un mensaje de la conducción.
DECLARE message1 DATE; message2 VARCHAR2(100); message3 INTEGER; message4 VARCHAR2(100); l_result INTEGER; BEGIN DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred'); DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); l_result := DBMS_PIPE.RECEIVE_MESSAGE ( pipename => 'ORDER_PIPE', timeout => DBMS_PIPE.MAXWAIT, credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME, location_uri => DBMS_PIPE.GET_LOCATION_URI); IF l_result = 0 THEN DBMS_PIPE.unpack_message(message1); DBMS_PIPE.unpack_message(message2); DBMS_PIPE.unpack_message(message3); DBMS_PIPE.unpack_message(message4); DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss')); DBMS_OUTPUT.put_line('Date of Order: ' || message1); DBMS_OUTPUT.put_line('Order Number: ' || message2); DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3); DBMS_OUTPUT.put_line('Item Type in Order: ' || message4); END IF; END; /Cuando se encuentra en la misma instancia de base de datos de IA autónoma, la credencial ya existe y no necesita ejecutar
DBMS_CLOUD.CREATE_CREDENTIALpara recibir un mensaje. Esto se aplica cuando la conducción se creó en la misma instancia, como se muestra en Create an Explicit Persistent Pipe and Send a Message.
Consulte Procedimiento SET_CREDENTIAL_NAME y Función GET_LOCATION_URI para obtener más información.
Consulte RECEIVE_MESSAGE Function para obtener más información.
Recuperación de un mensaje persistente mediante la creación de una canalización en una base de datos diferente
Describe los pasos para recuperar un mensaje persistente almacenado en el almacén de objetos en la nube con un conducto explícito en una instancia de base de datos de IA autónoma que es diferente de la instancia que envió el mensaje.
-
Almacene las credenciales del almacén de objetos mediante el procedimiento
DBMS_CLOUD.CREATE_CREDENTIAL. Por ejemplo:BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'my_persistent_pipe_cred', username => 'adb_user@example.com', password => 'password' ); END; /Esta operación almacena las credenciales en la base de datos en un formato cifrado. Puede utilizar cualquier nombre para el nombre de credencial. Tenga en cuenta que este paso solo es necesario una vez, a menos que cambien las credenciales del almacén de objetos. Una vez almacenadas las credenciales, puede utilizar el mismo nombre de credencial para acceder al almacén de objetos en la nube y enviar y recibir mensajes con
DBMS_PIPE.Para obtener información detallada sobre los parámetros, consulte Procedimiento CREATE_CREDENTIAL.
Nota: Algunas herramientas como SQL*Plus y SQL Developer utilizan el carácter de ampersand (
&) como carácter especial. Si tiene el carácter ampersand en la contraseña, utilice el comandoSET DEFINE OFFen esas herramientas, como se muestra en el ejemplo, para desactivar el carácter especial y obtener la credencial creada correctamente. -
Cree un conducto explícito con el mismo nombre que el conducto que envió el mensaje. Por ejemplo, cree un conducto denominado
ORDER_PIPE.DECLARE r_status INTEGER; BEGIN r_status := DBMS_PIPE.CREATE_PIPE(pipename => 'ORDER_PIPE'); END; /Consulte Función CREATE_PIPE.
-
Verifique que se haya creado la conducción.
SELECT ownerid, name, type FROM v$db_pipes WHERE name = 'ORDER_PIPE';OWNERID NAME TYPE ------- ---------- ------- 80 ORDER_PIPE PRIVATE -
Utilice los procedimientos
DBMS_PIPEpara definir la credencial de acceso y el URI de ubicación por defecto para el almacén de objetos, de modo queDBMS_PIPEpueda acceder al mensaje persistente.BEGIN DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred'); DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); END; /Estos procedimientos definen el nombre de credencial por defecto y el URI de ubicación por defecto para su uso con procedimientos
DBMS_PIPE.Si utiliza Oracle Cloud Infrastructure Object Storage para almacenar mensajes, puede utilizar los URI nativos de Oracle Cloud Infrastructure o los URI de Swift. Sin embargo, el URI de ubicación y la credencial deben coincidir en el tipo de la siguiente manera:
-
Si utiliza un formato de URI nativo para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar la autenticación de claves de firma nativas de Oracle Cloud Infrastructure en el objeto de credencial.
-
Si utiliza el formato URI de Swift para acceder a Oracle Cloud Infrastructure Object Storage, debe utilizar una autenticación de token de autenticación en el objeto de credencial.
Consulte Procedimiento SET_CREDENTIAL_NAME y Función GET_LOCATION_URI para obtener más información.
-
-
Reciba un mensaje del conducto persistente.
DECLARE message1 DATE; message2 VARCHAR2(100); message3 INTEGER; message4 VARCHAR2(100); l_result INTEGER; BEGIN DBMS_PIPE.SET_CREDENTIAL_NAME('my_persistent_pipe_cred'); DBMS_PIPE.SET_LOCATION_URI('https://objectstorage.us-phoenix-1.oraclecloud.com/n/namespace-string/b/bucketname1/'); l_result := DBMS_PIPE.RECEIVE_MESSAGE ( pipename => 'ORDER_PIPE', timeout => DBMS_PIPE.MAXWAIT, credential_name => DBMS_PIPE.GET_CREDENTIAL_NAME, location_uri => DBMS_PIPE.GET_LOCATION_URI); IF l_result = 0 THEN DBMS_PIPE.unpack_message(message1); DBMS_PIPE.unpack_message(message2); DBMS_PIPE.unpack_message(message3); DBMS_PIPE.unpack_message(message4); DBMS_OUTPUT.put_line('Order Received Successfully On: ' || TO_CHAR(sysdate, 'dd-mm-yyyy hh24:mi:ss')); DBMS_OUTPUT.put_line('Date of Order: ' || message1); DBMS_OUTPUT.put_line('Order Number: ' || message2); DBMS_OUTPUT.put_line('Number of Items In Order: ' || message3); DBMS_OUTPUT.put_line('Item Type in Order: ' || message4); END IF; END; /Consulte RECEIVE_MESSAGE Function para obtener más información.
Eliminación de una tubería persistente
Describe los pasos para eliminar un conducto persistente.
Los pipes persistentes envían y reciben mensajes almacenando mensajes en el almacén de objetos en la nube. Utilice DBMS_PIPE.REMOVE_PIPE para eliminar un conducto persistente en una instancia de base de datos de IA autónoma.
-
Llame a la función
DBMS_PIPE.REMOVE_PIPEpara eliminar un conducto.DECLARE l_result INTEGER; BEGIN l_result := DBMS_PIPE.REMOVE_PIPE('ORDER_PIPE'); END; /La función
REMOVE_PIPEelimina el canal de la instancia de la base de datos de IA autónoma en la que se ejecuta, peroREMOVE_PIPEno afecta a otras instancias de la base de datos de IA autónoma con un canal con el mismo nombre que utiliza el mismo URI de ubicación. -
En la instancia de base de datos de IA autónoma, si ejecuta
DBMS_PIPE.REMOVE_PIPE, verifique que se ha eliminado el conducto.SELECT ownerid, name, type FROM v$db_pipes WHERE name = 'ORDER_PIPE';No rows selected