使用PDO连接Firebird时运行中无法二次打开数据库的问题排查
问题
在Ubuntu 22.04.1服务器上,已安装Firebird 3.0.8、Apache 2.4和PHP 8.1.11(含php8.1-interbase扩展)。使用以下PDO脚本通过WEB访问数据库时单独运行正常:
<?php $utente = 'MyName'; $password = 'MyPW'; $database = 'firebird:host=localhost;dbname=/path/to/MYDB.FDB'; $connessione = new PDO($database, $utente, $password); $query = "SELECT..."; $comando = $connessione->prepare($query); $comando->execute(); $conta = 0; while ($riga[$conta] = $comando->fetch(PDO::FETCH_ASSOC)) {$conta++;} for ($i = 0; $i < $conta; $i++) { echo "$riga[$i]["COLUMN_NAME"]"; } $comando = null; $connessione = null; ?>
但该脚本执行期间,若通过另一个WEB连接或直接用FlameRobin访问数据库,会收到错误:
I/O error during "lock" operation for file "/path/to/MYDB.FDB"
Database already opened with engine instance, incompatible with current
此前使用PHP7.2的ibase_connect直接访问数据库:
$connessione = ibase_connect($database, $utente, $password); $query = "SELECT..."; $comando = ibase_query($connessione, $query); $conta = 0; while ($riga[$conta] = ibase_fetch_assoc($comando)) {$conta++;} ...
并未出现此类问题,请问问题出在哪里?
原因与解决方案
问题根源
你的PDO连接字符串使用本地文件路径直接访问,触发了Firebird的嵌入式引擎模式——该模式会独占数据库文件,同一时间仅允许一个引擎实例打开数据库,导致其他连接被拒绝。
而之前的ibase_connect默认通过Firebird服务端(fbserver)建立连接,属于客户端-服务端模式,服务端会统一管理并发连接,允许多个客户端同时访问数据库。
解决方法
修改PDO的DSN,明确指定通过Firebird服务端连接,而非直接访问本地文件:
// 修改后的数据库连接字符串 $database = 'firebird:host=localhost;dbname=localhost:/path/to/MYDB.FDB';
或使用默认端口3050的简写形式:
$database = 'firebird:dbname=localhost:/path/to/MYDB.FDB';
修改后PDO会通过Firebird服务端建立连接,服务端将处理并发访问,不会再出现独占锁问题。
另外需确保Firebird服务处于运行状态:
sudo systemctl status firebird3.0
若未运行,启动服务:
sudo systemctl start firebird3.0
内容的提问来源于stack exchange,提问作者Meandro
相关产品推荐
相关产品推荐

