前几天接到个需求:写一个脚本,每次都遍历这100个结构相同的表,每次删除每个表指定日期之前1万条记录
我首先想到的就是试试用go的协程了,毕竟是大量的数据删除,而且100张表……,而且之前一直很好奇go的协程是怎么使用的,有什么用,能干嘛?带着一大堆的好奇和疑问我就开始设计了,但是要怎么用呢?
我的思路是:初始化数据库连接之后,根据表名的规则table_01,table_02,……,table_99
,先拼装好表名,之后传到方法里面去执行sql,每次循环调用一次del方法,每个方法都是一个协程。
package main
import (
"fmt"
"strconv"
"sync"
"github.com/jmoiron/sqlx"
_ "github.com/go-sql-driver/mysql"
)
var wg sync.WaitGroup
var table string = "log_db_table_"
var Db *sqlx.DB
func init() {
// 初始化mysql
database, err := sqlx.Open("mysql", "root:root@tcp(192.168.1.71:3306)/log_db")
if err != nil {
fmt.Println("open mysql failed,", err)
return
}
fmt.Println("连接上mysql")
Db = database
}
func main() {
// 关闭mysql连接
defer Db.Close()
// 执行方法
sql()
wg.Wait()
}
func sql() {
for i := 0; i < 100; i++ {
wg.Add(1)
query := table
if i < 10 {
query = query + "0" + strconv.Itoa(i)
} else {
query = query + strconv.Itoa(i)
}
go del(query)
}
}
func del(table string) {
defer wg.Done()
//fmt.Println("delete from "+table +" where add_time < 1593446400 limit 2000")
res, err := Db.Exec("delete from "+table +" where add_time < 1593446400 limit 10000")
if err != nil {
fmt.Println("执行失败, ", err)
return
}
row,err := res.RowsAffected()
if err != nil {
fmt.Println("失败行数:",err)
}
fmt.Println("成功删除: ",row,"行")
}
构建脚本 我的go版本是1.16(centos7)、1.15(win10)
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.io
go mod init
# 初始化 go.mod
go mod tidy
# 自动加载引用到的包,如果没有,自己手写引入
go build -o delTimerHandler ./main.go
#编译当前脚本,并且指定文件名
# 这是在目录下就会有一个 delTimerHandler的可执行文件,根据当前所在系统所决定,如果是win则是exe,如果是linux则是无后缀的。
将脚本挂在crontab
上,让脚本每分钟执一次,并输出到指定的文件中
crontab -e
#内容
* * * * * /mnt/go-script/time/delTimerHandler >> /mnt/go-script/time/log.txt
保存退出之后就会执行
查看crontab
的指令
crontab -l
查看crontab
是否开启
systemctl status crond
systemctl reload crond
systemctl start crond
追踪cron
指令执行的日志
tail -f /var/log/cron
追踪脚本输出记录
tail -f /mnt/go-script/time/log.txt
测试脚本的过程中,数据是在本地的,100张表 每分钟操作100张表,每张表删除1万条……额,我本地肯定是不耐操的,想想就好,最好就是删除少一点咯,比如2000条,然后设计为每20秒执行一次脚本咯