您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

数据库备份与恢复

2024/3/15 2:09:52发布48次查看
一个thinkphp操作类,用来导出mysql数据和导入备份
query('show table status');
        $total = 0;
        foreach ($tabs as $k => $v) {
            $tabs[$k]['size'] = byteformat($v['data_length'] + $v['index_length']);
            $total+=$v['data_length'] + $v['index_length'];
        }
        //echo __app__./public/data/;
   // echo  $this->export($tablename=);
 //  echo $this->restore(./public/backup/20130704091642_tao_group_v1.sql);
        $this->assign(list, $tabs);
        $this->assign(total, byteformat($tota ));
        $this->assign(tables, count($tabs));
        $this->display();
    }
    public function import(){
        //echo c(db_backup);
        //print_r(glob(c(db_backup).*.sql))
        foreach (glob(c(db_backup).*.sql) as $filename) {
    $arr[]=array(filename=>$filename,size=>filesize($filename));
 }
// if(!empty($_get[file])){
//     $this->restore(i(file));
// }
        $this->assign(list, $arr);
     $this->display();    
    }
    public function truncate(){
        $table=i(table);
        if(!empty($table)){
        $m = m();
         $result = $m->query('truncate table '.$table);
if(empty($result)){
            $this->success(清空表成功!);
        }else{
            $this->error(清空表失败!);
          }
        }
    }
    public function delete(){
        $table=i(table);
        if(!empty($table)){
        $m = m();
         $result = $m->query('drop table '.$table);
if($result){
            $this->success(删除表成功!);
        }else{
            $this->error(删除表失败!);
          }
        }
    }
    /**
     * gettables 获取数据库表列表
     * @return array $tables      返回结果数组    
     */
    public function gettables() {
        $m = m();
        $res = $m->query ( show tables; );
        $tables = array ();
        foreach ( $res as $row ) {
foreach ($row as $v){
                $tables[]=$v;
            }
        }
        return $tables;
    }
    /**
     * 插入数据库备份基础信息
     *
     * @return string
     */
    private function _base() {
        $value = '';
        $value .= '-- mysql database dump' . $this->ds;
        $value .= '-- created by dbaction class, power by taotao. ' . $this->ds;
        $value .= '-- http://blog.kisscn.com ' . $this->ds;
        $value .= '--' . $this->ds;
        $value .= '-- 主机: ' . $this->host . $this->ds;
        $value .= '-- 生成日期: ' . date ( 'y' ) . ' 年  ' . date ( 'm' ) . ' 月 ' . date ( 'd' ) . ' 日 ' . date ( 'h:i' ) . $this->ds;
        $value .= '-- mysql版本: ' . mysql_get_server_info () . $this->ds;
        $value .= '-- php 版本: ' . phpversion () . $this->ds;
        $value .= $this->ds;
        $value .= '--' . $this->ds;
        $value .= '-- 数据库: `' . c(db_name) . '`'. $this->ds;
        $value .= '--' . $this->ds ;
        $value .= '-- -------------------------------------------------------';
        $value .= $this->ds . $this->ds;
        return $value;
    }
    /**
     * 插入表结构
     *
     * @param unknown_type $table            
     * @return string
     */
    private function _insert_table_structure($table) {
        $sql = '';
        $sql .= -- . $this->ds;
        $sql .= -- 表的结构 . $table .$this->ds.-- .$this->ds;
         $m = m();
        // 如果存在则删除表
        $sql .= drop table if exists ` . $table . '`' . $this->sqlend . $this->ds;
        // 获取详细表信息
        $res = $m->query ( 'show create table `' . $table . '`' );
        $sql .= $res [0][create table];
        $sql .= $this->sqlend . $this->ds;
        // 加上
        $sql .= $this->ds;
        $sql .= -- . $this->ds;
        $sql .= -- 转存表中的数据  . $table . $this->ds;
        $sql .= -- . $this->ds;
        $sql .= $this->ds;
        return $sql;
    }
/**
     * 插入语句构造
     *
     * @param string $table                     
     * @return string
     */
    private function _insert_record($table) {
        // sql字段逗号分割
$m=m();
        $res = $m->query ( 'select * from `' . $table . '`' );    
        // 循环每个子段下面的内容
            foreach ($res as $val){
        $comma = 0;
                $insert .= insert into ` . $table . ` values(;
                foreach ($val as $v){
        $insert.=$comma == 0 ?  : ,;
            $insert.= ( ' . mysql_escape_string ( $v ) . ');
                        $comma++;
}
            $insert .= ); . $this->ds;
}
return $insert;
    }
