数据备份
ts
import * as nodemailer from 'nodemailer';
import * as OSS from 'ali-oss'; // 阿里云 OSS SDK
import * as fs from 'fs';
import * as path from 'path';
import * as dayjs from 'dayjs';
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import mysqldump from 'mysqldump';
@Injectable()
export class TasksService {
private readonly logger = new Logger(TasksService.name);
constructor() {}
@Cron(CronExpression.EVERY_DAY_AT_1AM)
async execByTime() {
// 确保目录存在
const directory = path.resolve(__dirname, '../../backSql');
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory, { recursive: true });
}
// 生成 SQL 文件路径
const sqlFileName = `${dayjs(Date.now()).format('YYYY年MM月DD日HH时mm分ss秒')}.sql`;
const sqlFilePath = path.join(directory, sqlFileName);
// 执行数据库备份
this.logger.debug('开始备份数据库...');
await mysqldump({
connection: {
host: '119.96.24.5',
user: 'root',
password: 'Xianyu@666',
database: 'fast_pigeon_devops_test1',
},
dumpToFile: sqlFilePath,
});
this.logger.debug(`数据库备份完成,文件路径:${sqlFilePath}`);
// 发送邮件
await this.sendEmailWithAttachment(sqlFilePath);
// 上传到 OSS
await this.uploadToOSS(sqlFilePath, sqlFileName);
}
// 发送邮件
private async sendEmailWithAttachment(filePath: string) {
this.logger.debug('开始发送邮件...');
const transporter = nodemailer.createTransport({
host: 'smtp.163.com', // 邮件服务提供商的 SMTP 地址
port: 465,
secure: true, // 使用 SSL
auth: {
user: 'your_email@163.com', // 发件人邮箱
pass: 'your_email_password', // 发件人邮箱授权码
},
});
const mailOptions = {
from: '"SQL备份系统" <your_email@163.com>', // 发件人
to: 'recipient@example.com', // 收件人
subject: '每日 SQL 备份', // 邮件主题
text: '请查收附件中的 SQL 备份文件。', // 邮件正文
attachments: [
{
filename: path.basename(filePath), // 附件名称
path: filePath, // 附件路径
},
],
};
try {
await transporter.sendMail(mailOptions);
this.logger.debug('邮件发送成功!');
} catch (error) {
this.logger.error('邮件发送失败:', error);
}
}
// 上传到 OSS
private async uploadToOSS(filePath: string, fileName: string) {
this.logger.debug('开始上传到 OSS...');
const client = new OSS({
region: 'oss-cn-hangzhou', // 阿里云 OSS 区域
accessKeyId: 'your_access_key_id', // 阿里云 Access Key ID
accessKeySecret: 'your_access_key_secret', // 阿里云 Access Key Secret
bucket: 'your_bucket_name', // OSS 存储桶名称
});
try {
const result = await client.put(`backups/${fileName}`, filePath);
this.logger.debug(`上传到 OSS 成功,访问地址:${result.url}`);
} catch (error) {
this.logger.error('上传到 OSS 失败:', error);
}
}
}
关键点说明
- 备份 SQL 文件:
- 使用 [mysqldump](vscode-file://vscode-app/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 将数据库备份到本地文件。
- 发送邮件:
- 使用
nodemailer
发送邮件。 - 配置 SMTP 服务(如
smtp.163.com
)。 - 将 SQL 文件作为附件发送。
- 使用
- 上传到 OSS:
- 使用阿里云 OSS SDK 上传文件。
- 配置 OSS 的
region
、accessKeyId
、accessKeySecret
和bucket
。
- 日志记录:
- 使用 [Logger](vscode-file://vscode-app/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 记录备份、邮件发送和 OSS 上传的状态。
示例日志输出
[TasksService] 开始备份数据库... [TasksService] 数据库备份完成,文件路径:/path/to/backSql/2025年04月01日01时00分00秒.sql [TasksService] 开始发送邮件... [TasksService] 邮件发送成功! [TasksService] 开始上传到 OSS... [TasksService] 上传到 OSS 成功,访问地址:https://your_bucket_name.oss-cn-hangzhou.aliyuncs.com/backups/2025年04月01日01时00分00秒.sql
总结
- 备份 SQL 文件:使用 [mysqldump](vscode-file://vscode-app/Applications/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-sandbox/workbench/workbench.html) 将数据库备份到本地。
- 发送邮件:使用
nodemailer
将 SQL 文件作为附件发送到指定邮箱。 - 上传到 OSS:使用阿里云 OSS SDK 将 SQL 文件上传到云存储。
- 定时任务:通过
@Cron
注解每天定时执行备份、发送邮件和上传操作。