MDL-63315 DB: Postgres - Clear cursors in persistent connection

If there is a PHP fatal error and destructors do not run (this can
happen in out-of-memory errors, and maybe if there is an error in a
previous destructor) then Postgres cursors may be left open.

Usually this does not cause a problem because the connection is
closed anyway, but if using persistent connections, a future
request may reuse the connection with a cursor open. It then gets
errors when it tries to create a new cursor with the same name.

This change closes all cursors at the start of a persistent
connection.
This commit is contained in:
sam marshall
2019-09-02 14:08:57 +01:00
parent 310d6901f9
commit 46875866c6
+11
View File
@@ -187,6 +187,17 @@ class pgsql_native_moodle_database extends moodle_database {
throw new dml_connection_exception($dberr);
}
if (!empty($this->dboptions['dbpersist'])) {
// There are rare situations (such as PHP out of memory errors) when open cursors may
// not be closed at the end of a connection. When using persistent connections, the
// cursors remain open and 'get in the way' of future connections. To avoid this
// problem, close all cursors here.
$result = pg_query($this->pgsql, 'CLOSE ALL');
if ($result) {
pg_free_result($result);
}
}
if (!empty($this->dboptions['dbhandlesoptions'])) {
/* We don't trust people who just set the dbhandlesoptions, this code checks up on them.
* These functions do not talk to the server, they use the client library knowledge to determine state.