/**
     * 写入文件
     *
     * @param string $sql            
     * @param string $filename            
     * @param string $dir            
     * @return boolean
     */
    private function _write_file($sql, $filename, $dir) {
          $dir = c(db_backup);
        // 创建目录
        if (! is_dir ( $dir )) {
            mkdir ( $dir, 0777, true );
        }
        $re = true;
        if (! @$fp = fopen ( $dir . $filename, w+ )) {
            $re = false;
            $msg .= 打开文件失败!;
        }
        if (! @fwrite ( $fp, $sql )) {
            $re = false;
            $msg .= 写入文件失败,请文件是否可写;
        }
        if (! @fclose ( $fp )) {
            $re = false;
            $msg .= 关闭文件失败!;
        }
        return $re;
    }
    /**
     * 数据库备份
     * 参数:备份哪个表(可选),备份目录(可选,默认为backup),分卷大小(可选,默认2048,即2m)
     *
     * @param string $dir            
     * @param int $size            
     * @param array $tablename            
     */
    public function export() {
        $tablename=i(table);
         $dir = c(db_backup);
        // 创建目录
        if (! is_dir ( $dir )) {
            mkdir ( $dir, 0777, true ) or die ( '创建文件夹失败' );
        }
        $size = c(db_backup_size);
        $sql = '';
        $tables=explode(,, $tablename);
        //print_r($tables);
        $m=m();
        if(!empty($tablename)){
        foreach ($tables as $value) {
            $msg .= '正在备份表' . $value . '
';
            // 插入文件头信息
            $sql = $this->_base ();
            // 插入表结构信息
            $sql .= $this->_insert_table_structure ( $value );
            // 文件名前缀
            $filename = date ( 'ymdhis' ) . _ . $value;
            // 分卷标识
            $p = 1;
            $sql .= $this->_insert_record ( $value);
                        // 如果大于分卷大小,则写入文件
                        //$msg.=文件大小为:.strlen ( $sql );
                if (strlen ( $sql ) >= $size * 1024) {
                    $file = $filename . _v . $p . .sql;
                    if ($this->_write_file ( $sql, $file, $dir )) {
                        $msg .= 表- . $value . -卷- . $p . '
';
                        $msg.= -数据备份完成,生成备份文件 $dir$filename
;
                    } else {
                        $msg .= 备份表- . $value . -失败
;
                        return false;
                    }
                    // 下一个分卷
                    $p ++;
                    // 重置$sql变量为空,重新计算该变量大小
                    $sql = ;
                }else{
                            // sql大小不够分卷大小
            if ($sql != ) {
                $filename .=  .sql;
                if ($this->_write_file ( $sql, $filename, $dir )) {
                    $msg .= 表- . $value . -卷- . $p. '
'. -数据备份完成,生成备份文件 $dir$filename
;
                } else {
                    $msg .= 备份卷- . $p . -失败
;
                    return false;
                }
            }
                }
        }
        }else{
                    // 备份全部表
            if ($tables = $m->query( show table status from  . c(db_name) )) {
                $msg .= 读取数据库结构成功!
;
            } else {
                exit ( 读取数据库结构失败!
 );
            }
            // 插入dump信息
            $sql .= $this->_base ();
            // 文件名前面部分
            $filename = date ( 'ymdhis' ) . _all;
            // 查出所有表
            $tables = $m->query ( 'show tables' );
            // 第几分卷
            $p = 1;
            // 循环所有表
            foreach  ( $tables as $value) {
                foreach ($value as $v) {
// 获取表结构
                $sql .= $this->_insert_table_structure ( $v );
                    // 单条记录
                    $sql .= $this->_insert_record ( $v );
                  }
}
                  // 如果大于分卷大小,则写入文件
                    if (strlen ( $sql ) >= $size * 1024) {
$file = $filename . _v . $p . .sql;
                        // 写入文件
                        if ($this->_write_file ( $sql, $file, $dir )) {
                            $this->msg .= -卷- . $p . -数据备份完成,生成备份文件$dir$file
;
                        } else {
                            $this->msg .= 备份卷- . $p . -失败
;
                            return false;
                        }
                        // 下一个分卷
                        $p ++;
                        // 重置$sql变量为空,重新计算该变量大小
                        //$sql = ;
                    }
                // sql大小不够分卷大小
            if ($sql != ) {
                $filename .=  .sql;
                if ($this->_write_file ( $sql, $filename, $dir )) {
                    $msg .= 数据库- . c(db_name) . -卷- . $p. '
'. -数据备份完成,生成备份文件 $dir$filename
;
                } else {
                    $msg .= 备份卷- . $p . -失败
;
                    return false;
                }
            }
        }
        echo $msg; 
    }
