Почему мой сценарий резервного копирования базы данных не работает в php?

Я использую сценарий Резервного копирования базы данных David Walsh (http://davidwalsh.name/backup-mysql-database-php) для резервного копирования моей базы данных MYSQL как .sql файла к моему серверу.

Я создал пользователя, названного резервным копированием, и дал всему этому полномочия (только для проверки). Затем я поместил код в php файл и устанавливаю задание крона для выполнения 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','*');

Когда прогоны задания крона, резервное копирование не работает, и я получаю электронное письмо с ошибкой, которая появляется:


Предупреждение: mysql_fetch_row (): переданный аргумент не является допустимым ресурсом результата MySQL в/home5/ideapale/public_html/amatorders_basic/admin/backup.php на строке 18

На строке 18 этот код:

while($row = mysql_fetch_row($result))

Когда я работаю, SQL (ПОКАЖИТЕ ТАБЛИЦЫ) в phpMyAdmin, он хорошо работает и показывает мне список всех таблиц. Но по некоторым причинам, я получаю ошибку, когда php файл пытается выполнить SQL.

Почему мой сценарий резервного копирования базы данных не работает?

7
задан zeckdude 27 July 2010 в 06:52
поделиться

4 ответа

Это не сработает для резервного копирования вашей базы данных в виде сценария SQL, если ваша база данных не является просто игрушечной базой данных, эквивалентом сценария "hello world".

Этот сценарий ужасен. Вы не должны использовать его для резервного копирования базы данных. Этот сценарий был опубликован ранее: Сценарий дампа базы данных PHP - есть ли проблемы?

  • Нет проверки ошибок после mysql_connect () или mysql_queries (). Вы, вероятно, просто ввели неправильный пароль или что-то в этом роде, но никогда не узнаете, потому что сценарий не проверяет, было ли соединение успешным.

  • Он не создаст правильный оператор INSERT, если ваша база данных содержит какие-либо NULL.

  • Наборы символов не обрабатываются.

  • addlashes () не подходит для экранирования данных.

  • Имена таблиц не разделены.

  • Не выполняет резервное копирование представлений, процедур, функций или триггеров.

  • mysql_query () буферизует результаты, поэтому, если у вас есть таблица с тысячами строк или больше, вы превысите лимит памяти PHP. Фактически, сценарий объединяет серию операторов INSERT в одну переменную PHP. Итак, до его завершения ваша вся база данных будет представлена ​​в памяти.

Никто никогда не должен использовать этот сценарий. Это полная чушь, и я не говорю это легкомысленно.

Просто используйте shellexec () для запуска mysqldump.

@ Альваро Г. Викарио подметил, что вам не нужно даже использовать 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

Вот и все.

14
ответ дан 6 December 2019 в 11:45
поделиться

ИМХО скрипт выглядит очень слабым. Вам следует рассмотреть возможность использования mysqldump , если он доступен в вашей системе.

Обновление

Основная командная строка будет выглядеть так:

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

Вы можете протестировать mysqldump на своем локальном компьютере и, когда будете довольны результатами, либо создайте сценарий оболочки, либо добавьте его непосредственно как задачу cron.

3
ответ дан 6 December 2019 в 11:45
поделиться

Используйте функцию mysql_error(), чтобы увидеть, на что жалуется MySQL.

0
ответ дан 6 December 2019 в 11:45
поделиться

Вы должны убедиться, что 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
}
0
ответ дан 6 December 2019 в 11:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: