vitess.io/vitess@v0.16.2/go/test/endtoend/backup/vtbackup/main_test.go (about)

     1  /*
     2  Copyright 2019 The Vitess Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package vtbackup
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"os"
    23  	"os/exec"
    24  	"path"
    25  	"testing"
    26  
    27  	"vitess.io/vitess/go/test/endtoend/cluster"
    28  	"vitess.io/vitess/go/vt/log"
    29  )
    30  
    31  var (
    32  	primary          *cluster.Vttablet
    33  	replica1         *cluster.Vttablet
    34  	replica2         *cluster.Vttablet
    35  	localCluster     *cluster.LocalProcessCluster
    36  	newInitDBFile    string
    37  	cell             = cluster.DefaultCell
    38  	hostname         = "localhost"
    39  	keyspaceName     = "ks"
    40  	shardName        = "0"
    41  	dbPassword       = "VtDbaPass"
    42  	shardKsName      = fmt.Sprintf("%s/%s", keyspaceName, shardName)
    43  	dbCredentialFile string
    44  	commonTabletArg  = []string{
    45  		"--vreplication_healthcheck_topology_refresh", "1s",
    46  		"--vreplication_healthcheck_retry_delay", "1s",
    47  		"--vreplication_retry_delay", "1s",
    48  		"--degraded_threshold", "5s",
    49  		"--lock_tables_timeout", "5s",
    50  		"--watch_replication_stream",
    51  		"--enable_replication_reporter",
    52  		"--serving_state_grace_period", "1s"}
    53  )
    54  
    55  func TestMain(m *testing.M) {
    56  	defer cluster.PanicHandler(nil)
    57  	flag.Parse()
    58  
    59  	exitCode, err := func() (int, error) {
    60  		localCluster = cluster.NewCluster(cell, hostname)
    61  		defer localCluster.Teardown()
    62  
    63  		// Start topo server
    64  		err := localCluster.StartTopo()
    65  		if err != nil {
    66  			return 1, err
    67  		}
    68  
    69  		// Start keyspace
    70  		localCluster.Keyspaces = []cluster.Keyspace{
    71  			{
    72  				Name: keyspaceName,
    73  				Shards: []cluster.Shard{
    74  					{
    75  						Name: shardName,
    76  					},
    77  				},
    78  			},
    79  		}
    80  		shard := &localCluster.Keyspaces[0].Shards[0]
    81  		vtctldClientProcess := cluster.VtctldClientProcessInstance("localhost", localCluster.VtctldProcess.GrpcPort, localCluster.TmpDirectory)
    82  		_, err = vtctldClientProcess.ExecuteCommandWithOutput("CreateKeyspace", keyspaceName, "--durability-policy=semi_sync")
    83  		if err != nil {
    84  			return 1, err
    85  		}
    86  
    87  		// Create a new init_db.sql file that sets up passwords for all users.
    88  		// Then we use a db-credentials-file with the passwords.
    89  		dbCredentialFile = cluster.WriteDbCredentialToTmp(localCluster.TmpDirectory)
    90  		initDb, _ := os.ReadFile(path.Join(os.Getenv("VTROOT"), "/config/init_db.sql"))
    91  		sql := string(initDb)
    92  		newInitDBFile = path.Join(localCluster.TmpDirectory, "init_db_with_passwords.sql")
    93  		sql = sql + cluster.GetPasswordUpdateSQL(localCluster)
    94  		err = os.WriteFile(newInitDBFile, []byte(sql), 0666)
    95  		if err != nil {
    96  			return 1, err
    97  		}
    98  
    99  		extraArgs := []string{"--db-credentials-file", dbCredentialFile}
   100  		commonTabletArg = append(commonTabletArg, "--db-credentials-file", dbCredentialFile)
   101  
   102  		primary = localCluster.NewVttabletInstance("replica", 0, "")
   103  		replica1 = localCluster.NewVttabletInstance("replica", 0, "")
   104  		replica2 = localCluster.NewVttabletInstance("replica", 0, "")
   105  		shard.Vttablets = []*cluster.Vttablet{primary, replica1, replica2}
   106  
   107  		// Start MySql processes
   108  		var mysqlProcs []*exec.Cmd
   109  		for _, tablet := range shard.Vttablets {
   110  			tablet.VttabletProcess = localCluster.VtprocessInstanceFromVttablet(tablet, shard.Name, keyspaceName)
   111  			tablet.VttabletProcess.DbPassword = dbPassword
   112  			tablet.VttabletProcess.ExtraArgs = commonTabletArg
   113  			tablet.VttabletProcess.SupportsBackup = true
   114  
   115  			tablet.MysqlctlProcess = *cluster.MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, localCluster.TmpDirectory)
   116  			tablet.MysqlctlProcess.InitDBFile = newInitDBFile
   117  			tablet.MysqlctlProcess.ExtraArgs = extraArgs
   118  			proc, err := tablet.MysqlctlProcess.StartProcess()
   119  			if err != nil {
   120  				return 1, err
   121  			}
   122  			mysqlProcs = append(mysqlProcs, proc)
   123  		}
   124  		for _, proc := range mysqlProcs {
   125  			if err := proc.Wait(); err != nil {
   126  				return 1, err
   127  			}
   128  		}
   129  
   130  		// Create database
   131  		for _, tablet := range []cluster.Vttablet{*primary, *replica1} {
   132  			if err := tablet.VttabletProcess.CreateDB(keyspaceName); err != nil {
   133  				return 1, err
   134  			}
   135  		}
   136  
   137  		if localCluster.VtTabletMajorVersion >= 16 {
   138  			// If vttablets are any lower than version 16, then they are running the replication manager.
   139  			// Running VTOrc and replication manager sometimes creates the situation where VTOrc has set up semi-sync on the primary,
   140  			// but the replication manager starts replication on the replica without setting semi-sync. This hangs the primary.
   141  			// Even if VTOrc fixes it, since there is no ongoing traffic, the state remains blocked.
   142  			if err := localCluster.StartVTOrc(keyspaceName); err != nil {
   143  				return 1, err
   144  			}
   145  		}
   146  
   147  		return m.Run(), nil
   148  	}()
   149  
   150  	if err != nil {
   151  		log.Error(err.Error())
   152  		os.Exit(1)
   153  	} else {
   154  		os.Exit(exitCode)
   155  	}
   156  
   157  }