/**
     * 导入备份数据
     * 说明:分卷文件格式20120516211738_all_v1.sql
     * 参数:文件路径(必填)
     *
     * @param string $sqlfile            
     */
    function restore($file) {
        $sqlfile=c(db_backup).$file;
// 检测文件是否存在
        if (! file_exists ( $sqlfile )) {
            exit ( 文件不存在!请检查 );
        }
        $this->lock ( c(db_name) );
        // 获取数据库存储位置
        $sqlpath = pathinfo ( $sqlfile );
    //    $this->sqldir = $sqlpath ['dirname'];
        // 检测是否包含分卷,将类似20120516211738_all_v1.sql从_v分开,有则说明有分卷
        $volume = explode ( _v, $sqlfile );
        $volume_path = $volume [0];
        $msg .= 请勿刷新及关闭浏览器以防止程序被中止,如有不慎!将导致数据库结构受损
;
        $msg .= 正在导入备份数据,请稍等!
;
        if (empty ( $volume [1] )) {
             $msg .= 正在导入sql: . $sqlfile . '
';
            // 没有分卷
            if ($this->_import ( $sqlfile )) {
            echo    $msg .= 数据库导入成功!;
        //$this->success(数据库导入成功!);
            } else {
                exit ( '数据库导入失败!' );
            }
        } else {
            // 存在分卷,则获取当前是第几分卷,循环执行余下分卷
            $volume_id = explode ( .sq, $volume [1] );
            // 当前分卷为$volume_id
            $volume_id = intval ( $volume_id [0] );
            while ( $volume_id ) {
                $tmpfile = $volume_path . _v . $volume_id . .sql;
                // 存在其他分卷,继续执行
                if (file_exists ( $tmpfile )) {
                    // 执行导入方法
                    $msg .= 正在导入分卷 $volume_id : . $tmpfile . '
';
                    if ($this->_import ( $tmpfile )) {
} else {
                        $volume_id = $volume_id ? $volume_id :1;
                        exit ( 导入分卷: . $tmpfile . '失败!可能是数据库结构已损坏!请尝试从分卷1开始导入' );
                    }
                } else {
                    $msg .= 此分卷备份全部导入成功!
;
                    echo $msg;
                }
                $volume_id ++;
            }
        }
    }
    /**
     * 将sql导入到数据库(普通导入)
     *
     * @param string $sqlfile            
     * @return boolean
     */
    private function _import($sqlfile) {
        // sql文件包含的sql语句数组
        $sqls = array ();
        $f = fopen ( $sqlfile, rb );
        // 创建表缓冲变量
        $create_table = '';
        while ( ! feof ( $f ) ) {
            // 读取每一行sql
            $line = fgets ( $f );
            // 这一步为了将创建表合成完整的sql语句
            // 如果结尾没有包含';'(即为一个完整的sql语句,这里是插入语句),并且不包含'engine='(即创建表的最后一句)
            if (! preg_match ( '/;/', $line ) || preg_match ( '/engine=/', $line )) {
                // 将本次sql语句与创建表sql连接存起来
                $create_table .= $line;
                // 如果包含了创建表的最后一句
                if (preg_match ( '/engine=/', $create_table)) {
                    //执行sql语句创建表
                    $this->_insert_into($create_table);
                    // 清空当前,准备下一个表的创建
                    $create_table = '';
                }
                // 跳过本次
                continue;
            }
            //执行sql语句
            $this->_insert_into($line);
        }
        fclose ( $f );
        return true;
    }
    //插入单条sql语句
    private function _insert_into($sql){
        $m=m();
        if (! $m->query( trim ( $sql ) )) {
            $msg .= mysql_error ();
            return false;
        }
    }
        // 锁定数据库,以免备份或导入时出错
    private function lock($tablename, $op = write) {
        $m=m();
        if ($m->query( lock tables  . $tablename .   . $op ))
            return true;
        else
            return false;
    }
// 解锁
    private function unlock() {
        $m=m();
        if ($m->query ( unlock tables ))
            return true;
        else
            return false;
    }
}
/**
 +----------------------------------------------------------
 * 功能:计算文件大小
 +----------------------------------------------------------
 * @param int $bytes
 +----------------------------------------------------------
 * @return string 转换后的字符串
 +----------------------------------------------------------
 */
function byteformat($bytes) {
    $sizetext = array( b,  kb,  mb,  gb,  tb,  pb,  eb,  zb,  yb);
    return round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), 2) . $sizetext[$i];
}    备份效果:
ad:真正免费,域名+虚机+企业邮箱=0元
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product