Skip to content

Commit

Permalink
Merge branch 'master' into go-mysqlserver
Browse files Browse the repository at this point in the history
  • Loading branch information
dveeden authored Oct 28, 2024
2 parents 613ab2d + 5ad36fa commit c7f8a39
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 6 deletions.
62 changes: 56 additions & 6 deletions dump/dumper.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"io"
"os"
"os/exec"
"regexp"
"strings"

. "github.com/go-mysql-org/go-mysql/mysql"
Expand Down Expand Up @@ -44,6 +45,9 @@ type Dumper struct {

// see detectColumnStatisticsParamSupported
isColumnStatisticsParamSupported bool

mysqldumpVersion string
sourceDataSupported bool
}

func NewDumper(executionPath string, addr string, user string, password string) (*Dumper, error) {
Expand All @@ -67,7 +71,14 @@ func NewDumper(executionPath string, addr string, user string, password string)
d.IgnoreTables = make(map[string][]string)
d.ExtraOptions = make([]string, 0, 5)
d.masterDataSkipped = false
d.isColumnStatisticsParamSupported = d.detectColumnStatisticsParamSupported()

out, err := exec.Command(d.ExecutionPath, `--help`).CombinedOutput()
if err != nil {
return d, err
}
d.isColumnStatisticsParamSupported = d.detectColumnStatisticsParamSupported(out)
d.mysqldumpVersion = d.getMysqldumpVersion(out)
d.sourceDataSupported = d.detectSourceDataSupported(d.mysqldumpVersion)

d.ErrOut = os.Stderr

Expand All @@ -81,12 +92,47 @@ func NewDumper(executionPath string, addr string, user string, password string)
// But this parameter exists only for versions >=8.0.2 (https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-2.html).
//
// For environments where the version of mysql-server and mysqldump differs, we try to check this parameter and use it if available.
func (d *Dumper) detectColumnStatisticsParamSupported() bool {
out, err := exec.Command(d.ExecutionPath, `--help`).CombinedOutput()
if err != nil {
func (d *Dumper) detectColumnStatisticsParamSupported(helpOutput []byte) bool {
return bytes.Contains(helpOutput, []byte(`--column-statistics`))
}

// mysqldump Ver 10.19 Distrib 10.3.37-MariaDB, for linux-systemd (x86_64)`, `10.3.37-MariaDB
// opt/mysql/11.0.0/bin/mysqldump from 11.0.0-preview-MariaDB, client 10.19 for linux-systemd (x86_64)
func (d *Dumper) getMysqldumpVersion(helpOutput []byte) string {
mysqldumpVersionRegexpNew := regexp.MustCompile(`mysqldump Ver ([0-9][^ ]*) for`)
if m := mysqldumpVersionRegexpNew.FindSubmatch(helpOutput); m != nil {
return string(m[1])
}

mysqldumpVersionRegexpOld := regexp.MustCompile(`mysqldump Ver .* Distrib ([0-9][^ ]*),`)
if m := mysqldumpVersionRegexpOld.FindSubmatch(helpOutput); m != nil {
return string(m[1])
}

mysqldumpVersionRegexpMaria := regexp.MustCompile(`mysqldump from ([0-9][^ ]*), `)
if m := mysqldumpVersionRegexpMaria.FindSubmatch(helpOutput); m != nil {
return string(m[1])
}

return ""
}

func (d *Dumper) detectSourceDataSupported(version string) bool {
// Failed to detect mysqldump version
if version == "" {
return false
}

// MySQL 5.x
if version[0] == byte('5') {
return false
}

if strings.Contains(version, "MariaDB") {
return false
}
return bytes.Contains(out, []byte(`--column-statistics`))

return true
}

func (d *Dumper) SetCharset(charset string) {
Expand Down Expand Up @@ -169,7 +215,11 @@ func (d *Dumper) Dump(w io.Writer) error {
passwordArgIndex := len(args) - 1

if !d.masterDataSkipped {
args = append(args, "--master-data")
if d.sourceDataSupported {
args = append(args, "--source-data")
} else {
args = append(args, "--master-data")
}
}

if d.maxAllowedPacket > 0 {
Expand Down
62 changes: 62 additions & 0 deletions dump/dumper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package dump

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestGetMysqldumpVersion(t *testing.T) {
versions := []struct {
line string // mysqldump --help | head -1
version string // 9.1.0
}{
// Oracle MySQL
{`mysqldump Ver 10.13 Distrib 5.5.62, for linux-glibc2.12 (x86_64)`, `5.5.62`},
{`mysqldump Ver 10.13 Distrib 5.6.44, for linux-glibc2.12 (x86_64)`, `5.6.44`},
{`mysqldump Ver 10.13 Distrib 5.7.31, for linux-glibc2.12 (x86_64)`, `5.7.31`},
{`mysqldump Ver 10.13 Distrib 5.7.36, for linux-glibc2.12 (x86_64)`, `5.7.36`},
{`mysqldump Ver 8.0.11 for linux-glibc2.12 on x86_64 (MySQL Community Server - GPL)`, `8.0.11`},
{`mysqldump Ver 8.0.22 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.22`},
{`mysqldump Ver 8.0.25 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.25`},
{`mysqldump Ver 8.0.26 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.26`},
{`mysqldump Ver 8.0.27 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.27`},
{`mysqldump Ver 8.0.28 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.28`},
{`mysqldump Ver 8.0.31 for Linux on x86_64 (Source distribution)`, `8.0.31`},
{`mysqldump Ver 8.0.32 for Linux on x86_64 (MySQL Community Server - GPL)`, `8.0.32`},
{`mysqldump Ver 8.4.2 for FreeBSD14.0 on amd64 (Source distribution)`, `8.4.2`},
{`mysqldump Ver 9.1.0 for Linux on x86_64 (MySQL Community Server - GPL)`, `9.1.0`},

// MariaDB
{`mysqldump Ver 10.19 Distrib 10.3.37-MariaDB, for linux-systemd (x86_64)`, `10.3.37-MariaDB`},
{`mysqldump Ver 10.19 Distrib 10.6.11-MariaDB, for linux-systemd (x86_64)`, `10.6.11-MariaDB`},
{`opt/mysql/11.0.0/bin/mysqldump from 11.0.0-preview-MariaDB, client 10.19 for linux-systemd (x86_64)`, `11.0.0-preview-MariaDB`},
{`opt/mysql/11.2.2/bin/mysqldump from 11.2.2-MariaDB, client 10.19 for linux-systemd (x86_64)`, `11.2.2-MariaDB`},
}

d := new(Dumper)
for _, v := range versions {
ver := d.getMysqldumpVersion([]byte(v.line))
require.Equal(t, v.version, ver, v.line)
}
}

func TestDetectSourceDataSupported(t *testing.T) {
versions := []struct {
version string
supported bool
}{
{`5.7.40`, false},
{`8.0.11`, true},
{`8.4.1`, true},
{`9.1.0`, true},
{``, false},
{`10.3.37-MariaDB`, false},
{`11.2.2-MariaDB`, false},
}

d := new(Dumper)
for _, v := range versions {
require.Equal(t, v.supported, d.detectSourceDataSupported(v.version), v.version)
}
}

0 comments on commit c7f8a39

Please sign in to comment.