本段代码源于 gitHub项目
说明:笔者在源项目的基础上增加了数据导入功能,同时将压缩数据包的类库换成了ZipArchive,主要是因为 RecursiveIteratorIterator这个库太冷,笔者真的不太会,直接简单粗暴的换了。
<?php
<?php
namespace MyOrg\DbTools;
use Think\Log;
/**
* This class allows you to dump any local mongoDB database, utilizing shell command
* to do so. If there is an error, please verify that the backup folder has the
* correct permissions and this script has execute permissions.
*
* $tool = new MongoTool('/data/wwwroot/default/Data');
* $tool->restore('yangshenGM2','yangshenGM2_2016-01-24_15-21.zip','',true); //恢复指定数据库 全库恢复
* $tool->restore('yangshenGM2','yangshenGM2_2016-01-24_15-21.zip','user',true); //恢复指定数据表 单表恢复
* $tool->backUp('yangshenGM2','',true); //备份指定数据库 全库备份
* $tool->backUp('yangshenGM2','user',true); //备份指定数据库和数据表 单表备份
*
* 值得注意的是,备份和恢复是需要配套使用的!
*/
/**
* Mongo数据库备份恢复类库
* Class MongoTool
* @package MyOrg\DbTools
*/
class MongoTool {
private $targetPath; //最终zip包存放的地方
private $_DATE_TIME; //当前格式化了的时间,精确到分钟
private $workPath; //打包的路径,这里将最终确定zip包的目录结构
private $config; //数据库配置
private $tbName; //数据表名称
private $tmpPath; //用于存储中间导出的数据文件,在zip之后这里的文件会被删除
private $debug; //是否开启debug,开启就输出调试信息
public function __construct( $path, $config = [] ) {
if( empty($path) ){
E(L('_PARAM_ERROR_'));
}
$this->targetPath = rtrim($path, '/');
$this->_DATE_TIME = date('Y-m-d_H-i');
$conf = [
'DB_TYPE' => 'mongodb',
'DB_HOST' => '127.0.0.1',
'DB_NAME' => 'yangshenGM',
'DB_USER' => '',
'DB_PWD' => '',
'DB_PORT' => 27017,
'DB_PREFIX' => ''
];
$this->config = array_merge($conf, $config);
}
public function backUp( $tbName = '', $debug = false){
$this->debug = $debug;
if( !empty($tbName) ){
$this->tbName = $tbName;
}
$this->tmpPath = $this->targetPath . "/" . $this->config['DB_NAME'] . "_" . $this->_DATE_TIME;
$this->workPath = $this->tmpPath . "/" . $this->config['DB_NAME'];
$this->echoIfDebug("Backing up '{$this->config['DB_NAME']}' to '{$this->tmpPath}'");
$this->mongoDump();
$this->zipFiles();
$this->deleteTmpDir($this->tmpPath);
$this->echoIfDebug("Complete!");
}
public function restore( $fileName = '', $tbName = '', $debug = false){
$this->debug = $debug;
if( !empty($tbName) ){
$this->tbName = $tbName;
}
if( empty($fileName) ){
E(L('_PARAM_ERROR_'));
}
$this->tmpPath = $this->targetPath . "/" . $fileName;
$this->echoIfDebug("Restoring '{$this->config['DB_NAME']}' from '{$this->tmpPath}'");
$this->unzipFiles();
$this->mongoRestore();
$dir = $this->targetPath . '/tmp';
$this->deleteTmpDir($dir);
$this->echoIfDebug("Complete!");
}
private function echoIfDebug( $string ) {
if ($this->debug) {
Log::record($string,'DEBUG',true);
}
}
private function mongoDump() {
$this->echoIfDebug("Executing mongodump...");
if( empty($this->tbName) ){
if( $this->config['DB_USER'] ){
$command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} --out " . $this->tmpPath;
}else{
$command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --out " . $this->tmpPath;
}
}else{
if( $this->config['DB_USER'] ){
$command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --collection {$this->tbName} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} --out " . $this->tmpPath;
}else{
$command = "mongodump --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --collection {$this->tbName} --db {$this->config['DB_NAME']} --out " . $this->tmpPath;
}
}
$results = shell_exec($command);
$this->echoIfDebug("Command:{$command},Result:{$results}");
}
private function mongoRestore() {
$this->echoIfDebug("Executing mongorestore...");
if( empty($this->tbName) ){
if( $this->config['DB_USER'] ){
$command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} {$this->targetPath}/tmp";
}else{
$command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} {$this->targetPath}/tmp";
}
}else{
if( $this->config['DB_USER'] ){
$command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --collection {$this->tbName} -u {$this->config['DB_USER']} -p {$this->config['DB_PWD']} {$this->targetPath}/tmp/{$this->tbName}.bson";
}else{
$command = "mongorestore --host {$this->config['DB_HOST']}:{$this->config['DB_PORT']} --db {$this->config['DB_NAME']} --collection {$this->tbName} {$this->targetPath}/tmp/{$this->tbName}.bson";
}
}
$results = shell_exec($command);
$this->echoIfDebug("Command:{$command},Result:{$results}");
}
private function zipFiles() {
$this->echoIfDebug("Zipping files...");
chdir($this->workPath);
$zip = new \ZipArchive;
$zip->open($this->targetPath. '/' . $this->config['DB_NAME'] .'_'. $this->_DATE_TIME . '.zip', \ZipArchive::CREATE);
$dir = opendir($this->workPath);
while( $file = readdir($dir) ){
if( $file != '.' && $file != '..' ){
$zip->addFile($file);
$this->echoIfDebug("{$file} has been zip");
}
}
$zip->close();
}
private function unzipFiles() {
$this->echoIfDebug("unzipping files...");
chdir($this->targetPath);
$zip = new \ZipArchive;
$zip->open($this->tmpPath);
$zip->extractTo('tmp');
$zip->close();
}
private function deleteTmpDir( $dir ) {
$this->echoIfDebug("Deleting {$dir} ...");
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
foreach ( $files as $file ) {
$file->isDir() ? rmdir($file) : unlink($file);
}
rmdir($dir);
}
}
本文由 陌上花开 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Feb 15, 2017 at 09:23 am