Skip to content

数据库监控和日志 ​

监控看的是数据库当下的运行状态,日志记的是已经发生过的操作和事件。出了性能瓶颈或者故障,前者让你早点发现,后者让你查得清来龙去脉。

19.1 数据库监控的重要性 ​

数据库监控是对运行状态的持续监视。慢查询、锁等待、资源吃紧这类问题在监控里露头,才谈得上优化和修复。它主要盯着四件事:

  • 性能优化:通过监控指标,识别性能瓶颈,优化查询和数据库配置。
  • 故障排除:及时发现错误和异常,快速定位问题原因。
  • 容量规划:监控数据库资源使用情况,为未来的容量扩展提供数据支持。
  • 安全审计:记录数据库访问和操作日志,保障数据安全。

19.2 关键监控指标 ​

常用的监控指标有这几类,它们分别对应数据库的性能和健康状况:

  • 查询性能:查询的响应时间、吞吐量、慢查询等。
  • 连接数:当前活跃连接数、最大连接数、连接池使用情况等。
  • 资源使用:CPU使用率、内存使用率、磁盘I/O、网络I/O等。
  • 缓存命中率:数据库缓存的命中率和未命中率。
  • 锁等待:锁等待时间、死锁等。
  • 事务处理:事务提交和回滚的数量、事务响应时间等。

19.3 常用的数据库监控工具 ​

19.3.1 Prometheus ​

Prometheus是一款开源的监控系统和时序数据库,支持多种数据采集方式和查询语言,数据库的指标由它拉取、存储、查询。

19.3.2 Grafana ​

Grafana是一款开源的数据可视化工具,接上Prometheus这类数据源后,把监控指标画成图表和仪表板。

19.3.3 MySQL Performance Schema ​

MySQL Performance Schema是MySQL内置的性能监控工具,可以收集数据库运行时的详细性能数据,包括查询性能、锁等待、资源使用等。

19.3.4 pg_stat_statements ​

pg_stat_statements是PostgreSQL的扩展模块,可以记录和分析SQL查询的执行情况,包括查询频率、响应时间、执行计划等。

19.4 在Go中实现数据库监控 ​

在Go中,可以使用Prometheus客户端库对数据库进行监控,并将监控数据暴露给Prometheus进行采集和分析。

19.4.1 安装Prometheus客户端库 ​
bash
go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp
19.4.2 定义监控指标 ​

在Go代码中定义需要监控的指标:

go
var (
    queryDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "db_query_duration_seconds",
            Help:    "Duration of database queries.",
            Buckets: prometheus.DefBuckets,
        },
        []string{"query"},
    )
    activeConnections = prometheus.NewGauge(
        prometheus.GaugeOpts{
            Name: "db_active_connections",
            Help: "Number of active database connections.",
        },
    )
)

func init() {
    prometheus.MustRegister(queryDuration, activeConnections)
}
19.4.3 采集监控数据 ​

在数据库操作中采集监控数据:

go
func executeQuery(query string, db *sql.DB) {
    start := time.Now()
    _, err := db.Exec(query)
    duration := time.Since(start).Seconds()

    queryDuration.WithLabelValues(query).Observe(duration)

    if err != nil {
        log.Printf("Query failed: %v", err)
    }
}
19.4.4 暴露监控数据 ​

将监控数据暴露给Prometheus进行采集:

go
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))

19.5 数据库日志 ​

数据库日志是记录数据库操作和事件的重要工具,通过日志可以跟踪数据库的运行状态、查询执行情况、安全事件等。

19.5.1 常见的数据库日志类型 ​
  • 错误日志:记录数据库运行时的错误和异常信息。
  • 查询日志:记录所有执行的SQL查询,通常用于审计和分析。
  • 慢查询日志:记录执行时间超过设定阈值的慢查询,便于优化性能。
  • 事务日志:记录事务的提交和回滚情况,用于故障恢复。
19.5.2 在Go中记录数据库日志 ​

在Go中,可以使用标准库的日志包或第三方日志库(如Logrus、Zap)记录数据库操作日志。

go
package main

import (
    "database/sql"
    "log"
    "os"

    _ "github.com/go-sql-driver/mysql"
    "github.com/sirupsen/logrus"
)

func main() {
    // 设置日志输出
    logFile, err := os.OpenFile("db.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
    if err != nil {
        log.Fatal(err)
    }
    logrus.SetOutput(logFile)
    logrus.SetFormatter(&logrus.TextFormatter{
        FullTimestamp: true,
    })

    // 连接数据库
    db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
    if err != nil {
        logrus.WithError(err).Fatal("Failed to connect to database")
    }
    defer db.Close()

    // 执行查询
    query := "SELECT * FROM users"
    rows, err := db.Query(query)
    if err != nil {
        logrus.WithError(err).WithField("query", query).Error("Failed to execute query")
        return
    }
    defer rows.Close()

    logrus.WithField("query", query).Info("Query executed successfully")
}

19.6 日志分析和管理 ​

19.6.1 日志分析 ​

通过分析数据库日志,可以发现性能瓶颈、错误模式和安全事件。常用的日志分析工具包括ELK(Elasticsearch, Logstash, Kibana)堆栈和Splunk等。

19.6.2 日志管理 ​

有效的日志管理包括日志的存储、归档和清理策略。需要定期归档和清理旧日志,避免日志文件过大影响性能。

参考资料 ​

同层页面 ​

相关页面 ​

Hello Golang