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

DBAL-1057 Connection is not lazy anymore when platform detection is necessary #990

Closed
doctrinebot opened this issue Dec 5, 2014 · 23 comments · Fixed by #2671
Closed

DBAL-1057 Connection is not lazy anymore when platform detection is necessary #990

doctrinebot opened this issue Dec 5, 2014 · 23 comments · Fixed by #2671

Comments

@doctrinebot
Copy link

Jira issue originally created by user stof:

In DBAL 2.5, many driver can rely on different versions of the platform. Unless the version is explicitly provided, the driver will guess it at instantiation time, killing the lazyness of the connection.
This is a critical issue in any context using DI as it means that injecting the connection into anything else will connect to the server.

@doctrinebot
Copy link
Author

@doctrinebot
Copy link
Author

Comment created by stof:

Actually, the Connection class itself defers the guessing until the first time the platform is accessed. But many places in DBAL and in the ORM are retrieving the platform and storing it in a property of the class at instantiation time to avoid method calls when they need to access the platform. So this might be much harder to fix

@doctrinebot
Copy link
Author

Comment created by @deeky666:

[~stof] Can we analyze the use cases where retrieving the platform is necessary before actually connecting? I only know the custom type registering so far... Maybe we can defer that somehow?

@doctrinebot
Copy link
Author

Comment created by stof:

[~deeky666] the issue is that many places in DBAL and the ORM are retrieving the connection before they use it. the Connection class itself in DBAL is already deferring the guessing

@doctrinebot
Copy link
Author

Comment created by @deeky666:

[~stof] I know that. The question is WHY do those defered connections need to access Connection::getDatabasePlatform() without connecting? What are the use cases?

@doctrinebot
Copy link
Author

Comment created by stof:

[~deeky666] The issue is that all those objects are calling $connection->getDatabasePlatform() in their own constructor to store a reference to it for faster access later (no more method calls). This means that _instantiating_ the ORM (or some parts of DBAL) triggers the platform guessing, which connects to the DB. This breaks the lazyness and hurts DI contexts (maybe the ORM will not even be used in this process, but it was instantiated because of being a dependency in a complex object graph).

@doctrinebot
Copy link
Author

Comment created by stof:

and the issue is precisely that all these parts of Doctrine are _not_ deferring the retrieval of the platform.

@doctrinebot
Copy link
Author

Comment created by steffenbrem:

This is causing a lot of issues when using CI servers. Where it is very important that those things are lazy, since you do not have the database configured on most applications that build on a CI server.

@doctrinebot
Copy link
Author

Comment created by craigh:

This is also an issue for the project I am working as I am trying to use Symfony to to generate forms and so on in order to install the project. sForms and the main project's front controller trigger DI events and trigger this error. The workaround mentioned here (doctrine/DoctrineBundle#351 (comment)) fixes the problem but this cannot be a long term solution. I look forward to the fix for this issue.

@doctrinebot
Copy link
Author

Comment created by alanhartless:

I have the same issue as Craig. This poses a major hassle for applications that have an installer UI. We have a Symfony based application that gives the user options to configure the database such as driver, table, credentials, etc. Then the application will make a dynamic connection to check database, install data, etc. Eventually Symfony's cache is cleared to use the new credentials post install.

Because of this, the installer fails out of the box since it can't connect to the server.

We can't use the work around as mentioned above because of giving the option to choose what driver to use in the installer.

Thanks,
Alan

@doctrinebot
Copy link
Author

Comment created by craigh:

Tried an experiment today. As noted in the workaround you can set the server_version: 5.1 (or whatever your version is).

Well, my version is 5.5 so I originally used that. Today I tried 5 and 52 and 1 and they all worked!

so it seems that the actual version doesn't matter (at least when I need them, which is before_ I've actually set up the DB credentials) as long is there is _some value.

@doctrinebot
Copy link
Author

Comment created by @deeky666:

[~craigh] this is expected behaviour. You can theoretically specify any value you want, DBAL will try to find the appropriate platform for you by the specified version via version compare.
See the example for PostgreSQL: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php#L97-L119
As soon as the specified value/version does not match a specific platform version, DBAL will always fallback to the "default" platform (the one that was chosen by default prior 2.5).
Once the serverVersion parameter is set, auto detection of the proper platform is always bypassed.

@doctrinebot
Copy link
Author

Comment created by rosier:

Doctrine now also throws a connection exception when it tries to detect the database platform, but can't make a connection to the server. Even if the connection isn't really used.

I think it would be better to do a fallback to the "default" platform in that case and only throw an connection exception if the connection is required for something else than guessing the platform.

For example if you haven't set up the DB credentials yet and only call Doctrine\DBAL\Connection::getDatabasePlatform() you get the "default" platform.

@tristanbes
Copy link
Contributor

This still happens, and I don't know if I have to put when using mysql -V => mysql Ver 15.1 Distrib 10.0.22-MariaDB

Shall I use server_version: 10.0 or server_version: 5.6 since MariaDB is based on MySQL 5.6 engine ?

This "bug" makes Symfony 2.8 application not bootable without an access to the database

@deeky666
Copy link
Member

