Adding user, IP Address to PostgreSQL logging - postgresql

I assume I'm missing something easy in the docs, but for the life of me I can't figure out how to add the user id and IP address of the machine running the query in the log files in PostgreSQL. I can see it clearly in pg_stat_activity once it's happening, but when doing post mortems on database issues, it would be very helpful to see these in the logs.
I doubt it matters, but my server startup is this:
$BIN/pg_ctl -D /apps/pgdata9.5.0 -l /apps/logs/postgresql start
I was hoping there was a setting in postgresql.conf, but if there it it's eluded me.

https://www.postgresql.org/docs/current/static/runtime-config-logging.html
add %u %h to the log_line_prefix in postgres.conf
there's a table with other options in docs above
update:
query pg_settings.context to check if you need to restart
https://www.postgresql.org/docs/current/static/view-pg-settings.html
Context required to set the parameter's value (see below)
eg:
t=# select context from pg_settings where name = 'log_line_prefix';
context
---------
sighup

Related

Postgres secutiry - How to check current security precosions

I want to check the current security precosions on a Postgres DataBase, but cant figure out how to list roles and what are they allowed to do.
Is there any quick way to do that?
The \dp backslash-command in psql is the obvious starting point.
https://www.postgresql.org/docs/current/app-psql.html
If you start it with -E it will show you the queries it runs for the backslash commands.
Other than that you can dig into pg_roles and similar in the system tables.
https://www.postgresql.org/docs/current/catalogs.html

Get all database names through JDBC

Is there any way how to get all database names out of a postgres database using JDBC? I can get the current one, but thats not what I am looking for...
I have a jUnit rule, which creates database for each test and after the test it drops it, but in some special cases, when the JVM dies, the drop never happens. So I'd like to check in the rule also existing database and clean some, which are not used any more. What I am looking for is some \l metacommand (but I can't easily ssh to the machine from unit tests...)
What would be also a solution for me would be some database ttl, something like some amqp queues have, but I suppose thats not in postgres either...
Thanks
Just run:
select datname
from pg_database
through JDBC. It returns all databases on the server you are connected to.
If you know how to get the information you want through a psql meta command (e.g. \l) just run psql with the -E switch - all internal SQL queries for the meta commands are then printed to the console.
-l actually uses a query that is a bit more complicated, but to only the the names, the above is sufficient

ERROR: cannot execute CREATE TABLE in a read-only transaction

