mirror of
				https://github.com/1Panel-dev/1Panel.git
				synced 2025-10-31 19:26:02 +08:00 
			
		
		
		
	fix: 修改数据库备份逻辑 (#2315)
This commit is contained in:
		
							parent
							
								
									40c751cde2
								
							
						
					
					
						commit
						173e3e9cc1
					
				
					 8 changed files with 79 additions and 74 deletions
				
			
		|  | @ -42,7 +42,7 @@ func (u *BackupService) MysqlBackup(req dto.CommonBackup) error { | |||
| 
 | ||||
| 	record := &model.BackupRecord{ | ||||
| 		Type:       req.Type, | ||||
| 		Name:       dirName, | ||||
| 		Name:       fmt.Sprintf("%v", database.ID), | ||||
| 		DetailName: req.DetailName, | ||||
| 		Source:     "LOCAL", | ||||
| 		BackupType: "LOCAL", | ||||
|  |  | |||
|  | @ -298,7 +298,7 @@ func (u *CronjobService) handleDatabase(cronjob model.Cronjob, backup model.Back | |||
| 		record.BackupType = backup.Type | ||||
| 
 | ||||
| 		dirName := fmt.Sprintf("%s-%s", database.From, database.Name) | ||||
| 		record.Name = dirName | ||||
| 		record.Name = fmt.Sprintf("%v", database.ID) | ||||
| 		backupDir := path.Join(localDir, fmt.Sprintf("database/%s/%s/%s", database.Type, dirName, dbInfo.Name)) | ||||
| 		record.FileName = fmt.Sprintf("db_%s_%s.sql.gz", dbInfo.Name, startTime.Format("20060102150405")) | ||||
| 		if err = handleMysqlBackup(dbInfo.DatabaseID, dbInfo.Name, backupDir, record.FileName); err != nil { | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ func Init() { | |||
| 		migrations.UpdateAppInstallResource, | ||||
| 		migrations.DropDatabaseLocal, | ||||
| 		migrations.AddDatabaseID, | ||||
| 		migrations.RemoveDatabaseUnique, | ||||
| 		migrations.UpdataBackupRecord, | ||||
| 	}) | ||||
| 	if err := m.Migrate(); err != nil { | ||||
| 		global.LOG.Error(err) | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ package migrations | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
|  | @ -571,6 +572,23 @@ var AddTableFirewall = &gormigrate.Migration{ | |||
| var AddDatabases = &gormigrate.Migration{ | ||||
| 	ID: "20230831-add-databases", | ||||
| 	Migrate: func(tx *gorm.DB) error { | ||||
| 		var ( | ||||
| 			backups   []model.BackupRecord | ||||
| 			databases []model.Database | ||||
| 		) | ||||
| 		_ = tx.Where("type = ? OR type = ?", "mysql", "mariadb").Find(&backups).Error | ||||
| 		_ = tx.Where("from = ?", "remote").Find(&databases).Error | ||||
| 		_ = tx.Where("name = ? AND address = ? AND type = ?", "local", "127.0.0.1", "mysql").Delete(&model.Database{}).Error | ||||
| 		for _, backup := range backups { | ||||
| 			for _, database := range databases { | ||||
| 				if backup.Name == database.Name && backup.Type == database.Type { | ||||
| 					_ = tx.Model(&model.BackupRecord{}).Where("id = ?", backup.ID).Updates(map[string]interface{}{ | ||||
| 						"name": fmt.Sprintf("%v", database.ID), | ||||
| 					}).Error | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		installRepo := repo.NewIAppInstallRepo() | ||||
| 		mysql := addDatabaseData("mysql", installRepo) | ||||
| 		if mysql.AppInstallID != 0 { | ||||
|  | @ -609,6 +627,21 @@ var AddDatabases = &gormigrate.Migration{ | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		_ = tx.Where("type = ? OR type = ?", "mysql", "mariadb").Find(&backups).Error | ||||
| 		_ = tx.Where("from = ?", "local").Find(&databases).Error | ||||
| 		for _, backup := range backups { | ||||
| 			if _, err := strconv.Atoi(backup.Name); err == nil { | ||||
| 				continue | ||||
| 			} | ||||
| 			for _, database := range databases { | ||||
| 				if backup.Name == database.Name && backup.Type == database.Type { | ||||
| 					_ = tx.Model(&model.BackupRecord{}).Where("id = ?", backup.ID).Updates(map[string]interface{}{ | ||||
| 						"name": fmt.Sprintf("%v", database.ID), | ||||
| 					}).Error | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}, | ||||
| } | ||||
|  | @ -627,37 +660,15 @@ var UpdateDatabase = &gormigrate.Migration{ | |||
| 			return nil | ||||
| 		} | ||||
| 		for _, data := range datas { | ||||
| 			if data.Name == "local" && data.Address == "127.0.0.1" && data.Type == "mysql" { | ||||
| 				installRepo := repo.NewIAppInstallRepo() | ||||
| 				mysqlInfo, err := installRepo.LoadBaseInfo("mysql", "") | ||||
| 				if err != nil { | ||||
| 					continue | ||||
| 				} | ||||
| 				pass, err := encrypt.StringEncrypt(data.Password) | ||||
| 				if err != nil { | ||||
| 					global.LOG.Errorf("encrypt database %s password failed, err: %v", data.Name, err) | ||||
| 					continue | ||||
| 				} | ||||
| 				if err := tx.Model(&model.Database{}).Where("id = ?", data.ID).Updates(map[string]interface{}{ | ||||
| 					"app_install_id": mysqlInfo.ID, | ||||
| 					"name":           mysqlInfo.Name, | ||||
| 					"password":       pass, | ||||
| 					"port":           service.DatabaseKeys["mysql"], | ||||
| 					"address":        mysqlInfo.ServiceName, | ||||
| 				}).Error; err != nil { | ||||
| 					global.LOG.Errorf("updata database %s info failed, err: %v", data.Name, err) | ||||
| 				} | ||||
| 			} else { | ||||
| 				pass, err := encrypt.StringEncrypt(data.Password) | ||||
| 				if err != nil { | ||||
| 					global.LOG.Errorf("encrypt database %s password failed, err: %v", data.Name, err) | ||||
| 					continue | ||||
| 				} | ||||
| 				if err := tx.Model(&model.Database{}).Where("id = ?", data.ID).Updates(map[string]interface{}{ | ||||
| 					"password": pass, | ||||
| 				}).Error; err != nil { | ||||
| 					global.LOG.Errorf("updata database %s info failed, err: %v", data.Name, err) | ||||
| 				} | ||||
| 			pass, err := encrypt.StringEncrypt(data.Password) | ||||
| 			if err != nil { | ||||
| 				global.LOG.Errorf("encrypt database %s password failed, err: %v", data.Name, err) | ||||
| 				continue | ||||
| 			} | ||||
| 			if err := tx.Model(&model.Database{}).Where("id = ?", data.ID).Updates(map[string]interface{}{ | ||||
| 				"password": pass, | ||||
| 			}).Error; err != nil { | ||||
| 				global.LOG.Errorf("updata database %s info failed, err: %v", data.Name, err) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  | @ -707,7 +718,7 @@ var DropDatabaseLocal = &gormigrate.Migration{ | |||
| var AddDatabaseID = &gormigrate.Migration{ | ||||
| 	ID: "20230914-add-database-id", | ||||
| 	Migrate: func(tx *gorm.DB) error { | ||||
| 		if err := tx.AutoMigrate(&model.DatabaseMysql{}); err != nil { | ||||
| 		if err := tx.AutoMigrate(&model.DatabaseMysql{}, &model.Database{}); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		var ( | ||||
|  | @ -735,11 +746,27 @@ var AddDatabaseID = &gormigrate.Migration{ | |||
| 	}, | ||||
| } | ||||
| 
 | ||||
| var RemoveDatabaseUnique = &gormigrate.Migration{ | ||||
| 	ID: "20230914-update-database", | ||||
| var UpdataBackupRecord = &gormigrate.Migration{ | ||||
| 	ID: "20230915-update-backup-record", | ||||
| 	Migrate: func(tx *gorm.DB) error { | ||||
| 		if err := tx.AutoMigrate(&model.Database{}); err != nil { | ||||
| 			return err | ||||
| 		var ( | ||||
| 			backups   []model.BackupRecord | ||||
| 			databases []model.Database | ||||
| 		) | ||||
| 		_ = tx.Where("type = ? OR type = ?", "mysql", "mariadb").Find(&backups).Error | ||||
| 		_ = tx.Find(&databases).Error | ||||
| 		for _, backup := range backups { | ||||
| 			if _, err := strconv.Atoi(backup.Name); err == nil { | ||||
| 				continue | ||||
| 			} | ||||
| 			for _, database := range databases { | ||||
| 				if backup.Name == database.Name && backup.Type == database.Type { | ||||
| 					_ = tx.Model(&model.BackupRecord{}).Where("id = ?", backup.ID).Updates(map[string]interface{}{ | ||||
| 						"name": fmt.Sprintf("%v", database.ID), | ||||
| 					}).Error | ||||
| 					break | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}, | ||||
|  |  | |||
|  | @ -1,7 +1,6 @@ | |||
| package client | ||||
| 
 | ||||
| import ( | ||||
| 	mathRand "math/rand" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/1Panel-dev/1Panel/backend/utils/common" | ||||
|  | @ -112,26 +111,5 @@ func randomPassword(user string) string { | |||
| 	if len(user) > 6 { | ||||
| 		passwdItem = user[:6] | ||||
| 	} | ||||
| 	num := []rune("1234567890") | ||||
| 	uppercase := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ") | ||||
| 	lowercase := []rune("abcdefghijklmnopqrstuvwxyz") | ||||
| 	special := []rune(".%@!~_-") | ||||
| 
 | ||||
| 	b := make([]rune, 10) | ||||
| 	for i := 0; i < 2; i++ { | ||||
| 		b[i] = lowercase[mathRand.Intn(len(lowercase))] | ||||
| 	} | ||||
| 	for i := 2; i < 4; i++ { | ||||
| 		b[i] = uppercase[mathRand.Intn(len(uppercase))] | ||||
| 	} | ||||
| 	b[4] = special[mathRand.Intn(len(special))] | ||||
| 	for i := 5; i < 9; i++ { | ||||
| 		b[i] = num[mathRand.Intn(len(num))] | ||||
| 	} | ||||
| 
 | ||||
| 	for i := len(b) - 1; i > 0; i-- { | ||||
| 		j := mathRand.Intn(i + 1) | ||||
| 		b[i], b[j] = b[j], b[i] | ||||
| 	} | ||||
| 	return passwdItem + "-" + (string(b)) | ||||
| 	return passwdItem + "@" + common.RandStrAndNum(8) | ||||
| } | ||||
|  |  | |||
|  | @ -3,7 +3,13 @@ | |||
|         <el-drawer v-model="backupVisiable" :destroy-on-close="true" :close-on-click-modal="false" size="50%"> | ||||
|             <template #header> | ||||
|                 <DrawerHeader | ||||
|                     v-if="detailName" | ||||
|                     v-if="type === 'mysql' || type == 'mariadb'" | ||||
|                     :header="$t('commons.button.backup')" | ||||
|                     :resource="detailName" | ||||
|                     :back="handleClose" | ||||
|                 /> | ||||
|                 <DrawerHeader | ||||
|                     v-else-if="detailName" | ||||
|                     :header="$t('commons.button.backup')" | ||||
|                     :resource="name + '(' + detailName + ')'" | ||||
|                     :back="handleClose" | ||||
|  | @ -72,18 +78,15 @@ const backupVisiable = ref(false); | |||
| const type = ref(); | ||||
| const name = ref(); | ||||
| const detailName = ref(); | ||||
| const databaseID = ref(); | ||||
| 
 | ||||
| interface DialogProps { | ||||
|     type: string; | ||||
|     name: string; | ||||
|     databaseID: string; | ||||
|     detailName: string; | ||||
| } | ||||
| const acceptParams = (params: DialogProps): void => { | ||||
|     type.value = params.type; | ||||
|     name.value = params.name; | ||||
|     databaseID.value = params.databaseID; | ||||
|     detailName.value = params.detailName; | ||||
|     backupVisiable.value = true; | ||||
|     search(); | ||||
|  | @ -106,10 +109,9 @@ const search = async () => { | |||
| }; | ||||
| 
 | ||||
| const onBackup = async () => { | ||||
|     let nameItem = type.value === 'mysql' || type.value === 'mariadb' ? databaseID.value : name.value; | ||||
|     let params = { | ||||
|         type: type.value, | ||||
|         name: nameItem, | ||||
|         name: name.value, | ||||
|         detailName: detailName.value, | ||||
|     }; | ||||
|     loading.value = true; | ||||
|  | @ -125,11 +127,10 @@ const onBackup = async () => { | |||
| }; | ||||
| 
 | ||||
| const onRecover = async (row: Backup.RecordInfo) => { | ||||
|     let nameItem = type.value === 'mysql' || type.value === 'mariadb' ? databaseID.value : name.value; | ||||
|     let params = { | ||||
|         source: row.source, | ||||
|         type: type.value, | ||||
|         name: nameItem, | ||||
|         name: name.value, | ||||
|         detailName: detailName.value, | ||||
|         file: row.fileDir + '/' + row.fileName, | ||||
|     }; | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ | |||
|                             :stroke-width="12" | ||||
|                             :percentage="uploadPrecent" | ||||
|                         ></el-progress> | ||||
|                         <div v-if="type === 'mysql'" style="width: 80%" class="el-upload__tip"> | ||||
|                         <div v-if="type === 'mysql' || type === 'mariadb'" style="width: 80%" class="el-upload__tip"> | ||||
|                             <span class="input-help">{{ $t('database.supportUpType') }}</span> | ||||
|                             <span class="input-help"> | ||||
|                                 {{ $t('database.zipFormat') }} | ||||
|  | @ -123,7 +123,7 @@ const acceptParams = async (params: DialogProps): Promise<void> => { | |||
|     detailName.value = params.detailName; | ||||
| 
 | ||||
|     const pathRes = await loadBaseDir(); | ||||
|     if (type.value === 'mysql') { | ||||
|     if (type.value === 'mysql' || type.value === 'mariadb') { | ||||
|         title.value = name.value + ' [ ' + detailName.value + ' ]'; | ||||
|     } | ||||
|     if (type.value === 'website' || type.value === 'app') { | ||||
|  |  | |||
|  | @ -529,8 +529,7 @@ const buttons = [ | |||
|         click: (row: Database.MysqlDBInfo) => { | ||||
|             let params = { | ||||
|                 type: currentDB.value.type, | ||||
|                 name: currentDB.value.from + '-' + currentDB.value.database, | ||||
|                 databaseID: currentDB.value.id + '', | ||||
|                 name: currentDB.value.id + '', | ||||
|                 detailName: row.name, | ||||
|             }; | ||||
|             dialogBackupRef.value!.acceptParams(params); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue