duanlie1298 2019-05-31 08:03
浏览 26

Buffio扫描仪停止从mysqldump stdout中读取行的一半

am trying to write a program in go that able to export mysql database(using mysqldump) into .sql file, but somehow scanner.Text() only read halfway of the output from mysqldump. Following main package:

func main() {
    // Just to get list of database name from
    // []string{dbA, dbB}
    databases := pkg.GetDatabases()

    // Just to get mysql connection config
    dbConfig := pkg.NewConnection() 

    var wg sync.WaitGroup

    // How many goroutines need to be waited
    wg.Add(len(databases.Name))

    // databases.Name is a type []string hold database's name
    for _, name := range databases.Name {
        go dumping(name, dbConfig, &wg)
    }

    wg.Wait()

    fmt.Print("Main program exit!")
}

func dumping (name string, c *pkg.Connection, wg *sync.WaitGroup) {
    defer wg.Done()
    args := []string{
        fmt.Sprintf("--port=%s", c.Port),
        fmt.Sprintf("--host=%s", c.Host),
        fmt.Sprintf("--password=%s", ""),
    }
    args = append(args, name)
    log.Printf("exec mysqldump with %v", args)

    cmd := exec.Command("mysqldump", args...)

    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatalf("Error to execute mysqlump command: ", err)
        os.Exit(1)
    }
    scanner := bufio.NewScanner(stdout)
    go func() {
        for scanner.Scan() {
            fmt.Printf("%s
", scanner.Text())
        }
    }()

    err = cmd.Start()
    if err != nil {
        fmt.Fprintln(os.Stderr, "Error starting Cmd", err)
        os.Exit(1)
    }

    err = cmd.Wait()
    if err != nil {
        fmt.Fprintln(os.Stderr, "Error waiting for Cmd", err.Error())
        os.Exit(1)
    }
}

Output from fmt.Printf("%s ", scanner.Text()):

2019/05/31 15:43:03 exec mysqldump with [--port=3306 --host=127.0.0.1 --password= dbA]
-- MySQL dump 10.16  Distrib 10.3.9-MariaDB, for osx10.13 (x86_64)
--
-- Host: 127.0.0.1    Database: dbA
-- -----------------------------------------------------
-- Server version       10.3.9-MariaDB

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
Error waiting for Cmd exit status 2
exit status 1

If i run directly this command mysqldump -P 3306 -h 127.0.0.1 -u root --password="" dbA from a terminal, got a lot of sql statements that still left behind. Is there anything i missed?

Thanks.

  • 写回答

1条回答 默认 最新

  • douzhuo2002 2019-05-31 15:18
    关注

    Found the culprit. The real problem is i didn't provided --user=%s argument to the exec command. Should be:

    args := []string{
          fmt.Sprintf("--port=%s", c.Port),
          fmt.Sprintf("--host=%s", c.Host),
          fmt.Sprintf("--user=%s", c.User), <-- here
          fmt.Sprintf("--password=%s", ""),
    }
    

    How i found that? The error actually goes to cmd.Stderr:

    var out bytes.Buffer
    cmd.Stderr = &out
    if err != nil {
        log.Fatalf("Error to execute mysqlump command: ", err)
        os.Exit(1)
    }
    fmt.Printf("%q
    ", out.String())
    

    Which output the real error like following:

    "mysqldump: Got error: 1044: \"Access denied for user ''@'localhost' to database 'dbA'\" when selecting the database
    "
    
    评论

报告相同问题?

悬赏问题

  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 关于无人驾驶的航向角
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥30 BC260Y用MQTT向阿里云发布主题消息一直错误
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了