Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing upgrade path from / downgrade path to v8.0.0 #7294

Merged
merged 32 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c22820d
WIP: testing version upgrade
shlomi-noach Jan 14, 2021
f6b2e1a
add test to endtoend list
shlomi-noach Jan 14, 2021
fbb713c
add workflow file
shlomi-noach Jan 14, 2021
54503c8
test file
shlomi-noach Jan 14, 2021
28a755e
refactor test structure
shlomi-noach Jan 14, 2021
895077c
force vtdataroot path, base tablet uid, base port
shlomi-noach Jan 14, 2021
f10861a
skip creating keyspace
shlomi-noach Jan 17, 2021
2d37ac8
avoid initializing mysql if reusing data; expect tablets to be SERVIN…
shlomi-noach Jan 17, 2021
1c60d40
only creating and populating table if we created mysql in the first p…
shlomi-noach Jan 17, 2021
b52d1cf
renamed test. there's nothing 8.0 specific about it
shlomi-noach Jan 17, 2021
b59281c
renamed versionupgrade directory
shlomi-noach Jan 17, 2021
b47c567
some comments explaining the purpose of upgrade_test
shlomi-noach Jan 17, 2021
2ea57f0
supply force flags for versionupgrade test
shlomi-noach Jan 17, 2021
95bc6ce
run PR vs v8.0.0
shlomi-noach Jan 17, 2021
f56f458
a bit of debug info
shlomi-noach Jan 17, 2021
6177d1f
keep-data on test.go level
shlomi-noach Jan 17, 2021
b12482b
skip build
shlomi-noach Jan 17, 2021
e3837db
adding debug info
shlomi-noach Jan 17, 2021
7556694
adding debug info
shlomi-noach Jan 17, 2021
d8a5229
backup and restore bin/ dir
shlomi-noach Jan 17, 2021
38546d6
adding debug info
shlomi-noach Jan 17, 2021
a85e9e0
building HEAD branch, and then copying v8.0.0 binaries on top
shlomi-noach Jan 17, 2021
e6bd0e4
explicit ddl_strategy
shlomi-noach Jan 17, 2021
4da6114
temporary: trying with normal HEAD build
shlomi-noach Jan 17, 2021
9a5814d
do not pass -ddl_strategy for v8.0.0
shlomi-noach Jan 17, 2021
5077c18
copy directory
shlomi-noach Jan 17, 2021
e62170a
comments
shlomi-noach Jan 17, 2021
447cdd5
test downgrade path
shlomi-noach Jan 17, 2021
52e0bcf
build.env
shlomi-noach Jan 17, 2021
510917a
refactor steps a bit to make them more symmetrical
shlomi-noach Jan 17, 2021
a08be65
copyright year
shlomi-noach Jan 19, 2021
3c52a4c
typo
shlomi-noach Jan 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions .github/workflows/cluster_endtoend_upgrade.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Cluster (upgrade)
on: [push, pull_request]
jobs:

build:
name: Run endtoend tests on Cluster (upgrade)
runs-on: ubuntu-latest

steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.15

- name: Check out v8.0.0
uses: actions/checkout@v2
with:
ref: v8.0.0

- name: Get dependencies
run: |
# This prepares general purpose binary dependencies
# as well as v8.0.0 specific go modules
sudo apt-get update
sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata
sudo service mysql stop
sudo service etcd stop
sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
go mod download

wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt-get install -y gnupg2
sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
sudo apt-get update
sudo apt-get install percona-xtrabackup-24

- name: Building v8.0.0 binaries
timeout-minutes: 10
run: |
# We build v8.0.0 binaries and save them in a temporary location
source build.env
make build
mkdir -p /tmp/vitess-build-v8.0.0/
cp -R bin /tmp/vitess-build-v8.0.0/

- name: Check out HEAD
uses: actions/checkout@v2

