Skip to content

Commit

Permalink
DBZ-6981 Update scripts to match those used in Vitess 17.0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
twthorn committed Oct 4, 2023
1 parent 41976ef commit 25f1f0a
Show file tree
Hide file tree
Showing 10 changed files with 309 additions and 44 deletions.
19 changes: 10 additions & 9 deletions src/test/docker/local/env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,27 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source ./scripts/utils.sh

hostname=$(hostname -f)
vtctld_web_port=15000
export VTDATAROOT="${VTDATAROOT:-${PWD}/vtdataroot}"

function fail() {
echo "ERROR: $1"
exit 1
}

if [[ $EUID -eq 0 ]]; then
fail "This script refuses to be run as root. Please switch to a regular user."
fi

# mysqld might be in /usr/sbin which will not be in the default PATH
PATH="/usr/sbin:$PATH"
for binary in mysqld etcd etcdctl curl vtctlclient vttablet vtgate vtctld mysqlctl; do
for binary in mysqld etcd etcdctl curl vtctlclient vtctldclient vttablet vtgate vtctld mysqlctl; do
command -v "$binary" > /dev/null || fail "${binary} is not installed in PATH. See https://vitess.io/docs/get-started/local/ for install instructions."
done;

# vtctlclient has a separate alias setup below
for binary in vttablet vtgate vtctld mysqlctl vtorc vtctl; do
alias $binary="$binary --config-file-not-found-handling=ignore"
done;

ETCD_SERVER="localhost:2379"
TOPOLOGY_FLAGS="--topo_implementation etcd2 --topo_global_server_address $ETCD_SERVER --topo_global_root /vitess/global"
mkdir -p "${VTDATAROOT}/etcd"
Expand All @@ -43,9 +44,9 @@ mkdir -p "${VTDATAROOT}/tmp"
# In your own environment you may prefer to use config files,
# such as ~/.my.cnf

alias mysql="command mysql -h 127.0.0.1 -P 15306"
alias vtctlclient="command vtctlclient --server localhost:15999 --log_dir ${VTDATAROOT}/tmp --alsologtostderr"
alias vtctldclient="command vtctldclient --server localhost:15999 --log_dir ${VTDATAROOT}/tmp --alsologtostderr"
alias mysql="command mysql --no-defaults -h 127.0.0.1 -P 15306"
alias vtctlclient="command vtctlclient --server localhost:15999 --log_dir ${VTDATAROOT}/tmp --alsologtostderr --config-file-not-found-handling=ignore"
alias vtctldclient="command vtctldclient --server localhost:15999"

# Make sure aliases are expanded in non-interactive shell
shopt -s expand_aliases
19 changes: 16 additions & 3 deletions src/test/docker/local/initial_cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,33 @@

source ./env.sh

SIDECAR_DB_NAME=${SIDECAR_DB_NAME:-"_vt"}

# start topo server
CELL=zone1 ./scripts/etcd-up.sh

# start vtctld
CELL=zone1 ./scripts/vtctld-up.sh

vtctldclient CreateKeyspace --sidecar-db-name="${SIDECAR_DB_NAME}" --durability-policy=semi_sync test_unsharded_keyspace || fail "Failed to create and configure unsharded keyspace"
vtctldclient CreateKeyspace --sidecar-db-name="${SIDECAR_DB_NAME}" --durability-policy=semi_sync test_sharded_keyspace || fail "Failed to create and configure unsharded keyspace"

# start vttablets for unsharded keyspace test_unsharded_keyspace
for i in 100 101 102; do
CELL=zone1 TABLET_UID=$i ./scripts/mysqlctl-up.sh
CELL=zone1 KEYSPACE=test_unsharded_keyspace TABLET_UID=$i ./scripts/vttablet-up.sh
done

# start vtorc
source ./scripts/vtorc-up.sh

# Wait for all the tablets to be up and registered in the topology server
# and for a primary tablet to be elected in the shard and become healthy/serving.
#TODO: Uncomment below once fixed
#wait_for_healthy_shard test_unsharded_keyspace 0 || exit 1

# set one of the replicas to primary
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json PlannedReparentShard -- --keyspace_shard=test_unsharded_keyspace/0 --new_primary=zone1-100
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json InitShardPrimary -- --force test_unsharded_keyspace/0 zone1-100

# start vttablets for sharded keyspace test_sharded_keyspace
for i in 200 201 202; do
Expand All @@ -33,8 +46,8 @@ for i in 300 301 302; do
SHARD=80- CELL=zone1 KEYSPACE=test_sharded_keyspace TABLET_UID=$i ./scripts/vttablet-up.sh
done

vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json PlannedReparentShard -- --keyspace_shard=test_sharded_keyspace/-80 --new_primary=zone1-200
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json PlannedReparentShard -- --keyspace_shard=test_sharded_keyspace/80- --new_primary=zone1-300
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json InitShardPrimary -- --force test_sharded_keyspace/-80 zone1-200
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json InitShardPrimary -- --force test_sharded_keyspace/80- zone1-300

