Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose Doctrine support for persistent connections in PDO in Nextcloud settings #32899

Merged
merged 4 commits into from
Oct 3, 2022

Conversation

Retidurc
Copy link
Contributor

@Retidurc Retidurc commented Jun 16, 2022

This is a very naive PR to expose Doctrine support for persistent connections in PDO doctrine/dbal#2315 in Netxcloud settings.

This setting enable the use of PDO::ATTR_PERSISTENT in the PDO driver .

This, with the various "persistent" options suggested in the docs allow for php-fpm to keep open and reuse connexion to the backend database. Not unlike a pool of connexion we can encounter in other languages.

I am personally using this modification, with a postresql database and pgsql.allow_persistent = On for a small nextcloud shared between friends and haven't seen anything weird yet. Although my use case is fairly small and problems may arise on larger instances

@szaimen szaimen added the 3. to review Waiting for reviews label Jun 16, 2022
@szaimen szaimen added this to the Nextcloud 25 milestone Jun 16, 2022
@szaimen szaimen requested review from a team, icewind1991, skjnldsv and CarlSchwan and removed request for a team June 17, 2022 08:19
@PVince81
Copy link
Member

wouldn't it work to set it to "dbdriveroptions" directly in config.php, for example:

'dbdriveroptions' => [
   PDO::ATTR_PERSISTENT => true,
]

@Retidurc
Copy link
Contributor Author

wouldn't it work to set it to "dbdriveroptions" directly in config.php, for example:

'dbdriveroptions' => [
   PDO::ATTR_PERSISTENT => true,
]

It's more or less what my first try to tinker with PDO::ATTR_PERSISTENT looked like.

Although it works, I think it would be safer and more future-proof to expose a simple true/false flag, in turn enabling/disabling the setting in doctrine, rather than tuning the PDO driver from the nextcloud config file.

Let me explain:
PDO::ATTR_PERSISTENT may have some side effect, If there is an unpredictable error during the script execution, the connection is blocked and can not be re used. AFAIK, Doctrine dbal handles those cases when their own persistent option is enabled, they may handle more subtle cases in the future. Directly tuning the PDO driver will not enable this behavior. (and Kinda defeat the idea of using a abstraction layer)

This was referenced Aug 12, 2022
@blizzz blizzz mentioned this pull request Aug 24, 2022
@Retidurc Retidurc force-pushed the pdo-attr-persistent branch 3 times, most recently from bcd1308 to 34f314f Compare August 29, 2022 10:05
@blizzz blizzz mentioned this pull request Aug 30, 2022
@Retidurc Retidurc changed the title Expose Doctrine support for persistent connections in PDO in Netxcloud settings Expose Doctrine support for persistent connections in PDO in Nextcloud settings Sep 5, 2022
@blizzz blizzz mentioned this pull request Sep 6, 2022
@blizzz blizzz mentioned this pull request Sep 9, 2022
@Retidurc Retidurc force-pushed the pdo-attr-persistent branch 2 times, most recently from ea0f124 to 7afa744 Compare September 15, 2022 12:43
@skjnldsv skjnldsv mentioned this pull request Sep 15, 2022
@Retidurc Retidurc force-pushed the pdo-attr-persistent branch 2 times, most recently from 0b5c89c to 369b4c8 Compare September 16, 2022 18:26
Copy link
Member

@CarlSchwan CarlSchwan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm with this, maybe at some point we could do that by default when running php-fpm if we don't notice anything weird

@Retidurc
Copy link
Contributor Author

I'll also update doc on the other repo for this new tunable.

Friends already using this modification on their instances reported undesirable side effects when using

mysql.max_persistent=-1
mysql.max_links=-1

or

pgsql.max_persistent = -1
pgsql.max_links = -1

AKA "use an unlimited ammount of connexion to the db" , while php-fpm is set to pm = dynamic.

Thoses are the settings we can see here in the docs

As far as I can tell, php-fpm open a new connexion for each new children, and doesn't release the open connexion when a child is terminated.

It's not Nextcloud fault, but it's something to be aware of before enabling persistent connexion to the db.

