Scheduling a stored procedure in PostgreSQL 9.2.8 - postgresql

I've a simple stored procedure which calculates values from 1 table and insert it in another. I want to schedule it to run once in a day.
I came across pg_cron but it looks like it will only work for version 9.5 and above.
How to to schedule this sp or it;s select statement select * from stored_procedure_name() in postgres

as mentioned by #AlexM I started looking in Cron and found few useful links to do this outside of postgresql.
crontab in linux with 20 useful examples helps me out in understanding the structure for creating a new entry in the crontab.
edit the crontab file and added the following entry in it. As it's in the same server so no need to pass credentials for the postgresql
00 00 * * * psql -c "select query here;"

Unfortunately, the previous comments are correct. There is no scheduler within PostgreSQL nor any of the supplied utilities. Your only option is to use an external scheduler.

Related

Monitor postgres 9 queries

There is a postgres 9 with database AAA that is used by my application. I use pgadmin 4 to manage it manually.
I would like to check what queries are executed by this application on database AAA in real time.
I did a research about monitoring options in pgadmin in vain.
Is is possible to do that by using just pgadmin4? Or is it necessary to use another tool (if yes - what is he name of this tool)?
When I point pgAdmin4 at a 9.6 server, I see a dashboard by default which shows every session (done by querying pg_stat_activity). You can then drill down in a session to see the query. If a query last for less time than the monitoring interval, then you might not see it if the sample is taken at the wrong time.
If that isn't acceptable, then you should probably use a logging solution (like log_statemnt='all') or maybe the pg_stat_statements extension, rather than sample-based monitoring. pg_stat_statements doesn't integrate with the dashboard in pgAdmin4, but you can select from the view from an SQL window just like you can run any other SQL. I don't believe pgAdmin4 offers a built-in way to monitor the database server's log files, the way pgAdmin3 did.

how to properly create my own custom items and triggers for zabbix 4

