Hello
I found a problem when stopping the database with
pg_ctl stop -D /rt_global/testdb/data -m fast
bash-4.1$ pg_ctl --version : pg_ctl (PostgreSQL) 9.6.0
The problem is:
- The client (used libpq in c++ or also psql in a perl) tries to insert a counter into testtable
- Whenever an error is returned to the client, the client tries is to write it again
Problem:
- the psql client receives an error but the record was inserted into the table!
- So the record is finally insertet twice
The postgres log shows this:
< 2017-01-24 06:35:39.825 CET > LOG: duration: 1.345 ms statement: select * from insert_testtable(66705);
< 2017-01-24 06:35:39.825 CET > FATAL: terminating connection due to administrator command
< 2017-01-24 06:35:39.825 CET > STATEMENT: select * from insert_testtable(66705);
… Note: this record was inserted (see table below) and client got error
< 2017-01-24 06:35:39.826 CET > LOG: shutting down
< 2017-01-24 06:35:39.831 CET > LOG: database system is shut down
< 2017-01-24 06:35:45.887 CET > LOG: database system was shut down at 2017-01-24 06:35:39 CET
< 2017-01-24 06:35:45.887 CET > FATAL: the database system is starting up
< 2017-01-24 06:35:45.887 CET > LOG: MultiXact member wraparound protections are now enabled
< 2017-01-24 06:35:45.888 CET > LOG: autovacuum launcher started
< 2017-01-24 06:35:45.888 CET > LOG: database system is ready to accept connections
< 2017-01-24 06:35:45.895 CET > LOG: duration: 1.628 ms statement: select * from insert_testtable(66705);
Duplicate record was inserted:
db1=# select * from testtable where counter = 66705;
counter | insert_time
---------±---------------------------
66705 | 2017-01-24 06:35:39.823853 … inserted but application got error
66705 | 2017-01-24 06:35:45.893446 … application retried to insert it after restart of postmaster
(2 rows)
Question: Can anybody tell how to avoid this problem?
Note: I have expected e.g. that a pg_terminate_backend makes it consistent but my tests showed it makes same problem
as with simple pg_ctl stop -m fast
Is there such a “graceful stop” method ?
- to rollback a transation and to send error to client
- or to finish the transaction and send ok to client
(but should never finish the transaction and send error to client)
best regards