# create seq table unsharded keyspace, other tables and vschema in sharded keyspace
vtctlclient --grpc_auth_static_client_creds grpc_static_client_auth.json ApplySchema -- --sql-file create_tables_unsharded.sql test_unsharded_keyspace
Expand Down
21 changes: 9 additions & 12 deletions src/test/docker/local/scripts/etcd-up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,33 @@
# See the License for the specific language governing permissions and
# limitations under the License.

source ./env.sh
# This is an example script that creates a quorum of Etcd servers.

source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh"

cell=${CELL:-'test'}
export ETCDCTL_API=2

echo "Starting etcd..."

# Check that etcd is not already running
curl "http://${ETCD_SERVER}" > /dev/null 2>&1 && fail "etcd is already running. Exiting."

etcd --enable-v2=true --data-dir "${VTDATAROOT}/etcd/" --listen-client-urls "http://${ETCD_SERVER}" --advertise-client-urls "http://${ETCD_SERVER}" > "${VTDATAROOT}"/tmp/etcd.out 2>&1 &
etcd --data-dir "${VTDATAROOT}/etcd/" --listen-client-urls "http://${ETCD_SERVER}" --advertise-client-urls "http://${ETCD_SERVER}" > "${VTDATAROOT}"/tmp/etcd.out 2>&1 &
PID=$!
echo $PID > "${VTDATAROOT}/tmp/etcd.pid"
sleep 5

echo "add /vitess/global"
etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/global &

echo "add /vitess/$cell"
etcdctl --endpoints "http://${ETCD_SERVER}" mkdir /vitess/$cell &

# And also add the CellInfo description for the cell.
# If the node already exists, it's fine, means we used existing data.
echo "add $cell CellInfo"
set +e
# shellcheck disable=SC2086
vtctl $TOPOLOGY_FLAGS AddCellInfo \
vtctl $TOPOLOGY_FLAGS VtctldCommand AddCellInfo \
--root /vitess/$cell \
--server_address "${ETCD_SERVER}" \
--server-address "${ETCD_SERVER}" \
$cell
set -e

echo "etcd start done..."
echo "etcd is running!"


6 changes: 5 additions & 1 deletion src/test/docker/local/scripts/mysqlctl-up.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

source ./env.sh
# This is an example script that creates a single shard vttablet deployment.

source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh"

cell=${CELL:-'test'}
uid=$TABLET_UID
Expand All @@ -38,3 +40,5 @@ mysqlctl \
--tablet_uid $uid \
--mysql_port $mysql_port \
$action

echo -e "MySQL for tablet $alias is running!"
212 changes: 212 additions & 0 deletions src/test/docker/local/scripts/utils.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
#!/bin/bash

# Copyright 2023 The Vitess Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file contains utility functions that can be used throughout the
# various examples.

# Wait for the given number of tablets to show up in the topology server
# for the keyspace/shard. Example (wait for 2 tablets in commerce/0):
# wait_for_shard_tablets commerce 0 2
function wait_for_shard_tablets() {
if [[ -z ${1} || -z ${2} || -z ${3} ]]; then
fail "A keyspace, shard, and number of tablets must be specified when waiting for tablets to come up"
fi
local keyspace=${1}
local shard=${2}
local num_tablets=${3}
local wait_secs=180

for _ in $(seq 1 ${wait_secs}); do
cur_tablets=$(vtctldclient GetTablets --keyspace "${keyspace}" --shard "${shard}" | wc -l)
if [[ ${cur_tablets} -eq ${num_tablets} ]]; then
break
fi
sleep 1
done;

cur_tablets=$(vtctldclient GetTablets --keyspace "${keyspace}" --shard "${shard}" | wc -l)
if [[ ${cur_tablets} -lt ${num_tablets} ]]; then
fail "Timed out after ${wait_secs} seconds waiting for tablets to come up in ${keyspace}/${shard}"
fi
}

# Wait for a primary tablet to be elected and become healthy and serving
# in the given keyspace/shard. Example:
# wait_for_healthy_shard commerce 0
function wait_for_healthy_shard_primary() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A keyspace and shard must be specified when waiting for the shard's primary to be healthy"
fi
local keyspace=${1}
local shard=${2}
local unhealthy_indicator='"primary_alias": null'
local wait_secs=180

for _ in $(seq 1 ${wait_secs}); do
if ! vtctldclient --server=localhost:15999 GetShard "${keyspace}/${shard}" | grep -qi "${unhealthy_indicator}"; then
break
fi
sleep 1
done;

if vtctldclient --server=localhost:15999 GetShard "${keyspace}/${shard}" | grep -qi "${unhealthy_indicator}"; then
fail "Timed out after ${wait_secs} seconds waiting for a primary tablet to be elected and become healthy in ${keyspace}/${shard}"
fi
}


# Wait for a primary tablet to be writeable, ie read_only=0 and super_read_only=0
function wait_for_writeable_shard_primary() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A keyspace and shard must be specified when waiting for the shard's primary to be healthy"
fi
local keyspace=${1}
local shard=${2}
local wait_secs=30