@tristanbes we currently have no distinction for MariaDB servers. DBAL currently checks for substring mariadb in the version constraint and returns the "default" MySQL platform if found (this happen only on autodetection of course). If you want/need to explicitly set the server version, use a MySQL version number that MariaDB depends on to get the most suitable platform. So in your case 5.6 would be correct.
Please note that DBAL does not have official MariaDB support yet. It only contains some patches like the version evaluation thing mentioned, to be rather compatible.

Hope this helps for now.

@tristanbes
Copy link
Contributor

thanks @deeky666

@NeilJ247
Copy link

I am seeing the issue on AWS even with the server_version set. I get "php_network_getaddresses: getaddrinfo failed:" error message. The database we use is on AWS is MariaDB.

@Ocramius
Copy link
Member

I'd need a stack trace to understand the issue then...
On Jun 10, 2016 1:31 PM, "NeilJ247" notifications@github.com wrote:

I am seeing the issue on AWS even with the server_version set. I get
"php_network_getaddresses: getaddrinfo failed:" error message. The database
we use is on AWS is MariaDB.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#990 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAJakGVEM52uznDZwbL-Q7kAIK52BnS4ks5qKUsbgaJpZM4HBKai
.

@NeilJ247
Copy link

NeilJ247 commented Jun 10, 2016

@Ocramius Apologies should have explained more. Using Symfony3 with Doctrine 2.5. I've included the important parts of the stack trace. In this case the application tried to do a query for a login request and it barfs with the attached
stacktrace.txt

The config.yml has the version specified as below:

doctrine: dbal: driver: pdo_mysql host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 server_version: 5.6

This works fine for MySQL on my local machine but when the application is in AWS it doesn't work.

Thanks.

@Ocramius
Copy link
Member

Since you use Symfony, could you pleas continue the discussion on the
doctrine-bundle issue that I linked above?
On Jun 10, 2016 2:48 PM, "NeilJ247" notifications@github.com wrote:

@Ocramius https://github.com/Ocramius Apologies should have explained
more. Using Symfony3 with Doctrine 2.5. I've included the important parts
of the stack trace. In this case the application tried to do a query for a
login request and it barfs with this:

[2016-06-10 11:59:59] request.CRITICAL: Uncaught PHP Exception
Doctrine\DBAL\Exception\ConnectionException: "An exception occured in
driver: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo
failed: Name or service not known" at
/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php
line 103 Array
(
[exception] => [object](DoctrineDBALExceptionConnectionException%28code:
0%29: An exception occured in driver: SQLSTATE[HY000] [2002]
php_network_getaddresses: getaddrinfo failed: Name or service not known at
/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:103,
DoctrineDBALDriverPDOException%28code: 2002%29: SQLSTATE[HY000] [2002]
php_network_getaddresses: getaddrinfo failed: Name or service not known at
/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:47,
PDOException%28code: 2002%29: SQLSTATE[HY000] [2002] php_network_getaddresses:
getaddrinfo failed: Name or service not known at
/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43)
[stacktrace]
#0 /html/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php(133):
Doctrine\DBAL\Driver\AbstractMySQLDriver->convertException('An exception
oc...', Object(Doctrine\DBAL\Driver\PDOException))
#1
/html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php(47):
Doctrine\DBAL\DBALException::driverException(Object(Doctrine\DBAL\Driver\PDOMySql\Driver),
Object(Doctrine\DBAL\Driver\PDOException))
#2 /html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(360):
Doctrine\DBAL\Driver\PDOMySql\Driver->connect(Array, 'root', '', Array)
#3 /html/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(814):
Doctrine\DBAL\Connection->connect()
#4
/html/vendor/doctrine/orm/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php(712):
Doctrine\DBAL\Connection->executeQuery('SELECT t0.id AS...', Array, Array)

The config.yml has the version specified as below:

doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
server_version: 5.6

This works fine for MySQL on my local machine but when the application is
in AWS it doesn't work.

Thanks.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#990 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AAJakFvvtYUqHnxeMhIwyQ4TNxRLbOfgks5qKV0WgaJpZM4HBKai
.

@NeilJ247
Copy link

@Ocramius will do.

1ma added a commit to 1ma/docker-symfony that referenced this issue Jun 21, 2016
you must set the database software version in the config.yml file.
deeky666 added a commit to deeky666/dbal that referenced this issue Mar 9, 2017
deeky666 added a commit to deeky666/dbal that referenced this issue May 10, 2017
…fallback

fixes doctrine#990: try platform detection without database name as fallback
deeky666 added a commit to deeky666/dbal that referenced this issue May 10, 2017
deeky666 added a commit to deeky666/dbal that referenced this issue May 10, 2017
@Ocramius Ocramius added this to the 2.6 milestone May 10, 2017
@Ocramius
Copy link
Member

Handled in #2671

@Ocramius Ocramius changed the title DBAL-1057: Connection is not lazy anymore when guessing the platform is necessary DBAL-1057: Connection is not lazy anymore when platform detection is necessary Jul 22, 2017
@Ocramius Ocramius changed the title DBAL-1057: Connection is not lazy anymore when platform detection is necessary DBAL-1057 Connection is not lazy anymore when platform detection is necessary Jul 22, 2017
@github-actions
Copy link

github-actions bot commented Aug 4, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants