From 316945888f58bd1fea5d3fd634c0e6a76f8d69d2 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Mon, 3 Mar 2025 07:07:16 +0000 Subject: [PATCH 1/8] =?UTF-8?q?update=20actions/schema=5Ftab=5Fstruct.go.?= =?UTF-8?q?=20=E5=AF=B9=E7=BB=84=E5=90=88=E7=B4=A2=E5=BC=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=88=A4=E6=96=AD=E5=92=8C=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: david058 <371369527@qq.com> --- actions/schema_tab_struct.go | 37 +++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/actions/schema_tab_struct.go b/actions/schema_tab_struct.go index 74684ae..0aec374 100644 --- a/actions/schema_tab_struct.go +++ b/actions/schema_tab_struct.go @@ -278,7 +278,7 @@ func (stcls *schemaTable) TableColumnNameCheck(checkTableList []string, logThrea if err = ApplyDataFix(sqlS, stcls.datefix, stcls.sfile, stcls.destDrive, stcls.djdbc, logThreadSeq); err != nil { return nil, nil, err } - vlog = fmt.Sprintf("(%d) %s Target side %s table %s repair statement application is completed.", logThreadSeq, event, stcls.destDrive, v) + vlog = fmt.Sprintf("(%d) Target side %s table %s repair statement application is completed.", logThreadSeq, event, stcls.destDrive, v) global.Wlog.Debug(vlog) } } @@ -1065,17 +1065,52 @@ func (stcls *schemaTable) Index(dtabS []string, logThreadSeq, logThreadSeq2 int6 event string indexGenerate = func(smu, dmu map[string][]string, a *CheckSumTypeStruct, indexType string) []string { var cc, c, d []string + + // 首先比较索引名称 for k, _ := range smu { c = append(c, k) } for k, _ := range dmu { d = append(d, k) } + + // 如果索引名称不同,生成修复SQL if a.CheckMd5(strings.Join(c, ",")) != a.CheckMd5(strings.Join(d, ",")) { e, f := a.Arrcmp(c, d) dbf := dbExec.DataAbnormalFixStruct{Schema: stcls.schema, Table: stcls.table, SourceDevice: stcls.sourceDrive, DestDevice: stcls.destDrive, IndexType: indexType, DatafixType: stcls.datefix} cc = dbf.DataAbnormalFix().FixAlterIndexSqlExec(e, f, smu, stcls.sourceDrive, logThreadSeq) + } else { + // 即使索引名称相同,也要比较索引的具体内容 + for k, sColumns := range smu { + if dColumns, exists := dmu[k]; exists { + // 比较同名索引的列及其顺序 + if a.CheckMd5(strings.Join(sColumns, ",")) != a.CheckMd5(strings.Join(dColumns, ",")) { + // 索引内容不同,需要先删除旧索引,再创建新索引 + dbf := dbExec.DataAbnormalFixStruct{ + Schema: stcls.schema, + Table: stcls.table, + SourceDevice: stcls.sourceDrive, + DestDevice: stcls.destDrive, + IndexType: indexType, + DatafixType: stcls.datefix, + } + + // 1. 先生成删除旧索引的SQL + // 注意:PRIMARY KEY需要特殊处理,不能直接DROP + if indexType == "pri" { + cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` DROP PRIMARY KEY;", stcls.schema, stcls.table)) + } else { + cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` DROP INDEX `%s`;", stcls.schema, stcls.table, k)) + } + + // 2. 再生成创建新索引的SQL + indexDiff := map[string][]string{k: sColumns} + cc = append(cc, dbf.DataAbnormalFix().FixAlterIndexSqlExec([]string{k}, []string{}, indexDiff, stcls.sourceDrive, logThreadSeq)...) + } + } + } } + return cc } ) -- Gitee From e1a3fa3768e3b9ba481d39e25b9079e4addbc9f2 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Mon, 3 Mar 2025 07:28:44 +0000 Subject: [PATCH 2/8] =?UTF-8?q?update=20MySQL/my=5Fquery=5Ftable=5Fdate.go?= =?UTF-8?q?.=20=20=20=E5=AF=B9=E4=BA=8E=E7=BB=84=E5=90=88=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E9=99=A4=E4=BA=86=E7=B4=A2=E5=BC=95=E5=90=8D=EF=BC=8C?= =?UTF-8?q?=E8=BF=98=E8=BF=94=E5=9B=9E=E5=88=97=E5=90=8D=E5=92=8C=E5=88=97?= =?UTF-8?q?=E5=9C=A8=E7=B4=A2=E5=BC=95=E9=A1=BA=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: david058 <371369527@qq.com> --- MySQL/my_query_table_date.go | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/MySQL/my_query_table_date.go b/MySQL/my_query_table_date.go index 241ce94..412d283 100644 --- a/MySQL/my_query_table_date.go +++ b/MySQL/my_query_table_date.go @@ -19,7 +19,7 @@ func (my *QueryTable) QueryTableIndexColumnInfo(db *sql.DB, logThreadSeq int64) tableData []map[string]interface{} err error ) - strsql = fmt.Sprintf("select isc.COLUMN_NAME as columnName,isc.COLUMN_TYPE as columnType,isc.COLUMN_KEY as columnKey,isc.EXTRA as autoIncrement,iss.NON_UNIQUE as nonUnique,iss.INDEX_NAME as indexName,iss.SEQ_IN_INDEX IndexSeq,isc.ORDINAL_POSITION columnSeq from information_schema.columns isc inner join (select NON_UNIQUE,INDEX_NAME,SEQ_IN_INDEX,COLUMN_NAME from information_schema.STATISTICS where table_schema='%s' and table_name='%s') as iss on isc.column_name =iss.column_name where isc.table_schema='%s' and isc.table_name='%s';", my.Schema, my.Table, my.Schema, my.Table) + strsql = fmt.Sprintf("select isc.COLUMN_NAME as columnName,isc.COLUMN_TYPE as columnType,isc.COLUMN_KEY as columnKey,isc.EXTRA as autoIncrement,iss.NON_UNIQUE as nonUnique,iss.INDEX_NAME as indexName,iss.SEQ_IN_INDEX as IndexSeq,isc.ORDINAL_POSITION as columnSeq from information_schema.columns isc inner join (select NON_UNIQUE,INDEX_NAME,SEQ_IN_INDEX,COLUMN_NAME from information_schema.STATISTICS where table_schema='%s' and table_name='%s') as iss on isc.column_name =iss.column_name where isc.table_schema='%s' and isc.table_name='%s';", my.Schema, my.Table, my.Schema, my.Table) vlog = fmt.Sprintf("(%d) [%s] Generate a sql statement to query the index statistics of table %s.%s under the %s database.sql messige is {%s}", logThreadSeq, Event, my.Schema, my.Table, DBType, strsql) global.Wlog.Debug(vlog) dispos := dataDispos.DBdataDispos{DBType: DBType, LogThreadSeq: logThreadSeq, Event: Event, DB: db} @@ -62,14 +62,14 @@ func (my *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThread if currIndexName != indexName { indexName = currIndexName } - PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s", v["columnName"])) + PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s:%s", v["columnName"], v["IndexSeq"])) priIndexColumnMap["pri"] = PriIndexCol } else { if currIndexName != indexName { indexName = currIndexName - nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } else { - nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } } } @@ -77,14 +77,31 @@ func (my *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThread if v["nonUnique"].(string) != "0" { if currIndexName != indexName { indexName = currIndexName - multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } else { - multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } } } vlog = fmt.Sprintf("(%d) [%s] The index information screening of the specified table %s.%s under the %s library is completed", logThreadSeq, Event, my.Schema, my.Table, DBType) global.Wlog.Debug(vlog) + + // Log the values of the maps + if priVal, ok := priIndexColumnMap["pri"]; ok { + vlog = fmt.Sprintf("(%d) [%s] Primary index columns: %v", logThreadSeq, Event, priVal) + global.Wlog.Debug(vlog) + } + + for idxName, columns := range nultiseriateIndexColumnMap { + vlog = fmt.Sprintf("(%d) [%s] Unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) + global.Wlog.Debug(vlog) + } + + for idxName, columns := range multiseriateIndexColumnMap { + vlog = fmt.Sprintf("(%d) [%s] Non-unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) + global.Wlog.Debug(vlog) + } + return priIndexColumnMap, nultiseriateIndexColumnMap, multiseriateIndexColumnMap } -- Gitee From 63ac436efa8a4c1315e53a2baf14551851c8ce9d Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Mon, 3 Mar 2025 07:30:30 +0000 Subject: [PATCH 3/8] =?UTF-8?q?update=20Oracle/or=5Fquery=5Ftable=5Fdate.g?= =?UTF-8?q?o.=20=E5=A2=9E=E5=8A=A0=E5=AF=B9=E7=BB=84=E5=90=88=E7=B4=A2?= =?UTF-8?q?=E5=BC=95=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: david058 <371369527@qq.com> --- Oracle/or_query_table_date.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Oracle/or_query_table_date.go b/Oracle/or_query_table_date.go index fbf5f7c..86a8fb9 100644 --- a/Oracle/or_query_table_date.go +++ b/Oracle/or_query_table_date.go @@ -62,14 +62,14 @@ func (or *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThread if currIndexName != indexName { indexName = currIndexName } - PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s", v["columnName"])) + PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s:%s", v["columnName"], v["IndexSeq"])) priIndexColumnMap["pri"] = PriIndexCol } else { if currIndexName != indexName { indexName = currIndexName - nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } else { - nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } } } @@ -77,9 +77,9 @@ func (or *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThread if v["nonUnique"].(string) == "NONUNIQUE" { if currIndexName != indexName { indexName = currIndexName - multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } else { - multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s /*actions Column Type*/ %s", v["columnName"], v["columnType"])) + multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) } } } -- Gitee From 20e4a94028544139392b83259da6d82fd450e429 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Mon, 3 Mar 2025 07:36:11 +0000 Subject: [PATCH 4/8] =?UTF-8?q?update=20MySQL/my=5Fquery=5Ftable=5Fdate.go?= =?UTF-8?q?.=20=E6=B3=A8=E9=87=8A=E4=B8=80=E4=BA=9Blog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: david058 <371369527@qq.com> --- MySQL/my_query_table_date.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/MySQL/my_query_table_date.go b/MySQL/my_query_table_date.go index 412d283..47c37fd 100644 --- a/MySQL/my_query_table_date.go +++ b/MySQL/my_query_table_date.go @@ -87,20 +87,20 @@ func (my *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThread global.Wlog.Debug(vlog) // Log the values of the maps - if priVal, ok := priIndexColumnMap["pri"]; ok { - vlog = fmt.Sprintf("(%d) [%s] Primary index columns: %v", logThreadSeq, Event, priVal) - global.Wlog.Debug(vlog) - } + // if priVal, ok := priIndexColumnMap["pri"]; ok { + // vlog = fmt.Sprintf("(%d) [%s] Primary index columns: %v", logThreadSeq, Event, priVal) + // global.Wlog.Debug(vlog) + // } - for idxName, columns := range nultiseriateIndexColumnMap { - vlog = fmt.Sprintf("(%d) [%s] Unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) - global.Wlog.Debug(vlog) - } + // for idxName, columns := range nultiseriateIndexColumnMap { + // vlog = fmt.Sprintf("(%d) [%s] Unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) + // global.Wlog.Debug(vlog) + // } - for idxName, columns := range multiseriateIndexColumnMap { - vlog = fmt.Sprintf("(%d) [%s] Non-unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) - global.Wlog.Debug(vlog) - } + // for idxName, columns := range multiseriateIndexColumnMap { + // vlog = fmt.Sprintf("(%d) [%s] Non-unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) + // global.Wlog.Debug(vlog) + // } return priIndexColumnMap, nultiseriateIndexColumnMap, multiseriateIndexColumnMap } -- Gitee From 188440342fd8e4dd7a5f6014850c7167058ca521 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Mon, 3 Mar 2025 07:54:50 +0000 Subject: [PATCH 5/8] update actions/schema_tab_struct.go. Signed-off-by: david058 <371369527@qq.com> --- actions/schema_tab_struct.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/schema_tab_struct.go b/actions/schema_tab_struct.go index 0aec374..c1df633 100644 --- a/actions/schema_tab_struct.go +++ b/actions/schema_tab_struct.go @@ -278,7 +278,7 @@ func (stcls *schemaTable) TableColumnNameCheck(checkTableList []string, logThrea if err = ApplyDataFix(sqlS, stcls.datefix, stcls.sfile, stcls.destDrive, stcls.djdbc, logThreadSeq); err != nil { return nil, nil, err } - vlog = fmt.Sprintf("(%d) Target side %s table %s repair statement application is completed.", logThreadSeq, event, stcls.destDrive, v) + vlog = fmt.Sprintf("(%d) %s Target side %s table %s repair statement application is completed.", logThreadSeq, event, stcls.destDrive, v) global.Wlog.Debug(vlog) } } -- Gitee From e9bb5ec559c171257c1c43cbc2d24ae6c5cae529 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Tue, 4 Mar 2025 03:24:24 +0000 Subject: [PATCH 6/8] =?UTF-8?q?update=20actions/schema=5Ftab=5Fstruct.go?= =?UTF-8?q?=20=20=20=20=E7=B4=A2=E5=BC=95=E5=90=8D=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=EF=BC=8C=E7=BB=84=E5=90=88=E7=B4=A2=E5=BC=95=E4=B8=AD=E5=88=97?= =?UTF-8?q?=E9=A1=BA=E5=BA=8F=E4=B8=8D=E5=90=8C=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E7=B4=A2=E5=BC=95=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: david058 <371369527@qq.com> --- actions/schema_tab_struct.go | 115 ++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 22 deletions(-) diff --git a/actions/schema_tab_struct.go b/actions/schema_tab_struct.go index c1df633..2661f89 100644 --- a/actions/schema_tab_struct.go +++ b/actions/schema_tab_struct.go @@ -8,6 +8,8 @@ import ( "gt-checksum/global" "gt-checksum/inputArg" "os" + "sort" + "strconv" "strings" ) @@ -1063,57 +1065,109 @@ func (stcls *schemaTable) Index(dtabS []string, logThreadSeq, logThreadSeq2 int6 sqlS []string aa = &CheckSumTypeStruct{} event string + // 辅助函数:提取列名和序号 + extractColumnInfo = func(columnStr string) (string, int) { + // 从格式 "columnName/*seq*/1/*type*/columnType" 中提取信息 + parts := strings.Split(columnStr, "/*seq*/") + colName := strings.TrimSpace(parts[0]) + seqStr := strings.Split(parts[1], "/*type*/")[0] + seq, _ := strconv.Atoi(seqStr) + return colName, seq + } + + // 辅助函数:按序号排序列并返回纯列名 + sortColumns = func(columns []string) []string { + type ColumnInfo struct { + name string + seq int + } + var columnInfos []ColumnInfo + + // 提取列信息 + for _, col := range columns { + name, seq := extractColumnInfo(col) + columnInfos = append(columnInfos, ColumnInfo{name: name, seq: seq}) + } + + // 按序号排序 + sort.Slice(columnInfos, func(i, j int) bool { + return columnInfos[i].seq < columnInfos[j].seq + }) + + // 返回排序后的纯列名 + var result []string + for _, col := range columnInfos { + result = append(result, fmt.Sprintf("%s", col.name)) + } + return result + } + indexGenerate = func(smu, dmu map[string][]string, a *CheckSumTypeStruct, indexType string) []string { var cc, c, d []string + dbf := dbExec.DataAbnormalFixStruct{ + Schema: stcls.schema, + Table: stcls.table, + SourceDevice: stcls.sourceDrive, + DestDevice: stcls.destDrive, + IndexType: indexType, + DatafixType: stcls.datefix, + } // 首先比较索引名称 - for k, _ := range smu { + for k := range smu { c = append(c, k) } - for k, _ := range dmu { + for k := range dmu { d = append(d, k) } // 如果索引名称不同,生成修复SQL if a.CheckMd5(strings.Join(c, ",")) != a.CheckMd5(strings.Join(d, ",")) { e, f := a.Arrcmp(c, d) - dbf := dbExec.DataAbnormalFixStruct{Schema: stcls.schema, Table: stcls.table, SourceDevice: stcls.sourceDrive, DestDevice: stcls.destDrive, IndexType: indexType, DatafixType: stcls.datefix} - cc = dbf.DataAbnormalFix().FixAlterIndexSqlExec(e, f, smu, stcls.sourceDrive, logThreadSeq) + // 对于新增的索引,需要处理列顺序 + newIndexMap := make(map[string][]string) + for _, idx := range e { + if cols, ok := smu[idx]; ok { + // 对列进行排序并去除序号信息 + newIndexMap[idx] = sortColumns(cols) + } + } + cc = dbf.DataAbnormalFix().FixAlterIndexSqlExec(e, f, newIndexMap, stcls.sourceDrive, logThreadSeq) } else { // 即使索引名称相同,也要比较索引的具体内容 for k, sColumns := range smu { if dColumns, exists := dmu[k]; exists { - // 比较同名索引的列及其顺序 + // 比较同名索引的列及其顺序(包含序号信息的比较) if a.CheckMd5(strings.Join(sColumns, ",")) != a.CheckMd5(strings.Join(dColumns, ",")) { - // 索引内容不同,需要先删除旧索引,再创建新索引 - dbf := dbExec.DataAbnormalFixStruct{ - Schema: stcls.schema, - Table: stcls.table, - SourceDevice: stcls.sourceDrive, - DestDevice: stcls.destDrive, - IndexType: indexType, - DatafixType: stcls.datefix, - } - // 1. 先生成删除旧索引的SQL - // 注意:PRIMARY KEY需要特殊处理,不能直接DROP if indexType == "pri" { cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` DROP PRIMARY KEY;", stcls.schema, stcls.table)) } else { cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` DROP INDEX `%s`;", stcls.schema, stcls.table, k)) } - // 2. 再生成创建新索引的SQL - indexDiff := map[string][]string{k: sColumns} - cc = append(cc, dbf.DataAbnormalFix().FixAlterIndexSqlExec([]string{k}, []string{}, indexDiff, stcls.sourceDrive, logThreadSeq)...) + // 2. 获取排序后的纯列名 + sortedColumns := sortColumns(sColumns) + + // 3. 生成创建索引的SQL + if indexType == "pri" { + cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` ADD PRIMARY KEY(%s);", + stcls.schema, stcls.table, strings.Join(sortedColumns, ","))) + } else if indexType == "uni" { + cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` ADD UNIQUE INDEX `%s`(%s);", + stcls.schema, stcls.table, k, strings.Join(sortedColumns, ","))) + } else { + cc = append(cc, fmt.Sprintf("ALTER TABLE `%s`.`%s` ADD INDEX `%s`(%s);", + stcls.schema, stcls.table, k, strings.Join(sortedColumns, ","))) + } } } } } - return cc } ) + fmt.Println("-- gt-checksum checksum table index info -- ") event = fmt.Sprintf("[%s]", "check_table_index") //校验索引 @@ -1132,7 +1186,15 @@ func (stcls *schemaTable) Index(dtabS []string, logThreadSeq, logThreadSeq2 int6 return err } spri, suni, smul := idxc.TableIndexColumn().IndexDisposF(squeryData, logThreadSeq2) - vlog = fmt.Sprintf("(%d) %s The index column data of the source %s database table %s is {primary:%v,unique key:%v,index key:%v}", logThreadSeq, event, stcls.sourceDrive, i, spri, suni, smul) + vlog = fmt.Sprintf("(%d) %s The index column data of the source %s database table %s.%s is {primary:%v,unique key:%v,index key:%v}", + logThreadSeq, + event, + stcls.sourceDrive, + stcls.schema, + stcls.table, + spri, + suni, + smul) global.Wlog.Debug(vlog) idxc.Drivce = stcls.destDrive @@ -1145,12 +1207,21 @@ func (stcls *schemaTable) Index(dtabS []string, logThreadSeq, logThreadSeq2 int6 return err } dpri, duni, dmul := idxc.TableIndexColumn().IndexDisposF(dqueryData, logThreadSeq2) - vlog = fmt.Sprintf("(%d) %s The index column data of the source %s database table %s is {primary:%v,unique key:%v,index key:%v}", logThreadSeq, event, stcls.destDrive, i, dpri, duni, dmul) + vlog = fmt.Sprintf("(%d) %s The index column data of the dest %s database table %s.%s is {primary:%v,unique key:%v,index key:%v}", + logThreadSeq, + event, + stcls.destDrive, + stcls.schema, + stcls.table, + dpri, + duni, + dmul) global.Wlog.Debug(vlog) var pods = Pod{ Datafix: stcls.datefix, CheckObject: "Index", + Differences: "no", Schema: stcls.schema, Table: stcls.table, -- Gitee From ce3a38dc7f7eaa890018ac5c91d7b410c32d49a5 Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Tue, 4 Mar 2025 03:25:12 +0000 Subject: [PATCH 7/8] update MySQL/my_query_table_date.go. Signed-off-by: david058 <371369527@qq.com> --- MySQL/my_query_table_date.go | 105 ++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/MySQL/my_query_table_date.go b/MySQL/my_query_table_date.go index 47c37fd..49b16e5 100644 --- a/MySQL/my_query_table_date.go +++ b/MySQL/my_query_table_date.go @@ -41,67 +41,84 @@ func (my *QueryTable) QueryTableIndexColumnInfo(db *sql.DB, logThreadSeq int64) */ func (my *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThreadSeq int64) (map[string][]string, map[string][]string, map[string][]string) { var ( - nultiseriateIndexColumnMap = make(map[string][]string) - multiseriateIndexColumnMap = make(map[string][]string) - priIndexColumnMap = make(map[string][]string) - PriIndexCol, uniIndexCol, mulIndexCol []string - indexName string - currIndexName string - Event = "E_Index_Filter" + nultiseriateIndexColumnMap = make(map[string][]string) + multiseriateIndexColumnMap = make(map[string][]string) + priIndexColumnMap = make(map[string][]string) + indexName string + currIndexName string + Event = "E_Index_Filter" ) vlog = fmt.Sprintf("(%d) [%s] Start to filter the primary key index, unique index, and common index based on the index information of the specified table %s.%s under the %s library", logThreadSeq, Event, my.Schema, my.Table, DBType) global.Wlog.Debug(vlog) + + // 用于临时存储每个索引的列顺序 + indexColumns := make(map[string]map[string]string) + for _, v := range queryData { currIndexName = fmt.Sprintf("%s", v["indexName"]) if my.LowerCaseTableNames == "no" { currIndexName = strings.ToUpper(fmt.Sprintf("%s", v["indexName"])) } - //判断唯一索引(包含主键索引和普通索引) - if v["nonUnique"].(string) == "0" { - if currIndexName == "PRIMARY" { - if currIndexName != indexName { - indexName = currIndexName - } - PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s:%s", v["columnName"], v["IndexSeq"])) - priIndexColumnMap["pri"] = PriIndexCol - } else { - if currIndexName != indexName { - indexName = currIndexName - nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) - } else { - nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + + columnName := fmt.Sprintf("%s", v["columnName"]) + indexSeq := fmt.Sprintf("%s", v["IndexSeq"]) + columnType := fmt.Sprintf("%s", v["columnType"]) + + // 初始化map + if _, exists := indexColumns[currIndexName]; !exists { + indexColumns[currIndexName] = make(map[string]string) + } + + // 存储列的顺序信息 + indexColumns[currIndexName][indexSeq] = columnName + "/*seq*/" + indexSeq + "/*type*/" + columnType + + // 更新当前索引名 + if currIndexName != indexName { + indexName = currIndexName + } + } + + // 按照索引序号排序并添加到最终的map中 + for idxName, columns := range indexColumns { + // 获取所有序号并排序 + var seqNums []int + for seq := range columns { + seqNum, _ := strconv.Atoi(seq) + seqNums = append(seqNums, seqNum) + } + sort.Ints(seqNums) + + // 按序号顺序添加列 + var orderedColumns []string + for _, seq := range seqNums { + seqStr := strconv.Itoa(seq) + orderedColumns = append(orderedColumns, columns[seqStr]) + } + + // 根据索引类型添加到相应的map中 + if idxName == "PRIMARY" { + priIndexColumnMap["pri"] = orderedColumns + } else { + // 检查第一个匹配的索引列来确定是否为唯一索引 + isUnique := false + for _, v := range queryData { + if fmt.Sprintf("%s", v["indexName"]) == idxName { + isUnique = v["nonUnique"].(string) == "0" + break } } - } - //处理普通索引 - if v["nonUnique"].(string) != "0" { - if currIndexName != indexName { - indexName = currIndexName - multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + + if isUnique { + nultiseriateIndexColumnMap[idxName] = orderedColumns } else { - multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + multiseriateIndexColumnMap[idxName] = orderedColumns } } } + vlog = fmt.Sprintf("(%d) [%s] The index information screening of the specified table %s.%s under the %s library is completed", logThreadSeq, Event, my.Schema, my.Table, DBType) global.Wlog.Debug(vlog) - // Log the values of the maps - // if priVal, ok := priIndexColumnMap["pri"]; ok { - // vlog = fmt.Sprintf("(%d) [%s] Primary index columns: %v", logThreadSeq, Event, priVal) - // global.Wlog.Debug(vlog) - // } - - // for idxName, columns := range nultiseriateIndexColumnMap { - // vlog = fmt.Sprintf("(%d) [%s] Unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) - // global.Wlog.Debug(vlog) - // } - - // for idxName, columns := range multiseriateIndexColumnMap { - // vlog = fmt.Sprintf("(%d) [%s] Non-unique index '%s' columns: %v", logThreadSeq, Event, idxName, columns) - // global.Wlog.Debug(vlog) - // } - return priIndexColumnMap, nultiseriateIndexColumnMap, multiseriateIndexColumnMap } -- Gitee From f39faa0ba430e571481f788ed95f6de31fc35f4d Mon Sep 17 00:00:00 2001 From: david058 <371369527@qq.com> Date: Tue, 4 Mar 2025 03:25:42 +0000 Subject: [PATCH 8/8] update Oracle/or_query_table_date.go. Signed-off-by: david058 <371369527@qq.com> --- Oracle/or_query_table_date.go | 91 ++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 28 deletions(-) diff --git a/Oracle/or_query_table_date.go b/Oracle/or_query_table_date.go index 86a8fb9..4388db1 100644 --- a/Oracle/or_query_table_date.go +++ b/Oracle/or_query_table_date.go @@ -5,6 +5,7 @@ import ( "fmt" "gt-checksum/dataDispos" "gt-checksum/global" + "sort" "strconv" "strings" ) @@ -41,50 +42,84 @@ func (or *QueryTable) QueryTableIndexColumnInfo(db *sql.DB, logThreadSeq int64) */ func (or *QueryTable) IndexDisposF(queryData []map[string]interface{}, logThreadSeq int64) (map[string][]string, map[string][]string, map[string][]string) { var ( - nultiseriateIndexColumnMap = make(map[string][]string) - multiseriateIndexColumnMap = make(map[string][]string) - priIndexColumnMap = make(map[string][]string) - PriIndexCol, uniIndexCol, mulIndexCol []string - indexName string - currIndexName string - Event = "E_Index_Filter" + nultiseriateIndexColumnMap = make(map[string][]string) + multiseriateIndexColumnMap = make(map[string][]string) + priIndexColumnMap = make(map[string][]string) + indexName string + currIndexName string + Event = "E_Index_Filter" ) vlog = fmt.Sprintf("(%d) [%s] Start to filter the primary key index, unique index, and common index based on the index information of the specified table %s.%s under the %s library", logThreadSeq, Event, or.Schema, or.Table, DBType) global.Wlog.Debug(vlog) + + // 用于临时存储每个索引的列顺序 + indexColumns := make(map[string]map[string]string) + for _, v := range queryData { currIndexName = fmt.Sprintf("%s", v["indexName"]) if or.LowerCaseTableNames == "no" { currIndexName = strings.ToUpper(fmt.Sprintf("%s", v["indexName"])) } - //判断唯一索引(包含主键索引和普通索引) - if v["nonUnique"].(string) == "UNIQUE" { - if v["columnKey"].(string) == "1" { - if currIndexName != indexName { - indexName = currIndexName - } - PriIndexCol = append(PriIndexCol, fmt.Sprintf("%s:%s", v["columnName"], v["IndexSeq"])) - priIndexColumnMap["pri"] = PriIndexCol - } else { - if currIndexName != indexName { - indexName = currIndexName - nultiseriateIndexColumnMap[indexName] = append(uniIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) - } else { - nultiseriateIndexColumnMap[indexName] = append(nultiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + + columnName := fmt.Sprintf("%s", v["columnName"]) + indexSeq := fmt.Sprintf("%s", v["IndexSeq"]) + columnType := fmt.Sprintf("%s", v["columnType"]) + + // 初始化map + if _, exists := indexColumns[currIndexName]; !exists { + indexColumns[currIndexName] = make(map[string]string) + } + + // 存储列的顺序信息 + indexColumns[currIndexName][indexSeq] = columnName + "/*seq*/" + indexSeq + "/*type*/" + columnType + + // 更新当前索引名 + if currIndexName != indexName { + indexName = currIndexName + } + } + + // 按照索引序号排序并添加到最终的map中 + for idxName, columns := range indexColumns { + // 获取所有序号并排序 + var seqNums []int + for seq := range columns { + seqNum, _ := strconv.Atoi(seq) + seqNums = append(seqNums, seqNum) + } + sort.Ints(seqNums) + + // 按序号顺序添加列 + var orderedColumns []string + for _, seq := range seqNums { + seqStr := strconv.Itoa(seq) + orderedColumns = append(orderedColumns, columns[seqStr]) + } + + // 根据索引类型添加到相应的map中 + if idxName == "PRIMARY" { + priIndexColumnMap["pri"] = orderedColumns + } else { + // 检查第一个匹配的索引列来确定是否为唯一索引 + isUnique := false + for _, v := range queryData { + if fmt.Sprintf("%s", v["indexName"]) == idxName { + isUnique = v["nonUnique"].(string) == "0" + break } } - } - //处理普通索引 - if v["nonUnique"].(string) == "NONUNIQUE" { - if currIndexName != indexName { - indexName = currIndexName - multiseriateIndexColumnMap[indexName] = append(mulIndexCol, fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + + if isUnique { + nultiseriateIndexColumnMap[idxName] = orderedColumns } else { - multiseriateIndexColumnMap[indexName] = append(multiseriateIndexColumnMap[indexName], fmt.Sprintf("%s:%s /*actions Column Type*/ %s", v["columnName"], v["IndexSeq"], v["columnType"])) + multiseriateIndexColumnMap[idxName] = orderedColumns } } } + vlog = fmt.Sprintf("(%d) [%s] The index information screening of the specified table %s.%s under the %s library is completed", logThreadSeq, Event, or.Schema, or.Table, DBType) global.Wlog.Debug(vlog) + return priIndexColumnMap, nultiseriateIndexColumnMap, multiseriateIndexColumnMap } -- Gitee