欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > golang实现mysql实例存活检查及全量备份是否完成检查工具开发

golang实现mysql实例存活检查及全量备份是否完成检查工具开发

2024/10/24 5:07:07 来源:https://blog.csdn.net/weixin_50902636/article/details/143189269  浏览:    关键词:golang实现mysql实例存活检查及全量备份是否完成检查工具开发

在这里插入图片描述

系列文章目录

golang实现mysql全量备份工具
golang命令行框架cobra


文章目录

  • 系列文章目录
  • 前言
  • 一、引入cobra命令行框架
  • 二、工具开发过程
    • 1.引入库
    • 2.cobra-cli初始化项目
    • 3.修改cmd/root.go文件
    • 4.编写备份检查代码
    • 5.编写实例存活探测代码
    • 6.公共变量定义
  • 三、工具使用演示
    • 1.完整的目录结构
    • 2.命令工具使用
      • 2.1.源代码构建为二进制程序
      • 2.2.二进制程序帮助命令查看
      • 2.3.命令执行
        • 2.3.1. 使用自定义参数执行命令
        • 2.3.2.使用工具的默认值执行命令
  • 总结


前言

在顶部文章中,通过golang编写了一个mysql的全量备份工具,经过验证备份工具没有问题,可以正常使用。但是在正式的生产环境中,作为运维的你怎么确认昨天的备份是成功的?最普通的方式是登上服务器手动查看,这种方式在当前的自动化运维中显得有些low了。因为生产环境中避免不了prometheus监控的接入,因此,为了解决手动确认备份成功的问题,并结合Prometheus实现备份检查告警,通过golang的cobra命令行框架编写一个备份检查工具脚本和mysql实例存活探测脚本来实现。Cobra 的命令行工具 cobra-cli 进一步提高了编写命令行程序的效率,非常推荐使用它来实现命令行工具的开发,可以加快开发速度。


一、引入cobra命令行框架

因为要开发的工具最终是以二进制命令的方式在linux服务器中执行,恰好golang的标准库cobra满足该条件,因此使用它为基础实现备份检查和实例存活检查工具的开发在阅读下方的开发脚本过程前,先阅读顶部的第二篇文章golang命令行框架cobra,
对cobra的概念和命令使用有个整体了解后,阅读下方代码会更加容易

二、工具开发过程

1.引入库

命令如下(示例):

[root@python2 ~]# go get -u -v github.com/spf13/cobra      [root@python2 ~]# go install github.com/spf13/cobra-cli@latest

2.cobra-cli初始化项目

[root@python2 ~]# cobra-cli init mysql_golang_tools
[root@python2 ~]# tree mysql_golang_tools
├── mysql_golang_tools
│   ├── cmd
│   │   └── root.go
│   ├── LICENSE
│   └── main.go 

3.修改cmd/root.go文件

因为备份检查和存活检查工具是分别写在不同的文件中的,所以在root.go文件中将不必要的代码先删除掉

代码如下(示例):

/*
Copyright © 2024 NAME HERE <EMAIL ADDRESS>
*/
package cmdimport ("os""github.com/spf13/cobra"
)// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{Use:   "mysql_golang_tools",Short: "include mysql backupfile check and mysql alive check",Long:  `这是一个检查mysql 全量备份及mysql实例存活的golang脚本`,//Run: func(cmd *cobra.Command, args []string) { fmt.Println("hello cobra") },
}// Execute adds all child commands to the root command and sets flags appropriately.
// 命令执行入口处
func Execute() {err := rootCmd.Execute()if err != nil {os.Exit(1)}
}

4.编写备份检查代码

mysql全量备份可参考顶部文章golang实现mysql全量备份
采用上述工具备份完成后,备份日志及备份存放目录截图如下

代码功能(示例):

1、检查指定备份存放目录下是否存在对应的备份文件
2、检查指定备份日志文件中是否包含‘compeleted OK!’字样,如果包含则说明备份是成功且完整的,反之,备份失败
3、执行构建好的二进制程序后,返回值是 mysqlbackupcheck,port=xxxx status=0/1i
4、因为这个返回值后期在对接Prometheus的自定义监控时会使用到,这个后续再说
5、status=0i代表备份失败,反之status=1i代表备份成功。只有这两种状态

代码如下(示例):

