Never bootstrap node again - redux (#53)

* Never bootstrap node again - redux

* Don't bootstrap implicitly if bootstrap-var is set

Also refactor complicated conditionals, add/fix comments and README.
This commit is contained in:
ChristianCiach
2021-11-09 11:35:17 +01:00
committed by GitHub
parent 36911b8d2b
commit 0dc18c5a5b
5 changed files with 162 additions and 61 deletions

View File

@@ -78,7 +78,7 @@ mysql_extra_flags() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
get_galera_cluster_bootstrap_value() {
local cluster_bootstrap
@@ -91,21 +91,43 @@ get_galera_cluster_bootstrap_value() {
# That way, the node will join the existing Galera cluster instead of bootstrapping a new one.
# We disable the bootstrap right after processing environment variables in "run.sh" with "set_previous_boot".
# - Users can force a bootstrap to happen again on a node, by setting the environment variable "MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP".
# - Bootstrapping may happen implicitly when "MARIADB_GALERA_CLUSTER_BOOTSTRAP" is undefined.
# This is mostly expected to happen when running in Kubernetes and the Helm Chart value "galera.bootstrap.bootstrapFromNode" is not set.
# When the node is not marked to bootstrap, the node will join an existing cluster.
cluster_bootstrap="no" # initial value
if is_boolean_yes "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
elif ! is_boolean_yes "$(get_previous_boot)"; then
if is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$(get_previous_boot)"; then
cluster_bootstrap="no"
elif ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
elif is_boolean_yes "$(should_bootstrap_implicitly)"; then
cluster_bootstrap="yes"
else
cluster_bootstrap="no"
fi
fi
echo "$cluster_bootstrap"
}
########################
# Whether this node should bootstrap if not explicitly stated.
# Globals:
# DB_*
# Arguments:
# None
# Returns:
# Yes or no
#########################
should_bootstrap_implicitly() {
bootstrap_implicitly="no"
# If bootstrap value is explicitly defined, never bootstrap implicitly.
if is_empty_value "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
# TODO: Maybe we should only do this if we're sure that this container runs in Kubernetes?
if ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
bootstrap_implicitly="yes"
fi
fi
echo "$bootstrap_implicitly"
}
########################
# Whether the Galera cluster has other running nodes
# Globals:
@@ -113,7 +135,7 @@ get_galera_cluster_bootstrap_value() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
has_galera_cluster_other_nodes() {
local local_ip
@@ -170,10 +192,10 @@ has_galera_cluster_other_nodes() {
#########################
get_galera_cluster_address_value() {
local cluster_address
if ! is_boolean_yes "$(get_galera_cluster_bootstrap_value)" && is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
else
if is_boolean_yes "$(get_galera_cluster_bootstrap_value)"; then
cluster_address="gcomm://"
else
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
fi
debug "Set Galera cluster address to ${cluster_address}"
echo "$cluster_address"
@@ -233,7 +255,7 @@ mysql_validate() {
fi
if [[ -n "$DB_GALERA_FORCE_SAFETOBOOTSTRAP" ]] && ! is_yes_no_value "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
print_validation_error "The allowed values for MARDIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
print_validation_error "The allowed values for MARIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
fi
if [[ -z "$DB_GALERA_CLUSTER_NAME" ]]; then

View File

@@ -78,7 +78,7 @@ mysql_extra_flags() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
get_galera_cluster_bootstrap_value() {
local cluster_bootstrap
@@ -91,21 +91,43 @@ get_galera_cluster_bootstrap_value() {
# That way, the node will join the existing Galera cluster instead of bootstrapping a new one.
# We disable the bootstrap right after processing environment variables in "run.sh" with "set_previous_boot".
# - Users can force a bootstrap to happen again on a node, by setting the environment variable "MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP".
# - Bootstrapping may happen implicitly when "MARIADB_GALERA_CLUSTER_BOOTSTRAP" is undefined.
# This is mostly expected to happen when running in Kubernetes and the Helm Chart value "galera.bootstrap.bootstrapFromNode" is not set.
# When the node is not marked to bootstrap, the node will join an existing cluster.
cluster_bootstrap="no" # initial value
if is_boolean_yes "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
elif ! is_boolean_yes "$(get_previous_boot)"; then
if is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$(get_previous_boot)"; then
cluster_bootstrap="no"
elif ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
elif is_boolean_yes "$(should_bootstrap_implicitly)"; then
cluster_bootstrap="yes"
else
cluster_bootstrap="no"
fi
fi
echo "$cluster_bootstrap"
}
########################
# Whether this node should bootstrap if not explicitly stated.
# Globals:
# DB_*
# Arguments:
# None
# Returns:
# Yes or no
#########################
should_bootstrap_implicitly() {
bootstrap_implicitly="no"
# If bootstrap value is explicitly defined, never bootstrap implicitly.
if is_empty_value "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
# TODO: Maybe we should only do this if we're sure that this container runs in Kubernetes?
if ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
bootstrap_implicitly="yes"
fi
fi
echo "$bootstrap_implicitly"
}
########################
# Whether the Galera cluster has other running nodes
# Globals:
@@ -113,7 +135,7 @@ get_galera_cluster_bootstrap_value() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
has_galera_cluster_other_nodes() {
local local_ip
@@ -170,10 +192,10 @@ has_galera_cluster_other_nodes() {
#########################
get_galera_cluster_address_value() {
local cluster_address
if ! is_boolean_yes "$(get_galera_cluster_bootstrap_value)" && is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
else
if is_boolean_yes "$(get_galera_cluster_bootstrap_value)"; then
cluster_address="gcomm://"
else
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
fi
debug "Set Galera cluster address to ${cluster_address}"
echo "$cluster_address"
@@ -233,7 +255,7 @@ mysql_validate() {
fi
if [[ -n "$DB_GALERA_FORCE_SAFETOBOOTSTRAP" ]] && ! is_yes_no_value "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
print_validation_error "The allowed values for MARDIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
print_validation_error "The allowed values for MARIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
fi
if [[ -z "$DB_GALERA_CLUSTER_NAME" ]]; then

View File

@@ -78,7 +78,7 @@ mysql_extra_flags() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
get_galera_cluster_bootstrap_value() {
local cluster_bootstrap
@@ -91,21 +91,42 @@ get_galera_cluster_bootstrap_value() {
# That way, the node will join the existing Galera cluster instead of bootstrapping a new one.
# We disable the bootstrap right after processing environment variables in "run.sh" with "set_previous_boot".
# - Users can force a bootstrap to happen again on a node, by setting the environment variable "MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP".
# - Bootstrapping may happen implicitly when "MARIADB_GALERA_CLUSTER_BOOTSTRAP" is undefined.
# This is mostly expected to happen when running in Kubernetes and the Helm Chart value "galera.bootstrap.bootstrapFromNode" is not set.
# When the node is not marked to bootstrap, the node will join an existing cluster.
cluster_bootstrap="no" # initial value
if is_boolean_yes "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
elif ! is_boolean_yes "$(get_previous_boot)"; then
if is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$(get_previous_boot)"; then
cluster_bootstrap="no"
elif ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
elif is_boolean_yes "$(should_bootstrap_implicitly)"; then
cluster_bootstrap="yes"
else
cluster_bootstrap="no"
fi
fi
echo "$cluster_bootstrap"
}
# Whether this node should bootstrap if not explicitly stated.
# Globals:
# DB_*
# Arguments:
# None
# Returns:
# Yes or no
#########################
should_bootstrap_implicitly() {
bootstrap_implicitly="no"
# If bootstrap value is explicitly defined, never bootstrap implicitly.
if is_empty_value "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
# TODO: Maybe we should only do this if we're sure that this container runs in Kubernetes?
if ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
bootstrap_implicitly="yes"
fi
fi
echo "$bootstrap_implicitly"
}
########################
# Whether the Galera cluster has other running nodes
# Globals:
@@ -113,7 +134,7 @@ get_galera_cluster_bootstrap_value() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
has_galera_cluster_other_nodes() {
local local_ip
@@ -170,10 +191,10 @@ has_galera_cluster_other_nodes() {
#########################
get_galera_cluster_address_value() {
local cluster_address
if ! is_boolean_yes "$(get_galera_cluster_bootstrap_value)" && is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
else
if is_boolean_yes "$(get_galera_cluster_bootstrap_value)"; then
cluster_address="gcomm://"
else
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
fi
debug "Set Galera cluster address to ${cluster_address}"
echo "$cluster_address"
@@ -233,7 +254,7 @@ mysql_validate() {
fi
if [[ -n "$DB_GALERA_FORCE_SAFETOBOOTSTRAP" ]] && ! is_yes_no_value "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
print_validation_error "The allowed values for MARDIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
print_validation_error "The allowed values for MARIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
fi
if [[ -z "$DB_GALERA_CLUSTER_NAME" ]]; then

View File

@@ -78,7 +78,7 @@ mysql_extra_flags() {
# Arguments:
# None
# Returns:
# None
# Yes or no
#########################
get_galera_cluster_bootstrap_value() {
local cluster_bootstrap
@@ -91,29 +91,51 @@ get_galera_cluster_bootstrap_value() {
# That way, the node will join the existing Galera cluster instead of bootstrapping a new one.
# We disable the bootstrap right after processing environment variables in "run.sh" with "set_previous_boot".
# - Users can force a bootstrap to happen again on a node, by setting the environment variable "MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP".
# - Bootstrapping may happen implicitly when "MARIADB_GALERA_CLUSTER_BOOTSTRAP" is undefined.
# This is mostly expected to happen when running in Kubernetes and the Helm Chart value "galera.bootstrap.bootstrapFromNode" is not set.
# When the node is not marked to bootstrap, the node will join an existing cluster.
cluster_bootstrap="no" # initial value
if is_boolean_yes "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
elif ! is_boolean_yes "$(get_previous_boot)"; then
if is_boolean_yes "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
cluster_bootstrap="yes"
elif is_boolean_yes "$(get_previous_boot)"; then
cluster_bootstrap="no"
elif ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
elif is_boolean_yes "$(should_bootstrap_implicitly)"; then
cluster_bootstrap="yes"
else
cluster_bootstrap="no"
fi
fi
echo "$cluster_bootstrap"
}
########################
# Whether the Galera cluster has other running nodes
# Whether this node should bootstrap if not explicitly stated.
# Globals:
# DB_*
# Arguments:
# None
# Returns:
# Yes or no
#########################
should_bootstrap_implicitly() {
bootstrap_implicitly="no"
# If bootstrap value is explicitly defined, never bootstrap implicitly.
if is_empty_value "$DB_GALERA_CLUSTER_BOOTSTRAP"; then
# TODO: Maybe we should only do this if we're sure that this container runs in Kubernetes?
if ! is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
bootstrap_implicitly="yes"
fi
fi
echo "$bootstrap_implicitly"
}
########################
# Whether the Galera cluster has other running nodes.
# Globals:
# DB_*
# Arguments:
# None
# Returns:
# Yes or no
#########################
has_galera_cluster_other_nodes() {
local local_ip
@@ -170,10 +192,10 @@ has_galera_cluster_other_nodes() {
#########################
get_galera_cluster_address_value() {
local cluster_address
if ! is_boolean_yes "$(get_galera_cluster_bootstrap_value)" && is_boolean_yes "$(has_galera_cluster_other_nodes)"; then
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
else
if is_boolean_yes "$(get_galera_cluster_bootstrap_value)"; then
cluster_address="gcomm://"
else
cluster_address="$DB_GALERA_CLUSTER_ADDRESS"
fi
debug "Set Galera cluster address to ${cluster_address}"
echo "$cluster_address"
@@ -233,7 +255,7 @@ mysql_validate() {
fi
if [[ -n "$DB_GALERA_FORCE_SAFETOBOOTSTRAP" ]] && ! is_yes_no_value "$DB_GALERA_FORCE_SAFETOBOOTSTRAP"; then
print_validation_error "The allowed values for MARDIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
print_validation_error "The allowed values for MARIA_GALERA_FORCE_SAFETOBOOTSTRAP are yes or no."
fi
if [[ -z "$DB_GALERA_CLUSTER_NAME" ]]; then

View File

@@ -430,15 +430,22 @@ In a MariaDB Galera cluster the first node should be a bootstrap node (started w
#### Step 1: Bootstrap the cluster
The first step is to start the MariaDB Galera bootstrap node.
First let's create a docker bridge network for the containers to communicate.
```console
$ docker run -d --name mariadb-galera-0 \
docker network create galera
```
To bootstrap the Galera cluster we first have to start a bootstrap node.
```console
$ docker run -d --name mariadb-galera-0 --network galera \
-e MARIADB_GALERA_CLUSTER_NAME=my_galera \
-e MARIADB_GALERA_MARIABACKUP_USER=my_mariabackup_user \
-e MARIADB_GALERA_MARIABACKUP_PASSWORD=my_mariabackup_password \
-e MARIADB_ROOT_PASSWORD=my_root_password \
-e MARIADB_GALERA_CLUSTER_BOOTSTRAP=yes \
-e MARIADB_GALERA_CLUSTER_ADDRESS=gcomm://mariadb-galera-0,mariadb-galera-1 \
-e MARIADB_USER=my_user \
-e MARIADB_PASSWORD=my_password \
-e MARIADB_DATABASE=my_database \
@@ -447,19 +454,22 @@ $ docker run -d --name mariadb-galera-0 \
bitnami/mariadb-galera:latest
```
In the above command the container is configured as the bootstrap node by specifying the `MARIADB_GALERA_CLUSTER_BOOTSTRAP` parameter. The SST user is specified using the `MARIADB_GALERA_MARIABACKUP_USER` and `MARIADB_GALERA_MARIABACKUP_PASSWORD` parameters and a cluster name is specified using the `MARIADB_GALERA_CLUSTER_NAME` parameter.
In the above command the container is configured as the bootstrap node by setting the `MARIADB_GALERA_CLUSTER_BOOTSTRAP` parameter to `yes`. The SST user is specified using the `MARIADB_GALERA_MARIABACKUP_USER` and `MARIADB_GALERA_MARIABACKUP_PASSWORD` parameters and a cluster name is specified using the `MARIADB_GALERA_CLUSTER_NAME` parameter.
Even though `MARIADB_GALERA_CLUSTER_ADDRESS` is optional on the bootstrap node, it is best practice to always define the complete cluster address on every node. As bootstrapping only happens when the container is started the very first time, consecutive restarts of this container will use `MARIADB_GALERA_CLUSTER_ADDRESS` to join the rest of the cluster.
#### Step 2: Add nodes to the cluster
Next we add a new node to the cluster.
```console
$ docker run -d --name mariadb-galera-1 --link mariadb-galera-0:mariadb-galera \
$ docker run -d --name mariadb-galera-1 --network galera \
-e MARIADB_GALERA_CLUSTER_NAME=my_galera \
-e MARIADB_GALERA_CLUSTER_ADDRESS=gcomm://mariadb-galera:4567,0.0.0.0:4567 \
-e MARIADB_GALERA_CLUSTER_ADDRESS=gcomm://mariadb-galera-0,mariadb-galera-1 \
-e MARIADB_GALERA_MARIABACKUP_USER=my_mariabackup_user \
-e MARIADB_GALERA_MARIABACKUP_PASSWORD=my_mariabackup_password \
-e MARIADB_ROOT_PASSWORD=my_root_password \
-e MARIADB_GALERA_CLUSTER_BOOTSTRAP=no \
-e MARIADB_REPLICATION_USER=my_replication_user \
-e MARIADB_REPLICATION_PASSWORD=my_replication_password \
bitnami/mariadb-galera:latest
@@ -467,8 +477,12 @@ $ docker run -d --name mariadb-galera-1 --link mariadb-galera-0:mariadb-galera \
In the above command a new node is created and configured to join the bootstrapped MariaDB Galera cluster by specifying the `MARIADB_GALERA_CLUSTER_ADDRESS` parameter. The `MARIADB_GALERA_CLUSTER_NAME`, `MARIADB_GALERA_MARIABACKUP_USER` and `MARIADB_GALERA_MARIABACKUP_PASSWORD` are also specified for the Snapshot State Transfer (SST).
The parameter `MARIADB_GALERA_CLUSTER_BOOTSTRAP=no` is not strictly necessary. If it is omitted, the node will try to guess if bootstrapping is necessary. In most cases it will guess correctly, but in some environments it may guess incorrectly, especially when using Dockers host networking (`--network host`).
You now have a two node MariaDB Galera cluster up and running. Write to any node of the cluster are automatically propagated to every node. You can scale the cluster by adding/removing slaves without incurring any downtime.
It is recommended to start a third container, otherwise the cluster will stop working when one node goes down, because the loss of quorum.
> **Important**: If you need to stop the MariaDB Galera cluster, ensure you stop the bootstrap node only after you have stopped all other nodes in the cluster. This ensure you do not loose any write that may have occurred while the nodes were being stopped.
### Slow filesystems