- name: Run cluster endtoend test v8.0.0 (create cluster)
timeout-minutes: 5
run: |
# By checking out we deleted bin/ directory. We now restore our pre-built v8.0.0 binaries
cp -R /tmp/vitess-build-v8.0.0/bin .
# create the directory where we store test data; ensure it is empty:
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
source build.env
# We pass -skip-build so that we use the v8.0.0 binaries, not HEAD binaries
eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28

- name: Check out HEAD
uses: actions/checkout@v2


- name: Building HEAD binaries
timeout-minutes: 10
run: |
go mod download

source build.env
make build
mkdir -p /tmp/vitess-build-head/
cp -R bin /tmp/vitess-build-head/

- name: Run cluster endtoend test HEAD based on v8.0.0 data (upgrade path)
timeout-minutes: 5
run: |
# /tmp/vtdataroot exists from previous test

source build.env
# We built HEAD binaries manually in previous step and there's no need for the test to build.
eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28

- name: Run cluster endtoend test HEAD (create cluster)
timeout-minutes: 5
run: |
# create the directory where we store test data; ensure it is empty:
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot

source build.env
# We still have the binaries from previous step. No need to build
eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28


- name: Run cluster endtoend test v8.0.0 based on HEAD data (downgrade path)
timeout-minutes: 5
run: |
# /tmp/vtdataroot exists from previous test
cp -R /tmp/vitess-build-v8.0.0/bin .

source build.env
# We again built manually and there's no need for the test to build.
eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28
73 changes: 53 additions & 20 deletions go/test/endtoend/cluster/cluster_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ const (
)

var (
keepData = flag.Bool("keep-data", false, "don't delete the per-test VTDATAROOT subfolders")
topoFlavor = flag.String("topo-flavor", "etcd2", "choose a topo server from etcd2, zk2 or consul")
isCoverage = flag.Bool("is-coverage", false, "whether coverage is required")
keepData = flag.Bool("keep-data", false, "don't delete the per-test VTDATAROOT subfolders")
topoFlavor = flag.String("topo-flavor", "etcd2", "choose a topo server from etcd2, zk2 or consul")
isCoverage = flag.Bool("is-coverage", false, "whether coverage is required")
forceVTDATAROOT = flag.String("force-vtdataroot", "", "force path for VTDATAROOT, which may already be populated")
forcePortStart = flag.Int("force-port-start", 0, "force assigning ports based on this seed")
forceBaseTabletUID = flag.Int("force-base-tablet-uid", 0, "force assigning tablet ports based on this seed")
)

// LocalProcessCluster Testcases need to use this to iniate a cluster
Expand All @@ -57,6 +60,7 @@ type LocalProcessCluster struct {
TmpDirectory string
OriginalVTDATAROOT string
CurrentVTDATAROOT string
ReusingVTDATAROOT bool

VtgateMySQLPort int
VtgateGrpcPort int
Expand Down Expand Up @@ -192,10 +196,12 @@ func (cluster *LocalProcessCluster) StartTopo() (err error) {
}
}

cluster.VtctlProcess = *VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname)
if err = cluster.VtctlProcess.AddCellInfo(cluster.Cell); err != nil {
log.Error(err)
return
if !cluster.ReusingVTDATAROOT {
cluster.VtctlProcess = *VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname)
if err = cluster.VtctlProcess.AddCellInfo(cluster.Cell); err != nil {
log.Error(err)
return
}
}

cluster.VtctldProcess = *VtctldProcessInstance(cluster.GetAndReservePort(), cluster.GetAndReservePort(),
Expand Down Expand Up @@ -230,7 +236,9 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames
}

