Nil*_*hod 4 postgresql pdo pgbouncer laravel
我们在 Php Laravel 中构建了应用程序,对于数据库,我们使用 postgres sql。并且在 postgres 之上,我们配置了 pgBouncer,通过管理一个可供任何应用程序使用的空闲连接池来限制服务器端的最大连接数。
现在,我们面临应用程序 (Php Laravel) 中使用的布尔值 (True(0),False(1)) 的问题。执行任何 CRUD 操作时会出现以下错误。在下面的错误列中,“已撤销”是布尔类型。
列 \"revoked\" 是布尔类型,但表达式是整数类型您需要重写或强制转换表达式。(SQL: \"revoked\", \"created_at\") 值 (0, 2020-02-07 06:09:06)
现在经过探索,我开始知道需要将布尔值视为 pgBouncer 的字符串。所以我对位于“ \vendor\laravel\framework\src\Illuminate\Database ”的connection.php文件进行了更改。我已更改代码以考虑如下所述的布尔值。
public function bindValues($statement, $bindings)
{
foreach ($bindings as $key => $value) {
//if(is_bool($value))
$statement->bindValue(
is_string($key) ? $key : $key + 1, $value,
//is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR
is_int($value) ? PDO::PARAM_INT : is_bool($value) ? PDO::PARAM_STR : PDO::PARAM_STR
);
}
}
Run Code Online (Sandbox Code Playgroud)
After the above changes the error with the boolean values was solved.
But, now I am facing strange issues on the server, when I check the database log error I consistently get the below error.
ERROR: prepared statement "pdo_stmt_00000001" already exists STATEMENT: set names 'utf8' ERROR: prepared statement "pdo_stmt_00000001" does not exist STATEMENT: DEALLOCATE pdo_stmt_00000001
It really was strange, and after exploring the internet I have done the below changes in my database.php file, to disable the prepare statements.
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
'options' => [
\PDO::ATTR_EMULATE_PREPARES => true
]
]
Run Code Online (Sandbox Code Playgroud)
The reason behind seeting ATTR_EMULATE_PREPARES => true is becasue I have set "Transaction" mode in "pgbouncer.ini" file.
Now, to make prepared statements work in Transaction mode would need PgBouncer to keep track of them internally, which it does not do. So only way to keep using PgBouncer in this mode is to disable prepared statements in the client, which in my case is PHP Laravel and I have already handle it in the "database.php" file when the connection is made as shown in above code.
I have tried all the options, which are given in http://www.pgbouncer.org/faq.html#how-to-use-prepared-statements-with-transaction-pooling but it doesnot solve the prepare statment error shown in the database log.
错误:准备好的语句“pdo_stmt_00000001”已经存在语句:设置名称“utf8”错误:准备好的语句“pdo_stmt_00000001”不存在语句:DEALLOCATE pdo_stmt_00000001
请指导我相同的以及错误需要哪些进一步的设置。这些错误在客户端生产服务器上,我们不能继续在生产服务器中处理这些错误。
请尽早给我您宝贵的反馈,因为我从 5 天开始就面临这个问题,并尝试所有遇到的选项。
谢谢!
小智 9
1) 首先,您需要更改您在 database.php 的 pgsql 数组中的选项中提供的 PDO 选项,正确的方法如下所示。
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5434'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
'options' => [
PDO::ATTR_EMULATE_PREPARES => true
]
]
Run Code Online (Sandbox Code Playgroud)
2)其次,也是最重要的一点是确保您使用将“ATTR_EMULATE_PREPARES”设置为“true”与您尝试在Database.php文件中连接的每个数据库连接。
例如,
'test' => [
'driver' => 'pgsql',
'host' => env('test', '127.0.0.1'),
'port' => env('test', '5434'),
'database' => env('DB_TEST_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'test'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
'options' => [
PDO::ATTR_EMULATE_PREPARES => true
]
],
'test1' => [
'driver' => 'pgsql',
'host' => env('test1', '127.0.0.1'),
'port' => env('test1', '5434'),
'database' => env('DB_TEST1_DATABASE', 'test1'),
'username' => env('DB_USERNAME', 'test'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
'options' => [
PDO::ATTR_EMULATE_PREPARES => true
]
]
Run Code Online (Sandbox Code Playgroud)
请确保对您在应用程序中建立的每个数据库连接使用“ATTR_EMULATE_PREPARES”为真,在您的评论中,您仅与“pgsql”建立连接,该连接仅强调 postgres sql 连接,而不是与您的应用程序通信的数据库在 postgres 中。
希望这可以帮助您解决您的查询。享受!!!
| 归档时间: |
|
| 查看次数: |
2228 次 |
| 最近记录: |