Goでmysqldumpツールをつくる

golang mysql ssh mysqldump

プログラミング

2019-02-07 12:47:37

概要

このブログのDBバックアップを原始人のごとく手動でやっていたのでコマンド一発でバックアップをリモートからローカルにバックアップを取れるツールをgoでつくってみた。

パッケージ

  • "net"
    • ネットワークI/O、TCP/IP、UDP、ドメイン名前解決、Unixドメインソケットなどのインターフェースを提供してくれるやつ
  • "time"
    • 時間の計算や表示のための機能を提供してくれるやつ
  • "io/ioutil"
    • ファイル周りのI/Oユーティリティを提供してくれるやつ
  • "golang.org/x/crypto/ssh"
    • sshのクライアント・サーバーの実装を提供してくれるやつ
  • "github.com/BurntSushi/toml"
    • TOMLパーサー
    • goのjsonやxmlといったパーサーの標準ライブラリライクに作られているらしい
    • 焦げた寿司さん

実装 

ざっくり動く形まで実装してみた。Goに不慣れなので愚直な感じになっている。。。
あとテストがかけていない。

package main

import (
    "net"
    "time"
    "io/ioutil"
    "golang.org/x/crypto/ssh"
    "github.com/BurntSushi/toml"
)

type Config struct {
    SSH SSH
    Mysql Mysql
}

type SSH struct {
    IP string
    Port string
    User string
    IdentityFile string
}

type Mysql struct {
    MysqlConf string
    Database string
    DumpDir string
    DumpFilePrefix string
}

func dump() {
    var config Config
    if _, err := toml.DecodeFile("config.toml", &config); err != nil {
        panic(err)
    }

    buf, err := ioutil.ReadFile(config.SSH.IdentityFile)
    if err != nil {
        panic(err)
    }

    key, err := ssh.ParsePrivateKey(buf)
    if err != nil {
        panic(err)
    }

    conn, err := ssh.Dial("tcp", config.SSH.IP+":"+config.SSH.Port, &ssh.ClientConfig{
        User: config.SSH.User,
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(key),
        },
        HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
            return nil
        },
    })
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    session, err := conn.NewSession()
    if err != nil {
        panic(err)
    }
    defer session.Close()

  byte, err := session.Output("sudo mysqldump --defaults-file="+config.Mysql.MysqlConf+" "+config.Mysql.Database+" "+"--quick --single-transaction")
    if err != nil {
        panic(err)
    }

    ioutil.WriteFile(config.Mysql.DumpDir+config.Mysql.DumpFilePrefix+time.Now().Format("2006-01-02")+".sql", byte, 0644)
}

func main() {
    dump()
}

github

置いといた。

所感

とりあえずgoの色んな実装をみて知見を貯めていく...

参考

About the author

Image

bmf san @bmf_san
A web developer in Japan.