log.Infof("Starting keyspace: %v", keyspace.Name)
_ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name)
if !cluster.ReusingVTDATAROOT {
_ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name)
}
var mysqlctlProcessList []*exec.Cmd
for _, shardName := range shardNames {
shard := &Shard{
Expand All @@ -256,7 +264,7 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames
}
// Start Mysqlctl process
log.Infof("Starting mysqlctl for table uid %d, mysql port %d", tablet.TabletUID, tablet.MySQLPort)
tablet.MysqlctlProcess = *MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, cluster.TmpDirectory)
tablet.MysqlctlProcess = *MysqlCtlProcessInstanceOptionalInit(tablet.TabletUID, tablet.MySQLPort, cluster.TmpDirectory, !cluster.ReusingVTDATAROOT)
proc, err := tablet.MysqlctlProcess.StartProcess()
if err != nil {
log.Errorf("error starting mysqlctl process: %v, %v", tablet.MysqlctldProcess, err)
Expand All @@ -279,6 +287,9 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames
cluster.VtTabletExtraArgs,
cluster.EnableSemiSync)
tablet.Alias = tablet.VttabletProcess.TabletPath
if cluster.ReusingVTDATAROOT {
tablet.VttabletProcess.ServingStatus = "SERVING"
}
shard.Vttablets = append(shard.Vttablets, tablet)
// Apply customizations
for _, customizer := range customizers {
Expand All @@ -298,9 +309,11 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames
}
}
for _, tablet := range shard.Vttablets {
if _, err = tablet.VttabletProcess.QueryTablet(fmt.Sprintf("create database vt_%s", keyspace.Name), keyspace.Name, false); err != nil {
log.Errorf("error creating database for keyspace %v: %v", keyspace.Name, err)
return
if !cluster.ReusingVTDATAROOT {
if _, err = tablet.VttabletProcess.QueryTablet(fmt.Sprintf("create database vt_%s", keyspace.Name), keyspace.Name, false); err != nil {
log.Errorf("error creating database for keyspace %v: %v", keyspace.Name, err)
return
}
}

log.Infof("Starting vttablet for tablet uid %d, grpc port %d", tablet.TabletUID, tablet.GrpcPort)
Expand Down Expand Up @@ -358,11 +371,13 @@ func (cluster *LocalProcessCluster) SetupCluster(keyspace *Keyspace, shards []Sh

log.Infof("Starting keyspace: %v", keyspace.Name)

// Create Keyspace
err = cluster.VtctlProcess.CreateKeyspace(keyspace.Name)
if err != nil {
log.Error(err)
return
if !cluster.ReusingVTDATAROOT {
// Create Keyspace
err = cluster.VtctlProcess.CreateKeyspace(keyspace.Name)
if err != nil {
log.Error(err)
return
}
}

// Create shard
Expand Down Expand Up @@ -441,8 +456,18 @@ func NewCluster(cell string, hostname string) *LocalProcessCluster {
go cluster.CtrlCHandler()
cluster.OriginalVTDATAROOT = os.Getenv("VTDATAROOT")
cluster.CurrentVTDATAROOT = path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("vtroot_%d", cluster.GetAndReservePort()))
_ = createDirectory(cluster.CurrentVTDATAROOT, 0700)
if *forceVTDATAROOT != "" {
cluster.CurrentVTDATAROOT = *forceVTDATAROOT
}
if _, err := os.Stat(cluster.CurrentVTDATAROOT); err == nil {
// path/to/whatever exists
cluster.ReusingVTDATAROOT = true
} else {
_ = createDirectory(cluster.CurrentVTDATAROOT, 0700)
}
_ = os.Setenv("VTDATAROOT", cluster.CurrentVTDATAROOT)
log.Infof("Created cluster on %s. ReusingVTDATAROOT=%v", cluster.CurrentVTDATAROOT, cluster.ReusingVTDATAROOT)

rand.Seed(time.Now().UTC().UnixNano())
return cluster
}
Expand Down Expand Up @@ -591,7 +616,11 @@ func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initalBa
// GetAndReservePort gives port for required process
func (cluster *LocalProcessCluster) GetAndReservePort() int {
if cluster.nextPortForProcess == 0 {
cluster.nextPortForProcess = getPort()
if *forcePortStart > 0 {
cluster.nextPortForProcess = *forcePortStart
} else {
cluster.nextPortForProcess = getPort()
}
}
for {
cluster.nextPortForProcess = cluster.nextPortForProcess + 1
Expand Down Expand Up @@ -634,7 +663,11 @@ func getPort() int {
// GetAndReserveTabletUID gives tablet uid
func (cluster *LocalProcessCluster) GetAndReserveTabletUID() int {
if cluster.BaseTabletUID == 0 {
cluster.BaseTabletUID = getRandomNumber(10000, 0)
if *forceBaseTabletUID > 0 {
cluster.BaseTabletUID = *forceBaseTabletUID
} else {
cluster.BaseTabletUID = getRandomNumber(10000, 0)
}
}
cluster.BaseTabletUID = cluster.BaseTabletUID + 1
return cluster.BaseTabletUID
Expand Down
12 changes: 9 additions & 3 deletions go/test/endtoend/cluster/mysqlctl_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ func (mysqlctl *MysqlctlProcess) CleanupFiles(tabletUID int) {
os.RemoveAll(path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/vt_%010d/innodb", tabletUID)))
}

// MysqlCtlProcessInstance returns a Mysqlctl handle for mysqlctl process
// MysqlCtlProcessInstanceOptionalInit returns a Mysqlctl handle for mysqlctl process
// configured with the given Config.
func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string) *MysqlctlProcess {
func MysqlCtlProcessInstanceOptionalInit(tabletUID int, mySQLPort int, tmpDirectory string, initMySQL bool) *MysqlctlProcess {
mysqlctl := &MysqlctlProcess{
Name: "mysqlctl",
Binary: "mysqlctl",
Expand All @@ -172,11 +172,17 @@ func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string)
}
mysqlctl.MySQLPort = mySQLPort
mysqlctl.TabletUID = tabletUID
mysqlctl.InitMysql = true
mysqlctl.InitMysql = initMySQL
mysqlctl.SecureTransport = false
return mysqlctl
}

// MysqlCtlProcessInstance returns a Mysqlctl handle for mysqlctl process
// configured with the given Config.
func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string) *MysqlctlProcess {
return MysqlCtlProcessInstanceOptionalInit(tabletUID, mySQLPort, tmpDirectory, true)
}

// StartMySQL starts mysqlctl process
func StartMySQL(ctx context.Context, tablet *Vttablet, username string, tmpDirectory string) error {
tablet.MysqlctlProcess = *MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, tmpDirectory)
Expand Down
14 changes: 9 additions & 5 deletions go/test/endtoend/cluster/vtctlclient_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,20 @@ func (vtctlclient *VtctlClientProcess) InitShardMaster(Keyspace string, Shard st

// ApplySchemaWithOutput applies SQL schema to the keyspace
func (vtctlclient *VtctlClientProcess) ApplySchemaWithOutput(Keyspace string, SQL string, ddlStrategy string) (result string, err error) {
return vtctlclient.ExecuteCommandWithOutput(
args := []string{
"ApplySchema",
"-sql", SQL,
"-ddl_strategy", ddlStrategy,
Keyspace)
}
if ddlStrategy != "" {
args = append(args, "-ddl_strategy", ddlStrategy)
}
args = append(args, Keyspace)
return vtctlclient.ExecuteCommandWithOutput(args...)
}

// ApplySchema applies SQL schema to the keyspace
func (vtctlclient *VtctlClientProcess) ApplySchema(Keyspace string, SQL string) (err error) {
_, err = vtctlclient.ApplySchemaWithOutput(Keyspace, SQL, "")
_, err = vtctlclient.ApplySchemaWithOutput(Keyspace, SQL, "direct")
return err
}

Expand Down Expand Up @@ -96,7 +100,7 @@ func (vtctlclient *VtctlClientProcess) OnlineDDLCancelMigration(Keyspace, uuid s
)
}

// OnlineDDLCancelMigration cancels a given migration uuid
// OnlineDDLCancelAllMigrations cancels all migrations for a keyspace
func (vtctlclient *VtctlClientProcess) OnlineDDLCancelAllMigrations(Keyspace string) (result string, err error) {
return vtctlclient.ExecuteCommandWithOutput(
"OnlineDDL",
Expand Down
Loading