diff --git a/mayfly_go_web/src/views/ops/db/DbList.vue b/mayfly_go_web/src/views/ops/db/DbList.vue
index 3fa32a72..f52af841 100644
--- a/mayfly_go_web/src/views/ops/db/DbList.vue
+++ b/mayfly_go_web/src/views/ops/db/DbList.vue
@@ -80,8 +80,8 @@
 
             
                 详情
-
                 SQL执行记录
+                导出
             
 
             
@@ -180,6 +180,37 @@
             
         
 
+        
+            
+                
+                    
+                        
+                            
+                            
+                        
+                    
+                
+                
+                    
+                        
+                            
+                            
+                        
+                    
+                
+            
+
+            
+                
+                
+            
+
+            
+                取消
+                确定
+            
+        
+
          {
     state.showDumpInfo = false;
 };
 
+const onDumpDbs = async (row: any) => {
+    const dbs = row.database.split(' ');
+    const data = []
+    for (let name of dbs) {
+        data.push({
+            key: name,
+            label: name,
+        })
+    }
+    state.exportDialog.value = []
+    state.exportDialog.data = data
+    state.exportDialog.dbId = row.id;
+    state.exportDialog.contents = ["结构", "数据"]
+    state.exportDialog.extName = "sql"
+    state.exportDialog.visible = true;
+};
+
+/**
+ * 数据库信息导出
+ */
+const dumpDbs = () => {
+    isTrue(state.exportDialog.value.length > 0, '请添加要导出的数据库');
+    const a = document.createElement('a');
+    let type = 0
+    for (let c of state.exportDialog.contents) {
+        if (c == "结构") {
+            type += 1
+        } else if (c == "数据") {
+            type += 2
+        }
+    }
+    a.setAttribute(
+        'href',
+        `${config.baseApiUrl}/dbs/${state.exportDialog.dbId}/dump?db=${state.exportDialog.value.join(',')}&type=${type}&extName=${state.exportDialog.extName}&token=${getSession(
+            'token'
+        )}`
+    );
+    a.click();
+    state.exportDialog.visible = false;
+};
+
 const onShowRollbackSql = async (sqlExecLog: any) => {
     const columns = await dbApi.columnMetadata.request({ id: sqlExecLog.dbId, db: sqlExecLog.db, tableName: sqlExecLog.table });
     const primaryKey = getPrimaryKey(columns);
diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go
index 4af65bf4..83e2fea6 100644
--- a/server/internal/db/api/db.go
+++ b/server/internal/db/api/db.go
@@ -1,6 +1,7 @@
 package api
 
 import (
+	"compress/gzip"
 	"fmt"
 	"io"
 	"mayfly-go/internal/db/api/form"
@@ -32,6 +33,18 @@ type Db struct {
 	TagApp       tagapp.TagTree
 }
 
+type gzipResponseWriter struct {
+	writer *gzip.Writer
+}
+
+func (g gzipResponseWriter) WriteString(data string) {
+	g.writer.Write([]byte(data))
+}
+
+func (g gzipResponseWriter) Close() {
+	g.writer.Close()
+}
+
 const DEFAULT_ROW_SIZE = 5000
 
 // @router /api/dbs [get]
@@ -198,6 +211,10 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 			if err == io.EOF {
 				break
 			}
+			if err != nil {
+				d.MsgApp.CreateAndSend(rc.LoginAccount, ws.ErrMsg("sql脚本执行失败", fmt.Sprintf("[%s][%s] 解析SQL失败: [%s]", filename, dbConn.Info.GetLogDesc(), err.Error())))
+				return
+			}
 			sql := sqlparser.String(stmt)
 			execReq.Sql = sql
 			// 需要记录执行记录
@@ -219,38 +236,81 @@ func (d *Db) ExecSqlFile(rc *req.Ctx) {
 // 数据库dump
 func (d *Db) DumpSql(rc *req.Ctx) {
 	g := rc.GinCtx
-	db := getDbName(g)
+	dbId := getDbId(g)
+	dbNamesStr := g.Query("db")
 	dumpType := g.Query("type")
 	tablesStr := g.Query("tables")
-	biz.NotEmpty(tablesStr, "请选择要导出的表")
-	tables := strings.Split(tablesStr, ",")
+	extName := g.Query("extName")
+	switch extName {
+	case ".gz", ".gzip", "gz", "gzip":
+		extName = ".gz"
+	default:
+		extName = ""
+	}
 
 	// 是否需要导出表结构
 	needStruct := dumpType == "1" || dumpType == "3"
 	// 是否需要导出数据
 	needData := dumpType == "2" || dumpType == "3"
 
-	dbInstance := d.getDbConnection(rc.GinCtx)
-	biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, dbInstance.Info.TagPath), "%s")
+	db := d.DbApp.GetById(dbId)
+	biz.ErrIsNilAppendErr(d.TagApp.CanAccess(rc.LoginAccount.Id, db.TagPath), "%s")
 
 	now := time.Now()
-	filename := fmt.Sprintf("%s.%s.sql", db, now.Format("200601021504"))
+	filename := fmt.Sprintf("%s.%s.sql%s", db.Name, now.Format("20060102150405"), extName)
 	g.Header("Content-Type", "application/octet-stream")
 	g.Header("Content-Disposition", "attachment; filename="+filename)
+	if extName != ".gz" {
+		g.Header("Content-Encoding", "gzip")
+	}
 
-	writer := g.Writer
+	var dbNames, tables []string
+	if len(dbNamesStr) > 0 {
+		dbNames = strings.Split(dbNamesStr, ",")
+	}
+	if len(dbNames) == 1 && len(tablesStr) > 0 {
+		tables = strings.Split(tablesStr, ",")
+	}
+
+	writer := gzipResponseWriter{writer: gzip.NewWriter(g.Writer)}
+	defer writer.Close()
+	for _, dbName := range dbNames {
+		d.dumpDb(writer, dbId, dbName, tables, needStruct, needData, len(dbNames) > 1)
+	}
+
+	rc.ReqParam = fmt.Sprintf("DB[id=%d, tag=%s, name=%s, databases=%s, tables=%s, dumpType=%s]", db.Id, db.TagPath, db.Name, dbNamesStr, tablesStr, dumpType)
+}
+
+func (d *Db) dumpDb(writer gzipResponseWriter, dbId uint64, dbName string, tables []string, needStruct bool, needData bool, switchDb bool) {
+	dbConn := d.DbApp.GetDbConnection(dbId, dbName)
 	writer.WriteString("-- ----------------------------")
 	writer.WriteString("\n-- 导出平台: mayfly-go")
-	writer.WriteString(fmt.Sprintf("\n-- 导出时间: %s ", now.Format("2006-01-02 15:04:05")))
-	writer.WriteString(fmt.Sprintf("\n-- 导出数据库: %s ", db))
+	writer.WriteString(fmt.Sprintf("\n-- 导出时间: %s ", time.Now().Format("2006-01-02 15:04:05")))
+	writer.WriteString(fmt.Sprintf("\n-- 导出数据库: %s ", dbName))
 	writer.WriteString("\n-- ----------------------------\n")
 
-	dbmeta := d.getDbConnection(rc.GinCtx).GetMeta()
+	if switchDb {
+		switch dbConn.Info.Type {
+		case entity.DbTypeMysql:
+			writer.WriteString(fmt.Sprintf("use `%s`;\n", dbName))
+		default:
+			biz.IsTrue(false, "数据库类型必须为 %s", entity.DbTypeMysql)
+		}
+	}
+	dbMeta := dbConn.GetMeta()
+	if len(tables) == 0 {
+		ti := dbMeta.GetTableInfos()
+		tables = make([]string, len(ti))
+		for i, table := range ti {
+			tables[i] = table.TableName
+		}
+	}
+
 	for _, table := range tables {
 		if needStruct {
 			writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表结构: %s \n-- ----------------------------\n", table))
 			writer.WriteString(fmt.Sprintf("DROP TABLE IF EXISTS `%s`;\n", table))
-			writer.WriteString(dbmeta.GetCreateTableDdl(table) + ";\n")
+			writer.WriteString(dbMeta.GetCreateTableDdl(table) + ";\n")
 		}
 
 		if !needData {
@@ -262,7 +322,7 @@ func (d *Db) DumpSql(rc *req.Ctx) {
 
 		pageNum := 1
 		for {
-			columns, result, _ := dbmeta.GetTableRecord(table, pageNum, DEFAULT_ROW_SIZE)
+			columns, result, _ := dbMeta.GetTableRecord(table, pageNum, DEFAULT_ROW_SIZE)
 			resultLen := len(result)
 			if resultLen == 0 {
 				break
@@ -293,8 +353,6 @@ func (d *Db) DumpSql(rc *req.Ctx) {
 
 		writer.WriteString("COMMIT;\n")
 	}
-
-	rc.ReqParam = fmt.Sprintf("%s, tables: %s, dumpType: %s", dbInstance.Info.GetLogDesc(), tablesStr, dumpType)
 }
 
 // @router /api/db/:dbId/t-metadata [get]
diff --git a/server/internal/db/application/db.go b/server/internal/db/application/db.go
index 4dfcd067..74af778e 100644
--- a/server/internal/db/application/db.go
+++ b/server/internal/db/application/db.go
@@ -147,7 +147,7 @@ func (d *dbAppImpl) GetDbConnection(dbId uint64, dbName string) *DbConnection {
 
 	db := d.GetById(dbId)
 	biz.NotNil(db, "数据库信息不存在")
-	biz.IsTrue(strings.Contains(" "+db.Database+" ", " "+dbName+" "), "未配置该库的操作权限")
+	biz.IsTrue(strings.Contains(" "+db.Database+" ", " "+dbName+" "), "未配置数据库【%s】的操作权限", dbName)
 
 	instance := d.dbInstanceApp.GetById(db.InstanceId)
 	// 密码解密
diff --git a/server/internal/db/application/mysql_meta.go b/server/internal/db/application/mysql_meta.go
index 3d5808e0..8749e02a 100644
--- a/server/internal/db/application/mysql_meta.go
+++ b/server/internal/db/application/mysql_meta.go
@@ -152,7 +152,8 @@ func (mm *MysqlMetadata) GetTableIndex(tableName string) []Index {
 
 // 获取建表ddl
 func (mm *MysqlMetadata) GetCreateTableDdl(tableName string) string {
-	_, res, _ := mm.di.SelectData(fmt.Sprintf("show create table %s ", tableName))
+	_, res, err := mm.di.SelectData(fmt.Sprintf("show create table `%s` ", tableName))
+	biz.ErrIsNilAppendErr(err, "获取表结构失败: %s")
 	return res[0]["Create Table"].(string)
 }