Why does `pg_isready` not respect database option? - postgresql

When I run pg_isready with database option, I always get response that everything is ok:
pg_isready -h pgdb -U pdnsdf -d askldfjkasdjf
pgdb:5432 - accepting connections
Here database does not exists. So I expect it is not ready.
Why does pg_isready not respect database option?

Quote from the manual
It is not necessary to supply correct user name, password, or database name values to obtain the server status; however, if incorrect values are provided, the server will log a failed connection attempt.
If you want to see the error, you have to check the log file of the server.
Here database does not exists. So I expect it is not ready.
pg_isready checks if the server (instance, cluster, ..) is ready to accept connections. It is not intended to check if a specific database (or user or table) inside that cluster exists.

Related

pg_restore connection to database failed error while restoring backup

I have a backup file in tar format and there is no problem while getting this backup. However, when trying to restore this backup using the following script, I encountered "pg_restore: error: connection to database "db-dev" failed: FATAL: password authentication failed for user "db-dev-user"" error after entering password.
pg_restore -v -h 127.0.0.1 -p 5432 -d db-dev -U db-dev-user < C:\dB\db-dev.tar
I am trying to restore this backup to a Docker container where I can easily create an empty database with the same name (db-dev). I am also using Windows 10. So, how can I fix the problem? May the problem related to Docker?
The -U option must specify an existing user in the target database, and you have to specify the user's password when calling pg_restore.
Use a user with the permissions required to create the dumped objects and make sure that the target's pg_hba.conf allows the user database access from your client machine.

Stop PostgreSQL instance by port number

Is it possible to stop postgres instance just by the port number?
I have a pgsql running on port 5433 and when I try to run:
/usr/pgsql-10/bin/pg_ctl -D /var/lib/pgsql/new_cluster/data stop
This will work when I specify the -D, but let's say I don't know where the $PGDATA is and all I know is the port number this instance running on, is it possible to stop it?
/usr/pgsql-10/bin/pg_ctl -p 5433 stop
running this command result in:
waiting for server to shut down.... done
server stopped
but when I try to enter this instance by psql -p 5433 I still can get in.
*I know it might be possible doing this with systemctl but I need doing this without root permissions.
I try to do this because: I made a pg_basebackup and I want to stop the real database and run the one I just created by the pg_basebackup on the same port. just to verify that the backup is ok.
-p is not the port number in pg_ctl. The documentation says:
-p path
Specifies the location of the postgres executable. By default the postgres executable is taken from the same directory as pg_ctl, or failing that, the hard-wired installation directory. It is not necessary to use this option unless you are doing something unusual and get errors that the postgres executable was not found.
So that does nothing for pg_ctl stop, since that finds the process ID from postmaster.pid. You stopped the cluster that the environment variable PGDATA pointed to.
If you want to stop PostgreSQL by port number, connect as superuser (or a member of the pg_read_all_settings role) and run
SHOW config_file;
Then strip postgresql.conf from the output, and you have the argument to use with -D. That can easily be scripted.

URL to ping Postgres DB to check uptime

We have set up a series of uptime checks on all of our online services.
The last one is our Postgres DB. Given the connection URL in the format of:
postgres://username:password#domain-name:port/restriction
Does postgres comes out of the box with an http-callable url that would return a 200 if DB is up and 500 or nothing is DB is down?
You can use pg_isready to check the connection status of a PostgreSQL server
pg_isready --dbname=dbname --host=hostname --port=port --username=username
From the documentation:
pg_isready returns 0 to the shell if the server is accepting
connections normally, 1 if the server is rejecting connections (for
example during startup), 2 if there was no response to the connection
attempt, and 3 if no attempt was made (for example due to invalid
parameters).
No, it does not speak HTTP. You'd have to talk to the database using its driver software or make a small web service that does nothing but ping the database on demand.

psql: fatal: database "my_db" does not exist

psql -d my_db -U my_user -h my.com
same command works fine from other machines, but not from this particular machine.
I'm scratching my heads over many hours now and failed to google it.
Any ideas?
Try specifying the port via -p <port>. It may be that the Postgres binaries on this particular box were compiled with a different default port, or have the PGPORT environment variable set whereas the other boxes do not.
The default port is usually 5432, although that can be compiled in differently or set in the server config differently.
Since it says that the DB does not exist, as opposed to that it can't connect, I suspect that it's not a core networking issue (unless my.com happened to be rerouted via /etc/hosts to some other box that happened to also have a Postgres instance on it with the same password and access permissions, but that seems somewhat unlikely, unless perhaps it was redirected to localhost for testing, which could be the case, although that seems less likely).

psql: FATAL: Peer authentication failed for user "dev"

when i create a new user, but it cannot login the database.
I do that like this:
postgres#Aspire:/home/XXX$ createuser dev
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) y
then create a database:
postgres#Aspire:/home/XXX$ createdb -O dev test_development
after that, I try psql -U dev -W test_development to login, but get the error:
psql: FATAL: Peer authentication failed for user "dev"
I tried to solve the problem but failed.
Try:
psql -U user_name -h 127.0.0.1 -d db_name
where
-U is the database user name
-h is the hostname/IP of the local server, thus avoiding Unix domain sockets
-d is the database name to connect to
This is then evaluated as a "network" connection by Postgresql rather than a Unix domain socket connection, thus not evaluated as a "local" connect as you might see in pg_hba.conf:
local all all peer
Your connection failed because by default psql connects over UNIX sockets using peer authentication, that requires the current UNIX user to have the same user name as psql. So you will have to create the UNIX user dev and then login as dev or use sudo -u dev psql test_development for accessing the database (and psql should not ask for a password).
If you cannot or do not want to create the UNIX user, like if you just want to connect to your database for ad hoc queries, forcing a socket connection using psql --host=localhost --dbname=test_development --username=dev (as pointed out by #meyerson answer) will solve your immediate problem.
But if you intend to force password authentication over Unix sockets instead of the peer method, try changing the following pg_hba.conf* line:
from
# TYPE DATABASE USER ADDRESS METHOD
local all all peer
to
# TYPE DATABASE USER ADDRESS METHOD
local all all md5
peer means it will trust the identity (authenticity) of UNIX user. So not asking for a password.
md5 means it will always ask for a password, and validate it after hashing with MD5.
You can, of course, also create more specific rules for a specific database or user, with some users having peer and others requiring passwords.
After changing pg_hba.conf if PostgreSQL is running you'll need to make it re-read the configuration by reloading (pg_ctl reload) or restarting (sudo service postgresql restart).
* The file pg_hba.conf will most likely be at /etc/postgresql/9.x/main/pg_hba.conf
Edited: Remarks from #Chloe, #JavierEH, #Jonas Eicher, #fccoelho, #Joanis, #Uphill_What comments incorporated into answer.
Peer authentication means that postgres asks the operating system for your login name and uses this for authentication. To login as user "dev" using peer authentication on postgres, you must also be the user "dev" on the operating system.
You can find details to the authentication methods in the Postgresql documentation.
Hint: If no authentication method works anymore, disconnect the server from the network and use method "trust" for "localhost" (and double check that your server is not reachable through the network while method "trust" is enabled).
When you specify:
psql -U user
it connects via UNIX Socket, which by default uses peer authentication, unless specified in pg_hba.conf otherwise.
You can specify:
host database user 127.0.0.1/32 md5
host database user ::1/128 md5
to get TCP/IP connection on loopback interface (both IPv4 and IPv6) for specified database and user.
After changes you have to restart postgres or reload it's configuration.
Restart that should work in modern RHEL/Debian based distros:
service postgresql restart
Reload should work in following way:
pg_ctl reload
but the command may differ depending of PATH configuration - you may have to specify absolute path, which may be different, depending on way the postgres was installed.
Then you can use:
psql -h localhost -U user -d database
to login with that user to specified database over TCP/IP.
md5 stands for encrypted password, while you can also specify password for plain text passwords during authorisation. These 2 options shouldn't be of a great matter as long as database server is only locally accessible, with no network access.
Important note:
Definition order in pg_hba.conf matters - rules are read from top to bottom, like iptables, so you probably want to add proposed rules above the rule:
host all all 127.0.0.1/32 ident
While #flaviodesousa's answer would work, it also makes it mandatory for all users (everyone else) to enter a password.
Sometime it makes sense to keep peer authentication for everyone else, but make an exception for a service user. In that case you would want to add a line to the pg_hba.conf that looks like:
local all some_batch_user md5
I would recommend that you add this line right below the commented header line:
# TYPE DATABASE USER ADDRESS METHOD
local all some_batch_user md5
You will need to restart PostgreSQL using
sudo service postgresql restart
If you're using 9.3, your pg_hba.conf would most likely be:
/etc/postgresql/9.3/main/pg_hba.conf
This works for me when I run into it:
sudo -u username psql
I simply had to add -h localhost
The easiest solution:
CREATE USER dev WITH PASSWORD 'dev';
CREATE DATABASE test_development;
GRANT ALL PRIVILEGES ON DATABASE test_development to dev;
ALTER ROLE dev CREATEROLE CREATEDB;
In my case I was using different port. Default is 5432. I was using 5433. This worked for me:
$ psql -f update_table.sql -d db_name -U db_user_name -h 127.0.0.1 -p 5433
For people in the future seeing this, postgres is in the /usr/lib/postgresql/10/bin on my Ubuntu server.
I added it to the PATH in my .bashrc file, and add this line at the end
PATH=$PATH:/usr/lib/postgresql/10/bin
then on the command line
$> source ./.bashrc
I refreshed my bash environment. Now I can use postgres -D /wherever from any directory
pg_dump -h localhost -U postgres -F c -b -v -f mydb.backup mydb
Try in terminal:
>> psql -U role_name -d database -h hostname.<domain>.com -W