基于 Go 的PostgreSQL 数据库清理工具完整实现方案
用户需要两个工具功能:第一个是统计record_v2表中已删除数据量、一年前未删除的数据量和总条数;第二个是清理半年前标记为删除的数据。这应该是一个数据库维护工具,用于清理和监控数据。
完整代码文件 db_cleaner.go
package mainimport ("context""database/sql""fmt""log""time"_ "github.com/lib/pq" // PostgreSQL 驱动
)// 数据库配置(替换为实际值)
const (host = "localhost"port = 5432user = "postgres"password = "yourpassword"dbname = "yourdb"
)func main() {// 建立数据库连接psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",host, port, user, password, dbname)db, err := sql.Open("postgres", psqlInfo)if err != nil {log.Fatalf("数据库连接失败: %v", err)}defer db.Close()// 配置连接池db.SetMaxOpenConns(10)db.SetMaxIdleConns(5)db.SetConnMaxLifetime(time.Hour)// 工具1:统计报表if err := generateReport(db); err != nil {log.Printf("统计失败: %v", err)}// 工具2:清理半年前数据if err := cleanOldData(db); err != nil {log.Printf("清理失败: %v", err)}
}// 工具1:生成统计报表
func generateReport(db *sql.DB) error {ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)defer cancel()// 统计已删除数据量var deletedCount interr := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM record_v2 WHERE deleted = true`).Scan(&deletedCount)if err != nil {return fmt.Errorf("统计已删除数据失败: %w", err)}// 统计一年前未删除数据量oneYearAgo := time.Now().AddDate(-1, 0, 0).Format("2006-01-02")var oldUndeletedCount interr = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM record_v2 WHERE deleted = false AND created_at < $1`, oneYearAgo).Scan(&oldUndeletedCount)if err != nil {return fmt.Errorf("统计一年前未删除数据失败: %w", err)}// 统计总条数var totalCount interr = db.QueryRowContext(ctx, `SELECT COUNT(*) FROM record_v2`).Scan(&totalCount)if err != nil {return fmt.Errorf("统计总数失败: %w", err)}// 输出报表fmt.Println("\n===== 数据库统计报表 =====")fmt.Printf("✅ 已删除数据量: %d\n", deletedCount)fmt.Printf("⏳ 一年前未删除数据量: %d\n", oldUndeletedCount)fmt.Printf("📊 总记录数: %d\n", totalCount)fmt.Println("=========================")return nil
}// 工具2:清理半年前删除的数据
func cleanOldData(db *sql.DB) error {ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)defer cancel()// 开启事务(确保操作原子性)tx, err := db.BeginTx(ctx, nil)if err != nil {return fmt.Errorf("开启事务失败: %w", err)}defer tx.Rollback() // 安全回滚(若提交成功则自动跳过)// 计算半年前时间点sixMonthsAgo := time.Now().AddDate(0, -6, 0).Format("2006-01-02")// 执行清理(使用参数化查询防止SQL注入)res, err := tx.ExecContext(ctx,`DELETE FROM record_v2 WHERE deleted = true AND created_at < $1`,sixMonthsAgo)if err != nil {return fmt.Errorf("删除数据失败: %w", err)}// 获取影响行数rowsAffected, err := res.RowsAffected()if err != nil {return fmt.Errorf("获取影响行数失败: %w", err)}// 提交事务if err := tx.Commit(); err != nil {return fmt.Errorf("提交事务失败: %w", err)}fmt.Printf("\n♻️ 成功清理 %d 条半年前删除的数据\n", rowsAffected)return nil
}
关键实现说明
1. 数据库连接
- •
驱动加载:使用
github.com/lib/pq
作为 PostgreSQL 驱动(需go get
安装) - •
连接字符串:通过
psqlInfo
格式动态生成连接参数,支持 SSL 禁用模式 - •
连接池配置:通过
SetMaxOpenConns
等参数优化并发性能
一年前未删除数据:
- •
动态计算时间点:
time.Now().AddDate(-1, 0, 0)
- •
使用参数化查询避免 SQL 注入:
created_at < $1
- •
- •
结果获取:通过
QueryRowContext().Scan()
安全提取统计值
3. 数据清理工具
- •
时间范围控制:
事务保障:
- •
使用
BeginTx
开启事务 - •
defer tx.Rollback()
确保异常时自动回滚 - •
显式调用
tx.Commit()
提交变更
- •
- •
影响行数统计:通过
res.RowsAffected()
确认实际删除量
4. 安全增强
- •
上下文超时:所有操作绑定
context.WithTimeout
防止死锁 - •
参数化查询:清理工具中
$1
占位符避免 SQL 注入 - •
错误链式处理:通过
fmt.Errorf("...: %w", err)
保留原始错误
使用指南
安装依赖:
go get github.com/lib/pq
配置数据库:
const (host = "localhost" // 替换为实际主机port = 5432 // 替换为实际端口user = "postgres" // 替换为用户名password = "yourpassword" // 替换为密码dbname = "yourdb" // 替换为数据库名
)
运行程序:
go run db_cleaner.go
输出:
===== 数据库统计报表 =====
✅ 已删除数据量: 1520
⏳ 一年前未删除数据量: 870
📊 总记录数: 10000
=========================♻️ 成功清理 320 条半年前删除的数据