Skip to content

Commit

Permalink
Use only one table to operate - status table
Browse files Browse the repository at this point in the history
  • Loading branch information
AMecea committed May 10, 2019
1 parent 2037b0c commit 181909f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 47 deletions.
4 changes: 3 additions & 1 deletion pkg/controller/mysqlcluster/internal/syncer/statefullset.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ func (s *sfsSyncer) ensureContainersSpec() []core.Container {
"mysql",
fmt.Sprintf("--defaults-file=%s", confClientPath),
"-e",
fmt.Sprintf("SELECT * FROM %s.%s", constants.OperatorDbName, constants.OperatorReadinessTableName),
// nolint: gosec
fmt.Sprintf("SELECT * FROM %s.%s WHERE name='configured' AND value='1'",
constants.OperatorDbName, constants.OperatorStatusTableName),
},
},
})
Expand Down
52 changes: 22 additions & 30 deletions pkg/controller/node/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,9 @@ func (r *nodeSQLRunner) ChangeMasterTo(ctx context.Context, masterHost, user, pa

// MarkConfigurationDone write in a MEMORY table value. The readiness probe checks for that value to exist to succeed.
func (r *nodeSQLRunner) MarkConfigurationDone(ctx context.Context) error {
query := `
CREATE TABLE IF NOT EXISTS %s.%s (
ok tinyint(1) NOT NULL
) ENGINE=MEMORY;
INSERT INTO %[1]s.%[2]s VALUES (1);
`
query = fmt.Sprintf(query, constants.OperatorDbName, constants.OperatorReadinessTableName)
// nolint: gosec
query := fmt.Sprintf("REPLACE INTO %s.%s VALUES ('%s', '1');",
constants.OperatorDbName, constants.OperatorStatusTableName, "configured")

if err := r.runQuery(ctx, query); err != nil {
return fmt.Errorf("failed to mark configuration done, err: %s", err)
Expand Down Expand Up @@ -203,38 +198,35 @@ func (r *nodeSQLRunner) dbConn() (*sql.DB, func(), error) {
}

func (r *nodeSQLRunner) SetPurgedGTID(ctx context.Context) error {
// first check if the GTID should be set, if the table exists or if the GTID was set before (used)
// first check if the GTID should be set, if in the status table is a key with the GTID that was set
// nolint: gosec
qq := fmt.Sprintf("SELECT used FROM %[1]s.%[2]s WHERE id=1",
constants.OperatorDbName, constants.OperatorGtidsTableName)

var used bool
if err := r.readFromMysql(ctx, qq, &used); err != nil {
// if it's a: "Table doesn't exist" error then GTID should not be set, it's a master case.
if isMySQLError(err, 1146) || err == sql.ErrNoRows {
log.V(1).Info("GTID purged table does not exists", "host", r.Host())
return nil
qq := fmt.Sprintf("SELECT value FROM %s.%s WHERE name='%s'",
constants.OperatorDbName, constants.OperatorStatusTableName, "set_gtid_purged")

var value string
if err := r.readFromMysql(ctx, qq, &value); err != nil {
// if no rows found then continue to add GTID purged
if err != sql.ErrNoRows {
return err
}

return err
}

if used {
log.V(1).Info("GTID purged set", "host", r.Host())
if len(value) != 0 {
log.V(1).Info("GTID purged was already set", "host", r.Host(), "gtid_purged", value)
return nil
}

// GTID exists and should be set in a transaction
// nolint: gosec
query := fmt.Sprintf(`
SET @@SESSION.SQL_LOG_BIN = 0;
START TRANSACTION;
SELECT gtid INTO @gtid FROM %[1]s.%[2]s WHERE id=1 AND used=false;
RESET MASTER;
SET @@GLOBAL.GTID_PURGED = @gtid;
REPLACE INTO %[1]s.%[2]s VALUES (1, @gtid, true);
COMMIT;
`, constants.OperatorDbName, constants.OperatorGtidsTableName)
SET @@SESSION.SQL_LOG_BIN = 0;
START TRANSACTION;
SELECT value INTO @gtid FROM %[1]s.%[2]s WHERE name='%s';
RESET MASTER;
SET @@GLOBAL.GTID_PURGED = @gtid;
REPLACE INTO %[1]s.%[2]s VALUES ('%s', @gtid);
COMMIT;
`, constants.OperatorDbName, constants.OperatorStatusTableName, "backup_gtid_purged", "set_gtid_purged")

if err := r.runQuery(ctx, query); err != nil {
return err
Expand Down
25 changes: 15 additions & 10 deletions pkg/sidecar/appconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,19 +179,24 @@ func initFileQuery(cfg *Config, gtidPurged string) []byte {
[]string{"CREATE", "SELECT", "DELETE", "UPDATE", "INSERT"}, fmt.Sprintf("%s.%s", toolsDbName, toolsHeartbeatTableName),
[]string{"REPLICATION CLIENT"}, "*.*")...)

if len(gtidPurged) != 0 {
// If the xtrabackup information has GTID_PURGED then insert it into a table
// nolint: gosec
queries = append(queries, fmt.Sprintf(`
// create the status table used by the operator to configure or to mask MySQL node ready
// nolint: gosec
queries = append(queries, fmt.Sprintf(`
CREATE TABLE IF NOT EXISTS %[1]s.%[2]s (
id int PRIMARY KEY,
gtid varchar(512) NOT NULL,
used BOOLEAN DEFAULT false
)`, constants.OperatorDbName, constants.OperatorGtidsTableName))
name varchar(64) PRIMARY KEY,
value varchar(512) NOT NULL
)`, constants.OperatorDbName, constants.OperatorStatusTableName))

// mark node as not configured at startup, the operator will mark it configured
// nolint: gosec
queries = append(queries, fmt.Sprintf("REPLACE INTO %s.%s VALUES ('%s', '0')",
constants.OperatorDbName, constants.OperatorStatusTableName, "configured"))

if len(gtidPurged) != 0 {
// if gtid is found in the backup then set it in the status table to be processed by the operator
// nolint: gosec
queries = append(queries, fmt.Sprintf(`REPLACE INTO %s.%s (id, gtid) VALUES (1, '%s')`,
constants.OperatorDbName, constants.OperatorGtidsTableName, gtidPurged))
queries = append(queries, fmt.Sprintf(`REPLACE INTO %s.%s VALUES ('%s', '%s')`,
constants.OperatorDbName, constants.OperatorStatusTableName, "backup_gtid_purged", gtidPurged))
}

return []byte(strings.Join(queries, ";\n") + ";\n")
Expand Down
2 changes: 1 addition & 1 deletion pkg/sidecar/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (s *server) backupHandler(w http.ResponseWriter, r *http.Request) {

// nolint: gosec
xtrabackup := exec.Command("xtrabackup", "--backup", "--slave-info", "--stream=xbstream",
fmt.Sprintf("--tables-exclude=%s.%s", constants.OperatorDbName, constants.OperatorGtidsTableName),
fmt.Sprintf("--tables-exclude=%s.%s", constants.OperatorDbName, constants.OperatorStatusTableName),
"--host=127.0.0.1", fmt.Sprintf("--user=%s", s.cfg.ReplicationUser),
fmt.Sprintf("--password=%s", s.cfg.ReplicationPassword),
"--target-dir=/tmp/xtrabackup_backupfiles/")
Expand Down
8 changes: 3 additions & 5 deletions pkg/util/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,9 @@ const (
// SlaveLagQuery in hack/charts/mysql-operator/values.yaml.
OperatorDbName = "sys_operator"

// OperatorGtidsTableName represents the name of the table that is used to store the GTID
OperatorGtidsTableName = "gtids"

// OperatorReadinessTableName is the name of the table that is used to store a readiness flag (boolean)
OperatorReadinessTableName = "readiness"
// OperatorStatusTableName represents the name of the table that contains information about MySQL status, like:
// if mysql is configure by the operator, if PURGE_GTID is set or not, etc
OperatorStatusTableName = "status"

// ConfVolumeMountPath is the path where mysql configs will be mounted
ConfVolumeMountPath = "/etc/mysql"
Expand Down

0 comments on commit 181909f

Please sign in to comment.