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;
Related
I am new to Postgresql and so far I have not found a way to drop a table from specific database. To give some context:
We are doing a synchronization from Oracle to PostgreSQL of 5 tables. In postgres I have a database SoloCopy and the schema is the default public. In the Postgresql instance we have also 2 more databases SoloSynch and postgres (the default one).
What I want to do is to select SoloCopy database and:
DROP TABLE public.table1;
When I do the above DROP statement table1 is deleted only from the database that was selected when opening SQL Query. But I want to specify the database before that and to be irrelevant from where the SQL Query was open. How can I do that?
I found an answer on my own. Setup can be found here:
Psql in Task Scheduler does not run a file script
Basically I needed to use PSQL and with the connection string there I connect to a specific DB, which I can drop the tables from. The details for PGPASSWORD and the .bat file I ended up creating are in the link above. Had to start everything from CMD and switch to psql from there.
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;
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.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
postgresql database owner can't access database - “No relations found.”
The core problem: I have a Django website that's complaining about relations (tables) not existing when I connect to it after attempting to run a SQL script generated by pg_dump MY_DATABASE_NAME -cOx -E UTF8 > MY_SCRIPT_NAME.sql
Before running the script I'd could connect and all was right with the world.
After running the script I live in a world of pain that I've attempted to alleviate by examining and altering ownership of MY_DATABASE_NAME and tables using the various methods described in Modify OWNER on all tables simultaneously in PostgreSQL
It would seem that I can only see relations via \dt on MY_DATABASE_NAME only after having first logged in as the postgres user on my server like so: sudo su - postgres.
When I SSH and run psql MY_DATABASE_NAME -U MY_NON_POSTGRES_USER without switching to the postgres user, \dt' results in ano relations found` message.
At first I presumed permissions or ownership was the problem. I logged-in as my server's postgres user and changed owner of MY_DATABASE_NAME and all of its tables to MY_NON_POSTGRES_USER.
Same results as before. Relations show up for my postgres user, but logging in as another role results in a 'no relations found message', and my website complains that 'relation some_table doesn't exist'
Why is this happening to me?
Wow. I really just composed a TL;DR description of my question and realized immediately afterwards my folly:
Although I'd connected to MY_DATABASE_NAME and given ownership to the correct user for all tables and the database, I'd forgotten to:
REVOKE ALL ON SCHEMA public FROM MY_NON_POSTGRES_USER;
GRANT ALL ON SCHEMA public TO MY_NON_POSTGRES_USER;
No more pain. All is right with the world again.
We are using pg_dumpall to make backups of our psql database. We have user with superuser rights that runs pg_dumpall. Everything works fine.
The thing that in my opinin can be better is to limit that users rights (just in case).
So, my question is - can we create some user without superuser rights but with the rigtes to use pg_dumpall corretly?
Dumping database roles and their passwords will be a problem anyway. You could create a role that has SELECT-permissions on all databases and system tables, but then you have the same security issues as you will have with a superuser: passwords (or hashes) and all data can be retrieved.
I would use a superuser for making backups, it's his job anyway.