66 "io"
77 "os"
88 "os/exec"
9+ "regexp"
910 "strings"
1011
1112 . "github.com/go-mysql-org/go-mysql/mysql"
@@ -44,6 +45,9 @@ type Dumper struct {
4445
4546 // see detectColumnStatisticsParamSupported
4647 isColumnStatisticsParamSupported bool
48+
49+ mysqldumpVersion string
50+ sourceDataSupported bool
4751}
4852
4953func NewDumper (executionPath string , addr string , user string , password string ) (* Dumper , error ) {
@@ -67,7 +71,14 @@ func NewDumper(executionPath string, addr string, user string, password string)
6771 d .IgnoreTables = make (map [string ][]string )
6872 d .ExtraOptions = make ([]string , 0 , 5 )
6973 d .masterDataSkipped = false
70- d .isColumnStatisticsParamSupported = d .detectColumnStatisticsParamSupported ()
74+
75+ out , err := exec .Command (d .ExecutionPath , `--help` ).CombinedOutput ()
76+ if err != nil {
77+ return d , err
78+ }
79+ d .isColumnStatisticsParamSupported = d .detectColumnStatisticsParamSupported (out )
80+ d .mysqldumpVersion = d .getMysqldumpVersion (out )
81+ d .sourceDataSupported = d .detectSourceDataSupported (d .mysqldumpVersion )
7182
7283 d .ErrOut = os .Stderr
7384
@@ -81,12 +92,47 @@ func NewDumper(executionPath string, addr string, user string, password string)
8192// 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).
8293//
8394// For environments where the version of mysql-server and mysqldump differs, we try to check this parameter and use it if available.
84- func (d * Dumper ) detectColumnStatisticsParamSupported () bool {
85- out , err := exec .Command (d .ExecutionPath , `--help` ).CombinedOutput ()
86- if err != nil {
95+ func (d * Dumper ) detectColumnStatisticsParamSupported (helpOutput []byte ) bool {
96+ return bytes .Contains (helpOutput , []byte (`--column-statistics` ))
97+ }
98+
99+ // mysqldump Ver 10.19 Distrib 10.3.37-MariaDB, for linux-systemd (x86_64)`, `10.3.37-MariaDB
100+ // opt/mysql/11.0.0/bin/mysqldump from 11.0.0-preview-MariaDB, client 10.19 for linux-systemd (x86_64)
101+ func (d * Dumper ) getMysqldumpVersion (helpOutput []byte ) string {
102+ mysqldumpVersionRegexpNew := regexp .MustCompile (`mysqldump Ver ([0-9][^ ]*) for` )
103+ if m := mysqldumpVersionRegexpNew .FindSubmatch (helpOutput ); m != nil {
104+ return string (m [1 ])
105+ }
106+
107+ mysqldumpVersionRegexpOld := regexp .MustCompile (`mysqldump Ver .* Distrib ([0-9][^ ]*),` )
108+ if m := mysqldumpVersionRegexpOld .FindSubmatch (helpOutput ); m != nil {
109+ return string (m [1 ])
110+ }
111+
112+ mysqldumpVersionRegexpMaria := regexp .MustCompile (`mysqldump from ([0-9][^ ]*), ` )
113+ if m := mysqldumpVersionRegexpMaria .FindSubmatch (helpOutput ); m != nil {
114+ return string (m [1 ])
115+ }
116+
117+ return ""
118+ }
119+
120+ func (d * Dumper ) detectSourceDataSupported (version string ) bool {
121+ // Failed to detect mysqldump version
122+ if version == "" {
123+ return false
124+ }
125+
126+ // MySQL 5.x
127+ if version [0 ] == byte ('5' ) {
128+ return false
129+ }
130+
131+ if strings .Contains (version , "MariaDB" ) {
87132 return false
88133 }
89- return bytes .Contains (out , []byte (`--column-statistics` ))
134+
135+ return true
90136}
91137
92138func (d * Dumper ) SetCharset (charset string ) {
@@ -169,7 +215,11 @@ func (d *Dumper) Dump(w io.Writer) error {
169215 passwordArgIndex := len (args ) - 1
170216
171217 if ! d .masterDataSkipped {
172- args = append (args , "--master-data" )
218+ if d .sourceDataSupported {
219+ args = append (args , "--source-data" )
220+ } else {
221+ args = append (args , "--master-data" )
222+ }
173223 }
174224
175225 if d .maxAllowedPacket > 0 {
0 commit comments