Hola, les escribo por una duda que tengo para respaldar la base de datos de una aplicación que estamos desarrollando.
El asunto es así: el control de los usuarios y permisos de nuestra aplicación se apoya totalmente en los roles de postgresql, es decir, cada usuario de la aplicación se corresponde con uno de la base de datos, y lo mismo con los grupos, de forma que le dejamos el trabajo de la autenticación y privilegios sobre los diferentes elementos de la base de datos, a postgres. Los permisos de la aplicación son configurables, por lo que se estarán ejecutando GRANT y REVOKE contínuamente sobre ellos y las diferentes tablas, secuencias, funciones y esquemas. El problema viene cuando tenemos que respaldar, de momento usamos pg_dumpall manualmente con la limitación de respaldar una sola base de datos de la aplicación por todo el servidor, pues si por ejemplo, hay un usuario luis en base1, y restauramos la misma base en el mismo servidor, el usuario luis de ambas bases será el mismo. Esto no es nada deseable porque se pierde independencia entre bases de datos, como el hecho de que compartan contraseña (por tratarse del mismo usuario de postgres) o que su eliminación desde una base implique la eliminación en general de ese usuario. Como detalle al respecto, les comento que en la base de datos tenemos una tabla de usuarios con los datos "de alto nivel", como lo son el nombre completo, su pertenencia a un grupo y todas las referencias que le conceden o restringen el uso a las diferentes partes de la aplicación (que se traducen a grant y revoke sobre los diferentes objetos, como ya mencioné anteriormente). El único punto de unión entre este tipo de usuarios y los nativos de la base de datos, es el nombre o nick con el que se conectan. Evidentemente, al eliminar un usuario de la aplicación, se hará lo mismo con su contraparte en la base de datos. Para poder mantener una especie de encapsulamiento entre los usuarios y la única base de datos desde donde se podrá usar (sin interferir con las demás), estaba pensando en una solución a base de prefijos alfanuméricos. Por ejemplo, si ejecutando la aplicación en basededatos01 se crea un usuario juan, en realidad este se crearía de la forma xxxxxxxxjuan, donde las x representan una cadena generada aleatoriamente; luego, si conectándose a basededatos02 se crea un usuario del mismo nombre, se le asignaría un prefijo diferente -yyyyyyyyjuan-. Claro que desde la aplicación, este mecanismo sería imperceptible, dado que el usuario seguirá usando "juan" en una base de datos determinada, aunque teniendo como costo una conexión previa (con un usuario preestablecido y de pocos privilegios) al momento de iniciar su sesión, para consultar el nombre de usuario completo (que incluye el prefijo) para poder establecer la conexión real. Con la aproximación anterior, el respaldo de la base de datos requeriría algunos pasos adicionales a un simple pg_dump (desde aquí ya es una desventaja). Primero se comenzaría por crear un archivo con los comandos necesarios para la inserción de todos los usuarios/roles que tenía en uso dicha base de datos, esto de manera programada, para evitar incluir otros usuarios del servidor., seguido de esto, se haría un respaldo normal de la base, incluyendo grants y revokes, que se supone se corresponderán exactamente con los roles respaldados previamente, y al final lo más importante: como en este momento tenemos una base de datos y un respaldo con datos duplicados para los usuarios, a los de base de datos original se le reasignarán sus prefijos, de manera que se distingan de nuevo, y así al restaurarse en el mismo servidor no haya intersección de usuarios. Los inconvenientes principales que le veo a esto son la dependencia de un factor aleatorio, y la necesidad de cambiar los prefijos en cada respaldo, pero de momento no se me ocurre algo más limpio. Gracias de antemano por las sugerencias que puedan proporcionarme.
