我正在使用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时,我收到一个错误。
为什么我的数据库备份脚本不起作用?
除非您的数据库只是一个玩具数据库(相当于“ hello world”脚本),否则这将无法以SQL脚本备份数据库。
该脚本令人震惊。您不应该使用它来备份数据库。该脚本之前已发布:PHP数据库转储脚本- 有问题吗?
在mysql_connect()或mysql_queries()之后没有错误检查。您可能只是输入了错误的密码或其他密码,但您永远不会知道,因为脚本无法验证连接是否成功。
如果您的数据库包含任何NULL,它将不会产生正确的INSERT语句。
不处理字符集。
addlashes()不适合转义数据。
表名没有定界。
不备份视图,过程,功能或触发器。
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 Server,但是该用户可能配置为没有有效的主目录。您需要一个具有主目录的用户。我们称之为“ mybackup”。
在该用户的主目录下,创建一个.my.cnf包含以下内容的文件:
.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
应该是这样。