I have two 'similar' databases and I'm trying to replicate role membership between them.
Replicating the full database is not an option and they are quite big (about nine hours to restore).
I've tried with pg_dumpall --globals-only but it only creates the users and roles, there is nothing about role membership.
On the other hand, pg_dump works with single databases, and I can't find any information about dumping the roles membership.
I probably end writing some script that queries for membership information in one database and then 'grants' this information in the other one.
But I would like to know if there is an easier way to do this.
You're right, pg_dumpall --globals-only includes role membership.
The problem is that I was migrating and merging two different versions of Postgres. I needed some intermediate clusters to upgrade some extensions, but I forgot restoring roles to them.
After upgrading the extensions, I dumped the data and restored it in the final database without the role information :-(
The whole process takes about 14 hours, so, instead of starting the process again, I wrote a small script to copy the roles:
psql --host SOURCE_HOST --tuples-only --file get_role_grants.sql | psql -v ON_ERROR_STOP=1
With the contents of the file 'get_role_grants' being:
select concat('grant ', c.rolname, ' to ', a.rolname, ';') as grantcommand
from pg_roles a
inner join pg_auth_members b on a.oid=b.member
inner join pg_roles c on b.roleid=c.oid
order by a.rolname, c.rolname;
Related
I have a database called demo which has 4 tables.
I run psql -U user1 demo and am able to login, but I cannot see any of the tables.
One of the table is student. I can surely just reimport the data all again, but why wouldn't it show here?
My user1 is full admin and has access to everything, so I don't think it's a user related issue.
All my tables are also owned by user1, if this makes any difference.
I am not using a VM, everything is on my local machine.
You need to add university schema to your search_path. Either you can SET search_path TO ... or add it to search_path in postgresql.conf. Otherwise, you could perform your SELECT with fully-qualified table name:
SELECT * FROM university.student;
Disclosure: I work for EnterpriseDB (EDB)
Your tables are located in the schema university you need to use:
select *
from university.student;
To list the tables in that schema, use: \d university.*
I have a funny question about PostgreSQL database: What happens if the postgres database is dropped?
dropdb postgres worked.
createdb postgres worked too.
psql worked.
But I thought the users would be lost. Yet the old users are still there.
So where are the users stored for the database and which implications does dropping the postgres database have?
PostgreSQL metadata are stored in catalog tables, which are in the pg_catalog schema. These are accessible like regular views and tables.
There are shared system catalog tables which are shared between all databases. These tables are not affected when databases are dropped.
pg_authid, the table where the users are stored, is one of those shared catalogs. This is because in PostgreSQL, users don't belong to a database, but to the whole database cluster.
You can list all shared catalog tables like this:
SELECT relname FROM pg_class
WHERE relisshared AND relkind = 'r';
In the documentation you can find more information about the system catalogs.
When connecting to a Postgres server, you always need to specify which database you want to connect to.
When you set up a new server, you need something to connect to before you can run your first CREATE DATABASE statement.
That's all the postgres database is: a dummy database to use as a connection target for admin commands. There's no data in there, and you're free to drop it and use a different one instead (though whoever inherits your system will probably not thank you for it...).
As gil.fernandes said in his answer, server-wide objects like users are accessible from every database, but aren't stored inside any database in particular.
I have a postgres 9.6. I am using pg_dumpall with -c --if-exists options.
When I restore from this backup file as the superuser I am getting errors current user cannot be dropped when it tries to drop the role. And after that I am getting role "mysuperuser" already exists when it tries to create the superuser role.
These two errors does not effect the success of the restore. However, I do not want to get irrelevant errors like these.
What I can do is to remove the two lines which are dropping and creating the aforementioned superuser role.
Is there a better way to do this? Because in order to achieve that I need to open a huge file and edit it.
You might want to join one of the postgreql.org mailing list and see if this irritation has occurred for others. It's clearly not the ideal behaviour.
There is a simple work-around though. Create a new superuser (that doesn't exist in the backup) and use that user to do the restore.
I want to get a full backup of postgres 9.6. Including the users and permissions. However I want to exclude some tables. In pg_dump there is an option for excluding some tables (-T). However in pg_dumpall there are no such options.
Is there a way for getting a backup like this in a single command? Or should I get pg_dumpall (without tables) and pg_dump with -T? However in the second scenario these two dumps are not completely synchronised.
You'll have to use pg_dumpall -g and pg_dump -T.
True, the dumps will not share a single snapshot, but unless you add, modify or delete users and tablespaces very frequently, that should not be a problem in practice.
Long time MariaDB/MySQL DBA, two weeks into being a Postgres DBA and I'm stumped...
I am creating a script that scans a host and ennumerates the databases but I'm having difficulty nailing down the least-privilege Postgres permissions. The script works fine when testing with SUPERUSER, but I'm not sure what permissions beyond USAGE it needs. It seems that any combination I come up with isn't working.
All you need to get a list of databases in a PostgreSQL cluster is a database user that can connect to one of the databases. Then you can run the SQL statement
SELECT datname
FROM pg_database
WHERE datallowconn;