|
|
|
const {koaBody} = require('koa-body');
|
|
|
|
const Koa = require('koa');
|
|
|
|
const fs = require('fs');
|
|
|
|
const path = require('path');
|
|
|
|
const { spawn } = require('child_process')
|
|
|
|
const router = require('koa-router')()
|
|
|
|
, os = require('os')
|
|
|
|
, iconv = require("iconv-lite")
|
|
|
|
const moment = require('moment')
|
|
|
|
|
|
|
|
const { DATABASELIST, SERVER_PORT, SERVERHOST} = require('./config')
|
|
|
|
const mysqldump = require("mysqldump");
|
|
|
|
|
|
|
|
// 备份间隔时间
|
|
|
|
const mintues = 60 * 24;// minute
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// web服务
|
|
|
|
function server(){
|
|
|
|
const app = new Koa();
|
|
|
|
app.use(koaBody({
|
|
|
|
multipart: true, // 支持文件上传
|
|
|
|
formidable: {
|
|
|
|
maxFieldsSize: 500 * 1024 * 1024, // 最大文件为2兆
|
|
|
|
multipart: true // 是否支持 multipart-formdate 的表单
|
|
|
|
}
|
|
|
|
}));
|
|
|
|
router.post('/putfile', async ctx => {
|
|
|
|
const fileList = await getFileList()
|
|
|
|
console.log('请求备份', fileList)
|
|
|
|
if(fileList.length == 0){
|
|
|
|
ctx.body = [{state:false,filename:'无备份文件'}]
|
|
|
|
}else{
|
|
|
|
const bunneryList = await readFile(fileList)
|
|
|
|
ctx.body = bunneryList
|
|
|
|
deleteFile(fileList)
|
|
|
|
}
|
|
|
|
});
|
|
|
|
app.use(router.routes(), router.allowedMethods())
|
|
|
|
app.listen(SERVER_PORT, () => {
|
|
|
|
console.log('=> 备份服务已启动! http://127.0.0.1:' + SERVER_PORT)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// 本分服务
|
|
|
|
function back(){
|
|
|
|
/**
|
|
|
|
* 数据库备份程序
|
|
|
|
* */
|
|
|
|
function backSQL(user, passwd, database){
|
|
|
|
const filename = `./back/${ database }_${ moment().format("YYYY_MM_DD_HH_mm_ss") }.sql`
|
|
|
|
console.log(database);
|
|
|
|
mysqldump({
|
|
|
|
connection: {
|
|
|
|
host: SERVERHOST,
|
|
|
|
user: user,
|
|
|
|
password: passwd,
|
|
|
|
database: database,
|
|
|
|
},
|
|
|
|
dumpToFile: filename,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// 开始备份数据库
|
|
|
|
function startBackSQL(){
|
|
|
|
console.log('====>>', moment().format("YYYY-MM-DD HH:mm:ss"))
|
|
|
|
for(let item in DATABASELIST){
|
|
|
|
const i = DATABASELIST[item];
|
|
|
|
// 数据库信息
|
|
|
|
let user = "root", passwd = "root", database = i
|
|
|
|
runBackFunc(user, passwd, database)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function runBackFunc(user, passwd, database){
|
|
|
|
backSQL(user, passwd, database)
|
|
|
|
const outTime = getT() - new Date().getTime()
|
|
|
|
setTimeout(() => {
|
|
|
|
setInterval(() => {
|
|
|
|
backSQL(user, passwd, database)
|
|
|
|
}, 1000 * 60 * mintues)
|
|
|
|
},outTime)
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* 根据系统类型,读取编码格式
|
|
|
|
* */
|
|
|
|
function out(data){
|
|
|
|
if(os.platform() == 'win32'){
|
|
|
|
return iconv.decode(data, 'GBK')
|
|
|
|
}else{
|
|
|
|
return data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 读取文件目录
|
|
|
|
function getFileList(){
|
|
|
|
return new Promise((rec, res) => {
|
|
|
|
fs.readdir(__dirname + '/back', (err, fileList) => {
|
|
|
|
if(err){
|
|
|
|
res(err)
|
|
|
|
}else{
|
|
|
|
rec(fileList)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 读取文件
|
|
|
|
function readFile(fileList){
|
|
|
|
return new Promise(rec => {
|
|
|
|
const list = []
|
|
|
|
for(let i in fileList){
|
|
|
|
fs.readFile(__dirname + '/back/' + fileList[i],'utf8',function(err,datastr){
|
|
|
|
if(err){
|
|
|
|
list.push({
|
|
|
|
state:false,
|
|
|
|
filename:fileList[i]
|
|
|
|
})
|
|
|
|
}else{
|
|
|
|
list.push({
|
|
|
|
state:true,
|
|
|
|
filename:fileList[i],
|
|
|
|
file:datastr
|
|
|
|
})
|
|
|
|
}
|
|
|
|
if(i == fileList.length -1){
|
|
|
|
rec(list)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// 删除文件
|
|
|
|
function deleteFile(filelist){
|
|
|
|
for(let filename of filelist){
|
|
|
|
fs.unlink(__dirname + '/back/' + filename, (e, data) => {
|
|
|
|
if(e){
|
|
|
|
console.log('删除文件失败:', filename)
|
|
|
|
}else{
|
|
|
|
console.log('删除文件成功:', filename)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取明天凌晨时间
|
|
|
|
function getT(){
|
|
|
|
const temore = new Date().getTime() + 1000 * 60 * 60 * 24
|
|
|
|
const now = new Date(temore)
|
|
|
|
let year = now.getFullYear(); //得到年份
|
|
|
|
let month = now.getMonth();//得到月份
|
|
|
|
let date = now.getDate();//得到日期
|
|
|
|
return new Date(year + "-" + month + "-" + date).getTime()
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 启动本地备份
|
|
|
|
startBackSQL()
|
|
|
|
}
|
|
|
|
|
|
|
|
// server()
|
|
|
|
back()
|