我们在 Php Laravel 中构建了应用程序,对于数据库我们使用 postgres sql。此外,在 postgres 之上,我们还配置了 pgBouncer,通过管理可供任何应用程序使用的空闲连接池来限制服务器端的最大连接数。
现在,我们面临应用程序 (Php Laravel) 中使用的布尔值 (True(0),False(1)) 的问题。执行任何 CRUD 操作时都会出现以下错误。在下面的错误列中,“已撤销”是布尔类型。
列“revoked”是布尔类型,但表达式是整数类型
您将需要重写或转换表达式。 (SQL:\“撤销\”,\“created_at \”)值(0,2020-02-07 06:09:06)
现在经过探索,我开始知道布尔值需要被考虑为 pgBouncer 的字符串。所以我做了一些改变连接.php文件,位于“\vendor\laravel\framework\src\Illuminate\Database“。我已经更改了代码以考虑布尔值,如下所述。
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
);
}
}
经过上述更改后,布尔值的错误已解决。
但是,现在我在服务器上面临奇怪的问题,当我检查数据库日志错误时,我始终收到以下错误。
错误:准备好的语句“pdo_stmt_00000001”已存在
语句:设置名称“utf8”
错误:准备好的语句“pdo_stmt_00000001”不存在
语句:解除分配 pdo_stmt_00000001
这真的很奇怪,在探索互联网之后,我在我的程序中做了以下更改数据库.php文件,以禁用准备语句。
'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
]
]
设置原因ATTR_EMULATE_PREPARES => true是因为我设置了“交易“模式在”pgbouncer.ini" file.
现在,要使准备好的语句起作用交易模式需要 PgBouncer 在内部跟踪它们,但它不这样做。因此,在这种模式下继续使用 PgBouncer 的唯一方法是禁用客户端中的预准备语句,在我的例子中是 PHP Laravel,我已经在“数据库.php如上面代码所示,在建立连接时创建文件。
我已经尝试了所有选项,其中给出http://www.pgbouncer.org/faq.html#how-to-use-prepared-statements-with-transaction-pooling http://www.pgbouncer.org/faq.html#how-to-use-prepared-statements-with-transaction-pooling但它并没有解决准备语句错误显示在数据库日志中。
错误:准备好的语句“pdo_stmt_00000001”已存在
语句:设置名称“utf8”
错误:准备好的语句“pdo_stmt_00000001”不存在
语句:解除分配 pdo_stmt_00000001
请指导我同样的问题以及该错误需要哪些进一步的设置。这些错误发生在客户端生产服务器上,我们无法在生产服务器中继续处理这些错误。
请尽早向我提供您的宝贵反馈,因为我在 5 天后就遇到了这个问题,并尝试了遇到的所有选项。
Thanks!