diff --git a/sqle/locale/active.en.toml b/sqle/locale/active.en.toml index ca5b953d63..3c923a530f 100644 --- a/sqle/locale/active.en.toml +++ b/sqle/locale/active.en.toml @@ -34,6 +34,7 @@ ApMetaMySQLTopSQL = "MySQL TOP SQL" ApMetaObForOracleTopSQL = "OceanBase For Oracle TOP SQL" ApMetaOceanBaseForMySQLFullCollect = "Full Collect" ApMetaOceanBaseForMySQLSlowLog = "OceanBase For MySQL slow log" +ApMetaOracleSlowLog = "Oracle slow log" ApMetaOracleTopSQL = "Oracle TOP SQL" ApMetaPerformanceCollect = "Performance metrics" ApMetaPerformanceCollectTips = "Performance metric collection will incur significant performance overhead, so please enable it with caution. Once enabled, the system will continuously collect performance data (such as QPS, number of connections, etc.) for this data source and generate performance trend charts, which will be displayed on the Performance Insights page." diff --git a/sqle/locale/active.zh.toml b/sqle/locale/active.zh.toml index db04148b0d..48bada572b 100644 --- a/sqle/locale/active.zh.toml +++ b/sqle/locale/active.zh.toml @@ -34,6 +34,7 @@ ApMetaMySQLTopSQL = "MySQL TOP SQL" ApMetaObForOracleTopSQL = "OceanBase For Oracle TOP SQL" ApMetaOceanBaseForMySQLFullCollect = "全量采集" ApMetaOceanBaseForMySQLSlowLog = "慢日志" +ApMetaOracleSlowLog = "Oracle慢日志" ApMetaOracleTopSQL = "Oracle TOP SQL" ApMetaPerformanceCollect = "数据源性能指标" ApMetaPerformanceCollectTips = "性能指标采集将产生较大性能开销,请谨慎开启。开启后,系统将持续采集该数据源的性能数据(如QPS、连接数等),并生成性能趋势图表,体现在性能洞察页面。" diff --git a/sqle/locale/message_zh.go b/sqle/locale/message_zh.go index 18a24b8787..1bb62334ca 100644 --- a/sqle/locale/message_zh.go +++ b/sqle/locale/message_zh.go @@ -405,6 +405,7 @@ var ( ApMetaBaiduRdsMySQLSlowLog = &i18n.Message{ID: "ApMetaBaiduRdsMySQLSlowLog", Other: "百度云RDS MySQL慢日志"} ApMetaHuaweiRdsMySQLSlowLog = &i18n.Message{ID: "ApMetaHuaweiRdsMySQLSlowLog", Other: "华为云RDS MySQL慢日志"} ApMetaOracleTopSQL = &i18n.Message{ID: "ApMetaOracleTopSQL", Other: "Oracle TOP SQL"} + ApMetaOracleSlowLog = &i18n.Message{ID: "ApMetaOracleSlowLog", Other: "Oracle慢日志"} ApMetaAllAppExtract = &i18n.Message{ID: "ApMetaAllAppExtract", Other: "应用程序SQL抓取"} ApMetaTiDBAuditLog = &i18n.Message{ID: "ApMetaTiDBAuditLog", Other: "TiDB审计日志"} ApMetaSlowLog = &i18n.Message{ID: "ApMetaSlowLog", Other: "慢日志"} diff --git a/sqle/pkg/oracle/db.go b/sqle/pkg/oracle/db.go index ab0cb3dfce..623d3cc2ac 100644 --- a/sqle/pkg/oracle/db.go +++ b/sqle/pkg/oracle/db.go @@ -110,3 +110,48 @@ func (o *DB) QueryTopSQLs(ctx context.Context, collectIntervalMinute string, top } return ret, nil } + +func (o *DB) QuerySlowSQLs(ctx context.Context, collectIntervalMinute string, topN int, slowSQLThresholdMicroseconds int64, notInUsers []string) ([]*DynPerformanceSQLArea, error) { + var notInUsersStr string + if len(notInUsers) > 0 { + var notInUsersFormatted []string + var notInUserSqlTpl = `AND u.username NOT IN (%v)` + for _, user := range notInUsers { + notInUsersFormatted = append(notInUsersFormatted, fmt.Sprintf("'%s'", user)) + } + notInUsersStr = strings.Join(notInUsersFormatted, ",") + notInUsersStr = fmt.Sprintf(notInUserSqlTpl, notInUsersStr) + } + if topN == 0 { + topN = 100 + } + + query := fmt.Sprintf(DynPerformanceViewSQLAreaSlowLogTpl, collectIntervalMinute, slowSQLThresholdMicroseconds, notInUsersStr, topN) + rows, err := o.db.QueryContext(ctx, query) + if err != nil { + return nil, errors.Wrapf(err, "failed to query %s", query) + } + defer rows.Close() + + var ret []*DynPerformanceSQLArea + for rows.Next() { + res := DynPerformanceSQLArea{} + if err := rows.Scan( + &res.SQLFullText, + &res.Executions, + &res.ElapsedTime, + &res.UserIOWaitTime, + &res.CPUTime, + &res.DiskReads, + &res.BufferGets, + &res.UserName, + ); err != nil { + return nil, errors.Wrapf(err, "failed to scan %s", query) + } + ret = append(ret, &res) + } + if err := rows.Err(); err != nil { + return nil, errors.Wrapf(err, "failed to iterate %s", query) + } + return ret, nil +} diff --git a/sqle/pkg/oracle/perf.go b/sqle/pkg/oracle/perf.go index bc9d7c0d16..6be55e1f5f 100644 --- a/sqle/pkg/oracle/perf.go +++ b/sqle/pkg/oracle/perf.go @@ -38,6 +38,31 @@ SELECT * FROM ( %v ORDER BY %v DESC ) +WHERE + rownum <= %v +` + DynPerformanceViewSQLAreaSlowLogTpl = ` +SELECT * FROM ( + SELECT + s.sql_fulltext, + s.executions, + s.elapsed_time, + s.user_io_wait_time, + s.cpu_time, + s.disk_reads, + s.buffer_gets, + u.username + FROM + V$SQLAREA s + JOIN + DBA_USERS u ON s.parsing_user_id = u.user_id + WHERE + last_active_time >= SYSDATE - INTERVAL '%v' MINUTE + AND s.EXECUTIONS > 0 + AND s.elapsed_time / s.executions > %v + %v + ORDER BY s.elapsed_time / s.executions DESC +) WHERE rownum <= %v `