Repository: pingcap/dumpling
Pull request #208 (2020-12-02 09:46:32)

export: don't write SHOW MASTER STATUS when lacking privilege
<!--
Thank you for contributing to Dumpling! Please read the [CONTRIBUTING](https://github.com/pingcap/dumpling/blob/master/CONTRIBUTING.md) document **BEFORE** filing this PR.

If you want to open the **Challenge Program** pull request, please use the following template:
https://raw.githubusercontent.com/pingcap/.github/master/.github/PULL_REQUEST_TEMPLATE/challenge-program.md

You can use it with query parameters: https://github.com/pingcap/dumpling/compare/master...${you branch}?template=challenge-program.md
-->

### What problem does this PR solve? <!--add issue link with summary if exists-->

part of https://github.com/pingcap/dm/issues/1320

### What is changed and how it works?

don't write SHOW MASTER STATUS when lacking privilege

### Check List <!--REMOVE the items that are not applicable-->

Tests <!-- At least one of them must be included. -->

 - Unit test
 - Manual test

Side effects

 - Breaking backward compatibility (**but keep same with mydumper**)

Related changes

 
### Release note

- No release note



Patch:
diff --git a/v4/export/metadata.go b/v4/export/metadata.go
index d9cc602..e3a9f90 100644
--- a/v4/export/metadata.go
+++ b/v4/export/metadata.go
@@ -65,12 +65,14 @@ func (m *globalMetadata) recordGlobalMetaData(db *sql.Conn, serverType ServerTyp
 }
 
 func recordGlobalMetaData(db *sql.Conn, buffer *bytes.Buffer, serverType ServerType, afterConn bool, snapshot string) error {
-	// get master status info
-	buffer.WriteString("SHOW MASTER STATUS:")
-	if afterConn {
-		buffer.WriteString(" /* AFTER CONNECTION POOL ESTABLISHED */")
+	writeMasterStatusHeader := func() {
+		buffer.WriteString("SHOW MASTER STATUS:")
+		if afterConn {
+			buffer.WriteString(" /* AFTER CONNECTION POOL ESTABLISHED */")
+		}
+		buffer.WriteString("\n")
 	}
-	buffer.WriteString("\n")
+
 	switch serverType {
 	// For MySQL:
 	// mysql 5.6+
@@ -106,6 +108,7 @@ func recordGlobalMetaData(db *sql.Conn, buffer *bytes.Buffer, serverType ServerT
 		gtidSet := getValidStr(str, gtidSetFieldIndex)
 
 		if logFile != "" {
+			writeMasterStatusHeader()
 			fmt.Fprintf(buffer, "\tLog: %s\n\tPos: %s\n\tGTID:%s\n", logFile, pos, gtidSet)
 		}
 	// For MariaDB:
@@ -136,6 +139,7 @@ func recordGlobalMetaData(db *sql.Conn, buffer *bytes.Buffer, serverType ServerT
 		}
 
 		if logFile != "" {
+			writeMasterStatusHeader()
 			fmt.Fprintf(buffer, "\tLog: %s\n\tPos: %s\n\tGTID:%s\n", logFile, pos, gtidSet)
 		}
 	default:


Test patch:
diff --git a/v4/export/metadata_test.go b/v4/export/metadata_test.go
index 0cdf3ca..ed1e0c9 100644
--- a/v4/export/metadata_test.go
+++ b/v4/export/metadata_test.go
@@ -4,6 +4,7 @@ package export
 
 import (
 	"context"
+	"errors"
 	"fmt"
 
 	"github.com/DATA-DOG/go-sqlmock"
@@ -269,3 +270,18 @@ func (s *testMetaDataSuite) TestTiDBSnapshotMetaData(c *C) {
 		"\tGTID:\n\n")
 	c.Assert(mock.ExpectationsWereMet(), IsNil)
 }
+
+func (s *testMetaDataSuite) TestNoPrivilege(c *C) {
+	db, mock, err := sqlmock.New()
+	c.Assert(err, IsNil)
+	defer db.Close()
+	conn, err := db.Conn(context.Background())
+	c.Assert(err, IsNil)
+
+	mock.ExpectQuery("SHOW MASTER STATUS").WillReturnError(errors.New("lack SUPER or REPLICATION CLIENT privilege"))
+
+	m := newGlobalMetadata(s.createStorage(c), "")
+	// some consistencyType will ignore this error, this test make sure no extra message is written
+	c.Assert(m.recordGlobalMetaData(conn, ServerTypeTiDB, false), NotNil)
+	c.Assert(m.buffer.String(), Equals, "")
+}