//backupFileCheck.go
package cmdimport ("bufio""fmt""os""path/filepath""strings""time""github.com/spf13/cobra"
)var mysqlBackupDirectory, mysqlBackupLogDir string// 备份文件检查子命令入口
var backupFileCheck = &cobra.Command{Use:   "mysqlbackupcheck",Short: "这是mysql全量备份文件检查工具",Args:  cobra.ArbitraryArgs, //接收任意参数Run: func(cmd *cobra.Command, args []string) {CheckBackup(mysqlBackupDirectory, mysqlPort)},
}// checkBackup 检查备份文件和日志文件
func CheckBackup(backupDir string, port int) {yesterday := time.Now().AddDate(0, 0, -1)filename := fmt.Sprintf("full_%s.tar.gz", yesterday.Format("20060102"))filePath := filepath.Join(backupDir, filename)logFilePath := filepath.Join(mysqlBackupLogDir, fmt.Sprintf("full_backup_data_%s.log", yesterday.Format("2006-01-02")))// 检查备份文件是否存在if _, err := os.Stat(filePath); err == nil {//fmt.Printf("检测到备份文件: %s\n", filePath)if CheckLogFile(logFilePath) {//fmt.Printf("备份文件 %s 完整性检查通过。\n", filePath)status = 1 // 昨天的备份成功} else {fmt.Printf("备份文件 %s 的日志检查失败!\n", logFilePath)}} else if os.IsNotExist(err) {fmt.Printf("未找到备份文件: %s\n", filePath)} else {fmt.Printf("检查文件 %s 时发生错误: %v\n", filePath, err)}// 输出结果fmt.Printf("mysqlbackupcheck,port=%d status=%di\n", port, status)
}// checkLogFile 检查日志文件的最后一行是否包含 "completed OK!"
func CheckLogFile(logFilePath string) bool {file, err := os.Open(logFilePath)if err != nil {fmt.Printf("打开日志文件 %s 时发生错误: %v\n", logFilePath, err)return false}defer file.Close()/*创建一个 bufio.Scanner 对象,用于逐行读取文件中的内容。for scanner.Scan() 循环会遍历文件的每一行,将当前行的内容存储到 lastLine 变量中。经过完整的循环后,lastLine 中将保存文件的最后一行文本*/var lastLine stringscanner := bufio.NewScanner(file)for scanner.Scan() {lastLine = scanner.Text()}//在读取完所有行后,使用 scanner.Err() 检查在扫描过程中是否发生错误。如果发生错误,则打印错误信息并返回 falseif err := scanner.Err(); err != nil {fmt.Printf("读取日志文件 %s 时发生错误: %v\n", logFilePath, err)return false}//使用 strings.Contains() 函数检查 lastLine 是否包含字符串 "completed OK!"。return strings.Contains(lastLine, "completed OK!")
}
func init() {/*IntVarP 方法用于定义一个整数类型的命令行标志(flag)。第一个参数 &port 是一个指向变量的指针,它将接收命令行输入的值。第二个参数 "port" 是标志的名称,可以通过 --port 来指定。第三个参数 "p" 是短标志的名称,可以通过 -p 来指定。第四个参数 3306 是该标志的默认值。如果用户在运行程序时不指定 -p 或 --port 参数,则 port 变量将自动获取这个默认值。最后一个参数 "MySQL 端口" 是对该参数的描述。因此,在运行程序时,如果您不提供 -p 参数,port 将会默认设置为 3306。如果您希望使用不同的 MySQL 端口,您可以在命令行中指定该参数*/rootCmd.AddCommand(backupFileCheck)backupFileCheck.Flags().StringVarP(&mysqlBackupDirectory, "directory", "d", "/export/servers/data/mybackup/my3306/xtrabackup/data", "数据库备份存放目录")backupFileCheck.Flags().StringVarP(&mysqlBackupLogDir, "logDir", "L", "/export/servers/data/mybackup/my3306/xtrabackup/log", "数据库备份日志目录")backupFileCheck.Flags().IntVarP(&mysqlPort, "port", "P", 3306, "数据库端口")
}

5.编写实例存活探测代码

代码功能(示例):

1、通过golnag 的database/sql库以及"github.com/go-sql-driver/mysql"驱动库实现在连接mysql后	,使用标准库中的ping()方法进行探测
2、返回值是mysqlping,host=192.168.56.131,port=3308 status=0/1i 这样,方便后续对接Prometheus的自定义监控
3、status=0i代表实例已宕机,反之status=1i代码实例存活。只有这两种状态

代码如下(示例):

