我想要用PHP备份我的数据库。
我测试了链接的脚本,但是它永远不会结束,我试图在查询之前添加repair $table,但是它没有帮助。
因此,我想如果我跳过两个表(您可以在代码中看到),那么它工作得很好:
<?
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','*');
?>是否有任何方法可以找到给我带来问题的行,以便我可以编辑/删除它们?
-PS-
另外,如果我不跳过它们,我就不会有任何错误(脚本永远不会结束,这就是为什么我添加了一些丑陋的日志.知道为什么吗?)
-编辑-
另外,如果我试图通过例如sqlBuddy导出数据库,我也会得到错误:

发布于 2013-08-09 00:54:56
正如许多人所指出的那样,这个脚本(以及简单的“通过PHP转储MySQL”的方式)远非最优,但仍然比根本没有备份更好。
因为您只能使用PHP来访问数据库,所以您应该使用它来找出出了什么问题。
下面是对脚本的修改,它将只将一个表转储到一个文件中。它是一个调试脚本,而不是用于生产的导出工具(但是,您想用它做什么),这就是它在保存表的每一行后输出调试的原因。
正如Amit所建议的那样,数据在每次迭代时都会附加到目标文件中,但我认为PHP内存不是您的问题,如果内存不足,您应该得到一个PHP错误,或者服务器应该抛出至少一个HTTP 500,而不是永远运行脚本。
function progress_export( $file, $table, $idField, $offset = 0, $limit = 0 )
{
debug("Starting export of table $table to file $file");
// empty the output file
file_put_contents( $file, '' );
$return = '';
debug("Dumping schema");
$return.= 'DROP TABLE '.$table.';';
$row2 = mysql_fetch_row(mysql_query("SHOW CREATE TABLE $table"));
$return.= "\n\n".$row2[1].";\n\n";
file_put_contents( $file, $return, FILE_APPEND );
debug("Schema saved to $file");
$return = '';
debug( "Querying database for records" );
$query = "SELECT * FROM $table ORDER BY $idField";
// make offset/limit optional if we need them for further debug
if ( $offset && $limit )
{
$query .= " LIMIT $offset, $limit";
}
$result = mysql_query($query);
$i = 0;
while( $data = mysql_fetch_assoc( $result ) )
{
// Let's be verbose but at least, we will see when something goes wrong
debug( "Exporting row #".$data[$idField].", rows offset is $i...");
$return = "INSERT INTO $table (`". implode('`, `', array_keys( $data ) )."`) VALUES (";
$coma = '';
foreach( $data as $column )
{
$return .= $coma. "'". mysql_real_escape_string( $column )."'";
$coma = ', ';
}
$return .=");\n";
file_put_contents( $file, $return, FILE_APPEND );
debug( "Row #".$data[$idField]." saved");
$i++;
// Be sure to send data to browser
@ob_flush();
}
debug( "Completed export of $table to file $file" );
}
function debug( $message )
{
echo '['.date( "H:i:s" )."] $message <br/>";
}
// Update those settings :
$host = 'localhost';
$user = 'user';
$pass = 'pwd';
$base = 'database';
// Primary key to be sure how record are sorted
$idField = "id";
$table = "etiquetas";
// add some writable directory
$file = "$table.sql";
$link = mysql_connect($host,$user,$pass);
mysql_select_db($base,$link);
// Launching the script
progress_export( $file, $table, $idField );编辑脚本末尾的设置,并在两个表中的一个上运行它。
在脚本仍在处理时,您应该看到输出,并获得一些有关正在处理的行的引用,如下所示:
23:30:13启动表ezcontentobject的导出以文件ezcontentobject.sql 23:30:13倾销模式 23:30:13模式保存到ezcontentobject.sql 23:30:13查询记录数据库 23:30:13导出行#4,行偏移量为0. 23:30:13第4排得救 23:30:13出口行#10,行偏移为1. 23:30:13 #10行得救 23:30:13出口行#11,行偏移为2. 23:30:13 #11行得救 23:30:13出口行#12,行偏移为3. 23:30:13 #12行得救 23:30:13出口行#13,行偏移为4. 23:30:13行得救 等。
如果剧本完成了..。
好的,您将备份您的表(请注意,我没有测试生成的SQL)!
我想它不会完成的:
如果脚本没有到达第一个“导出行.”调试语句
然后问题是在查询时。
然后,您应该尝试使用偏移量和限制参数来限制查询,然后继续二分法,找出它挂起的位置。
生成仅限于1000个第一结果的查询的示例。
// Launching the script
progress_export( $file, $table, $idField, 0, 1000 );如果脚本显示挂起前导出的一些行
在对显示的最后一行id进行定罪之前,应尝试:
例如,50作为偏移,一些大的数字作为限制:
// Launching the script
progress_export( $file, $table, $idField, 50, 600000 );这是为了检查它自己是否导致了问题,或者它是否是一个临界的行数/数据量.
如果不能处理分配的资源,那么解决方案将是将导出分割成块。您可以使用一个接近此脚本的脚本来完成这一任务,输出一些HTML/javascript,将偏移量和限制作为参数重定向到它,而导出尚未完成(如果最终需要的话,我将编辑答案)。
一些线索:
我没有使用VPS的经验,但是您对CPU的使用难道没有一些限制吗?
如果您一次使用过多的资源,您的进程是否在某种程度上被排队?
那么那些没有问题就被抛出的桌子呢?是否有像这两张桌子那么大的桌子造成了这个问题?
发布于 2013-08-01 17:38:24
我不知道为什么这个“街区”..。但是这个脚本只适用于非常基本的数据库。
例如,它如何处理外键约束?这只是一个建议,可能是故意放弃的,但为什么不使用mysql_dump呢?
从你的壳里:
mysql_dump -h host -u user -p my_database > db-backup.sql编辑:,如Riggs所建议的,phpMyAdmin有备份工具,通常可以在主机上使用。
事实上,即使在您的主机上不可用,您仍然可以将其安装在您的http服务器上,并将其配置为访问远程DB服务器:
phpmyadmin
发布于 2013-08-09 12:16:54
如果您有相同的备份问题,无论是使用一些自定义脚本,还是使用诸如"sqlbuddy“之类的工具--那么得出的结论是,问题出在表和/或数据库中。
我将尝试复制有问题的表并备份这些表,而不是原始表,以查看附加内容:
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行后读取以下批处理。
https://stackoverflow.com/questions/18000676
复制相似问题