PRIMARY_TABLET="$(vtctldclient --server=localhost:15999 GetTablets --keyspace "$keyspace" --shard "$shard" | grep -w "primary" | awk '{print $1}')"
if [ -z "$PRIMARY_TABLET" ] ; then
fail "Cannot determine primary tablet for keyspace/shard $keyspace/$shard"
fi

for _ in $(seq 1 ${wait_secs}); do
if vtctldclient --server=localhost:15999 GetFullStatus "$PRIMARY_TABLET" | grep "super_read_only" | grep --quiet "false" ; then
break
fi
sleep 1
done
if vtctldclient --server=localhost:15999 GetFullStatus "$PRIMARY_TABLET" | grep "super_read_only" | grep --quiet "true" ; then
fail "Timed out after ${wait_secs} seconds waiting for a primary tablet $PRIMARY_TABLET to be writeable in ${keyspace}/${shard}"
fi
}

# Wait for the shard primary tablet's VReplication engine to open.
# There is currently no API call or client command that can be specifically used
# to check the VReplication engine's status (no vars in /debug/vars etc. either).
# So we use the Workflow listall client command as the method to check for that
# as it will return an error when the engine is closed -- even when there are
# no workflows.
function wait_for_shard_vreplication_engine() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A keyspace and shard must be specified when waiting for the shard primary tablet's VReplication engine to open"
fi
local keyspace=${1}
local shard=${2}
local wait_secs=90

for _ in $(seq 1 ${wait_secs}); do
if vtctlclient --server=localhost:15999 Workflow -- "${keyspace}" listall &>/dev/null; then
break
fi
sleep 1
done;

if ! vtctlclient --server=localhost:15999 Workflow -- "${keyspace}" listall &>/dev/null; then
fail "Timed out after ${wait_secs} seconds waiting for the primary tablet's VReplication engine to open in ${keyspace}/${shard}"
fi
}

# Wait for a specified number of the keyspace/shard's tablets to show up
# in the topology server (3 is the default if no value is specified) and
# then wait for one of the tablets to be promoted to primary and become
# healthy and serving. Lastly, wait for the new primary tablet's
# VReplication engine to fully open. Example:
# wait_for_healthy_shard commerce 0
function wait_for_healthy_shard() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A keyspace and shard must be specified when waiting for tablets to come up"
fi
local keyspace=${1}
local shard=${2}
local num_tablets=${3:-3}

wait_for_shard_tablets "${keyspace}" "${shard}" "${num_tablets}"
wait_for_healthy_shard_primary "${keyspace}" "${shard}"
wait_for_writeable_shard_primary "${keyspace}" "${shard}"
wait_for_shard_vreplication_engine "${keyspace}" "${shard}"
}

# Wait for a workflow to reach the running state. Example:
# wait_for_workflow_running customer customer2customer
function wait_for_workflow_running() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A keyspace and workflow must be specified when waiting for a workflow to reach the running state"
fi

local keyspace=${1}
local workflow=${2}
local wait_secs=90
local result=""

echo "Waiting for the ${workflow} workflow in the ${keyspace} keyspace to finish the copy phase..."

for _ in $(seq 1 ${wait_secs}); do
result=$(vtctldclient Workflow --keyspace="${keyspace}" show --workflow="${workflow}" 2>/dev/null | grep "Copy phase completed")
if [[ ${result} != "" ]]; then
break
fi
sleep 1
done;

if [[ ${result} == "" ]]; then
fail "Timed out after ${wait_secs} seconds waiting for the ${workflow} workflow in the ${keyspace} keyspace to reach the running state"
fi

echo "The ${workflow} workflow in the ${keyspace} keyspace is now running. $(sed -rn 's/.*"(Copy phase.*)".*/\1/p' <<< "${result}")."
}

# Stop the specified binary name using the provided PID file.
# Example:
# stop_process "vtadmin-web" "$VTDATAROOT/tmp/vtadmin-web.pid"
function stop_process() {
if [[ -z ${1} || -z ${2} ]]; then
fail "A binary name and PID file must be specified when attempting to shutdown a process"
fi

local binary_name="${1}"
local pidfile="${2}"
local pid=""
local wait_secs=90

if [[ -e "${pidfile}" ]]; then
pid=$(cat "${pidfile}")
echo "Stopping ${binary_name}..."
kill "${pid}"

# Wait for the process to terminate
for _ in $(seq 1 ${wait_secs}); do
if ! ps -p "${pid}" > /dev/null; then
break
fi
sleep 1
done
if ps -p "${pid}" > /dev/null; then
fail "Timed out after ${wait_secs} seconds waiting for the ${binary_name} using PID file ${pidfile} to terminate"
fi
else
echo "Skipping stopping ${binary_name} because the specified PID file (${pidfile}) does not exist."
fi
}

# Print error message and exit with error code.
function fail() {
echo "ERROR: ${1}"
exit 1
}

function output() {
echo -e "$@"
}
Loading

0 comments on commit 25f1f0a

Please sign in to comment.