Run postgres index creation in background - postgresql

I want to run index creation without any need for the client to remain connected to the server.
I found this thread, which mentions that the only way to create index in background is
psql -c "CREATE INDEX index_name ON table(column)" &
But this still requires the client to stay connected with the server. Since this is a old thread, would like to know if any new feature has been introduced in postgres which allows such a scenario.

No, this is still not possible.
I would run the command on the server itself, so there can be no network problem:
nohup psql -c "CREATE INDEX CONCURRENTLY ..." </dev/zero >/dev/null 2>&1 &
Then you can disconnect the session, and the command will keep running.

Related

Datagrip: Create postgres index without waiting for execution

Is there a way to submit a command in datagrip to a database without keeping the connection open / asynchronously? I'm attempting to create indexes concurrently, but I'd also like to close my laptop.
My datagrip workflow:
Select column in a database, click 'modify column', and eventually run code such as:
create index concurrently batchdisbursements_updated_index
on de_testing.batchdisbursements (updated);
However, these run as background tasks and cancel if I exit datagrip.
However, these run as background tasks and cancel if I exit datagrip.
What if you close your laptop without exiting datagrip? Datagrip is probably actively sending a cancellation message to PostgreSQL when you exit it. If you just close the laptop, I doubt it will do that. In that case, PostgreSQL won't notice the client has gone away until it tries to send a message, at which point the index creation should already be done and committed.
But this is a fragile plan. I would ssh to the server, run screen (or one of the fancier variants), run psql in that, and create the indexes from there.

How to restore a database runtime

I have a test database connected to a test server. I want to run set of selenium tests and I have to restore database after every test.
I made a backup with cli command "createdb" and I just drop the main table every time, but how can I restore database without turning the whole server off and on (can't use createdb with any open connections), as it would take hours or days to make a full set of tests?
I probably won't be given constant admin access to the server, unless it's necessary.
You can kill all connections vis SQL (see https://stackoverflow.com/a/5109190/2352344). Instead of dropping the whole database you can just remove the schema:
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
I think that instead of dropping the table, how about undoing or deleting the rows in the table. When you run the test, you know what entries will be made in the Table. With this information, just before the test terminates, invoke a script to delete the rows created due to running this test.
You can use a real tool for your backup/restore (Wal-E, barman or backrest). Particularly with backrest, you can do a diff restore where it restores only files that have changes.
I solved the problem by making a bash script that i run from java code.
String[] args = new String[]{"./script.sh"};
Process proc = new ProcessBuilder(args).start();
proc.waitFor();
script.sh:
#!/bin/bash
psql dbname -c "drop schema \"public\" cascade;"
psql dbname -c "create schema \"public\";"
psql dbname < "path/backupname"
I had to use script and not just make it arguments in args, probably becouse of the "<" sign. I found no flag replacement to it.

Postgresql needs to run command every time for startup

I'm on RHEL6 and have installed PostgreSQL. Now whenever I want to start development I need to run the following command to start PostgreSQL
/opt/PostgreSQL/9.5/bin/postgres -D /opt/PostgreSQL/9.5/data
Then it halts for that terminal and I need to start another session of postgresql into another terminal. Whats wrong in Installation? and How to rectify this problem?
Image of practical for better understanding
https://www.postgresql.org/docs/current/static/app-postgres.html
The utility command pg_ctl can be used to start and shut down the
postgres server safely and comfortably.
If at all possible, do not use SIGKILL to kill the main postgres
server. Doing so will prevent postgres from freeing the system
resources (e.g., shared memory and semaphores) that it holds before
terminating. This might cause problems for starting a fresh postgres
run.
use pg_ctl -D /opt/PostgreSQL/9.5/data start instead, otherwise one day your database will tell you about corrupted data

Postgres: how to start a procedure right after database start?

I have dozens of unlogged tables, and doc says that an unlogged table is automatically truncated after a crash or unclean shutdown.
Based on that, I need to check some tables after database starts to see if they are "empty" and do something about it.
So in short words, I need to execute a procedure, right after database is started.
How the best way to do it?
PS: I'm running Postgres 9.1 on Ubuntu 12.04 server.
There is no such feature available (at time of writing, latest version was PostgreSQL 9.2). Your only options are:
Start a script from the PostgreSQL init script that polls the database and when the DB is ready locks the tables and populates them;
Modify the startup script to use pg_ctl start -w and invoke your script as soon as pg_ctl returns; this has the same race condition but avoids the need to poll.
Teach your application to run a test whenever it opens a new pooled connection to detect this condition, lock the tables, and populate them; or
Don't use unlogged tables for this task if your application can't cope with them being empty when it opens a new connection
There's been discussion of connect-time hooks on pgsql-hackers but no viable implementation has been posted and merged.
It's possible you could do something like this with PostgreSQL bgworkers, but it'd be a LOT harder than simply polling the DB from a script.
Postgres now has pg_isready for determining if the database is ready.
https://www.postgresql.org/docs/11/app-pg-isready.html

how to terminate postgresql 8.3 sessions?

I am trying to terminate a session (a specific session or all sessions, doesnt matter) in postgresql 8.3 and am having trouble doing that. I know in newer versions (8.4 and later) there is a pg_terminate_backend command that will do the trick but this is not available in postgresql 8.3. If I use pg_stat_activity, I can see all the sessions that are active but have no way of terminating them.
The solution does not have to necessarily be sql commands but I would like it to be independent of the OS that is being used (i.e. no DOS/UNIX commands).
Stopping and starting the postgres service in windows services works perfectly but this is an OS specific approach. Using 'pg_ctl restart -D DATA_DIR' does not stop the service however. Actually using pg_ctl to try and restart the service at the time I am trying to do it causes some weird behavior. If there is a way I can somehow use pg_ctl to force shutdown the process like I assume windows does, then I can probably use that.
Anyways, I am looking for a way to terminate one or all sessions in postgresql 8.3 that is not platform specific. Any help would be great!
You can use pg_cancel_backend():
select pg_cancel_backend(55555);
You can use this with pg_stat_activity. For example:
select pg_cancel_backend(procpid)
from pg_stat_activity where current_query='<IDLE>';
If that doesn't work you can try this:
pg_ctl kill -TERM pid
That should be OS independent. I'm not sure if there's any real difference in behaviour.
Other than that you could try stopping and starting the server, but you indicated odd behaviour from that. (What kind?)
Finally, for an OS specific option, on linux you can of course try using the kill command. kill -15 (SIGTERM) is safe; that's basically what pg_terminate_backend uses: kill -15 <pid>. kill -9 is moderately unsafe and you should use it only as a last resort.
su - posgres
psql
SELECT pg_terminate_backend(pg_stat_activity.procpid) FROM pg_stat_activity WHERE procpid <> pg_backend_pid() AND datname = 'dbname' ;
drop database "database name";