0

我有能够备份和恢复数据库的功能。当数据库量较小时,此功能可以完美运行。但是,当数据规模较大时,无法完成备份过程并给出错误消息。这是错误消息的示例:

Fatal error: Out of memory (allocated 192151552) (tried to allocate 63963113 bytes) in C:\wamp\www\samfahEnterprise\processbackup.php on line 69

以下是我用来执行备份过程的脚本:

<?php
session_start();
// Include settings
include("config.php");
date_default_timezone_set("Asia/Singapore");

set_time_limit(0);
ini_set('memory_limit', '20000M');

 // Set the suffix of the backup filename
if ($table == '*') 
{
    $extname = 'all';
}else
{
    $extname = str_replace(",", "_", $table);
    $extname = str_replace(" ", "_", $extname);
}

// Generate the filename for the backup file
$filess = 'backup/dbbackup_' . date("d.m.Y_H_i_s") . '_' . $extname;

// Call the backup function for all tables in a DB
backup_tables($DBhost,$DBuser,$DBpass,$DBName,$table,$extname,$filess);

// Backup the table and save it to a sql file
function backup_tables($host,$user,$pass,$name,$tables,$bckextname,$filess)
{ 
    $link = mysql_connect($host,$user,$pass);
    mysql_select_db($name,$link);
    $return = "";   

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

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

        // First part of the output - remove the table
        $return .= 'DROP TABLE ' . $table . ';<|||||||>';

        // Second part of the output - create table
        $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
        $return .= "\n\n" . $row2[1] . ";<|||||||>\n\n";

        // Third part of the output - insert values into new table
        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 the sql file
    $handle = fopen($filess.'.sql','w+');
    fwrite($handle,$return);
    fclose($handle);



// Close MySQL Connection
mysql_close();
} 

$_SESSION['save'] = "<span style='color:#00FF00'>The backup has been created successfully.</span>";
echo "<script>window.location = 'utility.php';</script>";
?>
4

2 回答 2

1

您不应该为此使用 PHP。即使你实际上可以解决这个问题——这也不是一个好主意,因为你必须一个一个地处理你的表和其中的记录。因此,您会将内存大小更改为较长的执行时间。那将是:

  • 从表中读取行
  • 将其写入转储文件
  • 此行的可用内存

(目前,您正在尝试收集所有表数据,然后将其转储到文件中,当 DB 太大时无法在内存中分配)

在 MySQL 中有mysqldump - 创建 SQL 转储的特殊工具。除非有理由阻止您使用它 - 我建议您这样做(并且 - 如果您想使用 PHP,有exec()类似的功能)

于 2013-10-10T07:01:06.930 回答
0

尝试像这样调试它:

echo ini_get("memory_limit")."\n";
ini_set("memory_limit","1024M");
echo ini_get("memory_limit")."\n";
exit();

可能您必须设置正确的值。

于 2013-10-10T07:02:12.397 回答