多个环境数据库同步更新工具

178 阅读2分钟

不知道大家在日常工作中有没有遇到如下场景,有多个环境,其中的数据库更新需要我们到每个环境上去更新,我们就是有这样的场景,数据库docker部署的,DBA感觉特别麻烦,所以我们来撸一个相关的工具。

首先我们先要定义配置文件格式,方面的到服务器中执行命令

[  
    {  
        "name": "postgres",  
        "host": "10.255.175.229",  
        "password": "test123",  
        "database": "test",  
        "port": 22  
    },  
    {  
        "name": "postgres",  
        "host": "10.255.175.230",  
        "password": "test123",  
        "database": "test",  
        "port": 22  
    }  
]

其中name是我们的容器名

然后就要选定我们的编程语言了,我这里是用的是go, 废话少说,直接放代码

package main  
  
import (  
    "bufio"  
    "encoding/json"  
    "fmt"  
    "golang.org/x/crypto/ssh"  
    "log"  
    "os"
    "strconv"
)

type Config struct {  
    Name string `json:"name"`  
    Host string `json:"host"`  
    Password string `json:"password"`  
    Database string `json:"database"`  
    Port int `json:"port"`  
}

func getConfig() []Config {  
    // 读取JSON文件  
    data, err := os.ReadFile("config.json")  
    if err != nil {  
        log.Fatal("无法读取配置文件:", err)  
    }  

    // 解析JSON数据  
    var configs []Config  
    err = json.Unmarshal(data, &configs)  
    if err != nil {  
        log.Fatal("无法解析配置文件:", err)  
    }  
    return configs  
}

func main() {  
    sql, err := os.ReadFile("./update.sql")  
    if err != nil {  
        log.Fatal(err)  
    }  
    configs := getConfig()  
  
    for _, c := range configs {  

        // SSH连接的配置信息  
        config := &ssh.ClientConfig{  
            User: "root",  
            Auth: []ssh.AuthMethod{  
                ssh.Password(c.Password),  
            },  
            HostKeyCallback: ssh.InsecureIgnoreHostKey(),  
        }  

        // 建立SSH连接  
        client, err := ssh.Dial("tcp", c.Host+":"+strconv.Itoa(c.Port), config)  
        if err != nil {  
            log.Fatalf("拨号失败: %v", err)  
        }  

        defer client.Close()  

        // 创建一个新的会话  
        session, err := client.NewSession()  
        if err != nil {  
            log.Fatalf("创建会话失败: %v", err)  
        }  
        defer session.Close()  

        command := "docker exec -i " + c.Name + " psql -U postgres -d " + c.Database + " << EOF \n" + string(sql) + "\nEOF"  
        // 执行命令并获取输出  
        output, err := session.Output(command)  
        if err != nil {  
            log.Fatalf("不能够执行命令: %v", err)  
        }  
        // 输出命令执行结果  
        fmt.Println("[" + c.Host + "]: " + string(output))  
    }  
  
    fmt.Println("执行完毕,输入任意字符以退出:")  
    reader := bufio.NewReader(os.Stdin)  
    for {  
        _, err := reader.ReadString('\n')  
        if err != nil {  
        fmt.Println("读取输入时发生错误:", err)  
        os.Exit(1)  
        }  
        fmt.Println("程序已退出")  
        os.Exit(0)  
    }  
}

在当前目录创建一个update.sql,把需要更新的sql粘贴进去即可。

编译为windows可执行程序

export GOOS=windows
export GOARCH=amd64
go build -o db_update.exe db_update.go

以上的代码简单易懂,我觉得没有必要解释,如果有疑问请在评论区留言。

ps: 作为一个go语言新手,写的不太好,不喜勿喷,但欢迎指正!