|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Copyright 2025 The Vitess Authors. |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
| 16 | + |
| 17 | +# This is an example script that uses MySQL on 3306 as a topo server. |
| 18 | +source "$(dirname "${BASH_SOURCE[0]:-$0}")/../env.sh" |
| 19 | + |
| 20 | +cell=${CELL:-'test'} |
| 21 | + |
| 22 | +echo "Setting up mysql topo.." |
| 23 | + |
| 24 | +# Check if MySQL is already running |
| 25 | +# Extract user, password, host and port from MYSQL_TOPO_ADDR (format: user:password@tcp(host:port)/database) |
| 26 | +MYSQL_USER_PASS=$(echo "$MYSQL_TOPO_ADDR" | sed 's/@.*//') |
| 27 | +MYSQL_USER=$(echo "$MYSQL_USER_PASS" | cut -d: -f1) |
| 28 | +MYSQL_PASS=$(echo "$MYSQL_USER_PASS" | cut -d: -f2) |
| 29 | +MYSQL_HOST_PORT=$(echo "$MYSQL_TOPO_ADDR" | sed 's/.*@tcp(\([^)]*\)).*/\1/') |
| 30 | +MYSQL_HOST=$(echo "$MYSQL_HOST_PORT" | cut -d: -f1) |
| 31 | +MYSQL_PORT=$(echo "$MYSQL_HOST_PORT" | cut -d: -f2) |
| 32 | +CREATEUSER="CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED WITH mysql_native_password BY '${MYSQL_PASS}';" |
| 33 | +GRANTTOPO="GRANT ALL PRIVILEGES ON topo.* TO '${MYSQL_USER}'@'%'; GRANT REPLICATION SLAVE ON *.* TO '${MYSQL_USER}'@'%';" |
| 34 | + |
| 35 | +# For the MySQL topo implementation we expect to have a MySQL server running. |
| 36 | +# We first try to connect as the extracted user with the extracted password. |
| 37 | +if mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" -e "SELECT 1" > /dev/null 2>&1; then |
| 38 | + echo "MySQL is already running on $MYSQL_HOST:$MYSQL_PORT" |
| 39 | +elif mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u root -e "SELECT 1" > /dev/null 2>&1; then |
| 40 | + # if that fails, we try to connect as root with no password *and* create the topo user and then execute the GRANT statement. |
| 41 | + # if that fails, we bail and print an error message saying please create the topo user with this CREATE USER + GRANT statement. |
| 42 | + echo "MySQL is running, but '${MYSQL_USER}' does not exist. Attempting to create '${MYSQL_USER}' and grant privileges..." |
| 43 | + if ! mysql -u "$MYSQL_USER" -p"$MYSQL_PASS" -e "SELECT 1" 2>/dev/null; then |
| 44 | + if ! mysql -u root -e "$CREATEUSER" 2>/dev/null; then |
| 45 | + echo "Failed to create user '${MYSQL_USER}'@'%'." |
| 46 | + echo "Please create the user manually with the following commands:" |
| 47 | + echo " mysql -u root -e \"$CREATEUSER\"" |
| 48 | + echo " mysql -u root -e \"$GRANTTOPO\"" |
| 49 | + exit 1 |
| 50 | + fi |
| 51 | + if ! mysql -u root -e "$GRANTTOPO" 2>/dev/null; then |
| 52 | + echo "Failed to grant privileges to '${MYSQL_USER}'@'%'." |
| 53 | + echo "Please run the following command manually:" |
| 54 | + echo " mysql -u root -e \"$GRANTTOPO\"" |
| 55 | + exit 1 |
| 56 | + fi |
| 57 | + fi |
| 58 | + |
| 59 | +else |
| 60 | + echo "MySQL is not running, attempting to start it..." |
| 61 | + |
| 62 | + # Check if we're running in Docker (by checking for /.dockerenv file) |
| 63 | + if [[ -f /.dockerenv ]]; then |
| 64 | + echo "Detected Docker environment, starting MySQL..." |
| 65 | + |
| 66 | + # Create MySQL data directory and tmp directory |
| 67 | + mkdir -p "${VTDATAROOT}/mysql-topo" |
| 68 | + mkdir -p "${VTDATAROOT}/tmp" |
| 69 | + |
| 70 | + # Initialize MySQL data directory if it doesn't exist |
| 71 | + if [[ ! -d "${VTDATAROOT}/mysql-topo/mysql" ]]; then |
| 72 | + echo "Initializing MySQL data directory..." |
| 73 | + mysqld --initialize-insecure --user=vitess --datadir="${VTDATAROOT}/mysql-topo" > "${VTDATAROOT}/tmp/mysql-init.out" 2>&1 |
| 74 | + fi |
| 75 | + |
| 76 | + # Start MySQL server |
| 77 | + echo "Starting MySQL server..." |
| 78 | + mysqld --user=vitess \ |
| 79 | + --datadir="${VTDATAROOT}/mysql-topo" \ |
| 80 | + --socket="${VTDATAROOT}/mysql-topo/mysql.sock" \ |
| 81 | + --pid-file="${VTDATAROOT}/mysql-topo/mysql.pid" \ |
| 82 | + --port="$MYSQL_PORT" \ |
| 83 | + --bind-address="$MYSQL_HOST" \ |
| 84 | + --skip-networking=false \ |
| 85 | + --skip-mysqlx \ |
| 86 | + --gtid-mode=ON \ |
| 87 | + --enforce-gtid-consistency \ |
| 88 | + --log-bin \ |
| 89 | + --log-error="${VTDATAROOT}/tmp/mysql-topo.err" \ |
| 90 | + > "${VTDATAROOT}/tmp/mysql-topo.out" 2>&1 & |
| 91 | + |
| 92 | + PID=$! |
| 93 | + echo $PID > "${VTDATAROOT}/tmp/mysql-topo.pid" |
| 94 | + |
| 95 | + # Wait for MySQL to start |
| 96 | + echo "Waiting for MySQL to start..." |
| 97 | + for i in {1..30}; do |
| 98 | + if mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u root -e "SELECT 1" > /dev/null 2>&1; then |
| 99 | + echo "MySQL started successfully" |
| 100 | + break |
| 101 | + fi |
| 102 | + if [[ $i -eq 30 ]]; then |
| 103 | + echo "Failed to start MySQL after 30 seconds" |
| 104 | + echo "MySQL error log:" |
| 105 | + cat "${VTDATAROOT}/tmp/mysql-topo.err" 2>/dev/null || echo "No error log found" |
| 106 | + exit 1 |
| 107 | + fi |
| 108 | + sleep 1 |
| 109 | + done |
| 110 | + |
| 111 | + # Create the topo database |
| 112 | + echo "Creating topo database..." |
| 113 | + mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u root -e "CREATE DATABASE IF NOT EXISTS topo;" || { |
| 114 | + echo "Failed to create topo database" |
| 115 | + exit 1 |
| 116 | + } |
| 117 | + # Creating the topo user and granting privileges |
| 118 | + echo "Creating topo user and granting privileges..." |
| 119 | + mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u root -e "$CREATEUSER" || { |
| 120 | + echo "Failed to create user '${MYSQL_USER}'@'%'" |
| 121 | + exit 1 |
| 122 | + } |
| 123 | + mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u root -e "$GRANTTOPO" || { |
| 124 | + echo "Failed to grant privileges to '${MYSQL_USER}'@'%'" |
| 125 | + exit 1 |
| 126 | + } |
| 127 | + |
| 128 | + else |
| 129 | + echo "Error: MySQL is not running and this script can only auto-start MySQL in Docker environments." |
| 130 | + echo "Please start MySQL manually before calling mysql-up.sh" |
| 131 | + echo "You can start MySQL with a command like:" |
| 132 | + echo " sudo systemctl start mysql" |
| 133 | + echo " # or" |
| 134 | + echo " sudo service mysql start" |
| 135 | + echo " # or start it manually with mysqld" |
| 136 | + exit 1 |
| 137 | + fi |
| 138 | +fi |
| 139 | + |
| 140 | +mysql -h "$MYSQL_HOST" -P "$MYSQL_PORT" -u "$MYSQL_USER" -p"$MYSQL_PASS" -e "CREATE DATABASE IF NOT EXISTS topo" || true |
| 141 | + |
| 142 | +# And also add the CellInfo description for the cell. |
| 143 | +# If the node already exists, it's fine, means we used existing data. |
| 144 | +echo "add ${cell} CellInfo" |
| 145 | +set +e |
| 146 | +command vtctldclient --server internal --topo-implementation mysql --topo-global-server-address $MYSQL_TOPO_ADDR AddCellInfo \ |
| 147 | + --root "/vitess/${cell}" \ |
| 148 | + --server-address "$MYSQL_TOPO_ADDR" \ |
| 149 | + "${cell}" |
| 150 | +set -e |
| 151 | + |
| 152 | +echo "mysql topo set!" |
0 commit comments