I'm trying to setup the pgexercises data in my local machine. When I run: psql -U <username> -f clubdata.sql -d postgres -x I get the error: psql:clubdata.sql:6: ERROR: cannot execute CREATE SCHEMA in a read-only transaction.
Why did it create a read-only database on my local machine? Can I change this?
Normally the most plausible reasons for this kind of error are :
trying create statements on a read-only replica (the entire instance is read-only).
<username> has default_transaction_read_only set to ON
the database has default_transaction_read_only set to ON
The script mentioned has in its first lines:
CREATE DATABASE exercises;
\c exercises
CREATE SCHEMA cd;
and you report that the error happens with CREATE SCHEMA at line 6, not before.
That means that the CREATE DATABASE does work, when run by <username>.
And it wouldn't work if any of the reasons above was directly applicable.
One possibility that would technically explain this would be that default_transaction_read_only would be ON in the postgresql.conf file, and set to OFF for the database postgres, the one that the invocation of psql connects to, through an ALTER DATABASE statement that supersedes the configuration file.
That would be why CREATE DATABASE works, but then as soon as it connects to a different database with \c, the default_transaction_read_only setting of the session would flip to ON.
But of course that would be a pretty weird and unusual configuration.
Reached out to pgexercises.com and they were able to help me.
I ran these commands(separately):
psql -U <username> -d postgres
begin;
set transaction read write;
alter database exercises set default_transaction_read_only = off;
commit;
\q
Then I dropped the database from the terminal dropdb exercises and ran script again psql -U <username> -f clubdata.sql -d postgres -x -q
I was having getting cannot execute CREATE TABLE in a read-only transaction, cannot execute DELETE TABLE in a read-only transaction and others.
They all followed a cannot execute INSERT in a read-only transaction. It was like the connection had switched itself over to read-only in the middle of my batch processing.
Turns out, I was running out of storage!
Write access was disabled when the database could no longer write anything. I am using Postgres on Azure. I don't know if the same effect would happen if I was on a dedicated server.
I had same issue for Postgre Update statement
SQL Error: 0, SQLState: 25006 ERROR: cannot execute UPDATE in a read-only transaction
Verified Database access by running below query and it will return either true or false
SELECT pg_is_in_recovery()
true -> Database has only Read Access
false -> Database has full Access
if returns true then check with DBA team for the full access and also try for ping in command prompt and ensure the connectivity.
ping <database hostname or dns>
Also verify if you have primary and standby node for the database
In my case I had a master and replication nodes, and the master node became replication node, which I believe switched it into hot_standby mode. So I was trying to write data into a node that was meant only for reading, therefore the "read-only" problem.
You can query the node in question with SELECT pg_is_in_recovery(), and if it returns True then it is "read-only", and I suppose you should switch to using whatever master node you have now.
I got this information from: https://serverfault.com/questions/630753/how-to-change-postgresql-database-from-read-only-to-writable.
So full credit and my thanks goes to Craig Ringer!
Dbeaver: In my case
This was on.
This doesn't quite answer the original question, but I received the same error and found this page, which ultimately led to a fix.
My issue was trying to run a function with temp tables being created and dropped. The function was created with SECURITY DEFINER privileges, and the user had access locally.
In a different environment, I received the cannot execute DROP TABLE in a read-only transaction error message. This environment was AWS Aurora, and by default, non-admin developers were given read-only privileges. Their server connections were thus set up to use the read-only node of Aurora (-ro- is in the connection url), which must put the connection in the read-only state. Running the same function with the same user against the write node worked.
Seems like a good use case for table variables like SQL Server has! Or, at least, AWS should modify their flow to allow temp tables to be created and dropped on read nodes.
This occurred when I was restoring a production database locally, the database is still doing online recovery from the WAL records.
A little bit unexpected as I assumed pgbackgrest was creating instantly recoverable restores, perhaps not.
91902 postgres 20 0 1445256 14804 13180 D 4.3 0.3 0:28.06 postgres: startup recovering 000000010000001E000000A5
If like me you are trying to create DB on heroku and are stuck as this message shows up on the dataclip tab
I did this,
Choose Resources from(Overview Resources Deploy Metrics Activity Access Settings)
Choose Settings out of (Overview, Durability, Settings, Dataclip)
Then in Administration->Database Credentials choose View Credentials...
then open terminal and fill that info here and enter
psql --host=***************.amazonaws.com --port=5432 --username=*********pubxl --password --dbname=*******lol
then it'll ask for password, copy-paste from there and you can run Postgres cmds.
I suddenly started facing this error on postgres installed on my windows machine, when I was running alter query from dbeaver, all I did was deleted the connection of postgres from dbeaver and created a new connection
If you are using Azure Database for PostgreSQL your server gets into read-only mode when the storage used is near total capacity.
The error you get is exactly:
ERROR: cannot execute XXXXXXXXX in a read-only transaction
https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-compute-storage
I just had this error. My cause was not granting permission to the SEQUENCE
GRANT ALL ON SEQUENCE word_mash_word_cube_template_description_reference_seq TO ronshome_user;
If you are facing this issue with an RDS instance cluster, please check your endpoint and use the Writer instance endpoint. Then it should work now.
Issue can be dur to Intellij config:
Go to Database view> click on Data Source Properties (Shift + enter)> (Select your data source)>
Options tab> Under Connection : uncheck Read-only
For me it was Azure PostgreSQL failing over to standby during maintaince in Azure and never failing back to master when PostgreSQL was in HA mode. You can check this event in Service Health and also check which zone you current VM is running from. If it's 2 and not 1 them most likely that's the result of events described above.

Postgres turn on log_statement programmatically

I want to turn on logging of all SQL statements that modify the database. I could get that on my own machine by setting the log_statement flag in the configuration file, but it needs to be enabled on the user's machine. How do you enable it from program code? (I'm using Python with psycopg2 if it matters.)
Turning on logging of SQL statements that modify the database can be achieved by:
ALTER SYSTEM SET log_statement TO 'mod';
-- Make it effective by triggering configuration reload (no server restart required).
SELECT pg_reload_conf();
-- To make sure the modification is not limited to the current session scope
-- it is better to log out from postgresql and log back in.
-- Check value of log_statement configuration, expected: mod
SELECT * FROM pg_settings WHERE name = 'log_statement';
This requires superuser access rights.
Check hereafter links to documentation for more details:
ALTER SYSTEM
pg_reload_conf()
The "it needs to be enabled on the user's machine" phrase is confusing, indeed... I assume you mean "from the user (client) side".
In Postgresql some server run-time parameters can be changed from a connection, but only from a superuser - and only for those settings that do not require a server restart.
I'm not sure if that includes the many log options. You might try with something like:
SELECT set_config('log_XXX', 'off', false);
where log_XXX is to be replaced by the respective logging setting, and 'false' by the value you want to set.
If that does not work, I guess you are out of luck.

Determine cluster directory from Postgres service

Is it possible to determine the cluster directory being used by a Postgres server, from the server itself -- i.e. the service, (under Windows) was started by something like:
C:\foo\postgres.exe -D "D:\emr\data"
Is there a SELECT query or function one can make to the running server to retrieve the value D:\emr\data?
(For completeness)
And even shorter:
SHOW data_directory;
SELECT setting FROM pg_settings WHERE name = 'data_directory'