我正在使用 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 作业运行时,备份不起作用,我收到一封包含出现的错误的电子邮件:
Warning: mysql_fetch_row(): supplied argument is not a valid MySQL result resource in /home5/ideapale/public_html/amatorders_basic/admin/backup.php on line 18
第 18 行是这段代码:
while($row = mysql_fetch_row($result))
当我在 phpMyAdmin 中运行 SQL(SHOW TABLES) 时,它工作正常并向我显示所有表的列表。但出于某种原因,当 php 文件尝试运行 SQL 时,我收到错误消息。
为什么我的数据库备份脚本不起作用?
最佳答案
这将无法将您的数据库备份为 SQL 脚本,除非您的数据库只是一个玩具数据库,相当于“hello world”脚本。
那个脚本太可怕了。您不应该使用它来备份数据库。该脚本之前已发布:PHP Database Dump Script - are there any issues?
在 mysql_connect() 或 mysql_queries() 之后没有错误检查。您可能只是输入了错误的密码或其他内容,但您永远不会知道,因为脚本不会验证连接是否成功。
如果您的数据库包含任何 NULL,它不会生成正确的 INSERT 语句。
不处理字符集。
addslashes() 是 not suitable用于转义数据。
表名没有分隔。
不备份 View 、过程、函数或触发器。
mysql_query() 缓冲结果,因此如果您有一个包含数千行或更多行的表,您将超出 PHP 内存限制。事实上,该脚本将一系列 INSERT 语句连接成一个 PHP 变量。因此在它完成之前,您将在内存中表示您的整个数据库。
任何人都不应该使用该脚本。这完全是垃圾,我不会随便这么说。
只需使用 shellexec() 来运行 mysqldump。
@Álvaro G. 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
应该是这样吧。
关于php - 为什么我的数据库备份脚本不能在 php 中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3341285/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R