I'll take a closer look later to see if it's something coming from doctrine dbal or php itself. In the meantime, I'll try to find sane default or alternatives to the aforementioned settings.

This was referenced Sep 20, 2022
@blizzz blizzz modified the milestones: Nextcloud 25, Nextcloud 26 Sep 22, 2022
Signed-off-by: Retidurc Silvernight <retidurc@silvernight.social>
Signed-off-by: Retidurc Silvernight <retidurc@silvernight.social>
Signed-off-by: Retidurc Silvernight <retidurc@silvernight.social>
Signed-off-by: Retidurc Silvernight <retidurc@silvernight.social>
@szaimen szaimen added 4. to release Ready to be released and/or waiting for tests to finish and removed 3. to review Waiting for reviews labels Sep 29, 2022
@blizzz
Copy link
Member

blizzz commented Oct 1, 2022

At the moment we don't set it, if not given, and doctrine sets permanent connections by default for the relevant engines:

ack ATTR_PERSISTENT 3rdparty/
3rdparty/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
23:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
36:            $pdoOptions[PDO::ATTR_PERSISTENT] = true;

Applying the change would switch the normal behaviour to non-persistent connections.

@Retidurc
Copy link
Contributor Author

Retidurc commented Oct 1, 2022

At the moment we don't set it, if not given, and doctrine sets permanent connections by default for the relevant engines:

ack ATTR_PERSISTENT 3rdparty/
3rdparty/doctrine/dbal/src/Driver/PDO/OCI/Driver.php
21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php
23:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php
21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;

3rdparty/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php
36:            $pdoOptions[PDO::ATTR_PERSISTENT] = true;

Applying the change would switch the normal behaviour to non-persistent connections.

If you check those files, there is a if statement around all thoses lines.

grep -rin -B 2 -A1 "PDO::ATTR_PERSISTENT" .
./doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php-21-
./doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php-22-        if (! empty($params['persistent'])) {
./doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php:23:            $driverOptions[PDO::ATTR_PERSISTENT] = true;
./doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php-24-        }

./doctrine/dbal/src/Driver/PDO/MySQL/Driver.php-19-
./doctrine/dbal/src/Driver/PDO/MySQL/Driver.php-20-        if (! empty($params['persistent'])) {
./doctrine/dbal/src/Driver/PDO/MySQL/Driver.php:21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;
./doctrine/dbal/src/Driver/PDO/MySQL/Driver.php-22-        }

./doctrine/dbal/src/Driver/PDO/OCI/Driver.php-19-
./doctrine/dbal/src/Driver/PDO/OCI/Driver.php-20-        if (! empty($params['persistent'])) {
./doctrine/dbal/src/Driver/PDO/OCI/Driver.php:21:            $driverOptions[PDO::ATTR_PERSISTENT] = true;
./doctrine/dbal/src/Driver/PDO/OCI/Driver.php-22-        }

./doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php-34-
./doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php-35-        if (! empty($params['persistent'])) {
./doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php:36:            $pdoOptions[PDO::ATTR_PERSISTENT] = true;
./doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php-37-        }

This is set only if "persistent" is present in the config passed to doctrine. Wich is what I'm doing there

@blizzz
Copy link
Member

blizzz commented Oct 3, 2022

If you check those files, there is a if statement around all thoses lines.

Darn, misinterpreted 😵‍💫

@blizzz blizzz merged commit 3efc9d7 into nextcloud:master Oct 3, 2022
@welcome
Copy link

welcome bot commented Oct 3, 2022

Thanks for your first pull request and welcome to the community! Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/server/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22

@szaimen
Copy link
Contributor

szaimen commented Jul 23, 2023

I'll take a closer look later to see if it's something coming from doctrine dbal or php itself. In the meantime, I'll try to find sane default or alternatives to the aforementioned settings.

@Retidurc did you do you research on the topic?
What is your conclousion? If using that setting, does one need to set
pgsql.max_persistent = -1
pgsql.max_links = -1
to not-unlimited?

@szaimen szaimen added the pending documentation This pull request needs an associated documentation update label Jul 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
4. to release Ready to be released and/or waiting for tests to finish enhancement pending documentation This pull request needs an associated documentation update
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants