我使用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():提供的参数 不是有效的MySQL结果资源 在 /home5/ideapale/public_html/amatorders_basic/admin/backup.php 的 在线 18
第18行是这段代码:
while($row = mysql_fetch_row($result))
当我在phpMyAdmin中运行SQL(SHOW TABLES)时,它工作正常并向我显示所有表的列表。但由于某种原因,我在php文件尝试运行SQL时收到错误。
为什么我的数据库备份脚本不起作用?
答案 0 :(得分:14)
这不能用于将数据库备份为SQL脚本,除非您的数据库只是一个玩具数据库,相当于“hello world”脚本。
那个剧本令人震惊。您不应该使用它来备份数据库。该脚本之前已发布:PHP Database Dump Script - are there any issues?
在mysql_connect()或mysql_queries()之后没有错误检查。你可能只是给了一个错误的密码或其他东西,但你永远不会知道,因为脚本没有验证连接是否成功。
如果您的数据库包含任何NULL,它将不会产生正确的INSERT语句。
不处理字符集。
addslashes()not suitable用于转义数据。
表名称未分隔。
不备份视图,过程,函数或触发器。
mysql_query()缓冲结果,因此如果您有一个包含数千行或更多行的表,那么您将超出PHP内存限制。实际上,该脚本将一系列INSERT语句连接成一个PHP变量。因此,在完成之前,您将在内存中显示整个数据库。
没有人应该使用该脚本。这完全是垃圾,我不会轻易说。
只需使用shellexec()运行mysqldump。
@ÁlvaroG。Vicario有一个很好的观点,你甚至不需要使用PHP来完成这项任务。我假设您需要从PHP脚本进行备份。以下是我将如何从cron脚本创建备份:
创建一个shell脚本,可以随意调用它,例如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目录,并将我们的shell脚本放入其中。
mkdir ~mybackup/bin
mv mymysqldump ~mybackup/bin
现在您可以运行shell脚本来测试它:
sh ~mybackup/bin/mymysqldump
现在为该用户创建一个cron文件:
crontab -u mybackup
@daily ~mybackup/bin/mymysqldump
应该是它。
答案 1 :(得分:3)
脚本看起来很弱IMHO。您应该考虑使用系统中可用的mysqldump。
基本命令行是:
mysqldump -hYOURHOSTNAME -uYOURUSER -pYOURPASSWORD infocap > dump.sql
您可以在本地计算机上测试mysqldump,一旦您对结果感到满意,可以创建一个shell脚本或直接将其添加为cron任务。
答案 2 :(得分:0)
使用mysql_error()函数查看MySQL抱怨的内容。
答案 3 :(得分: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
}