//checkMysqlAlive.go
package cmdimport ("database/sql""fmt"_ "github.com/go-sql-driver/mysql""github.com/spf13/cobra"
)var mysqlHost, mysqlUser, mysqlPwd string// mysql实例通过ping 存活检查
var pingMysqlCheck = &cobra.Command{Use:   "mysqlping",Short: "这是mysql ping alive 检查工具",Args:  cobra.ArbitraryArgs, //接收任意参数Run: func(cmd *cobra.Command, args []string) {CheckMysqlAlive(mysqlUser, mysqlPwd, mysqlHost, mysqlPort)},
}func CheckMysqlAlive(mysqluser, mysqlpwd, mysqlhost string, mysqlport int) {dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s",mysqlUser, mysqlPwd, mysqlHost, mysqlPort, "mysql")db, err := sql.Open("mysql", dsn)if err != nil {fmt.Printf("failed to open database connection: %v", err)}if err = db.Ping(); err != nil {fmt.Printf("mysqlping,host=%s,port=%d status=%di\n", mysqlHost, mysqlPort, status)} else {status := 1fmt.Printf("mysqlping,host=%s,port=%d status=%di\n", mysqlHost, mysqlPort, status)}}func init() {//将子命令pingMysqlCheck添加到主命令rootCmd中rootCmd.AddCommand(pingMysqlCheck)pingMysqlCheck.Flags().StringVarP(&mysqlUser, "user", "u", "monitor", "数据库用户")pingMysqlCheck.Flags().StringVarP(&mysqlPwd, "pwd", "p", "monitor", "数据库密码")pingMysqlCheck.Flags().StringVarP(&mysqlHost, "host", "H", "127.0.0.1", "数据库IP")pingMysqlCheck.Flags().IntVarP(&mysqlPort, "port", "P", 3306, "数据库端口")
}

6.公共变量定义

//common.go
package cmd//该文件用于定义公共变量及公共函数等
var mysqlPort, status int

至此,代码功能已完成,接下来对命令工具的使用做一下演示

三、工具使用演示

1.完整的目录结构

在这里插入图片描述

2.命令工具使用

2.1.源代码构建为二进制程序

[root@python2 mysql_golang_tools]# go build -o mysqlCheckTools main.go

2.2.二进制程序帮助命令查看

父命令帮助手册

[root@python2 mysql_golang_tools]# ./mysqlCheckTools -h
这是一个检查mysql 全量备份及mysql实例存活的golang脚本Usage:mysql_golang_tools [command]Available Commands:completion       Generate the autocompletion script for the specified shellhelp             Help about any commandmysqlbackupcheck 这是mysql全量备份文件检查工具mysqlpingcheck   这是mysql ping alive 检查工具Flags:-h, --help   help for mysql_golang_toolsUse "mysql_golang_tools [command] --help" for more information about a command

两个子命令帮助手册

 [root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlbackupcheck -h这是mysql全量备份文件检查工具Usage:mysql_golang_tools mysqlbackupcheck [flags]Flags:-d, --directory string   数据库备份存放目录 (default "/export/servers/data/mybackup/my3306/xtrabackup/data")-h, --help               help for mysqlbackupcheck-L, --logDir string      数据库备份日志目录 (default "/export/servers/data/mybackup/my3306/xtrabackup/log")-P, --port int           数据库端口 (default 3306)[root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlpingcheck -h这是mysql ping alive 检查工具Usage:mysql_golang_tools mysqlpingcheck [flags]Flags:-h, --help          help for mysqlpingcheck-H, --host string   数据库IP (default "127.0.0.1")-P, --port int      数据库端口 (default 3306)-p, --pwd string    数据库密码 (default "monitor")-u, --user string   数据库用户 (default "monitor")

2.3.命令执行

2.3.1. 使用自定义参数执行命令

mysql实例存活探测

[root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlpingcheck -H 192.168.56.131 -P 3308 -p dbbackup -u dbbackup
mysqlping,host=192.168.56.131,port=3308 status=0i

mysql全量备份检查

[root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlbackupcheck -d /opt/servers/data/mybackup/my3306/xtrabackup/data -L /opt/servers/data/mybackup/my3306/xtrabackup/log -P 3307
2.3.2.使用工具的默认值执行命令

准备数据库备份文件
在这里插入图片描述

#mysql实例状态检测
[root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlpingcheck mysqlping,host=127.0.0.1,port=3306 status=0i#mysql备份情况检查
[root@python2 mysql_golang_tools]# ./mysqlCheckTools mysqlbackupcheckmysqlbackupcheck,port=3306 status=1i

总结

写本篇文章的主要目的是加强对cobra命令行框架的使用,其次是为了满足项目需求,对全量备份结果进行自定义监控。实现自定义监控的过程在下一篇文章中,此篇文章不做概述。Cobra 不仅支持子命令,还能够完美兼容 pflag 和 Viper 包,因为这三个包都是同一个作者开发的。关于标志,Cobra 支持持久标志、本地标志以及将标志标记为必选。Cobra 可以将标志绑定到 Viper,方便使用 viper.Get() 来获取标志的值。对于命令行参数,Cobra 提供了不少验证函数,我们也可以自定义验证函数。最后,Cobra 的命令行工具 cobra-cli 进一步提高了编写命令行程序的效率,非常推荐使用。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com