先說下關於數據庫備份與恢復的原理:
1、查找所有表->2、查找所有字段->3、查找所有數據->4、生成SQL
備份注意點:
2=>需要列出所有字段名,字段類型等相關信息
3=>讀取數據出來注意特殊符號的轉換addslashes()
4=>把數據格式化生成對應的SQL
mysql_list_tables() 表查詢函數,類似mysql_query() 函數 mysql_fetch_field() 字段信息函數,返回句柄 恢復注意點: 1、 注意數據庫的大小,過大或者過多的表分段處理
<?php $mysql_dbname = "php100"; mysql_connect("localhost", "root", ""); mysql_select_db($mysql_dbname); $sql_list = mysql_list_tables($mysql_dbname); while ($row_data = mysql_fetch_row($sql_list)) { echo $row_data[0] . "<br>"; get_table_fd($row_data[0], "sql"); // $fp=fopen("sql/$tablename.sql","w+"); // fwrite($fp,$field); // fclose($fp); } function get_table_fd($tablename) { $field = "CREATE TABLE `$tablename`(\n"; $result = mysql_query("select * from $tablename"); while ($meta = mysql_fetch_field($result)) { if ($meta->not_null) $not_null = "not_null"; $field .= "`$meta->name` $meta->type($meta->max_length) $not_null; \n"; } $field .= ")\n"; return $field; } ?>
在網上找到個不錯的類庫,可直接拿來用,記錄一下
1、db.php 數據庫類
2、backup.php 備份
3、restore.php 恢復
下載附件
db.php
1 <? 2 class db{ 3 4 var $linkid; 5 var $sqlid; 6 var $record; 7 8 function db($host="",$username="",$password="",$database="") 9 { 10 if(!$this->linkid) @$this->linkid = mysql_connect($host, $username, $password) or die("連接服務器失敗."); 11 @mysql_select_db($database,$this->linkid) or die("無法打開數據庫"); 12 mysql_query('set names gbk'); 13 return $this->linkid;} 14 15 function query($sql) 16 {if($this->sqlid=mysql_query($sql,$this->linkid)) return $this->sqlid; 17 else { 18 $this->err_report($sql,mysql_error); 19 return false;} 20 } 21 22 function nr($sql_id="") 23 {if(!$sql_id) $sql_id=$this->sqlid; 24 return mysql_num_rows($sql_id);} 25 26 function nf($sql_id="") 27 {if(!$sql_id) $sql_id=$this->sqlid; 28 return mysql_num_fields($sql_id);} 29 30 function nextrecord($sql_id="") 31 {if(!$sql_id) $sql_id=$this->sqlid; 32 if($this->record=mysql_fetch_array($sql_id)) return $this->record; 33 else return false; 34 } 35 36 function f($name) 37 { 38 if($this->record[$name]) return $this->record[$name]; 39 else return false; 40 } 41 42 function close() {mysql_close($this->linkid);} 43 44 function lock($tblname,$op="WRITE") 45 {if(mysql_query("lock tables ".$tblname." ".$op)) return true; else return false;} 46 47 function unlock() 48 {if(mysql_query("unlock tables")) return true; else return false;} 49 50 function ar() { 51 return @mysql_affected_rows($this->linkid); 52 } 53 54 function i_id() { 55 return mysql_insert_id(); 56 } 57 58 function err_report($sql,$err) 59 { 60 echo "Mysql查詢錯誤<br>"; 61 echo "查詢語句:".$sql."<br>"; 62 echo "錯誤信息:".$err; 63 } 64 }?>
backup.php
1 <? 2 global $mysqlhost, $mysqluser, $mysqlpwd, $mysqldb; 3 $mysqlhost=""; //host name 4 $mysqluser=""; //login name 5 $mysqlpwd=""; //password 6 $mysqldb=""; //name of database 7 8 include("mydb.php"); 9 $d=new db($mysqlhost,$mysqluser,$mysqlpwd,$mysqldb); 10 /*--------------界面--------------*/if(!$_POST['act']){/*----------------------*/ 11 $msgs[]="服務器備份目錄為backup"; 12 $msgs[]="對於較大的數據表,強烈建議使用分卷備份"; 13 $msgs[]="只有選擇備份到服務器,才能使用分卷備份功能"; 14 show_msg($msgs); 15 ?> 16 <form name="form1" method="post" action="backup.php"> 17 <table width="99%" border="1" cellpadding='0' cellspacing='1'> 18 <tr align="center" class='header'><td colspan="2">數據備份</td></tr> 19 <tr><td colspan="2">備份方式</td></tr> 20 <tr><td><input type="radio" name="bfzl" value="quanbubiao"> 備份全部數據</td><td>備份全部數據表中的數據到一個備份文件</td></tr> 21 <tr><td><input type="radio" name="bfzl" value="danbiao">備份單張表數據 22 <select name="tablename"><option value="">請選擇</option> 23 <? 24 $d->query("show table status from $mysqldb"); 25 while($d->nextrecord()){ 26 echo "<option value='".$d->f('Name')."'>".$d->f('Name')."</option>";} 27 ?> 28 </select></td><td>備份選中數據表中的數據到單獨的備份文件</td></tr> 29 <tr><td colspan="2">使用分卷備份</td></tr> 30 <tr><td colspan="2"><input type="checkbox" name="fenjuan" value="yes"> 31 分卷備份 <input name="filesize" type="text" size="10">K</td></tr> 32 <tr><td colspan="2">選擇目標位置</td></tr> 33 <tr><td colspan="2"><input type="radio" name="weizhi" value="server" checked>備份到服務器</td></tr><tr class="cells"><td colspan='2'> <input type="radio" name="weizhi" value="localpc"> 34 備份到本地</td></tr> 35 <tr><td colspan="2" align='center'><input type="submit" name="act" value="備份"></td></tr> 36 </table></form> 37 <?/*-------------界面結束-------------*/}/*---------------------------------*/ 38 /*----*/else{/*--------------主程序-----------------------------------------*/ 39 if($_POST['weizhi']=="localpc"&&$_POST['fenjuan']=='yes') 40 {$msgs[]="只有選擇備份到服務器,才能使用分卷備份功能"; 41 show_msg($msgs); pageend();} 42 if($_POST['fenjuan']=="yes"&&!$_POST['filesize']) 43 {$msgs[]="您選擇了分卷備份功能,但未填寫分卷文件大小"; 44 show_msg($msgs); pageend();} 45 if($_POST['weizhi']=="server"&&!writeable("./backup")) 46 {$msgs[]="備份文件存放目錄'./backup'不可寫,請修改目錄屬性"; 47 show_msg($msgs); pageend();} 48 49 /*----------備份全部表-------------*/if($_POST['bfzl']=="quanbubiao"){/*----*/ 50 /*----不分卷*/if(!$_POST['fenjuan']){/*--------------------------------*/ 51 if(!$tables=$d->query("show table status from $mysqldb")) 52 {$msgs[]="讀數據庫結構錯誤"; show_msg($msgs); pageend();} 53 $sql=""; 54 while($d->nextrecord($tables)) 55 { 56 $table=$d->f("Name"); 57 $sql.=make_header($table); 58 $d->query("select * from $table"); 59 $num_fields=$d->nf(); 60 while($d->nextrecord()) 61 {$sql.=make_record($table,$num_fields);} 62 } 63 $filename=date("Ymd",time())."_all.sql"; 64 if($_POST['weizhi']=="localpc") down_file($sql,$filename); 65 elseif($_POST['weizhi']=="server") 66 {if(write_file($sql,$filename)) 67 $msgs[]="全部數據表數據備份完成,生成備份文件'./backup/$filename'"; 68 else $msgs[]="備份全部數據表失敗"; 69 show_msg($msgs); 70 pageend(); 71 } 72 /*-----------------不要卷結束*/}/*-----------------------*/ 73 /*-----------------分卷*/else{/*-------------------------*/ 74 if(!$_POST['filesize']) 75 {$msgs[]="請填寫備份文件分卷大小"; show_msg($msgs);pageend();} 76 if(!$tables=$d->query("show table status from $mysqldb")) 77 {$msgs[]="讀數據庫結構錯誤"; show_msg($msgs); pageend();} 78 $sql=""; $p=1; 79 $filename=date("Ymd",time())."_all"; 80 while($d->nextrecord($tables)) 81 { 82 $table=$d->f("Name"); 83 $sql.=make_header($table); 84 $d->query("select * from $table"); 85 $num_fields=$d->nf(); 86 while($d->nextrecord()) 87 {$sql.=make_record($table,$num_fields); 88 if(strlen($sql)>=$_POST['filesize']*1000){ 89 $filename.=("_v".$p.".sql"); 90 if(write_file($sql,$filename)) 91 $msgs[]="全部數據表-卷-".$p."-數據備份完成,生成備份文件'./backup/$filename'"; 92 else $msgs[]="備份表-".$_POST['tablename']."-失敗"; 93 $p++; 94 $filename=date("Ymd",time())."_all"; 95 $sql="";} 96 } 97 } 98 if($sql!=""){$filename.=("_v".$p.".sql"); 99 if(write_file($sql,$filename)) 100 $msgs[]="全部數據表-卷-".$p."-數據備份完成,生成備份文件'./backup/$filename'";} 101 show_msg($msgs); 102 /*---------------------分卷結束*/}/*--------------------------------------*/ 103 /*--------備份全部表結束*/}/*---------------------------------------------*/ 104 105 /*--------備份單表------*/elseif($_POST['bfzl']=="danbiao"){/*------------*/ 106 if(!$_POST['tablename']) 107 {$msgs[]="請選擇要備份的數據表"; show_msg($msgs); pageend();} 108 /*--------不分卷*/if(!$_POST['fenjuan']){/*-------------------------------*/ 109 $sql=make_header($_POST['tablename']); 110 $d->query("select * from ".$_POST['tablename']); 111 $num_fields=$d->nf(); 112 while($d->nextrecord()) 113 {$sql.=make_record($_POST['tablename'],$num_fields);} 114 $filename=date("Ymd",time())."_".$_POST['tablename'].".sql"; 115 if($_POST['weizhi']=="localpc") down_file($sql,$filename); 116 elseif($_POST['weizhi']=="server") 117 {if(write_file($sql,$filename)) 118 $msgs[]="表-".$_POST['tablename']."-數據備份完成,生成備份文件'./backup/$filename'"; 119 else $msgs[]="備份表-".$_POST['tablename']."-失敗"; 120 show_msg($msgs); 121 pageend(); 122 } 123 /*----------------不要卷結束*/}/*------------------------------------*/ 124 /*----------------分卷*/else{/*--------------------------------------*/ 125 if(!$_POST['filesize']) 126 {$msgs[]="請填寫備份文件分卷大小"; show_msg($msgs);pageend();} 127 $sql=make_header($_POST['tablename']); $p=1; 128 $filename=date("Ymd",time())."_".$_POST['tablename']; 129 $d->query("select * from ".$_POST['tablename']); 130 $num_fields=$d->nf(); 131 while ($d->nextrecord()) 132 { 133 $sql.=make_record($_POST['tablename'],$num_fields); 134 if(strlen($sql)>=$_POST['filesize']*1000){ 135 $filename.=("_v".$p.".sql"); 136 if(write_file($sql,$filename)) 137 $msgs[]="表-".$_POST['tablename']."-卷-".$p."-數據備份完成,生成備份文件'./backup/$filename'"; 138 else $msgs[]="備份表-".$_POST['tablename']."-失敗"; 139 $p++; 140 $filename=date("Ymd",time())."_".$_POST['tablename']; 141 $sql="";} 142 } 143 if($sql!=""){$filename.=("_v".$p.".sql"); 144 if(write_file($sql,$filename)) 145 $msgs[]="表-".$_POST['tablename']."-卷-".$p."-數據備份完成,生成備份文件'./backup/$filename'";} 146 show_msg($msgs); 147 /*----------分卷結束*/}/*--------------------------------------------------*/ 148 /*----------備份單表結束*/}/*----------------------------------------------*/ 149 150 /*---*/}/*-------------主程序結束------------------------------------------*/ 151 152 function write_file($sql,$filename) 153 { 154 $re=true; 155 if(!@$fp=fopen("./backup/".$filename,"w+")) {$re=false; echo "failed to open target file";} 156 if(!@fwrite($fp,$sql)) {$re=false; echo "failed to write file";} 157 if(!@fclose($fp)) {$re=false; echo "failed to close target file";} 158 return $re; 159 } 160 161 function down_file($sql,$filename) 162 { 163 ob_end_clean(); 164 header("Content-Encoding: none"); 165 header("Content-Type: ".(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') ? 'application/octetstream' : 'application/octet-stream')); 166 167 header("Content-Disposition: ".(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') ? 'inline; ' : 'attachment; ')."filename=".$filename); 168 169 header("Content-Length: ".strlen($sql)); 170 header("Pragma: no-cache"); 171 172 header("Expires: 0"); 173 echo $sql; 174 $e=ob_get_contents(); 175 ob_end_clean(); 176 } 177 178 function writeable($dir) 179 { 180 181 if(!is_dir($dir)) { 182 @mkdir($dir, 0777); 183 } 184 185 if(is_dir($dir)) 186 { 187 188 if($fp = @fopen("$dir/test.test", 'w')) 189 { 190 @fclose($fp); 191 @unlink("$dir/test.test"); 192 $writeable = 1; 193 } 194 else { 195 $writeable = 0; 196 } 197 198 } 199 200 return $writeable; 201 202 } 203 204 function make_header($table) 205 {global $d; 206 $sql="DROP TABLE IF EXISTS ".$table."\n"; 207 $d->query("show create table ".$table); 208 $d->nextrecord(); 209 $tmp=preg_replace("/\n/","",$d->f("Create Table")); 210 $sql.=$tmp."\n"; 211 return $sql; 212 } 213 214 function make_record($table,$num_fields) 215 {global $d; 216 $comma=""; 217 $sql .= "INSERT INTO ".$table." VALUES("; 218 for($i = 0; $i < $num_fields; $i++) 219 {$sql .= ($comma."'".mysql_escape_string($d->record[$i])."'"); $comma = ",";} 220 $sql .= ")\n"; 221 return $sql; 222 } 223 224 function show_msg($msgs) 225 { 226 $title="提示:"; 227 echo "<table width='100%' border='1' cellpadding='0' cellspacing='1'>"; 228 echo "<tr><td>".$title."</td></tr>"; 229 echo "<tr><td><br><ul>"; 230 while (list($k,$v)=each($msgs)) 231 { 232 echo "<li>".$v."</li>"; 233 } 234 echo "</ul></td></tr></table>"; 235 } 236 237 function pageend() 238 { 239 exit(); 240 } 241 ?>
restore.php
<? session_start(); global $mysqlhost, $mysqluser, $mysqlpwd, $mysqldb; $mysqlhost=""; //host name $mysqluser=""; //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); ?> <form action="" method="post" enctype="multipart/form-data" name="restore.php"> <table width="91%" border="0" cellpadding="0" cellspacing="1"> <tr align="center" class="header"><td colspan="2" align="center">數據恢復</td></tr> <tr><td width="33%"><input type="radio" name="restorefrom" value="server" checked> 從服務器文件恢復 </td><td width="67%"><select name="serverfile"> <option value="">-請選擇-</option> <? $handle=opendir('./backup'); while ($file = readdir($handle)) { if(eregi("^[0-9]{8,8}([0-9a-z_]+)(\.sql)$",$file)) echo "<option value='$file'>$file</option>";} closedir($handle); ?> </select> </td></tr> <tr><td><input type="radio" name="restorefrom" value="localpc"> 從本地文件恢復</td> <td><input type="hidden" name="MAX_FILE_SIZE" value="1500000"><input type="file" name="myfile"></td></tr> <tr><td colspan="2" align="center"> <input type="submit" name="act" value="恢復"></td> </tr></table></form> <?/**************************界面結束*/}/*************************************/ /****************************主程序*/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 language='javascript'>"; 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 language='javascript'>"; 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 "<table width='100%' border='1' cellpadding='0' cellspacing='1'>"; echo "<tr><td>".$title."</td></tr>"; echo "<tr><td><br><ul>"; while (list($k,$v)=each($msgs)) { echo "<li>".$v."</li>"; } echo "</ul></td></tr></table>"; } function pageend() { exit(); } ?>
有很多軟件可以使用,比如phpmyadmin,sqlyog等等
下載一個phpmyadmin並且配置好(網上有如何配置),其中就有備份還原數據庫的圖標,很簡單
補充:----------------------
對啊,點導出,然後執行就可以了啊
能生成文件但是內容為空,說明:php執行沒問題,mysqldump也運行,初步判斷問題出在mysqldump沒正常運行。建議你到服務器上運行 "C:\Program Files\MySQL\MySQL Server 5.0\bin\mysqldump -uroot -hlocalhost -p123 --opt -B rsgl > ../bak/xxx.sql"
看能否正常生成sql文件