3

データベースを PHP でバックアップしたかったのです。

リンクされたスクリプトをテストしましたが、終了することはありませんでした。クエリの前に を追加しようとしましたrepair $tableが、役に立ちませんでした。

したがって、2 つのテーブルをスキップするだけで (コードで確認できます)、正常に動作することがわかりました。

<?

error_reporting(E_ALL);
ini_set('error_reporting',1);
require('../basedatos.php');

echo 'included<br>';
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{


    echo '1<br>';
    //get all of the tables
    if($tables == '*')
    {
        $tables = array();
        $result = mysql_query('SHOW TABLES') or die(msyql_error());
        while($row = mysql_fetch_row($result))
        {
            $tables[] = $row[0];
        }
    }
    else
    {
        $tables = is_array($tables) ? $tables : explode(',',$tables);
    }
    echo '2<br>';
    //cycle through
    foreach($tables as $table)
    {
        if($table == 'etiquetas' || $table == 'links') continue;
        $repair = mysql_query("REPAIR table $table") or die(mysql_error());
        echo '3- '.$table.'<br>';
        $result = mysql_query('SELECT * FROM '.$table) or die(msyql_error());
        $num_fields = mysql_num_fields($result);

        $return.= 'DROP TABLE '.$table.';';
        $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table))  or die(msyql_error());
        $return.= "\n\n".$row2[1].";\n\n";

        for ($i = 0; $i < $num_fields; $i++) 
        {
            while($row = mysql_fetch_row($result))
            {
                $return.= 'INSERT INTO '.$table.' VALUES(';
                for($j=0; $j<$num_fields; $j++) 
                {
                    $row[$j] = addslashes($row[$j]);
                    $row[$j] = ereg_replace("\n","\\n",$row[$j]);
                    if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
                    if ($j<($num_fields-1)) { $return.= ','; }
                }
                $return.= ");\n";
            }
        }
        $return.="\n\n\n";

    }
    echo '4<br>';
    //save file
    $handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
    fwrite($handle,$return);
    fclose($handle);
}
backup_tables('localhost','username','password','*');
?>

問題を起こしている行を見つけて編集/削除できる方法はありますか?

-追伸-

また、それらをスキップしなければエラーは発生しません (スクリプトが最後まで到達しないため、醜いログをいくつか追加しました..理由はありますか?

-編集-

また、たとえば sqlBuddy を介してデータベースをエクスポートしようとすると、エラーも発生します。

ここに画像の説明を入力

4

6 に答える 6

1

いくつかのカスタム スクリプトと「sqlbuddy」などのツールのいずれかで同じバックアップの問題がある場合、結論は、問題はテーブルや DB にあるということです。

問題のあるテーブルをコピーして、元のテーブルの代わりにそれらをバックアップして、何が追加されるかを確認します。

CREATE TABLE etiquetas_copy AS SELECT * FROM etiquetas

コピーをバックアップできない場合、行数が決定的に問題であると思います。一部のプロバイダは、リソースを大量に使用するスクリプトや DB リクエストを恣意的に (場合によっては黙って) 強制終了します。

コメントで提案されているように、一度に 1000 行のバックアップを試みることができます。そんな感じ:

    $result = mysql_query('SELECT * FROM '.$table." LIMIT $n,$n+1000") or die(msyql_error());

それをラップする必要があり、1000行が処理されたら次のバッチを読み取るために、フェッチされた行の数が1000である間に数行が「回転」するループです。

于 2013-08-09T12:16:54.883 に答える
1

問題のあるテーブルでのみスクリプトを実行しようとしましたか? これらのテーブルにはバイナリ フィールドがありますか (BLOB のようなものですか?)。

PHP で処理する前に、フィールドの出力をエスケープしてみてください: HEX(field1)、HEX(field2)、HEX(field3) FROM リンクを選択します。

次に、INSERT ステートメントを次のように記述します。 INSERT INTO links (field1,field2,field3) VALUES (UNHEX(),UNHEX(),UNHEX());

また、ereg_replace の代わりに preg_replace を使用する必要があります。100倍くらい速いです。そのため、大きなデータに対して実行している場合、スクリプトの速度が低下する可能性があります。

最後に、エラーが発生するはずなので、エラー ログの構成を実際に調べる必要があります。それがphpエラー、メモリ制限エラー、最大実行時間エラーなどであるかどうか。

あなたのプロジェクトと同じように。

于 2013-08-09T14:01:36.477 に答える
1

出力を変数に保存する代わりに、file_put_contents と FILE_APPEND フラグを使用してクエリをファイルに書き込みます。時間がかかると思われる場合は、ビューアでファイルを調べるか、webroot ディレクトリにファイルを作成してブラウザで開いて、何が起こっているかを確認できます...

于 2013-08-06T06:29:16.260 に答える