为什么PHP PDO在使用持久连接时连接到不同的数据库?

时间:2022-09-26 08:43:11

I connect to MySQL using PHP's PDO like this:

我使用PHP的PDO连接到MySQL,如下所示:

$driver_options[PDO::ATTR_PERSISTENT] = true;
$db = new PDO('mysql:host='.$host.';dbname='.$db_name, $user, $pass, $driver_options);

I have 2 databases (let's call them database_A and database_B) on this server and sometimes very strange thing happens. Even though, $db_name is 100% set to 'database_A', connection is made to 'database_B'.

我在这台服务器上有2个数据库(让我们称之为database_A和database_B),有时会发生非常奇怪的事情。即使$ db_name 100%设置为'database_A',也会连接到'database_B'。

It's happening completely random. I can run the same script 10 times over again and everything is fine. And 11th time this problem happens.

它完全随机发生。我可以再次运行相同的脚本10次,一切都很好。第11次这个问题发生了。

I would never expect this to happen. It gave me a lot of headache. Can anyone explain it ? And is the only solution not to use persistence ?

我永远不会指望这种情况发生。它让我很头疼。有谁能解释一下?并且是不使用持久性的唯一解决方案?

3 个解决方案

#1


4  

PDO::ATTR_PERSISTENT is partially supported and is dependent on the the PHP version and SQL server you're using. I would recommend never setting this attribute to true in the drive options due to it's instability.

部分支持PDO :: ATTR_PERSISTENT,它依赖于您正在使用的PHP版本和SQL服务器。我建议永远不要在驱动器选项中将此属性设置为true,因为它不稳定。

I was able to replicate your case and i found that the ODBC Connection Pooling layer was caching the connection and since your connection is being set to persistent, the cache was being reset each time i made a new connection.

我能够复制你的情况,我发现ODBC连接池层正在缓存连接,并且由于你的连接被设置为持久性,每次我建立新连接时都会重置缓存。

#2


0  

$driver_options[PDO::ATTR_PERSISTENT] = true;
$db = new PDO('mysql:host='.$host.';dbname='.$db_name, $user, $pass,    $driver_options);

When you do the above, the PDO connection is placed in the "persistent connection pool", but the pool purpose is not to cache the database, but rather the memory allocation, authentication and setup groundwork. That is what uses time (not so much, at that).

当您执行上述操作时,PDO连接将放置在“持久连接池”中,但池的目的不是缓存数据库,而是缓存内存分配,身份验证和设置基础。这就是使用时间(不是那么多)。

Whatever else you supply in the new PDO() call is LOST.

你在新的PDO()调用中提供的其他内容是LOST。

And if you have two databases with the same credentials, you can get them swapped at random -- as you experienced.

如果你有两个具有相同凭据的数据库,你可以随意交换它们 - 正如你所经历的那样。

So, do not specify the DB in the new PDO statement, but use the USE databasename SQL statement as soon as the new PDO object is ready.

因此,不要在新的PDO语句中指定DB,而是在新的PDO对象准备好后立即使用USE databasename SQL语句。

Or, as PankajKumar suggests, set up different credentials for the two DBs. Then the mistaken cache hit will not happen (but is wont to happen again as soon as someone reuses those same credentials - such as 'ubuntu/ubuntu' or 'root/').

或者,正如PankajKumar建议的那样,为两个DB设置不同的凭据。然后错误的缓存命中将不会发生(但是一旦有人重用那些相同的凭证 - 例如'ubuntu / ubuntu'或'root /',它就不会再发生)。

#3


0  

I suppose you are running this in production, or a dev system which is reloaded not so often.

我想你是在生产中运行它,或者是不经常重新加载的开发系统。

Therefore please restart all your php workers/instances/threads and check if the problem occurs again.

因此,请重新启动所有php worker / instances / threads并检查问题是否再次发生。

I believe one of these processes is holding your old configuration. And silently causes your errors, randomly when your webserver actually chooses to use the old thing.

我相信其中一个进程正在保留您的旧配置。当您的网络服务器实际选择使用旧的东西时,随机地默默地导致您的错误。

#1


4  

PDO::ATTR_PERSISTENT is partially supported and is dependent on the the PHP version and SQL server you're using. I would recommend never setting this attribute to true in the drive options due to it's instability.

部分支持PDO :: ATTR_PERSISTENT,它依赖于您正在使用的PHP版本和SQL服务器。我建议永远不要在驱动器选项中将此属性设置为true,因为它不稳定。

I was able to replicate your case and i found that the ODBC Connection Pooling layer was caching the connection and since your connection is being set to persistent, the cache was being reset each time i made a new connection.

我能够复制你的情况,我发现ODBC连接池层正在缓存连接,并且由于你的连接被设置为持久性,每次我建立新连接时都会重置缓存。

#2


0  

$driver_options[PDO::ATTR_PERSISTENT] = true;
$db = new PDO('mysql:host='.$host.';dbname='.$db_name, $user, $pass,    $driver_options);

When you do the above, the PDO connection is placed in the "persistent connection pool", but the pool purpose is not to cache the database, but rather the memory allocation, authentication and setup groundwork. That is what uses time (not so much, at that).

当您执行上述操作时,PDO连接将放置在“持久连接池”中,但池的目的不是缓存数据库,而是缓存内存分配,身份验证和设置基础。这就是使用时间(不是那么多)。

Whatever else you supply in the new PDO() call is LOST.

你在新的PDO()调用中提供的其他内容是LOST。

And if you have two databases with the same credentials, you can get them swapped at random -- as you experienced.

如果你有两个具有相同凭据的数据库,你可以随意交换它们 - 正如你所经历的那样。

So, do not specify the DB in the new PDO statement, but use the USE databasename SQL statement as soon as the new PDO object is ready.

因此,不要在新的PDO语句中指定DB,而是在新的PDO对象准备好后立即使用USE databasename SQL语句。

Or, as PankajKumar suggests, set up different credentials for the two DBs. Then the mistaken cache hit will not happen (but is wont to happen again as soon as someone reuses those same credentials - such as 'ubuntu/ubuntu' or 'root/').

或者,正如PankajKumar建议的那样,为两个DB设置不同的凭据。然后错误的缓存命中将不会发生(但是一旦有人重用那些相同的凭证 - 例如'ubuntu / ubuntu'或'root /',它就不会再发生)。

#3


0  

I suppose you are running this in production, or a dev system which is reloaded not so often.

我想你是在生产中运行它,或者是不经常重新加载的开发系统。

Therefore please restart all your php workers/instances/threads and check if the problem occurs again.

因此,请重新启动所有php worker / instances / threads并检查问题是否再次发生。

I believe one of these processes is holding your old configuration. And silently causes your errors, randomly when your webserver actually chooses to use the old thing.

我相信其中一个进程正在保留您的旧配置。当您的网络服务器实际选择使用旧的东西时,随机地默默地导致您的错误。