drqwbh2150 2015-09-11 14:40
浏览 87
已采纳

许多操作后来自PHP的SQL连接错误

I'm currently looping to create a MBTiles map, and add information to my database each time. Here's how I configured my connection and execute actions during the loop:

if ($pdo_mbtiles == null) {
    echo "Opening new database connection".PHP_EOL;
    $pdo_mbtiles = new PDO('sqlite:'.$filename,
            '',
            '',
            array(
                PDO::ATTR_PERSISTENT => true
                )
            );
    $pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    $pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}


$q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
$q->bindParam(':zoom_level', $zoom_level);
$q->bindParam(':tile_column', $tile_column);
$q->bindParam(':tile_rowTMS', $tile_rowTMS);
$q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
$q->execute();

After 1018 times looping (this number doesn't change no matter how many times I try), I get this error message:

SQLSTATE[HY000]: General error: 14 unable to open database file

I checked the solution written here: How to prevent SQLITE SQLSTATE[HY000] [14]? but the echoed message only appears at the first time of the loop, so I assume the PDO connection isn't closed.

I didn't find other documentation relevant to this error code.

What could possibly go wrong here?

I tried to move the prepare and bind commands in a condition as follows. The exception isn't raised, but only the first tile is saved (or every tile is saved on top of the first one, not sure):

if ($pdo_mbtiles == null) {
    echo "Opening new database connection".PHP_EOL;
    $pdo_mbtiles = new PDO('sqlite:'.$filename,
            '',
            '',
            array(
                PDO::ATTR_PERSISTENT => true
                )
            );
    $pdo_mbtiles->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    $pdo_mbtiles->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}

if ($q == null) {
    $q = $pdo_mbtiles->prepare("INSERT INTO tiles (zoom_level, tile_column, tile_row,tile_data) VALUES (:zoom_level, :tile_column, :tile_rowTMS, :tile_data)");
    $q->bindParam(':zoom_level', $zoom_level);
    $q->bindParam(':tile_column', $tile_column);
    $q->bindParam(':tile_rowTMS', $tile_rowTMS);
    $q->bindParam(':tile_data', $tile_data, PDO::PARAM_LOB);
}
$q->execute();

Here are the files during the generation: files_during_process

And here after the exception is raised: files_after_process

Also, when the exception is raised, I do a var_dump of my $pdo_mbtiles, and here's the result (exactly the same as when I do it with a success):

object(PDO)#116 (0) {
}

Edit: Still trying to solve this problem, I simplified the code to create the MBTiles file. No success yet, but here's a sample if anyone want's to reproduce the issue. You can download it from https://www.dropbox.com/s/33vqamc9tn4c3ux/sample_PHP_MBTiles_generation_bug.zip?dl=0

  • 写回答

2条回答 默认 最新

  • douganbi7686 2015-09-17 14:42
    关注

    The error message was misleading. After many hours of debugging, I found that it was completely unrelated to my database connection. It's juste that I used fopen() to get tiles data, and didn't fclose() after registration, thus reaching the limit of 1024.

    1024 is because I used six require or require_once statements, so 1018 tile requests + 6 require = 1024 opened connections.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥170 如图所示配置eNSP
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真
  • ¥20 设计一款异域新娘的视频相亲软件需要哪些技术支持
  • ¥15 stata安慰剂检验作图但是真实值不出现在图上