This is an automated email from the ASF dual-hosted git repository.
jiafengzheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 1cc735f20b [feature](docker)Refactor Image build script (#16528)
1cc735f20b is described below
commit 1cc735f20bfd06f5fa1bc22daeeba08a5c01f4af
Author: FreeOnePlus <[email protected]>
AuthorDate: Fri Feb 10 18:30:54 2023 +0800
[feature](docker)Refactor Image build script (#16528)
Co-authored-by: Yijia Su <[email protected]>
---
docker/runtime/be/Dockerfile | 4 +-
docker/runtime/be/resource/entry_point.sh | 184 ++++++++++++++++++
docker/runtime/be/resource/init_be.sh | 274 ++++++++++++++++++--------
docker/runtime/fe/resource/init_fe.sh | 307 ++++++++++++++++++++----------
4 files changed, 588 insertions(+), 181 deletions(-)
diff --git a/docker/runtime/be/Dockerfile b/docker/runtime/be/Dockerfile
index d4b60eec65..95eda2ca1c 100644
--- a/docker/runtime/be/Dockerfile
+++ b/docker/runtime/be/Dockerfile
@@ -35,6 +35,8 @@ RUN apt-get update && \
mv apache-doris-be-x.x.x-bin-x86_64 /opt/apache-doris/be
ADD resource/init_be.sh /opt/apache-doris/be/bin
+ADD resource/entry_point.sh /usr/local/bin
+RUN chmod 755 /usr/local/bin/entry_point.sh
RUN chmod 755 /opt/apache-doris/be/bin/init_be.sh
-ENTRYPOINT ["/opt/apache-doris/be/bin/init_be.sh"]
+ENTRYPOINT ["bash","entry_point.sh"]
diff --git a/docker/runtime/be/resource/entry_point.sh
b/docker/runtime/be/resource/entry_point.sh
new file mode 100644
index 0000000000..ab2ec6a3d3
--- /dev/null
+++ b/docker/runtime/be/resource/entry_point.sh
@@ -0,0 +1,184 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+set -eo pipefail
+shopt -s nullglob
+
+# Obtain necessary and basic information to complete initialization
+
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+# ie: doris_warn "task may be risky!"
+# out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may be risky!
+doris_log() {
+ local type="$1"
+ shift
+ # accept argument string or stdin
+ local text="$*"
+ if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+ local dt="$(date -Iseconds)"
+ printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+ doris_log Note "$@"
+}
+doris_warn() {
+ doris_log Warn "$@" >&2
+}
+doris_error() {
+ doris_log ERROR "$@" >&2
+ exit 1
+}
+
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ [ "${#FUNCNAME[@]}" -ge 2 ] &&
+ [ "${FUNCNAME[0]}" = '_is_sourced' ] &&
+ [ "${FUNCNAME[1]}" = 'source' ]
+}
+
+docker_setup_env() {
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "${DORIS_HOME}/be/storage/data" ]; then
+ DATABASE_ALREADY_EXISTS='true'
+ fi
+}
+
+get_doris_args() {
+ local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print
$0}'))
+ for i in "${feServerArray[@]}"; do
+ val=${i}
+ val=${val// /}
+ tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, "");
print$1}')
+ tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+ feIpArray[$tmpFeId]=${tmpFeIp}
+ done
+
+ declare -g MASTER_FE_IP BE_HOST_IP BE_HEARTBEAT_PORT
+ MASTER_FE_IP=${feIpArray[1]}
+ doris_note "masterFe = ${MASTER_FE_IP}"
+ BE_HOST_IP=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
+ BE_HEARTBEAT_PORT=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, "");
print$2}')
+ doris_note "be_addr = ${BE_HOST_IP}:${BE_HEARTBEAT_PORT}"
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql [mysql-cli-args]
+# ie: docker_process_sql --database=mydb <<<'INSERT ...'
+# ie: docker_process_sql --database=mydb <my-file.sql
+docker_process_sql() {
+ set +e
+ mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" 2>/dev/null
+}
+
+check_be_status() {
+ set +e
+ local is_fe_start=false
+ for i in {1..300}; do
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_warn "start check be status~"
+ fi
+ docker_process_sql <<<"show backends;" | grep
"[[:space:]]${BE_HOST_IP}[[:space:]]" | grep
"[[:space:]]${BE_HEARTBEAT_PORT}[[:space:]]" | grep "[[:space:]]true[[:space:]]"
+ be_join_status=$?
+ if [[ "${be_join_status}" == 0 ]]; then
+ doris_note "Verify that BE is registered to FE successfully"
+ is_fe_start=true
+ break
+ else
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_note "register is failed, wait next~"
+ fi
+ fi
+ sleep 1
+ done
+ if ! [[ $is_fe_start ]]; then
+ doris_error "Failed to register BE to FE!Tried 30 times!Maybe FE Start
Failed!"
+ fi
+}
+
+# usage: docker_process_init_files [file [file [...]]]
+# ie: docker_process_init_files /always-initdb.d/*
+# process initializer files, based on file extensions
+docker_process_init_files() {
+ local f
+ for f; do
+ case "$f" in
+ *.sh)
+ if [ -x "$f" ]; then
+ doris_note "$0: running $f"
+ "$f"
+ else
+ doris_note "$0: sourcing $f"
+ . "$f"
+ fi
+ ;;
+ *.sql)
+ doris_note "$0: running $f"
+ docker_process_sql <"$f"
+ echo
+ ;;
+ *.sql.bz2)
+ doris_note "$0: running $f"
+ bunzip2 -c "$f" | docker_process_sql
+ echo
+ ;;
+ *.sql.gz)
+ doris_note "$0: running $f"
+ gunzip -c "$f" | docker_process_sql
+ echo
+ ;;
+ *.sql.xz)
+ doris_note "$0: running $f"
+ xzcat "$f" | docker_process_sql
+ echo
+ ;;
+ *.sql.zst)
+ doris_note "$0: running $f"
+ zstd -dc "$f" | docker_process_sql
+ echo
+ ;;
+ *) doris_warn "$0: ignoring $f" ;;
+ esac
+ echo
+ done
+}
+
+_main() {
+ docker_setup_env
+ # get init args
+ get_doris_args
+ # Start Doris BE
+ {
+ set +e
+ bash init_be.sh 2>/dev/null
+ } &
+ # check BE started status
+ check_be_status
+ if [ -z ${DATABASE_ALREADY_EXISTS} ]; then
+ # run script
+ docker_process_init_files /docker-entrypoint-initdb.d/*
+ fi
+
+ # keep BE started status
+ wait
+ exec "$@"
+}
+
+if ! _is_sourced; then
+ _main "$@"
+fi
diff --git a/docker/runtime/be/resource/init_be.sh
b/docker/runtime/be/resource/init_be.sh
index e4de6b7c7e..bd85416af6 100644
--- a/docker/runtime/be/resource/init_be.sh
+++ b/docker/runtime/be/resource/init_be.sh
@@ -16,90 +16,198 @@
# specific language governing permissions and limitations
# under the License.
-FE_SERVERS=""
-BE_ADDR=""
-
-ARGS=$(getopt -o -h: --long fe_servers:,be_addr: -n "$0" -- "$@")
-
-eval set -- "${ARGS}"
-
-while [[ -n "$1" ]]; do
- case "$1" in
- --fe_servers)
- FE_SERVERS=$2
- shift
- ;;
- --be_addr)
- BE_ADDR=$2
- shift
- ;;
- --) ;;
-
- *)
- echo "Error option $1"
- break
- ;;
- esac
+set -eo pipefail
+shopt -s nullglob
+
+DORIS_HOME="/opt/apache-doris"
+
+# Obtain necessary and basic information to complete initialization
+
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+# ie: doris_warn "task may be risky!"
+# out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may be risky!
+doris_log() {
+ local type="$1"
shift
-done
-
-#echo FE_SERVERS = $FE_SERVERS
-echo "DEBUG >>>>>> FE_SERVERS=[${FE_SERVERS}]"
-echo "DEBUG >>>>>> BE_ADDR=[${BE_ADDR}]"
-
-feIpArray=()
-feEditLogPortArray=()
-
-IFS=","
-# shellcheck disable=SC2206
-feServerArray=(${FE_SERVERS})
-
-for i in "${!feServerArray[@]}"; do
- val=${feServerArray[i]}
- val=${val// /}
- tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, "");
print$1}')
- tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
- tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
- feIpArray[tmpFeId]=${tmpFeIp}
- feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
-done
-
-be_ip=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
-be_heartbeat_port=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$2}')
-
-echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
-echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
-echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
-echo "DEBUG >>>>>> be_addr = ${be_ip}:${be_heartbeat_port}"
-
-priority_networks=$(echo "${be_ip}" | awk -F '.' '{print$1"."$2"."$3".0/24"}')
-echo "DEBUG >>>>>> Append the configuration [priority_networks =
${priority_networks}] to /opt/apache-doris/be/conf/fe.conf"
-echo "priority_networks = ${priority_networks}"
>>/opt/apache-doris/be/conf/be.conf
-
-registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add
backend '${be_ip}:${be_heartbeat_port}'\""
-echo "DEBUG >>>>>> registerMySQL = ${registerMySQL}"
-
-registerShell="/opt/apache-doris/be/bin/start_be.sh &"
-echo "DEBUG >>>>>> registerShell = ${registerShell}"
-
-for ((i = 0; i <= 20; i++)); do
-
- ## check be register status
- echo "mysql -uroot -P9030 -h${feIpArray[1]} -e \"show backends\" | grep \"
${be_ip} \" | grep \" ${be_heartbeat_port} \""
- mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show backends" | grep
"[[:space:]]${be_ip}[[:space:]]" | grep
"[[:space:]]${be_heartbeat_port}[[:space:]]"
- be_join_status=$?
- echo "DEBUG >>>>>> The " "${i}" "time to register BE node,
be_join_status=${be_join_status}"
- if [[ "${be_join_status}" == 0 ]]; then
- ## be registe successfully
- echo "DEBUG >>>>>> run command ${registerShell}"
- eval "${registerShell}"
+ # accept argument string or stdin
+ local text="$*"
+ if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+ local dt="$(date -Iseconds)"
+ printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+ doris_log Note "$@"
+}
+doris_warn() {
+ doris_log Warn "$@" >&2
+}
+doris_error() {
+ doris_log ERROR "$@" >&2
+ exit 1
+}
+
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ [ "${#FUNCNAME[@]}" -ge 2 ] &&
+ [ "${FUNCNAME[0]}" = '_is_sourced' ] &&
+ [ "${FUNCNAME[1]}" = 'source' ]
+}
+
+docker_setup_env() {
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "${DORIS_HOME}/be/storage/data" ]; then
+ DATABASE_ALREADY_EXISTS='true'
+ fi
+}
+
+# Check the variables required for startup
+docker_required_variables_env() {
+ if [[ $FE_SERVERS =~
^.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}(,.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4})*$
]]; then
+ doris_warn "FE_SERVERS" $FE_SERVERS
else
- ## be doesn't registe
- echo "DEBUG >>>>>> run commnad ${registerMySQL}"
- eval "${registerMySQL}"
- if [[ "${i}" == 20 ]]; then
- echo "DEBUG >>>>>> BE Start Or Register FAILED!"
+ doris_error "FE_SERVERS rule error!example:
\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT[,\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT]..."
+ fi
+ if [[ $BE_ADDR =~
^[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}$
]]; then
+ doris_warn "BE_ADDR" $BE_ADDR
+ else
+ doris_error "BE_ADDR rule error!example:
\$BE_HOST_IP:\$HEARTBEAT_SERVICE_PORT"
+ fi
+}
+
+get_doris_be_args() {
+ local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print
$0}'))
+ for i in "${feServerArray[@]}"; do
+ val=${i}
+ val=${val// /}
+ tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, "");
print$1}')
+ tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+ tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, "");
print$3}')
+ check_arg "tmpFeIp" $tmpFeIp
+ feIpArray[$tmpFeId]=${tmpFeIp}
+ check_arg "tmpFeEditLogPort" $tmpFeEditLogPort
+ feEditLogPortArray[$tmpFeId]=${tmpFeEditLogPort}
+ done
+
+ declare -g MASTER_FE_IP BE_HOST_IP BE_HEARTBEAT_PORT PRIORITY_NETWORKS
+ MASTER_FE_IP=${feIpArray[1]}
+ check_arg "MASTER_FE_IP" $MASTER_FE_IP
+ BE_HOST_IP=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, ""); print$1}')
+ check_arg "BE_HOST_IP" $BE_HOST_IP
+ BE_HEARTBEAT_PORT=$(echo "${BE_ADDR}" | awk -F ':' '{ sub(/ /, "");
print$2}')
+ check_arg "BE_HEARTBEAT_PORT" $BE_HEARTBEAT_PORT
+
+ PRIORITY_NETWORKS=$(echo "${BE_HOST_IP}" | awk -F '.'
'{print$1"."$2"."$3".0/24"}')
+ check_arg "priority_networks" $PRIORITY_NETWORKS
+
+ doris_note "feIpArray = ${feIpArray[*]}"
+ doris_note "feEditLogPortArray = ${feEditLogPortArray[*]}"
+ doris_note "masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
+ doris_note "be_addr = ${BE_HOST_IP}:${BE_HEARTBEAT_PORT}"
+ doris_note "priority_networks = ${PRIORITY_NETWORKS}"
+ # wait fe start
+ check_be_status true
+}
+
+add_priority_networks() {
+ doris_note "add priority_networks ${1} to ${DORIS_HOME}/be/conf/be.conf"
+ echo "priority_networks = ${1}" >>${DORIS_HOME}/be/conf/be.conf
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql sql_script
+docker_process_sql() {
+ set +e
+ mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" >2 &
+ 1>/dev/null
+}
+
+register_be_to_fe() {
+ set +e
+ # check fe status
+ local is_fe_start=false
+ for i in {1..300}; do
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_note "Register BE to FE is failed. retry."
fi
- sleep 5
+ docker_process_sql <<<"alter system add backend
'${BE_HOST_IP}:${BE_HEARTBEAT_PORT}'"
+ register_be_status=$?
+ if [[ $register_be_status == 0 ]]; then
+ doris_note "BE successfully registered to FE!"
+ is_fe_start=true
+ break
+ else
+ check_be_status
+ if [ -n "$BE_ALREADY_EXISTS" ]; then
+ doris_warn "Same backend already exists! No need to register
again!"
+ break
+ fi
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_warn "register_be_status: ${register_be_status}"
+ doris_warn "BE failed registered to FE!"
+ fi
+ fi
+ sleep 1
+ done
+ if ! [[ $is_fe_start ]]; then
+ doris_error "Failed to register BE to FE!Tried 30 times!Maybe FE Start
Failed!"
fi
-done
+}
+
+# Check whether the passed parameters are empty to avoid subsequent task
execution failures. At the same time,
+# enumeration checks can be added, such as checking whether a certain
parameter appears repeatedly, etc.
+check_arg() {
+ if [ -z $2 ]; then
+ doris_error "$1 is null!"
+ fi
+}
+
+# 这里可用 docker_process_sql() 函数封装,为了方便调试,暂未封装
+check_be_status() {
+ set +e
+ for i in {1..300}; do
+ if [[ $(($i % 20)) == 1 ]]; then
+ if [[ $1 == true ]]; then
+ doris_note "MASTER FE is not started. retry."
+ else
+ doris_note "BE is not register. retry."
+ fi
+ fi
+ if [[ $1 == true ]]; then
+ docker_process_sql <<<"show frontends" | grep
"[[:space:]]${MASTER_FE_IP}[[:space:]]"
+ else
+ docker_process_sql <<<"show backends" | grep
"[[:space:]]${BE_HOST_IP}[[:space:]]" | grep
"[[:space:]]${BE_HEARTBEAT_PORT}[[:space:]]"
+ fi
+ be_join_status=$?
+ if [[ "${be_join_status}" == 0 ]]; then
+ if [[ $1 == true ]]; then
+ doris_note "MASTER FE is started!"
+ else
+ doris_note "Init Check - Verify that BE is registered to FE
successfully"
+ BE_ALREADY_EXISTS=true
+ fi
+ break
+ fi
+ sleep 1
+ done
+}
+
+_main() {
+ docker_setup_env
+ docker_required_variables_env
+ get_doris_be_args
+
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ add_priority_networks $PRIORITY_NETWORKS
+ fi
+
+ register_be_to_fe
+ check_be_status
+ doris_note "Ready to start BE!"
+ start_be.sh
+ exec "$@"
+}
+
+if ! _is_sourced; then
+ _main "$@"
+fi
diff --git a/docker/runtime/fe/resource/init_fe.sh
b/docker/runtime/fe/resource/init_fe.sh
index 64e97a08dc..bcc546553d 100644
--- a/docker/runtime/fe/resource/init_fe.sh
+++ b/docker/runtime/fe/resource/init_fe.sh
@@ -16,111 +16,224 @@
# specific language governing permissions and limitations
# under the License.
-FE_ID=0
-FE_SERVERS=""
-
-ARGS=$(getopt -o -h: --long fe_id:,fe_servers: -n "$0" -- "$@")
-
-eval set -- "${ARGS}"
-
-while [[ -n "$1" ]]; do
- case "$1" in
- --fe_id)
- FE_ID=$2
- shift
- ;;
- --fe_servers)
- FE_SERVERS=$2
- shift
- ;;
- --) ;;
-
- *)
- echo "Error option $1"
- break
- ;;
- esac
- shift
-done
-
-echo "DEBUG >>>>>> FE_ID = [${FE_ID}]"
-echo "DEBUG >>>>>> FE_SERVERS = [${FE_SERVERS}]"
-
-feIpArray=()
-feEditLogPortArray=()
-
-IFS=","
-# shellcheck disable=SC2206
-feServerArray=(${FE_SERVERS})
-
-for i in "${!feServerArray[@]}"; do
-
- val=${feServerArray[i]}
- val=${val// /}
- tmpFeId=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, "");
print$1}')
- tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
- tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$3}')
- echo "DEBUG >>>>>> tmpFeId = [${tmpFeId}]"
- echo "DEBUG >>>>>> tmpFeIp = [${tmpFeIp}]"
- echo "DEBUG >>>>>> tmpFeEditLogPort = [${tmpFeEditLogPort}]"
-
- feIpArray[tmpFeId]=${tmpFeIp}
- feEditLogPortArray[tmpFeId]=${tmpFeEditLogPort}
-
-done
-
-echo "DEBUG >>>>>> feIpArray = ${feIpArray[*]}"
-echo "DEBUG >>>>>> feEditLogPortArray = ${feEditLogPortArray[*]}"
-echo "DEBUG >>>>>> masterFe = ${feIpArray[1]}:${feEditLogPortArray[1]}"
-echo "DEBUG >>>>>> currentFe =
${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}"
-
-priority_networks=$(echo "${feIpArray[FE_ID]}" | awk -F '.'
'{print$1"."$2"."$3".0/24"}')
-echo "DEBUG >>>>>> Append the configuration [priority_networks =
${priority_networks}] to /opt/doris-fe/conf/fe.conf"
-echo "priority_networks = ${priority_networks}"
>>/opt/apache-doris/fe/conf/fe.conf
-
-if [[ "${FE_ID}" != 1 ]]; then
+set -eo pipefail
+shopt -s nullglob
- ## if current node is not master
- ## PREPARE1: registe follower from mysql client
- ## PREPARE2: call start_fe.sh using --help optional
- ## STEP1: check master fe service works
- ## STEP2: if feMasterStat == true; register PREPARE1 & PREPARE2 [retry 3
times, sleep 10s]
+DORIS_HOME="/opt/apache-doris"
- ## PREPARE1: registe follower from mysql client
- registerMySQL="mysql -uroot -P9030 -h${feIpArray[1]} -e \"alter system add
follower '${feIpArray[FE_ID]}:${feEditLogPortArray[FE_ID]}'\""
+# Obtain necessary and basic information to complete initialization
- ## PREPARE2: call start_fe.sh using --help optional
- registerShell="/opt/apache-doris/fe/bin/start_fe.sh --helper
'${feIpArray[1]}:${feEditLogPortArray[1]}'"
+# logging functions
+# usage: doris_[note|warn|error] $log_meg
+# ie: doris_warn "task may fe risky!"
+# out: 2023-01-08T19:08:16+08:00 [Warn] [Entrypoint]: task may fe risky!
+doris_log() {
+ local type="$1"
+ shift
+ # accept argument string or stdin
+ local text="$*"
+ if [ "$#" -eq 0 ]; then text="$(cat)"; fi
+ local dt="$(date -Iseconds)"
+ printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text"
+}
+doris_note() {
+ doris_log Note "$@"
+}
+doris_warn() {
+ doris_log Warn "$@" >&2
+}
+doris_error() {
+ doris_log ERROR "$@" >&2
+ exit 1
+}
+
+# check to see if this file is being run or sourced from another script
+_is_sourced() {
+ [ "${#FUNCNAME[@]}" -ge 2 ] &&
+ [ "${FUNCNAME[0]}" = '_is_sourced' ] &&
+ [ "${FUNCNAME[1]}" = 'source' ]
+}
+
+docker_setup_env() {
+ declare -g DATABASE_ALREADY_EXISTS
+ if [ -d "${DORIS_HOME}/fe/doris-meta/image" ]; then
+ DATABASE_ALREADY_EXISTS='true'
+ fi
+}
+
+# Check the variables required for startup
+docker_required_variables_env() {
+ if [[ $FE_SERVERS =~
^.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4}(,.+:[1-2]{0,1}[0-9]{0,1}[0-9]{1}(\.[1-2]{0,1}[0-9]{0,1}[0-9]{1}){3}:[1-6]{0,1}[0-9]{1,4})*$
]]; then
+ doris_warn "FE_SERVERS" $FE_SERVERS
+ else
+ doris_error "FE_SERVERS rule error!example:
\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT[,\$FE_NAME:\$FE_HOST_IP:\$FE_EDIT_LOG_PORT]..."
+ fi
+ if [[ $FE_ID =~ ^[1-9]{1}$ ]]; then
+ doris_warn "FE_ID" $FE_ID
+ else
+ doris_error "FE_ID rule error!If FE is the role of Master, please set
FE_ID=1, and ensure that all IDs correspond to the IP of the current node."
+ fi
+}
+
+get_doris_fe_args() {
+ local feServerArray=($(echo "${FE_SERVERS}" | awk '{gsub (/,/," "); print
$0}'))
+ for i in "${feServerArray[@]}"; do
+ val=${i}
+ val=${val// /}
+ tmpFeName=$(echo "${val}" | awk -F ':' '{ sub(/fe/, ""); sub(/ /, "");
print$1}')
+ tmpFeIp=$(echo "${val}" | awk -F ':' '{ sub(/ /, ""); print$2}')
+ tmpFeEditLogPort=$(echo "${val}" | awk -F ':' '{ sub(/ /, "");
print$3}')
+ check_arg "TMP_FE_NAME" $tmpFeName
+ feIpArray[$tmpFeName]=${tmpFeIp}
+ check_arg "TMP_FE_EDIT_LOG_PORT" $tmpFeEditLogPort
+ feEditLogPortArray[$tmpFeName]=${tmpFeEditLogPort}
+ done
- echo "DEBUG >>>>>> FE is follower, fe_id = ${FE_ID}"
- echo "DEBUG >>>>>> registerMySQL = 【${registerMySQL}】"
- echo "DEBUG >>>>>> registerShell = 【${registerShell}】"
- echo "DEBUG >>>>>> feMasterStat = 【mysql -uroot -P9030 -h ${feIpArray[1]}
-e \"show frontends\" | grep \"${feIpArray[1]}_9010\" | grep -E
\"true[[:space:]]*true\"】"
+ declare -g MASTER_FE_IP CURRENT_FE_IP MASTER_FE_EDIT_PORT
CURRENT_FE_EDIT_PORT PRIORITY_NETWORKS CURRENT_FE_IS_MASTER
+ MASTER_FE_IP=${feIpArray[1]}
+ check_arg "MASTER_FE_IP" $MASTER_FE_IP
+ MASTER_FE_EDIT_PORT=${feEditLogPortArray[1]}
+ check_arg "MASTER_FE_EDIT_PORT" $MASTER_FE_EDIT_PORT
+ CURRENT_FE_IP=${feIpArray[FE_ID]}
+ check_arg "CURRENT_FE_IP" $CURRENT_FE_IP
+ CURRENT_FE_EDIT_PORT=${feEditLogPortArray[FE_ID]}
+ check_arg "CURRENT_FE_EDIT_PORT" $CURRENT_FE_EDIT_PORT
+
+ if [ ${MASTER_FE_IP} == ${CURRENT_FE_IP} ]; then
+ CURRENT_FE_IS_MASTER=true
+ else
+ CURRENT_FE_IS_MASTER=false
+ fi
+
+ PRIORITY_NETWORKS=$(echo "${CURRENT_FE_IP}" | awk -F '.'
'{print$1"."$2"."$3".0/24"}')
+ check_arg "PRIORITY_NETWORKS" $PRIORITY_NETWORKS
+
+ doris_note "FE_IP_ARRAY = ${feIpArray[*]}"
+ doris_note "FE_EDIT_LOG_PORT_ARRAY = ${feEditLogPortArray[*]}"
+ doris_note "MASTER_FE = ${feIpArray[1]}:${feEditLogPortArray[1]}"
+ doris_note "CURRENT_FE = ${CURRENT_FE_IP}:${CURRENT_FE_EDIT_PORT}"
+ doris_note "PRIORITY_NETWORKS = ${PRIORITY_NETWORKS}"
+ # wait fe start
+ check_fe_status true
+}
+
+add_priority_networks() {
+ doris_note "add priority_networks ${1} to ${DORIS_HOME}/fe/conf/fe.conf"
+ echo "priority_networks = ${1}" >>${DORIS_HOME}/fe/conf/fe.conf
+}
+
+# Execute sql script, passed via stdin
+# usage: docker_process_sql sql_script
+docker_process_sql() {
+ set +e
+ mysql -uroot -P9030 -h${MASTER_FE_IP} --comments "$@" 2>/dev/null
+}
+
+docker_setup_db() {
+ set +e
+ # check fe status
+ local is_fe_start=false
+ if [ ${CURRENT_FE_IS_MASTER} == true ]; then
+ doris_note "Current FE is Master FE! No need to register again!"
+ return
+ fi
+ for i in {1..300}; do
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_note "ADD FOLLOWER failed, retry."
+ fi
+ docker_process_sql <<<"alter system add FOLLOWER
'${CURRENT_FE_IP}:${CURRENT_FE_EDIT_PORT}'"
+ register_fe_status=$?
+ if [[ $register_fe_status == 0 ]]; then
+ doris_note "FE successfully registered!"
+ is_fe_start=true
+ break
+ else
+ check_fe_status
+ if [ -n "$CURRENT_FE_ALREADY_EXISTS" ]; then
+ doris_warn "Same frontend already exists! No need to register
again!"
+ break
+ fi
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_warn "register_fe_status: ${register_fe_status}"
+ doris_warn "FE failed registered!"
+ fi
+ fi
+ sleep 1
+ done
+ if ! [[ $is_fe_start ]]; then
+ doris_error "Failed to register CURRENT_FE to FE!Tried 30 times!Maybe
FE Start Failed!"
+ fi
+}
+
+# Check whether the passed parameters are empty to avoid subsequent task
execution failures. At the same time,
+# enumeration checks can fe added, such as checking whether a certain
parameter appears repeatedly, etc.
+check_arg() {
+ if [ -z $2 ]; then
+ doris_error "$1 is null!"
+ fi
+}
+
+# 这里可用 docker_process_sql() 函数封装,为了方便调试,暂未封装
+check_fe_status() {
+ set +e
+ declare -g CURRENT_FE_ALREADY_EXISTS
+ if [ ${CURRENT_FE_IS_MASTER} == true ]; then
+ doris_note "Current FE is Master FE! No need check fe status!"
+ return
+ fi
+ for i in {1..300}; do
+ if [[ $(($i % 20)) == 1 ]]; then
+ doris_note "try session Master FE."
+ fi
+ if [[ $1 == true ]]; then
+ docker_process_sql <<<"show frontends" | grep
"[[:space:]]${MASTER_FE_IP}[[:space:]]" | grep
"[[:space:]]${MASTER_FE_EDIT_PORT}[[:space:]]"
+ else
+ docker_process_sql <<<"show frontends" | grep
"[[:space:]]${CURRENT_FE_IP}[[:space:]]" | grep
"[[:space:]]${CURRENT_FE_EDIT_PORT}[[:space:]]"
+ fi
+ fe_join_status=$?
+ if [[ "${fe_join_status}" == 0 ]]; then
+ if [[ $1 == true ]]; then
+ doris_note "Master FE is started!"
+ else
+ doris_note "Verify that CURRENT_FE is registered to FE
successfully"
+ fi
+ CURRENT_FE_ALREADY_EXISTS=true
+ break
+ else
+ if [[ $(($i % 20)) == 1 ]]; then
+ if [[ $1 == true ]]; then
+ doris_note "Master FE is not started, retry."
+ else
+ doris_warn "Verify that CURRENT_FE is registered to FE
failed, retry."
+ fi
+ fi
+ fi
+ sleep 1
+ done
+}
- ## STEP1: check FE master status
+_main() {
+ docker_setup_env
+ docker_required_variables_env
+ get_doris_fe_args
- for ((i = 0; i <= 2000; i++)); do
+ if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
+ add_priority_networks $PRIORITY_NETWORKS
+ fi
- ## run STEP1 & STEP2, and then break
- echo "Run registerShell command, [ registerMySQL = ${registerMySQL} ]"
- eval "${registerMySQL}"
- sleep 2
+ docker_setup_db
+ check_fe_status
+ doris_note "Ready to start CURRENT_FE!"
- ## followerJoined: Joined = 0, doesn't join = 1
- mysql -uroot -P9030 -h"${feIpArray[1]}" -e "show frontends" | grep
"${feIpArray[FE_ID]}_9010" | grep -E "false[[:space:]]*false"
- followerJoined=$?
+ if [ $CURRENT_FE_IS_MASTER == true ]; then
+ start_fe.sh
+ else
+ start_fe.sh --helper ${MASTER_FE_IP}:${MASTER_FE_EDIT_PORT}
+ fi
- if [[ "${followerJoined}" == 0 ]]; then
- echo "Run registerShell command, [ registerShell =
${registerShell} ]"
- eval "${registerShell}"
- echo "The resutl of run registerShell command, [ res = $? ]"
- fi
- sleep 5
- done
+ exec "$@"
+}
-else
- registerShell="/opt/apache-doris/fe/bin/start_fe.sh"
- eval "${registerShell}"
- echo "DEBUG >>>>>> FE is master, fe_id = ${FE_ID}"
- echo "DEBUG >>>>>> registerShell = ${registerShell}"
+if ! _is_sourced; then
+ _main "$@"
fi
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]