最近工作中常常需要備份遠程服務器上的mysql數據庫到本機,一開始采用直接備份mysql的data目錄的辦法,但由于編碼不同的原因經常產生問題。后來朋友推薦我使用一個非常方便小巧的php程序——mydb。一共包含三個文件:
1. mydb.php //DB類
代碼如下:
? class?db{? var?$linkid;? var?$sqlid;? var?$record;? function?db($host="",$username="",$password="",$database="")? ????{? ????if(!$this->linkid)??@$this->linkid?=?mysql_connect($host,?$username,?$password)?or?die("連接服務器失敗.");? ????@mysql_select_db($database,$this->linkid)?or?die("無法打開數據庫");? ????return?$this->linkid;}? function?query($sql)? ????{if($this->sqlid=mysql_query($sql,$this->linkid))?return?$this->sqlid;? ????else?{? ????????$this->err_report($sql,mysql_error);? ????return?false;}? ????}? function?nr($sql_id="")? ????{if(!$sql_id)?$sql_id=$this->sqlid;? ????return?mysql_num_rows($sql_id);}? function?nf($sql_id="")? ????{if(!$sql_id)?$sql_id=$this->sqlid;? ????return?mysql_num_fields($sql_id);}? function?nextrecord($sql_id="")? ????{if(!$sql_id)?$sql_id=$this->sqlid;? ????if($this->record=mysql_fetch_array($sql_id))??return?$this->record;? ????else?return?false;? ????}? function?f($name)? ????{? ????if($this->record[$name])?return?$this->record[$name];? ????else?return?false;? ????}? function?close()?{mysql_close($this->linkid);}? function?lock($tblname,$op="WRITE")? ????{if(mysql_query("lock?tables?".$tblname."?".$op))?return?true;?else?return?false;}? function?unlock()? ????{if(mysql_query("unlock?tables"))?return?true;?else?return?false;}? function?ar()?{? ????return?@mysql_affected_rows($this->linkid);? ??}? function?i_id()?{? ????????return?mysql_insert_id();? ????}? function?err_report($sql,$err)? ????{? echo?"Mysql查詢錯誤<br>";? echo?"查詢語句:".$sql."<br>";? echo?"錯誤信息:".$err;? ????}? /****************************************類結束***************************/? }?>
2. backup.php //備份腳本
代碼如下:
? global?$mysqlhost,?$mysqluser,?$mysqlpwd,?$mysqldb;? $mysqlhost="localhost";?//host?name? $mysqluser="root";??????????????//login?name? $mysqlpwd="";??????????????//password? $mysqldb="";????????//name?of?database? include("mydb.php");? $d=new?db($mysqlhost,$mysqluser,$mysqlpwd,$mysqldb);? /*--------------界面--------------*/if(!$_POST['act']){/*----------------------*/? $msgs[]="服務器備份目錄為backup";? $msgs[]="對于較大的數據表,強烈建議使用分卷備份";? $msgs[]="只有選擇備份到服務器,才能使用分卷備份功能";? show_msg($msgs);? ?>?
? /*————-界面結束————-*/}/*———————————*/? /*—-*/else{/*————–主程序—————————————–*/? if($_POST[‘weizhi’]==”localpc”&&$_POST[‘fenjuan’]==’yes’)? ????{$msgs[]=”只有選擇備份到服務器,才能使用分卷備份功能”;? show_msg($msgs);?pageend();}? if($_POST[‘fenjuan’]==”yes”&&!$_POST[‘filesize’])? ????{$msgs[]=”您選擇了分卷備份功能,但未填寫分卷文件大小”;? show_msg($msgs);?pageend();}? if($_POST[‘weizhi’]==”server”&&!writeable(“./backup”))? ????{$msgs[]=”備份文件存放目錄’./backup’不可寫,請修改目錄屬性”;? show_msg($msgs);?pageend();}? /*———-備份全部表————-*/if($_POST[‘bfzl’]==”quanbubiao”){/*—-*/? /*—-不分卷*/if(!$_POST[‘fenjuan’]){/*——————————–*/? if(!$tables=$d->query(“show?table?status?from?$mysqldb”))? ????{$msgs[]=”讀數據庫結構錯誤”;?show_msg($msgs);?pageend();}? $sql=””;? while($d->nextrecord($tables))? ????{? ????$table=$d->f(“Name”);? ????$sql.=make_header($table);? ????$d->query(“select?*?from?$table”);? ????$num_fields=$d->nf();? ????while($d->nextrecord())? ????{$sql.=make_record($table,$num_fields);}? ????}? $filename=date(“Ymd”,time()).”_all.sql”;? if($_POST[‘weizhi’]==”localpc”)?down_file($sql,$filename);? elseif($_POST[‘weizhi’]==”server”)? ????{if(write_file($sql,$filename))? $msgs[]=”全部數據表數據備份完成,生成備份文件’./backup/$filename'”;? ????else?$msgs[]=”備份全部數據表失敗”;? ????show_msg($msgs);? ????pageend();? ????}? /*—————–不要卷結束*/}/*———————–*/? /*—————–分卷*/else{/*————————-*/? if(!$_POST[‘filesize’])? ????{$msgs[]=”請填寫備份文件分卷大小”;?show_msg($msgs);pageend();}? if(!$tables=$d->query(“show?table?status?from?$mysqldb”))? ????{$msgs[]=”讀數據庫結構錯誤”;?show_msg($msgs);?pageend();}? $sql=””;?$p=1;? $filename=date(“Ymd”,time()).”_all”;? while($d->nextrecord($tables))? {? ????$table=$d->f(“Name”);? ????$sql.=make_header($table);? ????$d->query(“select?*?from?$table”);? ????$num_fields=$d->nf();? ????while($d->nextrecord())? ????{$sql.=make_record($table,$num_fields);? ????if(strlen($sql)>=$_POST[‘filesize’]*1000){? ????????????$filename.=(“_v”.$p.”.sql”);? ????????????if(write_file($sql,$filename))? ????????????$msgs[]=”全部數據表-卷-“.$p.”-數據備份完成,生成備份文件’./backup/$filename'”;? ????????????else?$msgs[]=”備份表-“.$_POST[‘tablename’].”-失敗”;? ????????????$p++;? ????????????$filename=date(“Ymd”,time()).”_all”;? ????????????$sql=””;}? ????}? }? if($sql!=””){$filename.=(“_v”.$p.”.sql”);????????? if(write_file($sql,$filename))? $msgs[]=”全部數據表-卷-“.$p.”-數據備份完成,生成備份文件’./backup/$filename'”;}? show_msg($msgs);? /*———————分卷結束*/}/*————————————–*/? /*——–備份全部表結束*/}/*———————————————*/? /*——–備份單表——*/elseif($_POST[‘bfzl’]==”danbiao”){/*————*/? if(!$_POST[‘tablename’])? ????{$msgs[]=”請選擇要備份的數據表”;?show_msg($msgs);?pageend();}? /*——–不分卷*/if(!$_POST[‘fenjuan’]){/*——————————-*/? $sql=make_header($_POST[‘tablename’]);? $d->query(“select?*?from?“.$_POST[‘tablename’]);? $num_fields=$d->nf();? while($d->nextrecord())? ????{$sql.=make_record($_POST[‘tablename’],$num_fields);}? $filename=date(“Ymd”,time()).”_”.$_POST[‘tablename’].”.sql”;? if($_POST[‘weizhi’]==”localpc”)?down_file($sql,$filename);? elseif($_POST[‘weizhi’]==”server”)? ????{if(write_file($sql,$filename))? $msgs[]=”表-“.$_POST[‘tablename’].”-數據備份完成,生成備份文件’./backup/$filename'”;? ????else?$msgs[]=”備份表-“.$_POST[‘tablename’].”-失敗”;? ????show_msg($msgs);? ????pageend();? ????}? /*—————-不要卷結束*/}/*————————————*/? /*—————-分卷*/else{/*————————————–*/? if(!$_POST[‘filesize’])? ????{$msgs[]=”請填寫備份文件分卷大小”;?show_msg($msgs);pageend();}? $sql=make_header($_POST[‘tablename’]);?$p=1;?? ????$filename=date(“Ymd”,time()).”_”.$_POST[‘tablename’];? ????$d->query(“select?*?from?“.$_POST[‘tablename’]);? ????$num_fields=$d->nf();? ????while?($d->nextrecord())?? ????{????? ????????$sql.=make_record($_POST[‘tablename’],$num_fields);? ???????if(strlen($sql)>=$_POST[‘filesize’]*1000){? ????????????$filename.=(“_v”.$p.”.sql”);? ????????????if(write_file($sql,$filename))? ????????????$msgs[]=”表-“.$_POST[‘tablename’].”-卷-“.$p.”-數據備份完成,生成備份文件’./backup/$filename'”;? ????????????else?$msgs[]=”備份表-“.$_POST[‘tablename’].”-失敗”;? ????????????$p++;? ????????????$filename=date(“Ymd”,time()).”_”.$_POST[‘tablename’];? ????????????$sql=””;}? ????}? if($sql!=””){$filename.=(“_v”.$p.”.sql”);????????? if(write_file($sql,$filename))? $msgs[]=”表-“.$_POST[‘tablename’].”-卷-“.$p.”-數據備份完成,生成備份文件’./backup/$filename'”;}? show_msg($msgs);? /*———-分卷結束*/}/*————————————————–*/? /*———-備份單表結束*/}/*———————————————-*/? /*—*/}/*————-主程序結束——————————————*/? function?write_file($sql,$filename)? {? $re=true;? if(!@$fp=fopen(“./backup/”.$filename,”w+”))?{$re=false;?echo?“failed?to?open?target?file”;}? if(!@fwrite($fp,$sql))?{$re=false;?echo?“failed?to?write?file”;}? if(!@fclose($fp))?{$re=false;?echo?“failed?to?close?target?file”;}? return?$re;? }? function?down_file($sql,$filename)? {? ????ob_end_clean();? ????header(“Content-Encoding:?none”);? ????header(“Content-Type:?“.(strpos($_SERVER[‘HTTP_USER_AGENT’],?‘MSIE’)???‘application/octetstream’?:?‘application/octet-stream’));? ????header(“Content-Disposition:?“.(strpos($_SERVER[‘HTTP_USER_AGENT’],?‘MSIE’)???‘inline;?‘?:?‘attachment;?‘).”filename=”.$filename);? ????header(“Content-Length:?“.strlen($sql));? ????header(“Pragma:?no-cache”);? ????header(“Expires:?0”);? ????echo?$sql;? ????$e=ob_get_contents();? ????ob_end_clean();? }? function?writeable($dir)? {? ????if(!is_dir($dir))?{? ????@mkdir($dir,?0777);? ????}? ????if(is_dir($dir))?? ????{? ????if($fp?=?@fopen(“$dir/test.test”,?‘w’))? ????????{? @fclose($fp);? ????@unlink(“$dir/test.test”);? ????$writeable?=?1;? }?? ????else?{? $writeable?=?0;? ????}? }? ????return?$writeable;? }? function?make_header($table)? {global?$d;? $sql=”DROP?TABLE?IF?EXISTS?“.$table.”n”;? $d->query(“show?create?table?“.$table);? $d->nextrecord();? $tmp=preg_replace(“/n/”,””,$d->f(“Create?Table”));? $sql.=$tmp.”n”;? return?$sql;? }? function?make_record($table,$num_fields)? {global?$d;? $comma=””;? $sql?.=?“INSERT?INTO?“.$table.”?VALUES(“;? for($i?=?0;?$i?record[$i]).”‘”);?$comma?=?“,”;}? $sql?.=?“)n”;? return?$sql;? }? function?show_msg($msgs)? {? $title=”提示:”;? echo?“
“.$title.” |
“;? ????}? echo?“ |
“;? }? function?pageend()? {? exit();? }? ?>
3. restore.php //還原腳本
代碼如下:
? session_start();? global?$mysqlhost,?$mysqluser,?$mysqlpwd,?$mysqldb;? $mysqlhost="localhost";?//host?name? $mysqluser="root";??????????????//login?name? $mysqlpwd="";??????????????//password? $mysqldb="";????????//name?of?database? include("mydb.php");? $d=new?db($mysqlhost,$mysqluser,$mysqlpwd,$mysqldb);? /******界面*/if(!$_POST['act']&&!$_SESSION['data_file']){/**********************/? $msgs[]="本功能在恢復備份數據的同時,將全部覆蓋原有數據,請確定是否需要恢復,以免造成數據損失";? $msgs[]="數據恢復功能只能恢復由dShop導出的數據文件,其他軟件導出格式可能無法識別";? $msgs[]="從本地恢復數據需要服務器支持文件上傳并保證數據尺寸小于允許上傳的上限,否則只能使用從服務器恢復";? $msgs[]="如果您使用了分卷備份,只需手工導入文件卷1,其他數據文件會由系統自動導入";? show_msg($msgs);? ?>?
? /**************************界面結束*/}/*************************************/? /****************************主程序*/if($_POST[‘act’]==”恢復”){/**************/? /***************服務器恢復*/if($_POST[‘restorefrom’]==”server”){/**************/? if(!$_POST[‘serverfile’])? ????{$msgs[]=”您選擇從服務器文件恢復備份,但沒有指定備份文件”;? ?????show_msg($msgs);?pageend();????}? if(!eregi(“_v[0-9]+”,$_POST[‘serverfile’]))? ????{$filename=”./backup/”.$_POST[‘serverfile’];? ????if(import($filename))?$msgs[]=”備份文件”.$_POST[‘serverfile’].”成功導入數據庫”;? ????else?$msgs[]=”備份文件”.$_POST[‘serverfile’].”導入失敗”;? ????show_msg($msgs);?pageend();????????? ????}? else? ????{? ????$filename=”./backup/”.$_POST[‘serverfile’];? ????if(import($filename))?$msgs[]=”備份文件”.$_POST[‘serverfile’].”成功導入數據庫”;? ????else?{$msgs[]=”備份文件”.$_POST[‘serverfile’].”導入失敗”;show_msg($msgs);pageend();}? ????$voltmp=explode(“_v”,$_POST[‘serverfile’]);? ????$volname=$voltmp[0];? ????$volnum=explode(“.sq”,$voltmp[1]);? ????$volnum=intval($volnum[0])+1;? ????$tmpfile=$volname.”_v”.$volnum.”.sql”;? ????if(file_exists(“./backup/”.$tmpfile))? ????????{? ????????$msgs[]=”程序將在3秒鐘后自動開始導入此分卷備份的下一部份:文件”.$tmpfile.”,請勿手動中止程序的運行,以免數據庫結構受損”;? ????????$_SESSION[‘data_file’]=$tmpfile;? ????????show_msg($msgs);? ????????sleep(3);? ????????echo?“<script>"; echo "location='restore.php';"; echo "</script>”;?? ????????}? ????else? ????????{? ????????$msgs[]=”此分卷備份全部導入成功”;? ????????show_msg($msgs);? ????????}? ????}? /**************服務器恢復結束*/}/********************************************/? /*****************本地恢復*/if($_POST[‘restorefrom’]==”localpc”){/**************/? ????switch?($_FILES[‘myfile’][‘error’])? ????{? ????case?1:? ????case?2:? ????$msgs[]=”您上傳的文件大于服務器限定值,上傳未成功”;? ????break;? ????case?3:? ????$msgs[]=”未能從本地完整上傳備份文件”;? ????break;? ????case?4:? ????$msgs[]=”從本地上傳備份文件失敗”;? ????break;? ????case?0:? ????break;? ????}? ????if($msgs){show_msg($msgs);pageend();}? $fname=date(“Ymd”,time()).”_”.sjs(5).”.sql”;? if?(is_uploaded_file($_FILES[‘myfile’][‘tmp_name’]))?{? ????copy($_FILES[‘myfile’][‘tmp_name’],?“./backup/”.$fname);}? if?(file_exists(“./backup/”.$fname))?? ????{? ????$msgs[]=”本地備份文件上傳成功”;? ????if(import(“./backup/”.$fname))?{$msgs[]=”本地備份文件成功導入數據庫”;?unlink(“./backup/”.$fname);}? ????else?$msgs[]=”本地備份文件導入數據庫失敗”;? ????}? else?($msgs[]=”從本地上傳備份文件失敗”);? show_msg($msgs);? /****本地恢復結束*****/}/****************************************************/? /****************************主程序結束*/}/**********************************/? /*************************剩余分卷備份恢復**********************************/? if(!$_POST[‘act’]&&$_SESSION[‘data_file’])? {? ????$filename=”./backup/”.$_SESSION[‘data_file’];? ????if(import($filename))?$msgs[]=”備份文件”.$_SESSION[‘data_file’].”成功導入數據庫”;? ????else?{$msgs[]=”備份文件”.$_SESSION[‘data_file’].”導入失敗”;show_msg($msgs);pageend();}? ????$voltmp=explode(“_v”,$_SESSION[‘data_file’]);? ????$volname=$voltmp[0];? ????$volnum=explode(“.sq”,$voltmp[1]);? ????$volnum=intval($volnum[0])+1;? ????$tmpfile=$volname.”_v”.$volnum.”.sql”;? ????if(file_exists(“./backup/”.$tmpfile))? ????????{? ????????$msgs[]=”程序將在3秒鐘后自動開始導入此分卷備份的下一部份:文件”.$tmpfile.”,請勿手動中止程序的運行,以免數據庫結構受損”;? ????????$_SESSION[‘data_file’]=$tmpfile;? ????????show_msg($msgs);? ????????sleep(3);? ????????echo?“<script>"; echo "location='restore.php';"; echo "</script>”;?? ????????}? ????else? ????????{? ????????$msgs[]=”此分卷備份全部導入成功”;? ????????unset($_SESSION[‘data_file’]);? ????????show_msg($msgs);? ????????}? }? /**********************剩余分卷備份恢復結束*******************************/? function?import($fname)? {global?$d;? $sqls=file($fname);? foreach($sqls?as?$sql)? ????{? ????str_replace(“r”,””,$sql);? ????str_replace(“n”,””,$sql);? ????if(!$d->query(trim($sql)))?return?false;? ????}? return?true;? }? function?show_msg($msgs)? {? $title=”提示:”;? echo?“
“.$title.” |
“;? ????}? echo?“ |
“;? }? function?pageend()? {? exit();? }? ?>
文件結構非常清晰,只要在文件2和3里面設置好數據庫服務器的地址、用戶名、密碼就可以備份還原數據了。需要注意的是:
·使用時候要在同級目錄下建一個Backup目錄,權限需要可寫,用于存放導出的腳本。
·當備份的數據庫比較大的時候,服務器腳本超時時間要調大一些。
·支持分卷備份,還原時候只要選擇分卷備份的第一個腳本就會自動還原所有的腳本。
·分卷文件大小不要太大,最好不超過2MB。
·安全起見,腳本不用時候記得從服務器上刪除。
【相關推薦】
1.?Mysql免費視頻教程
2.?Mysql免費視頻教程
3.?Mysql免費視頻教程
4.?Mysql免費視頻教程
5.?Mysql免費視頻教程