:)
I have Zabbix 4.4.1 installed on Ubuntu 19.10.
I have a postgresql plugin configured and working properly so it checks my database metrics.
I have a a table that I want to check a timestamp column for the last inserted row. column name is insert_time.
if the last inserted row have a insert time of more then 5 minutes to product warning and 10 minutes to product error.
I'm new to zabbix.. all I did so far is for googling, not sure if that's the way to go.. it's probably not cause it's not working :)
ok so first thing I did is created a bash files at /etc/zabbix/mytools, get-last-insert-time.sh.
I perform the query and send the output to zabbix_sender with the following template:
#!/bin/bash
PGPASSWORD=<PASSWORD> -U <USER> <DB> -t -c "<RELEVANT QUERY>" | awk '{$1=$1};1' | tr -d "\n" | xargs -I {} /usr/bin/zabbix_sender -z $ZABBIXSERVER -p $ZABBIXPORT -s $ZABBIXAGENT -k "my.pgsql.cdr.last_insert_time" -o {}
is there a way to test this step? how can I make sure that zabbix_sender receives that information? is there some kind of.. zabbix_sender_sniffer of some sort ? :)
next.. I created a configuration files at /etc/zabbix/zabbix_agentd.d called get-last-insert-time.conf with the following template:
UserParameter=my_pgsql_cdr_last_insert_time,/etc/zabbix/mytools/get-last-insert-time.sh;echo $?
here the key is my_pgsql_cdr_last_insert_time while the key in zabbix_sender is my.pgsql.cdr.last_insert_time. as far as I understand these should be two different keys.
why?!
then I created a template and attached it to the relevant host and I created 2 items for it:
item for insert time with the key my.pgsql.cdr.last_insert_time and of type Zabbix Trapper
a Zabbix Agent item with the key my_pgsql_cdr_last_insert_time Type of information: text.
is that the type of information for timestamp ?
now on Overview -> latest data I see:
CDR last insert time with no data
and Run my database trappers insert time that is... the text is disabled? it's in gray.. and there is also no data.
so before I begin to create an alert. what did I do wrong ?
any information regarding this issue would be greatly appreciated.
update
thanks Jan Garaj for this valuable information.
I was expecting that creating such a trigger should be easier then what I found on google, glad to see I was correct.
I edited my bash scripts to return seconds since epoch, since it's from postgresql it returns float, so I configured the items as float. I do see in latest data that the items receive the proper values.
I created triggers, I made sure that the warning trigger depends on the critical trigger so they won't both appear on the same time.
for example I created this trigger {cdrs:pgsql.cdr.last_insert_time.fuzzytime(300)}=0 so if the last insert time is greater then 5 minutes to return a critical error. the problem is that it returns a critical error.. always! even when it shouldn't. I couldn't find a way to debug this. so besides actually getting the triggers to work properly everything else is well configured.
any ideas ?
update 2
when I configured the script to return a timestamp, I changed it to a different timezone instead of living it as it is, which actually compared the data with current time + 2 hours in the future :)
I found that out while going to latest data, checking the timestamp and converting it to actual time. so everything works now thanks a lot!
It looks over complicated, because you are mixing sender with agent approach. Simpler approach - agent only:
UserParameter=pgsql.cdr.last_insert_time,/etc/zabbix/mytools/get-last-insert-time.sh
Script /etc/zabbix/mytools/get-last-insert-time.sh returns last insert Unix timestamp only, e.g.1574111464 (no new line and don't use zabbix_sender in the script). Keep in mind, that zabbix agent uses zabbix user usually, so you need to configure proper script (exec) permissions, eventually env variables.
Test it with zabbix-get from the Zabbix server, e.g.:
zabbix_get -s <HOST IP> -p 10050 -k "pgsql.cdr.last_insert_time"
For any issue on the agent side: increase log agent level and watch agent logs
When you sort agent part, then create template with item key pgsql.cdr.last_insert_time and Numeric (unsigned) type. Trigger can use fuzzytime(60) function.

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

How to handle large result sets with psql?

I have a query which gives about 14M rows (I was not aware of this). When I use psql to run the query, my Fedora machine froze. Also after the query was done, I could not use Fedora anymore and had to restart my machine. When I redirected standard output to a file, Fedora also froze.
So how should I handle large resultsets with psql?
psql accumulates complete results in client memory by default. This behavior is usual for all libpq based Postgres applications or drivers. The solutions are cursors - then you are fetching only N rows from server. Cursors can be used by psql too. You can change it by setting FETCH_COUNT variable, then it will use cursors with batch retrieval size FETCH_COUNT.
postgres=# \set FETCH_COUNT 1000
postgres=# select * from generate_series(1,100000); -- big query

PostgreSQL How to check if my function is still running

Just a quick question .
I have one heavy function in PostgreSQL 9.3 , how I can check if the function is still running after several hours and how to run a function in background in psql ( my connection is unstable from time to time)
Thanks
For long running functions, it can be useful to have them RAISE LOG or RAISE NOTICE from time to time, indicating progress. If they're looping over millions of records, you might emit a log message every few thousand records.
Some people also (ab)use a SEQUENCE, where they get the nextval of the sequence in their function, and then directly read the sequence value to check progress. This is crude but effective. I prefer logging whenever possible.
To deal with disconnects, run psql on the remote side over ssh rather than connecting to the server directly over the PostgreSQL protocol. As Christian suggests, use screen so the remote psql doesn't get killed when the ssh session dies.
Alternately, you can use the traditional unix command nohup, which is available everywhere:
nohup psql -f the_script.sql </dev/null &
which will run psql in the background, writing all output and errors to a file named nohup.out.
You may also find that if you enable TCP keepalives, you don't lose remote connections anyway.
pg_stat_activity is a good hint to check if your function is still running. Also use screen or tmux on the server to ensure that it will survive a reconnect.
1 - Login to the psql console.
$ psql -U user -d database
2- Issue a \x command to format the results.
3- SELECT * from pg_stat_activity;
4- Scroll until you see your function name on the list. It should have an active status.
5- Check if there are any blocks on the table that your function relies on using:
SELECT k_locks.pid AS pid_blocking, k_activity.usename AS user_blocking, k_activity.query AS query_blocking, locks.pid AS pid_blocked, activity.usename AS user_blocked, activity.query AS query_blocked, to_char(age(now(), activity.query_start), 'HH24h:MIm:SSs') AS blocking_age FROM pg_catalog.pg_locks locks JOIN pg_catalog.pg_stat_activity activity ON locks.pid = activity.pid JOIN pg_catalog.pg_locks k_locks ON locks.locktype = k_locks.locktype and locks.database is not distinct from k_locks.database and locks.relation is not distinct from k_locks.relation and locks.page is not distinct from k_locks.page and locks.tuple is not distinct from k_locks.tuple and locks.virtualxid is not distinct from k_locks.virtualxid and locks.transactionid is not distinct from k_locks.transactionid and locks.classid is not distinct from k_locks.classid and locks.objid is not distinct from k_locks.objid and locks.objsubid is not distinct from k_locks.objsubid and locks.pid <> k_locks.pid JOIN pg_catalog.pg_stat_activity k_activity ON k_locks.pid = k_activity.pid WHERE k_locks.granted and not locks.granted ORDER BY activity.query_start;