7

David Walsh ( http://davidwalsh.name/backup-mysql-database-php ) によるデータベース バックアップ スクリプトを使用して、MYSQL データベースを .sql ファイルとしてサーバーにバックアップしています。

backup という名前のユーザーを作成し、すべての権限を付与しました (念のため)。次に、コードを php ファイルに入れ、cron ジョブをセットアップして php ファイルを実行します。

これはコードです:

/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{

    $link = mysql_connect($host,$user,$pass);
    mysql_select_db($name,$link);

    //get all of the tables
    if($tables == '*')
    {
        $tables = array();
        $result = mysql_query('SHOW TABLES');
        while($row = mysql_fetch_row($result))
        {
            $tables[] = $row[0];
        }
    }
    else
    {
        $tables = is_array($tables) ? $tables : explode(',',$tables);
    }

    //cycle through
    foreach($tables as $table)
    {
        $result = mysql_query('SELECT * FROM '.$table);
        $num_fields = mysql_num_fields($result);

        $return.= 'DROP TABLE '.$table.';';
        $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
        $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";
    }

    //save file
    $handle = fopen('../backup/db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
    fwrite($handle,$return);
    fclose($handle);
}

backup_tables('localhost','alupto_backup','pass','*');

cron ジョブを実行すると、バックアップが機能せず、次のようなエラーが記載された電子メールが届きます。


警告: mysql_fetch_row(): 指定された引数は、 18 行目の/home5/ideapale/public_html/amatorders_basic/admin/backup.phpの有効な MySQL 結果リソースではありません

18 行目には次のコードがあります。

while($row = mysql_fetch_row($result))

phpMyAdmin で SQL(SHOW TABLES) を実行すると、問題なく動作し、すべてのテーブルのリストが表示されます。しかし、何らかの理由で、php ファイルが SQL を実行しようとするとエラーが発生します。

データベース バックアップ スクリプトが機能しないのはなぜですか?

4

4 に答える 4

14

これは、データベースがおもちゃのデータベース ("hello world" スクリプトに相当するもの) でない限り、データベースを SQL スクリプトとしてバックアップする場合には機能しません。

あの脚本は恐ろしい。データベースのバックアップには使用しないでください。そのスクリプトは以前に投稿されています: PHP データベース ダンプ スクリプト - 問題はありますか?

  • mysql_connect() または mysql_queries() の後にエラー チェックはありません。おそらく間違ったパスワードか何かを入力しただけでしょうが、スクリプトは接続が成功したことを確認しないため、決してわかりません.

  • データベースに NULL が含まれている場合、正しい INSERT ステートメントは生成されません。

  • 文字セットは扱いません。

  • addslashes() は、データのエスケープには適していません

  • テーブル名は区切りません。

  • ビュー、プロシージャ、関数、またはトリガーをバックアップしません。

  • mysql_query() は結果をバッファリングするため、数千行以上のテーブルがある場合、PHP のメモリ制限を超えてしまいます。実際、スクリプトは一連の INSERT ステートメントを単一の PHP 変数に連結します。したがって、完了する前に、データベース全体がメモリに表示されます。

誰もそのスクリプトを使用しないでください。 それはまったくのゴミであり、私はそれを軽くは言いません.

shellexec() を使用して mysqldump を実行するだけです。

@Álvaro G. Vicario には良い点があります。このタスクに PHP を使用する必要さえありません。PHPスクリプトからバックアップを作成する必要があると想定していました。cron スクリプトからバックアップを作成する方法は次のとおりです。

シェル スクリプトを作成します。mymysqldump.sh など、任意の名前を付けることができます。これが私がそれを書く方法です:

:
: ${BACKUP_HOST:="localhost"}
: ${BACKUP_DATABASE:="mydatabase"}
: ${BACKUP_DIR:="/opt/local/var/db/mysql5/backups"}
: ${BACKUP_FILE:="${DATABASE}-`date +%Y%m%d%H%M%S`"}

mysqldump -h ${BACKUP_HOST} ${BACKUP_DATABASE} > ${BACKUP_DIR}/${BACKUP_FILE}

もちろん、環境の必要に応じて変数の値をカスタマイズしてください。

ユーザー名とパスワードがこのファイルにないことに気付くかもしれません。誰でも読めるようにパスワードを平文でスクリプトに入れないでください。代わりに、より安全にするためにオプション ファイルに入れます。

cron からバックアップを実行する特別なオペレーティング システム ユーザーを作成します。お使いのシステムには、MySQL サーバーを実行するための特別なユーザー "mysql" または "_mysql" が存在する場合がありますが、このユーザーは有効なホーム ディレクトリを持たないように構成されている可能性があります。ホーム ディレクトリを持つユーザーが必要です。「mybackup」としましょう。

そのユーザーのホーム ディレクトリの下.my.cnfに、次の内容のファイルを作成します。

[mysqldump]
user = alupto_backup
password = xyzzy

「alupto_backup」と「xyzzy」は、MySQL のユーザー名とそのパスワードです (環境に合わせて変更してください)。このファイルの所有者とモードを設定して、その所有者だけがファイルを読み取れるようにします。

chown mybackup .my.cnf
chmod 600 .my.cnf

このユーザーのホームの下に bin ディレクトリを作成し、そこにシェル スクリプトを配置します。

mkdir ~mybackup/bin
mv mymysqldump ~mybackup/bin

これで、シェル スクリプトを実行してテストできます。

sh ~mybackup/bin/mymysqldump

このユーザーの cron ファイルを作成します。

crontab -u mybackup

@daily ~mybackup/bin/mymysqldump

それだけです。

于 2010-07-27T07:08:31.843 に答える
3

スクリプトは非常に弱く見えます。システムで使用できる場合は、 mysqldumpの使用を検討する必要があります。

アップデート

基本的なコマンド ラインは次のようになります。

mysqldump -hYOURHOSTNAME -uYOURUSER -pYOURPASSWORD infocap > dump.sql

ローカル コンピューターで mysqldump をテストし、満足のいく結果が得られたら、シェル スクリプトを作成するか、それを cron タスクとして直接追加します。

于 2010-07-27T07:05:04.730 に答える
0

mysql_error() 関数を使用して、MySQL が不平を言っていることを確認します。

于 2010-07-27T06:56:16.870 に答える
0

mysql_query最初に非ストリームを返さないようにする必要があります。これを試して:

....

if (false !== ($result = mysql_query('SHOW TALBES')) {
    while($row = mysql_fetch_row($result))
    {
        $tables[] = $row[0];
    }
} else {
    // see Mchl's point about mysql_error
}
于 2010-07-27T06:58:35.390 に答える