You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
backSQL/server.js

162 lines
4.8 KiB

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} = require('./config')
// 备份间隔时间
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(host, user, passwd, database){
return new Promise(rec => {
const cout = os.platform() == 'win32' ? '-r' : '>'
, filename = `back/BACKUP_${ database }_${ moment().format("YYYY_MM_DD_HH_mm_ss") }.sql`
const backProcess = spawn('mysqldump',['-u'+user, '-p'+passwd, database, cout + filename]);
backProcess.stdout.on('data', data => console.log('Data : ', out(data)))
backProcess.stderr.on('data', data => console.log('Error: ', out(data)))
backProcess.on('close', code => {
console.log('Exit :', code.toString())
rec(filename)
})
})
}
// 开始备份数据库
function startBackSQL(){
// 数据库信息
let host = "localhost"
, user = "root"
, passwd = "root"
, database = "develop"
backSQL(host, user, passwd, database)
const outTime = getT() - new Date().getTime()
for(let item in DATABASELIST){
const i = DATABASELIST[item];
database = i;
setTimeout(() => {
setInterval(() => {
backSQL(host, 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()