PHP Rename()不能总是在Windows环境中找到源文件(代码2)



我的环境是:Windows,MSSQL和PHP 5.4。

我的场景:我正在执行一个小型外壳脚本,该脚本从我想要的数据库中创建完整的备份到临时文件夹,然后将其移至新位置。

备份良好,文件是在我的临时文件夹中创建的。然后,我将其重命名为第二个文件夹,有时还可以,有时它找不到源文件。

当然,在这一点上,我知道我可以跳过临时位置,但是找不到文件困扰我的实际问题。为什么如此随机,并且可能还会影响我在此之前编写的其他文件功能...我还需要控制文件如何以及何时移动到目标。

基本代码很简单(尽管这是我实际代码的简化版本,因为我怀疑任何人都会对我的错误处理/记录条件感兴趣):

$query = "use test; backup database test to disk '//server01/temp/backups/file.bak', COMPRESSION;";
if($SQLClass->query($query)) { 
    $source="////server01//temp//backups//file.bak";
    $destination="////server02//storage//backups//file.bak";
    if(!rename($source , $destination)) {
        //handleError is just a class function of mine that logs and outputs errors.
        $this->handleError("Moving {$source} to {$destination} failed.");
    }
}
else {
    die('backup failed');
}

我尝试的是:

  • 我在它之前添加了一个file_exists,并且当重命名时找不到源文件。
  • 由于找不到文件,copy()和unlink()也无法正常工作
  • 尝试过clearstatcache()
  • SQL备份完成后尝试睡眠(10)

这些根本没有帮助。我和Google似乎对下一步该怎么做或尝试。当然,我可以进行一些shell_execect,但这不会消除我对早期产品的担忧。

我只是在尝试多次运行命令时才注意到这个问题。ClearStatCache()无法触摸的文件名是否有某种缓存?它似乎与某种幽灵文件现象有关,其中PHP迟到了文件系统内容或此类。

我将感谢有关接下来要做什么的任何想法,如果您读到这么远,谢谢:)。

您可以尝试调用系统的copy命令。当我必须在两个NFS共享之间复制文件时,我曾经有像您这样的问题(在Linux框上)。它只是不时失败,没有明显的原因。我切换到cp(Windows复制的模拟)问题已经消失了。

肯定不是完美的,但对我有用。

它可能与缓存相关,或者MySQL进程尚未发布该文件。MySQL将文件将文件转移到另一个 temp文件中,首先将文件移至您的 temp文件夹。当文件移动时,其他过程可能无法访问。

首先,当出现错误时,我将尝试在temp dir中 glob()。也许您注意到它还没有完成。

您还尝试实现诸如10个重试迭代之类的东西,并有所延迟?

$notMoved = 0;
while($notMoved < 10){
    $source="////server01//temp//backups//file.bak";
    $destination="////server02//storage//backups//file.bak";
    if(!rename($source , $destination)) {
        //handleError is just a class function of mine that logs and outputs errors.
        if ($notMoved++ < 10){
           sleep(20);
        } else {
           $this->handleError("Moving {$source} to {$destination} failed.");
           break;
        }
    }else{
       break;
    }
}

绕过问题:

  • 不要倾倒并移动
  • 移动然后转储: - )

(OFC。当时您的备份商店将是一个)

    $source="////server01//temp//backups//file.bak";
    $destination="////server02//storage//backups//file.bak";
    if(!rename($source , $destination)) {
        //handleError is just a class function of mine that logs and outputs errors.
        $this->handleError("Moving {$source} to {$destination} failed.");
    }
$query = "use test; backup database test to disk '//server01/temp/backups/file.bak', COMPRESSION;";
if($SQLClass->query($query)) { 
  //done :-)
}
else {
    die('backup failed');
}

尝试

$source = "\server01tempbackupsfile.bak";
$destination = "\server02storagebackupsfile.bak";
$content = file_get_content($source);
file_put_contents($destination, $content);

最新更新