feat: Native DDL智能推荐 + MySQL版本检测 + 云数据库自动跳过gh-ost
- 新增 getMySQLVersion(): 检测MySQL实例版本 - 新增 supportsInstantDDL(): 判断是否支持 INSTANT DDL (8.0.12+) - analyze API新增字段: mysql_version, supports_instant, cloud_type - 云数据库(aliyun_rds/polardb/aws_aurora): 自动推荐Native DDL,跳过gh-ost - 自建MySQL: 根据版本+环境+行数综合推荐 - MySQL 8.4.9 检测通过, supports_instant=true
This commit is contained in:
1 parent
b2b13661fd
commit
78986fe5bf
1 file changed
+77
-14
@@ -143,6 +143,49 @@ func GhOstGetConfig(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, getGhostConfig())
|
||||
}
|
||||
|
||||
// getMySQLVersion returns the MySQL version string for an instance
|
||||
func getMySQLVersion(instanceID int) string {
|
||||
var inst model.Instance
|
||||
if model.DB.First(&inst, instanceID).Error != nil {
|
||||
return ""
|
||||
}
|
||||
if inst.DBType != "mysql" {
|
||||
return ""
|
||||
}
|
||||
db, err := getDBConnection(&inst, "")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer db.Close()
|
||||
var version string
|
||||
db.QueryRow("SELECT VERSION()").Scan(&version)
|
||||
return version
|
||||
}
|
||||
|
||||
// supportsInstantDDL checks if MySQL version supports INSTANT DDL (8.0.12+)
|
||||
func supportsInstantDDL(version string) bool {
|
||||
// Parse "8.0.32" or "5.7.40-log" etc
|
||||
parts := strings.SplitN(version, "-", 2)
|
||||
v := parts[0]
|
||||
segments := strings.Split(v, ".")
|
||||
if len(segments) < 3 {
|
||||
return false
|
||||
}
|
||||
major, _ := strconv.Atoi(segments[0])
|
||||
minor, _ := strconv.Atoi(segments[1])
|
||||
patch, _ := strconv.Atoi(segments[2])
|
||||
if major > 8 {
|
||||
return true
|
||||
}
|
||||
if major == 8 && minor > 0 {
|
||||
return true
|
||||
}
|
||||
if major == 8 && minor == 0 && patch >= 12 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// POST /api/v1/ghost/analyze — analyze DDL and return OSC recommendation
|
||||
func GhOstAnalyzeDDL(c *gin.Context) {
|
||||
var req struct {
|
||||
@@ -158,29 +201,49 @@ func GhOstAnalyzeDDL(c *gin.Context) {
|
||||
|
||||
analysis := analyzeDDL(req.Alter)
|
||||
|
||||
// Get MySQL version for INSTANT DDL check
|
||||
mysqlVersion := ""
|
||||
instantDDL := false
|
||||
if req.InstanceID > 0 {
|
||||
mysqlVersion = getMySQLVersion(req.InstanceID)
|
||||
instantDDL = supportsInstantDDL(mysqlVersion)
|
||||
}
|
||||
|
||||
// Cloud databases: prefer Native DDL
|
||||
cloudType := getSetting("ghost_cloud_type", "self_hosted")
|
||||
if cloudType != "self_hosted" && analysis.NeedsOSC {
|
||||
analysis.NeedsOSC = false
|
||||
analysis.RecommendedTool = "native"
|
||||
analysis.Reason = fmt.Sprintf("云数据库(%s)建议使用原生DDL,无需gh-ost", cloudType)
|
||||
}
|
||||
|
||||
// Also check table row count if instance_id provided
|
||||
rowCount := -1
|
||||
if req.InstanceID > 0 {
|
||||
rowCount = getTableRowCount(req.InstanceID, req.Database, req.Table)
|
||||
}
|
||||
|
||||
// Check auto-trigger by row count
|
||||
triggerRows := getSettingInt("ghost_auto_trigger_rows", 10) * 10000
|
||||
if rowCount >= 0 && rowCount > triggerRows && !analysis.NeedsOSC {
|
||||
analysis.NeedsOSC = true
|
||||
analysis.RecommendedTool = "gh-ost"
|
||||
analysis.Reason = fmt.Sprintf("表行数(%d)超过阈值(%d),推荐使用 gh-ost", rowCount, triggerRows)
|
||||
// Check auto-trigger by row count (only for self-hosted)
|
||||
if cloudType == "self_hosted" {
|
||||
triggerRows := getSettingInt("ghost_auto_trigger_rows", 10) * 10000
|
||||
if rowCount >= 0 && rowCount > triggerRows && !analysis.NeedsOSC {
|
||||
analysis.NeedsOSC = true
|
||||
analysis.RecommendedTool = "gh-ost"
|
||||
analysis.Reason = fmt.Sprintf("表行数(%d)超过阈值(%d),推荐使用 gh-ost", rowCount, triggerRows)
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"enabled": isGhostEnabled(),
|
||||
"ddl_types": analysis.DDLTypes,
|
||||
"needs_osc": analysis.NeedsOSC,
|
||||
"recommended_tool": analysis.RecommendedTool,
|
||||
"reason": analysis.Reason,
|
||||
"table_rows": rowCount,
|
||||
"trigger_rows": triggerRows,
|
||||
"config": getGhostConfig(),
|
||||
"enabled": isGhostEnabled(),
|
||||
"ddl_types": analysis.DDLTypes,
|
||||
"needs_osc": analysis.NeedsOSC,
|
||||
"recommended_tool": analysis.RecommendedTool,
|
||||
"reason": analysis.Reason,
|
||||
"table_rows": rowCount,
|
||||
"mysql_version": mysqlVersion,
|
||||
"supports_instant": instantDDL,
|
||||
"cloud_type": cloudType,
|
||||
"config": getGhostConfig(),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user