mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
!89 feat: 给数据库备份和恢复配置操作权限
* feat: 给数据库备份和恢复配置操作权限 * refactor: 数据库备份与恢复采用最新依赖注入机制
This commit is contained in:
@@ -62,8 +62,15 @@
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item :command="{ type: 'detail', data }"> 详情 </el-dropdown-item>
|
||||
<el-dropdown-item :command="{ type: 'dumpDb', data }" v-if="supportAction('dumpDb', data.type)"> 导出 </el-dropdown-item>
|
||||
<el-dropdown-item :command="{ type: 'dbBackup', data }" v-if="supportAction('dbBackup', data.type)"> 备份 </el-dropdown-item>
|
||||
<el-dropdown-item :command="{ type: 'dbRestore', data }" v-if="supportAction('dbRestore', data.type)"> 恢复 </el-dropdown-item>
|
||||
<el-dropdown-item :command="{ type: 'backupDb', data }" v-if="actionBtns[perms.backupDb] && supportAction('backupDb', data.type)">
|
||||
备份
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:command="{ type: 'restoreDb', data }"
|
||||
v-if="actionBtns[perms.restoreDb] && supportAction('restoreDb', data.type)"
|
||||
>
|
||||
恢复
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -193,6 +200,8 @@ const perms = {
|
||||
base: 'db',
|
||||
saveDb: 'db:save',
|
||||
delDb: 'db:del',
|
||||
backupDb: 'db:backup',
|
||||
restoreDb: 'db:restore',
|
||||
};
|
||||
|
||||
const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Db.value), SearchItem.slot('instanceId', '实例', 'instanceSelect')];
|
||||
@@ -208,7 +217,8 @@ const columns = ref([
|
||||
]);
|
||||
|
||||
// 该用户拥有的的操作列按钮权限
|
||||
const actionBtns = hasPerms([perms.base, perms.saveDb]);
|
||||
// const actionBtns = hasPerms([perms.base, perms.saveDb]);
|
||||
const actionBtns = hasPerms(Object.values(perms));
|
||||
const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(220).fixedRight().alignCenter();
|
||||
|
||||
const route = useRoute();
|
||||
@@ -345,11 +355,11 @@ const handleMoreActionCommand = (commond: any) => {
|
||||
onDumpDbs(data);
|
||||
return;
|
||||
}
|
||||
case 'dbBackup': {
|
||||
case 'backupDb': {
|
||||
onShowDbBackupDialog(data);
|
||||
return;
|
||||
}
|
||||
case 'dbRestore': {
|
||||
case 'restoreDb': {
|
||||
onShowDbRestoreDialog(data);
|
||||
return;
|
||||
}
|
||||
@@ -455,7 +465,7 @@ const supportAction = (action: string, dbType: string): boolean => {
|
||||
switch (dbType) {
|
||||
case DbType.mysql:
|
||||
case DbType.mariadb:
|
||||
actions = ['dumpDb', 'dbBackup', 'dbRestore'];
|
||||
actions = ['dumpDb', 'backupDb', 'restoreDb'];
|
||||
}
|
||||
return actions.includes(action);
|
||||
};
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
type DbBackup struct {
|
||||
DbBackupApp *application.DbBackupApp
|
||||
DbApp application.Db
|
||||
DbBackupApp *application.DbBackupApp `inject:""`
|
||||
DbApp application.Db `inject:""`
|
||||
}
|
||||
|
||||
// todo: 鉴权,避免未经授权进行数据库备份和恢复
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
)
|
||||
|
||||
type DbRestore struct {
|
||||
DbRestoreApp *application.DbRestoreApp
|
||||
DbApp application.Db
|
||||
DbRestoreApp *application.DbRestoreApp `inject:""`
|
||||
DbApp application.Db `inject:""`
|
||||
}
|
||||
|
||||
// GetPageList 获取数据库恢复任务
|
||||
|
||||
@@ -2,18 +2,11 @@ package application
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mayfly-go/internal/db/domain/repository"
|
||||
"mayfly-go/internal/db/infrastructure/persistence"
|
||||
"mayfly-go/pkg/ioc"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
dbBackupApp *DbBackupApp
|
||||
dbRestoreApp *DbRestoreApp
|
||||
dbBinlogApp *DbBinlogApp
|
||||
)
|
||||
|
||||
func InitIoc() {
|
||||
persistence.Init()
|
||||
|
||||
@@ -22,38 +15,21 @@ func InitIoc() {
|
||||
ioc.Register(new(dbSqlExecAppImpl), ioc.WithComponentName("DbSqlExecApp"))
|
||||
ioc.Register(new(dbSqlAppImpl), ioc.WithComponentName("DbSqlApp"))
|
||||
ioc.Register(new(dataSyncAppImpl), ioc.WithComponentName("DbDataSyncTaskApp"))
|
||||
|
||||
ioc.Register(newDbScheduler(), ioc.WithComponentName("DbScheduler"))
|
||||
ioc.Register(new(DbBackupApp), ioc.WithComponentName("DbBackupApp"))
|
||||
ioc.Register(new(DbRestoreApp), ioc.WithComponentName("DbRestoreApp"))
|
||||
ioc.Register(newDbBinlogApp(), ioc.WithComponentName("DbBinlogApp"))
|
||||
}
|
||||
|
||||
func Init() {
|
||||
sync.OnceFunc(func() {
|
||||
repositories := &repository.Repositories{
|
||||
Instance: persistence.GetInstanceRepo(),
|
||||
Backup: persistence.NewDbBackupRepo(),
|
||||
BackupHistory: persistence.NewDbBackupHistoryRepo(),
|
||||
Restore: persistence.NewDbRestoreRepo(),
|
||||
RestoreHistory: persistence.NewDbRestoreHistoryRepo(),
|
||||
Binlog: persistence.NewDbBinlogRepo(),
|
||||
BinlogHistory: persistence.NewDbBinlogHistoryRepo(),
|
||||
}
|
||||
var err error
|
||||
dbApp := GetDbApp()
|
||||
scheduler, err := newDbScheduler(repositories)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("初始化 dbScheduler 失败: %v", err))
|
||||
}
|
||||
dbBackupApp, err = newDbBackupApp(repositories, dbApp, scheduler)
|
||||
if err != nil {
|
||||
if err := GetDbBackupApp().Init(); err != nil {
|
||||
panic(fmt.Sprintf("初始化 dbBackupApp 失败: %v", err))
|
||||
}
|
||||
dbRestoreApp, err = newDbRestoreApp(repositories, dbApp, scheduler)
|
||||
if err != nil {
|
||||
if err := GetDbRestoreApp().Init(); err != nil {
|
||||
panic(fmt.Sprintf("初始化 dbRestoreApp 失败: %v", err))
|
||||
}
|
||||
dbBinlogApp, err = newDbBinlogApp(repositories, dbApp, scheduler)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("初始化 dbBinlogApp 失败: %v", err))
|
||||
}
|
||||
|
||||
GetDataSyncTaskApp().InitCronJob()
|
||||
})()
|
||||
}
|
||||
@@ -75,15 +51,15 @@ func GetDbSqlExecApp() DbSqlExec {
|
||||
}
|
||||
|
||||
func GetDbBackupApp() *DbBackupApp {
|
||||
return dbBackupApp
|
||||
return ioc.Get[*DbBackupApp]("DbBackupApp")
|
||||
}
|
||||
|
||||
func GetDbRestoreApp() *DbRestoreApp {
|
||||
return dbRestoreApp
|
||||
return ioc.Get[*DbRestoreApp]("DbRestoreApp")
|
||||
}
|
||||
|
||||
func GetDbBinlogApp() *DbBinlogApp {
|
||||
return dbBinlogApp
|
||||
return ioc.Get[*DbBinlogApp]("DbBinlogApp")
|
||||
}
|
||||
|
||||
func GetDataSyncTaskApp() DataSyncTask {
|
||||
|
||||
@@ -9,74 +9,67 @@ import (
|
||||
"mayfly-go/pkg/model"
|
||||
)
|
||||
|
||||
func newDbBackupApp(repositories *repository.Repositories, dbApp Db, scheduler *dbScheduler) (*DbBackupApp, error) {
|
||||
var jobs []*entity.DbBackup
|
||||
if err := repositories.Backup.ListToDo(&jobs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := scheduler.AddJob(context.Background(), false, entity.DbJobTypeBackup, jobs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
app := &DbBackupApp{
|
||||
backupRepo: repositories.Backup,
|
||||
instanceRepo: repositories.Instance,
|
||||
backupHistoryRepo: repositories.BackupHistory,
|
||||
dbApp: dbApp,
|
||||
scheduler: scheduler,
|
||||
}
|
||||
return app, nil
|
||||
type DbBackupApp struct {
|
||||
DbApp Db `inject:"DbApp"`
|
||||
Scheduler *dbScheduler `inject:"DbScheduler"`
|
||||
InstanceRepo repository.Instance `inject:"DbInstanceRepo"`
|
||||
BackupRepo repository.DbBackup `inject:"DbBackupRepo"`
|
||||
BackupHistoryRepo repository.DbBackupHistory `inject:"DbBackupHistoryRepo"`
|
||||
}
|
||||
|
||||
type DbBackupApp struct {
|
||||
backupRepo repository.DbBackup
|
||||
instanceRepo repository.Instance
|
||||
backupHistoryRepo repository.DbBackupHistory
|
||||
dbApp Db
|
||||
scheduler *dbScheduler
|
||||
func (app *DbBackupApp) Init() error {
|
||||
var jobs []*entity.DbBackup
|
||||
if err := app.BackupRepo.ListToDo(&jobs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := app.Scheduler.AddJob(context.Background(), false, entity.DbJobTypeBackup, jobs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Close() {
|
||||
app.scheduler.Close()
|
||||
app.Scheduler.Close()
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Create(ctx context.Context, jobs []*entity.DbBackup) error {
|
||||
return app.scheduler.AddJob(ctx, true /* 保存到数据库 */, entity.DbJobTypeBackup, jobs)
|
||||
return app.Scheduler.AddJob(ctx, true /* 保存到数据库 */, entity.DbJobTypeBackup, jobs)
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Update(ctx context.Context, job *entity.DbBackup) error {
|
||||
return app.scheduler.UpdateJob(ctx, job)
|
||||
return app.Scheduler.UpdateJob(ctx, job)
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Delete(ctx context.Context, jobId uint64) error {
|
||||
// todo: 删除数据库备份历史文件
|
||||
return app.scheduler.RemoveJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
return app.Scheduler.RemoveJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Enable(ctx context.Context, jobId uint64) error {
|
||||
return app.scheduler.EnableJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
return app.Scheduler.EnableJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Disable(ctx context.Context, jobId uint64) error {
|
||||
return app.scheduler.DisableJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
return app.Scheduler.DisableJob(ctx, entity.DbJobTypeBackup, jobId)
|
||||
}
|
||||
|
||||
func (app *DbBackupApp) Start(ctx context.Context, jobId uint64) error {
|
||||
return app.scheduler.StartJobNow(ctx, entity.DbJobTypeBackup, jobId)
|
||||
return app.Scheduler.StartJobNow(ctx, entity.DbJobTypeBackup, jobId)
|
||||
}
|
||||
|
||||
// GetPageList 分页获取数据库备份任务
|
||||
func (app *DbBackupApp) GetPageList(condition *entity.DbJobQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||
return app.backupRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||
return app.BackupRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||
}
|
||||
|
||||
// GetDbNamesWithoutBackup 获取未配置定时备份的数据库名称
|
||||
func (app *DbBackupApp) GetDbNamesWithoutBackup(instanceId uint64, dbNames []string) ([]string, error) {
|
||||
return app.backupRepo.GetDbNamesWithoutBackup(instanceId, dbNames)
|
||||
return app.BackupRepo.GetDbNamesWithoutBackup(instanceId, dbNames)
|
||||
}
|
||||
|
||||
// GetHistoryPageList 分页获取数据库备份历史
|
||||
func (app *DbBackupApp) GetHistoryPageList(condition *entity.DbBackupHistoryQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||
return app.backupHistoryRepo.GetHistories(condition, pageParam, toEntity, orderBy...)
|
||||
return app.BackupHistoryRepo.GetHistories(condition, pageParam, toEntity, orderBy...)
|
||||
}
|
||||
|
||||
func NewIncUUID() (uuid.UUID, error) {
|
||||
|
||||
@@ -11,32 +11,26 @@ import (
|
||||
)
|
||||
|
||||
type DbBinlogApp struct {
|
||||
binlogRepo repository.DbBinlog
|
||||
binlogHistoryRepo repository.DbBinlogHistory
|
||||
backupRepo repository.DbBackup
|
||||
backupHistoryRepo repository.DbBackupHistory
|
||||
dbApp Db
|
||||
DbApp Db `inject:"DbApp"`
|
||||
Scheduler *dbScheduler `inject:"DbScheduler"`
|
||||
BinlogRepo repository.DbBinlog `inject:"DbBinlogRepo"`
|
||||
BinlogHistoryRepo repository.DbBinlogHistory `inject:"DbBinlogHistoryRepo"`
|
||||
BackupRepo repository.DbBackup `inject:"DbBackupRepo"`
|
||||
BackupHistoryRepo repository.DbBackupHistory `inject:"DbBackupHistoryRepo"`
|
||||
context context.Context
|
||||
cancel context.CancelFunc
|
||||
waitGroup sync.WaitGroup
|
||||
scheduler *dbScheduler
|
||||
}
|
||||
|
||||
func newDbBinlogApp(repositories *repository.Repositories, dbApp Db, scheduler *dbScheduler) (*DbBinlogApp, error) {
|
||||
func newDbBinlogApp() *DbBinlogApp {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
svc := &DbBinlogApp{
|
||||
binlogRepo: repositories.Binlog,
|
||||
binlogHistoryRepo: repositories.BinlogHistory,
|
||||
backupRepo: repositories.Backup,
|
||||
backupHistoryRepo: repositories.BackupHistory,
|
||||
dbApp: dbApp,
|
||||
scheduler: scheduler,
|
||||
context: ctx,
|
||||
cancel: cancel,
|
||||
context: ctx,
|
||||
cancel: cancel,
|
||||
}
|
||||
svc.waitGroup.Add(1)
|
||||
go svc.run()
|
||||
return svc, nil
|
||||
return svc
|
||||
}
|
||||
|
||||
func (app *DbBinlogApp) run() {
|
||||
@@ -54,7 +48,7 @@ func (app *DbBinlogApp) run() {
|
||||
if app.closed() {
|
||||
break
|
||||
}
|
||||
if err := app.scheduler.AddJob(app.context, false, entity.DbJobTypeBinlog, jobs); err != nil {
|
||||
if err := app.Scheduler.AddJob(app.context, false, entity.DbJobTypeBinlog, jobs); err != nil {
|
||||
logx.Error("DbBinlogApp: 添加 BINLOG 同步任务失败: ", err.Error())
|
||||
}
|
||||
timex.SleepWithContext(app.context, entity.BinlogDownloadInterval)
|
||||
@@ -63,7 +57,7 @@ func (app *DbBinlogApp) run() {
|
||||
|
||||
func (app *DbBinlogApp) loadJobs() ([]*entity.DbBinlog, error) {
|
||||
var instanceIds []uint64
|
||||
if err := app.backupRepo.ListDbInstances(true, true, &instanceIds); err != nil {
|
||||
if err := app.BackupRepo.ListDbInstances(true, true, &instanceIds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jobs := make([]*entity.DbBinlog, 0, len(instanceIds))
|
||||
@@ -90,7 +84,7 @@ func (app *DbBinlogApp) closed() bool {
|
||||
}
|
||||
|
||||
func (app *DbBinlogApp) AddJobIfNotExists(ctx context.Context, job *entity.DbBinlog) error {
|
||||
if err := app.binlogRepo.AddJobIfNotExists(ctx, job); err != nil {
|
||||
if err := app.BinlogRepo.AddJobIfNotExists(ctx, job); err != nil {
|
||||
return err
|
||||
}
|
||||
if job.Id == 0 {
|
||||
@@ -101,7 +95,7 @@ func (app *DbBinlogApp) AddJobIfNotExists(ctx context.Context, job *entity.DbBin
|
||||
|
||||
func (app *DbBinlogApp) Delete(ctx context.Context, jobId uint64) error {
|
||||
// todo: 删除 Binlog 历史文件
|
||||
if err := app.binlogRepo.DeleteById(ctx, jobId); err != nil {
|
||||
if err := app.BinlogRepo.DeleteById(ctx, jobId); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -7,72 +7,63 @@ import (
|
||||
"mayfly-go/pkg/model"
|
||||
)
|
||||
|
||||
func newDbRestoreApp(repositories *repository.Repositories, dbApp Db, scheduler *dbScheduler) (*DbRestoreApp, error) {
|
||||
var jobs []*entity.DbRestore
|
||||
if err := repositories.Restore.ListToDo(&jobs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := scheduler.AddJob(context.Background(), false, entity.DbJobTypeRestore, jobs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
app := &DbRestoreApp{
|
||||
restoreRepo: repositories.Restore,
|
||||
instanceRepo: repositories.Instance,
|
||||
backupHistoryRepo: repositories.BackupHistory,
|
||||
restoreHistoryRepo: repositories.RestoreHistory,
|
||||
binlogHistoryRepo: repositories.BinlogHistory,
|
||||
dbApp: dbApp,
|
||||
scheduler: scheduler,
|
||||
}
|
||||
return app, nil
|
||||
type DbRestoreApp struct {
|
||||
DbApp Db `inject:"DbApp"`
|
||||
Scheduler *dbScheduler `inject:"DbScheduler"`
|
||||
InstanceRepo repository.Instance `inject:"DbInstanceRepo"`
|
||||
BackupHistoryRepo repository.DbBackupHistory `inject:"DbBackupHistoryRepo"`
|
||||
RestoreRepo repository.DbRestore `inject:"DbRestoreRepo"`
|
||||
RestoreHistoryRepo repository.DbRestoreHistory `inject:"DbRestoreHistoryRepo"`
|
||||
BinlogHistoryRepo repository.DbBinlogHistory `inject:"DbBinlogHistoryRepo"`
|
||||
}
|
||||
|
||||
type DbRestoreApp struct {
|
||||
restoreRepo repository.DbRestore
|
||||
instanceRepo repository.Instance
|
||||
backupHistoryRepo repository.DbBackupHistory
|
||||
restoreHistoryRepo repository.DbRestoreHistory
|
||||
binlogHistoryRepo repository.DbBinlogHistory
|
||||
dbApp Db
|
||||
scheduler *dbScheduler
|
||||
func (app *DbRestoreApp) Init() error {
|
||||
var jobs []*entity.DbRestore
|
||||
if err := app.RestoreRepo.ListToDo(&jobs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := app.Scheduler.AddJob(context.Background(), false, entity.DbJobTypeRestore, jobs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Close() {
|
||||
app.scheduler.Close()
|
||||
app.Scheduler.Close()
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Create(ctx context.Context, job *entity.DbRestore) error {
|
||||
return app.scheduler.AddJob(ctx, true /* 保存到数据库 */, entity.DbJobTypeRestore, job)
|
||||
return app.Scheduler.AddJob(ctx, true /* 保存到数据库 */, entity.DbJobTypeRestore, job)
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Update(ctx context.Context, job *entity.DbRestore) error {
|
||||
return app.scheduler.UpdateJob(ctx, job)
|
||||
return app.Scheduler.UpdateJob(ctx, job)
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Delete(ctx context.Context, jobId uint64) error {
|
||||
// todo: 删除数据库恢复历史文件
|
||||
return app.scheduler.RemoveJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
return app.Scheduler.RemoveJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Enable(ctx context.Context, jobId uint64) error {
|
||||
return app.scheduler.EnableJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
return app.Scheduler.EnableJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
}
|
||||
|
||||
func (app *DbRestoreApp) Disable(ctx context.Context, jobId uint64) error {
|
||||
return app.scheduler.DisableJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
return app.Scheduler.DisableJob(ctx, entity.DbJobTypeRestore, jobId)
|
||||
}
|
||||
|
||||
// GetPageList 分页获取数据库恢复任务
|
||||
func (app *DbRestoreApp) GetPageList(condition *entity.DbJobQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||
return app.restoreRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||
return app.RestoreRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||||
}
|
||||
|
||||
// GetDbNamesWithoutRestore 获取未配置定时恢复的数据库名称
|
||||
func (app *DbRestoreApp) GetDbNamesWithoutRestore(instanceId uint64, dbNames []string) ([]string, error) {
|
||||
return app.restoreRepo.GetDbNamesWithoutRestore(instanceId, dbNames)
|
||||
return app.RestoreRepo.GetDbNamesWithoutRestore(instanceId, dbNames)
|
||||
}
|
||||
|
||||
// GetHistoryPageList 分页获取数据库备份历史
|
||||
func (app *DbRestoreApp) GetHistoryPageList(condition *entity.DbRestoreHistoryQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||||
return app.restoreHistoryRepo.GetDbRestoreHistories(condition, pageParam, toEntity, orderBy...)
|
||||
return app.RestoreHistoryRepo.GetDbRestoreHistories(condition, pageParam, toEntity, orderBy...)
|
||||
}
|
||||
|
||||
@@ -21,31 +21,23 @@ const (
|
||||
type dbScheduler struct {
|
||||
mutex sync.Mutex
|
||||
runner *runner.Runner[entity.DbJob]
|
||||
dbApp Db
|
||||
backupRepo repository.DbBackup
|
||||
backupHistoryRepo repository.DbBackupHistory
|
||||
restoreRepo repository.DbRestore
|
||||
restoreHistoryRepo repository.DbRestoreHistory
|
||||
binlogRepo repository.DbBinlog
|
||||
binlogHistoryRepo repository.DbBinlogHistory
|
||||
DbApp Db `inject:"DbApp"`
|
||||
BackupRepo repository.DbBackup `inject:"DbBackupRepo"`
|
||||
BackupHistoryRepo repository.DbBackupHistory `inject:"DbBackupHistoryRepo"`
|
||||
RestoreRepo repository.DbRestore `inject:"DbRestoreRepo"`
|
||||
RestoreHistoryRepo repository.DbRestoreHistory `inject:"DbRestoreHistoryRepo"`
|
||||
BinlogRepo repository.DbBinlog `inject:"DbBinlogRepo"`
|
||||
BinlogHistoryRepo repository.DbBinlogHistory `inject:"DbBinlogHistoryRepo"`
|
||||
binlogTimes map[uint64]time.Time
|
||||
}
|
||||
|
||||
func newDbScheduler(repositories *repository.Repositories) (*dbScheduler, error) {
|
||||
scheduler := &dbScheduler{
|
||||
dbApp: GetDbApp(),
|
||||
backupRepo: repositories.Backup,
|
||||
backupHistoryRepo: repositories.BackupHistory,
|
||||
restoreRepo: repositories.Restore,
|
||||
restoreHistoryRepo: repositories.RestoreHistory,
|
||||
binlogRepo: repositories.Binlog,
|
||||
binlogHistoryRepo: repositories.BinlogHistory,
|
||||
}
|
||||
func newDbScheduler() *dbScheduler {
|
||||
scheduler := &dbScheduler{}
|
||||
scheduler.runner = runner.NewRunner[entity.DbJob](maxRunning, scheduler.runJob,
|
||||
runner.WithScheduleJob[entity.DbJob](scheduler.scheduleJob),
|
||||
runner.WithRunnableJob[entity.DbJob](scheduler.runnableJob),
|
||||
)
|
||||
return scheduler, nil
|
||||
return scheduler
|
||||
}
|
||||
|
||||
func (s *dbScheduler) scheduleJob(job entity.DbJob) (time.Time, error) {
|
||||
@@ -55,11 +47,11 @@ func (s *dbScheduler) scheduleJob(job entity.DbJob) (time.Time, error) {
|
||||
func (s *dbScheduler) repo(typ entity.DbJobType) repository.DbJob {
|
||||
switch typ {
|
||||
case entity.DbJobTypeBackup:
|
||||
return s.backupRepo
|
||||
return s.BackupRepo
|
||||
case entity.DbJobTypeRestore:
|
||||
return s.restoreRepo
|
||||
return s.RestoreRepo
|
||||
case entity.DbJobTypeBinlog:
|
||||
return s.binlogRepo
|
||||
return s.BinlogRepo
|
||||
default:
|
||||
panic(errors.New(fmt.Sprintf("无效的数据库任务类型: %v", typ)))
|
||||
}
|
||||
@@ -185,7 +177,7 @@ func (s *dbScheduler) backupMysql(ctx context.Context, job entity.DbJob) error {
|
||||
DbInstanceId: backup.DbInstanceId,
|
||||
DbName: backup.DbName,
|
||||
}
|
||||
conn, err := s.dbApp.GetDbConnByInstanceId(backup.DbInstanceId)
|
||||
conn, err := s.DbApp.GetDbConnByInstanceId(backup.DbInstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -205,7 +197,7 @@ func (s *dbScheduler) backupMysql(ctx context.Context, job entity.DbJob) error {
|
||||
history.BinlogSequence = binlogInfo.Sequence
|
||||
history.BinlogPosition = binlogInfo.Position
|
||||
|
||||
if err := s.backupHistoryRepo.Insert(ctx, history); err != nil {
|
||||
if err := s.BackupHistoryRepo.Insert(ctx, history); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -213,7 +205,7 @@ func (s *dbScheduler) backupMysql(ctx context.Context, job entity.DbJob) error {
|
||||
|
||||
func (s *dbScheduler) restoreMysql(ctx context.Context, job entity.DbJob) error {
|
||||
restore := job.(*entity.DbRestore)
|
||||
conn, err := s.dbApp.GetDbConnByInstanceId(restore.DbInstanceId)
|
||||
conn, err := s.DbApp.GetDbConnByInstanceId(restore.DbInstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -231,14 +223,14 @@ func (s *dbScheduler) restoreMysql(ctx context.Context, job entity.DbJob) error
|
||||
}
|
||||
|
||||
latestBinlogSequence, earliestBackupSequence := int64(-1), int64(-1)
|
||||
binlogHistory, ok, err := s.binlogHistoryRepo.GetLatestHistory(restore.DbInstanceId)
|
||||
binlogHistory, ok, err := s.BinlogHistoryRepo.GetLatestHistory(restore.DbInstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
latestBinlogSequence = binlogHistory.Sequence
|
||||
} else {
|
||||
backupHistory, ok, err := s.backupHistoryRepo.GetEarliestHistory(restore.DbInstanceId)
|
||||
backupHistory, ok, err := s.BackupHistoryRepo.GetEarliestHistory(restore.DbInstanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -251,7 +243,7 @@ func (s *dbScheduler) restoreMysql(ctx context.Context, job entity.DbJob) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.binlogHistoryRepo.InsertWithBinlogFiles(ctx, restore.DbInstanceId, binlogFiles); err != nil {
|
||||
if err := s.BinlogHistoryRepo.InsertWithBinlogFiles(ctx, restore.DbInstanceId, binlogFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.restorePointInTime(ctx, dbProgram, restore); err != nil {
|
||||
@@ -267,7 +259,7 @@ func (s *dbScheduler) restoreMysql(ctx context.Context, job entity.DbJob) error
|
||||
CreateTime: time.Now(),
|
||||
DbRestoreId: restore.Id,
|
||||
}
|
||||
if err := s.restoreHistoryRepo.Insert(ctx, history); err != nil {
|
||||
if err := s.RestoreHistoryRepo.Insert(ctx, history); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -338,7 +330,7 @@ func relatedToBinlog(typ entity.DbJobType) bool {
|
||||
}
|
||||
|
||||
func (s *dbScheduler) restorePointInTime(ctx context.Context, program dbi.DbProgram, job *entity.DbRestore) error {
|
||||
binlogHistory, err := s.binlogHistoryRepo.GetHistoryByTime(job.DbInstanceId, job.PointInTime.Time)
|
||||
binlogHistory, err := s.BinlogHistoryRepo.GetHistoryByTime(job.DbInstanceId, job.PointInTime.Time)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -351,7 +343,7 @@ func (s *dbScheduler) restorePointInTime(ctx context.Context, program dbi.DbProg
|
||||
Sequence: binlogHistory.Sequence,
|
||||
Position: position,
|
||||
}
|
||||
backupHistory, err := s.backupHistoryRepo.GetLatestHistory(job.DbInstanceId, job.DbName, target)
|
||||
backupHistory, err := s.BackupHistoryRepo.GetLatestHistory(job.DbInstanceId, job.DbName, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -360,7 +352,7 @@ func (s *dbScheduler) restorePointInTime(ctx context.Context, program dbi.DbProg
|
||||
Sequence: backupHistory.BinlogSequence,
|
||||
Position: backupHistory.BinlogPosition,
|
||||
}
|
||||
binlogHistories, err := s.binlogHistoryRepo.GetHistories(job.DbInstanceId, start, target)
|
||||
binlogHistories, err := s.BinlogHistoryRepo.GetHistories(job.DbInstanceId, start, target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -397,7 +389,7 @@ func (s *dbScheduler) restorePointInTime(ctx context.Context, program dbi.DbProg
|
||||
|
||||
func (s *dbScheduler) restoreBackupHistory(ctx context.Context, program dbi.DbProgram, job *entity.DbRestore) error {
|
||||
backupHistory := &entity.DbBackupHistory{}
|
||||
if err := s.backupHistoryRepo.GetById(backupHistory, job.DbBackupHistoryId); err != nil {
|
||||
if err := s.BackupHistoryRepo.GetById(backupHistory, job.DbBackupHistoryId); err != nil {
|
||||
return err
|
||||
}
|
||||
return program.RestoreBackupHistory(ctx, backupHistory.DbName, backupHistory.DbBackupId, backupHistory.Uuid)
|
||||
@@ -406,14 +398,14 @@ func (s *dbScheduler) restoreBackupHistory(ctx context.Context, program dbi.DbPr
|
||||
func (s *dbScheduler) fetchBinlogMysql(ctx context.Context, backup entity.DbJob) error {
|
||||
instanceId := backup.GetJobBase().DbInstanceId
|
||||
latestBinlogSequence, earliestBackupSequence := int64(-1), int64(-1)
|
||||
binlogHistory, ok, err := s.binlogHistoryRepo.GetLatestHistory(instanceId)
|
||||
binlogHistory, ok, err := s.BinlogHistoryRepo.GetLatestHistory(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ok {
|
||||
latestBinlogSequence = binlogHistory.Sequence
|
||||
} else {
|
||||
backupHistory, ok, err := s.backupHistoryRepo.GetEarliestHistory(instanceId)
|
||||
backupHistory, ok, err := s.BackupHistoryRepo.GetEarliestHistory(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -422,7 +414,7 @@ func (s *dbScheduler) fetchBinlogMysql(ctx context.Context, backup entity.DbJob)
|
||||
}
|
||||
earliestBackupSequence = backupHistory.BinlogSequence
|
||||
}
|
||||
conn, err := s.dbApp.GetDbConnByInstanceId(instanceId)
|
||||
conn, err := s.DbApp.GetDbConnByInstanceId(instanceId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -431,5 +423,5 @@ func (s *dbScheduler) fetchBinlogMysql(ctx context.Context, backup entity.DbJob)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.binlogHistoryRepo.InsertWithBinlogFiles(ctx, instanceId, binlogFiles)
|
||||
return s.BinlogHistoryRepo.InsertWithBinlogFiles(ctx, instanceId, binlogFiles)
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ type instanceAppImpl struct {
|
||||
}
|
||||
|
||||
// 注入DbInstanceRepo
|
||||
func (i *instanceAppImpl) InjectDbInstanceRepo(repo repository.Instance) {
|
||||
i.Repo = repo
|
||||
func (app *instanceAppImpl) InjectDbInstanceRepo(repo repository.Instance) {
|
||||
app.Repo = repo
|
||||
}
|
||||
|
||||
// GetPageList 分页获取数据库实例
|
||||
|
||||
@@ -480,7 +480,7 @@ func (svc *DbProgramMysql) GetBinlogEventPositionAtOrAfterTime(ctx context.Conte
|
||||
return posParsed, nil
|
||||
}
|
||||
}
|
||||
return 0, errors.Errorf("在 %s 之后没有 binlog 事件", targetTime.Format(time.DateTime))
|
||||
return 0, errors.Errorf("在 %s 之后没有 binlog 事件", targetTime.Local().Format(time.DateTime))
|
||||
}
|
||||
|
||||
// ReplayBinlog replays the binlog for `originDatabase` from `startBinlogInfo.Position` to `targetTs`, read binlog from `binlogDir`.
|
||||
|
||||
@@ -10,10 +10,15 @@ func Init() {
|
||||
ioc.Register(newDbRepo(), ioc.WithComponentName("DbRepo"))
|
||||
ioc.Register(newDbSqlRepo(), ioc.WithComponentName("DbSqlRepo"))
|
||||
ioc.Register(newDbSqlExecRepo(), ioc.WithComponentName("DbSqlExecRepo"))
|
||||
ioc.Register(NewDbBackupHistoryRepo(), ioc.WithComponentName("DbBackupHistoryRepo"))
|
||||
ioc.Register(NewDbRestoreHistoryRepo(), ioc.WithComponentName("DbRestoreHistoryRepo"))
|
||||
ioc.Register(newDataSyncTaskRepo(), ioc.WithComponentName("DbDataSyncTaskRepo"))
|
||||
ioc.Register(newDataSyncLogRepo(), ioc.WithComponentName("DbDataSyncLogRepo"))
|
||||
|
||||
ioc.Register(NewDbBackupRepo(), ioc.WithComponentName("DbBackupRepo"))
|
||||
ioc.Register(NewDbBackupHistoryRepo(), ioc.WithComponentName("DbBackupHistoryRepo"))
|
||||
ioc.Register(NewDbRestoreRepo(), ioc.WithComponentName("DbRestoreRepo"))
|
||||
ioc.Register(NewDbRestoreHistoryRepo(), ioc.WithComponentName("DbRestoreHistoryRepo"))
|
||||
ioc.Register(NewDbBinlogRepo(), ioc.WithComponentName("DbBinlogRepo"))
|
||||
ioc.Register(NewDbBinlogHistoryRepo(), ioc.WithComponentName("DbBinlogHistoryRepo"))
|
||||
}
|
||||
|
||||
func GetInstanceRepo() repository.Instance {
|
||||
|
||||
@@ -2,7 +2,8 @@ package router
|
||||
|
||||
import (
|
||||
"mayfly-go/internal/db/api"
|
||||
"mayfly-go/internal/db/application"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ioc"
|
||||
"mayfly-go/pkg/req"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -12,9 +13,10 @@ func InitDbBackupRouter(router *gin.RouterGroup) {
|
||||
dbs := router.Group("/dbs")
|
||||
|
||||
d := &api.DbBackup{
|
||||
DbBackupApp: application.GetDbBackupApp(),
|
||||
DbApp: application.GetDbApp(),
|
||||
//DbBackupApp: application.GetDbBackupApp(),
|
||||
//DbApp: application.GetDbApp(),
|
||||
}
|
||||
biz.ErrIsNil(ioc.Inject(d))
|
||||
|
||||
reqs := []*req.Conf{
|
||||
// 获取数据库备份任务
|
||||
|
||||
@@ -2,7 +2,8 @@ package router
|
||||
|
||||
import (
|
||||
"mayfly-go/internal/db/api"
|
||||
"mayfly-go/internal/db/application"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ioc"
|
||||
"mayfly-go/pkg/req"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -12,9 +13,10 @@ func InitDbRestoreRouter(router *gin.RouterGroup) {
|
||||
dbs := router.Group("/dbs")
|
||||
|
||||
d := &api.DbRestore{
|
||||
DbRestoreApp: application.GetDbRestoreApp(),
|
||||
DbApp: application.GetDbApp(),
|
||||
//DbRestoreApp: application.GetDbRestoreApp(),
|
||||
//DbApp: application.GetDbApp(),
|
||||
}
|
||||
biz.ErrIsNil(ioc.Inject(d))
|
||||
|
||||
reqs := []*req.Conf{
|
||||
// 获取数据库备份任务
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
ALTER TABLE `t_db_instance`
|
||||
MODIFY `port` int (8) NULL comment '数据库端口',
|
||||
MODIFY `username` varchar (255) NULL comment '数据库用户名';
|
||||
MODIFY `username` varchar (255) NULL comment '数据库用户名';
|
||||
|
||||
INSERT INTO `mayfly-go`.`t_sys_resource` (`id`, `pid`, `ui_path`, `type`, `status`, `name`, `code`, `weight`, `meta`, `creator_id`, `creator`, `modifier_id`, `modifier`, `create_time`, `update_time`, `is_deleted`, `delete_time`)
|
||||
VALUES (161, 49, 'dbms23ax/xleaiec2/3NUXQFIO/', 2, 1, '数据库备份', 'db:backup', 1705973876, 'null', 1, 'admin', 1, 'admin', '2024-01-23 09:37:56', '2024-01-23 09:37:56', 0, NULL),
|
||||
(160, 49, 'dbms23ax/xleaiec2/ghErkTdb/', 2, 1, '数据库恢复', 'db:restore', 1705973909, 'null', 1, 'admin', 1, 'admin', '2024-01-23 09:38:29', '2024-01-23 09:38:29', 0, NULL);
|
||||
|
||||
Reference in New Issue
Block a user