This is an automated email from the ASF dual-hosted git repository.
joemcdonnell pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new 8af0ce8ed IMPALA-13001: Support graceful and force shutdown for
impala.sh
8af0ce8ed is described below
commit 8af0ce8ed6659fdda9b81847d4871c14036e173c
Author: Xiang Yang <[email protected]>
AuthorDate: Sat Apr 13 08:45:56 2024 +0000
IMPALA-13001: Support graceful and force shutdown for impala.sh
This patch add graceful and force shutdown support for impala.sh.
This patch also keep the stdout and stderr log when startup.
This patch also fix some bugs in the impala.sh, including:
- empty service name check.
- restart command cannot work.
Testing:
- Manually deploy package on Ubuntu22.04 and verify it.
Change-Id: Ib7743234952ba6b12694ecc68a920d59fea0d4ba
Reviewed-on: http://gerrit.cloudera.org:8080/21297
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
.gitignore | 2 ++
package/bin/impala.sh | 85 ++++++++++++++++++++++++++++++++--------------
package/conf/impala-env.sh | 14 +++++++-
3 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/.gitignore b/.gitignore
index c66967175..4f2171377 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,6 +42,8 @@ CMakeDoxygenDefaults.cmake
CPackConfig.cmake
CPackSourceConfig.cmake
_CPack_Packages
+install_manifest.txt
+package/build/
# Build timestamp files
.*timestamp
diff --git a/package/bin/impala.sh b/package/bin/impala.sh
index 219f7cacb..3ef3dbe6f 100755
--- a/package/bin/impala.sh
+++ b/package/bin/impala.sh
@@ -49,13 +49,14 @@ status() {
while [[ $# -gt 0 ]]; do
case ${1} in
impalad|catalogd|admissiond|statestored) service=${1} && shift && break
;;
- *) usage && exit 1 ;;
+ *) >&2 usage && exit 1 ;;
esac
done
+ [[ ${service} != "" ]] || (>&2 usage && exit 1)
local service_pidfile_key=${service^^}_PIDFILE
local service_pidfile=${!service_pidfile_key}
if [[ ! -f ${service_pidfile} ]]; then
- echo "${service} is stopped."
+ >&2 echo "${service} is stopped."
return 1
fi
local pid=$(cat ${service_pidfile})
@@ -63,15 +64,15 @@ status() {
echo "${service} is running with PID ${pid}."
return 0
fi
- echo "${service} is stopped."
+ >&2 echo "${service} is stopped."
return 1
}
# Return 0 if service is stopped in expected time, else otherwise.
stop_await() {
local service=${1} service_pidfile=${2} counts=${3} period=${4}
- [[ "${counts}" == "0" ]] && exit 0
- for ((i=1; i<=${counts}; i++)); do
+ [[ "${counts}" == "0" ]] && return 0
+ for ((i=1; ${counts} == -1 || i<=${counts}; i++)); do
[[ ${i} -gt 1 ]] && sleep ${period}
if ! kill -0 ${pid} &> /dev/null; then
rm ${service_pidfile} && echo "(${i}/${counts}) ${service} is stopped."
&& return 0
@@ -82,36 +83,54 @@ stop_await() {
return 1
}
-#TODO: Add graceful shutdown for impalads
stop() {
- local service= counts=20 period=2
+ local service= counts=20 period=2 signal=SIGTERM force=false grace=false
while [[ $# -gt 0 ]]; do
case ${1} in
-c) counts=${2} && shift 2 ;;
-p) period=${2} && shift 2 ;;
+ -f) signal=SIGKILL && force=true && shift 1 ;;
+ -g) signal=SIGRTMIN && grace=true && shift 1 ;;
impalad|catalogd|admissiond|statestored) service=${1} && shift && break
;;
- *) usage && exit 1 ;;
+ *) >&2 usage && exit 1 ;;
esac
done
check_counts ${counts} ${period}
+ [[ ${service} != "" ]] || (>&2 usage && exit 1)
+ # Disable graceful shutdown timeout.
+ [[ ${grace} == true ]] && counts=-1 || true
+ if [[ ${grace} == true && ${force} == true ]]; then
+ echo "Cannot use '-g' and '-f' together."
+ exit 1
+ fi
+ if [[ ${grace} == true && ${service} != impalad ]]; then
+ echo "Warning: Cannot apply '-g' to ${service} service."
+ signal=SIGTERM
+ fi
local service_pidfile_key=${service^^}_PIDFILE
local service_pidfile=${!service_pidfile_key}
if [[ ! -f ${service_pidfile} ]]; then
echo "Already stopped: PID file '${service_pidfile}' not found."
- exit 0
+ return 0
fi
local pid=$(cat ${service_pidfile})
if ! ps -p ${pid} -o comm=|grep ${service} &> /dev/null ; then
rm ${service_pidfile}
echo "Already stopped: ${service} is not running with PID ${pid}." \
"Removed stale file '${service_pidfile}'."
- exit 0
+ return 0
fi
echo "Killing ${service} with PID ${pid}."
- kill ${pid}
+ kill -${signal} ${pid}
if ! stop_await ${service} ${service_pidfile} ${counts} ${period}; then
- echo "Timed out waiting ${service} to stop, check logs for more details."
- exit 1
+ if [[ ${grace} == true ]]; then
+ kill -SIGKILL ${pid}
+ echo "Timed out waiting ${service} to graceful shutdown."
+ return 0
+ else
+ echo "Timed out waiting ${service} to stop, check logs for more details."
+ return 1
+ fi
fi
}
@@ -147,20 +166,29 @@ start() {
case ${1} in
-c) counts=${2} && shift 2 ;;
-p) period=${2} && shift 2 ;;
+ # Ignore the '-f' and '-g' parameter to support the restart command.
+ -f|-g) shift 1 ;;
impalad|catalogd|admissiond|statestored) service=${1} && shift && break
;;
- *) usage && exit 1 ;;
+ *) >&2 usage && exit 1 ;;
esac
done
check_counts ${counts} ${period}
- status ${service} && exit 0
+ [[ ${service} != "" ]] || (>&2 usage && exit 1)
+ status ${service} 2> /dev/null && return 0
local service_flagfile=${IMPALA_HOME}/conf/${service}_flags
+ local service_stdout_key=${service^^}_OUTFILE
+ local service_stderr_key=${service^^}_ERRFILE
local service_pidfile_key=${service^^}_PIDFILE
+ local service_stdout=${!service_stdout_key}
+ local service_stderr=${!service_stderr_key}
local service_pidfile=${!service_pidfile_key}
mkdir -p $(dirname ${service_pidfile})
+ echo "Service stdout is redirected to '${service_stdout}'."
+ echo "Service stderr is redirected to '${service_stderr}'."
# User can override '--flagfile' in the following commandline arguments.
${IMPALA_HOME}/sbin/${service} \
--flagfile=${service_flagfile} \
- ${@} &
+ ${@} >> ${service_stdout} 2>> ${service_stderr} &
local pid=$!
echo ${pid} > ${service_pidfile}
# Sleep 1s so the glog output won't be messed up with waiting messages.
@@ -173,18 +201,19 @@ restart() {
}
health() {
- local service= counts=20 period=2
+ local service= counts=20 period=2 code=
while [[ $# -gt 0 ]]; do
case ${1} in
-c) counts=${2} && shift 2 ;;
-p) period=${2} && shift 2 ;;
impalad|catalogd|admissiond|statestored) service=${1} && shift ;;
- *) usage && exit 1 ;;
+ *) >&2 usage && exit 1 ;;
esac
done
check_counts ${counts} ${period}
[[ "${counts}" == "0" ]] && exit 0
- status ${service} || exit 1
+ [[ ${service} != "" ]] || (>&2 usage && exit 1)
+ status ${service} > /dev/null || exit 1
# Determine Web Server port
local service_flagfile=${IMPALA_HOME}/conf/${service}_flags
local service_pidfile_key=${service^^}_PIDFILE
@@ -207,8 +236,8 @@ health() {
# Request healthz code
for ((i=1; i<=${counts}; i++)); do
[[ ${i} -gt 1 ]] && sleep ${period} || true
- local code=$(curl -s http://localhost:${port}/healthz)
- if [[ $? != 0 ]]; then
+ if ! code=$(curl -s http://localhost:${port}/healthz); then
+ status ${service} > /dev/null || exit 1
echo "(${i}/${counts}) ${service} on port ${port} is not ready."
elif [[ "${code}" != "OK" ]]; then
echo "(${i}/${counts}) Waiting for ${service} to be ready."
@@ -237,10 +266,16 @@ usage() {
echo " stop: stop an Impala daemon service, wait until service is stopped."
echo " options:"
echo " -c: maximum count of checks, defaults to 20."
+ echo " -f: force kill a daemon service."
+ echo " -g: graceful shutdown the impalad service."
echo " -p: seconds of period between checks, defaults to 2."
echo
echo " restart: restart an Impala daemon service."
- echo " options: same as start command."
+ echo " options:"
+ echo " -c: maximum count of checks, defaults to 20."
+ echo " -f: force kill a daemon service."
+ echo " -g: graceful shutdown the impalad service."
+ echo " -p: seconds of period between checks, defaults to 2."
echo
echo " status: check the process status of an Impala daemon service."
echo
@@ -261,11 +296,11 @@ version() {
main() {
[[ $# -ge 1 && ${1} == "--help" ]] && usage && exit 0
[[ $# -ge 1 && ${1} == "--version" ]] && version && exit 0
- [[ $# -lt 2 ]] && usage && exit 1
+ [[ $# -lt 2 ]] && >&2 usage && exit 1
local command=${1}
case ${command} in
- start|stop|restart|status|health) shift && init && ${command} $@ ;;
- *) usage && exit 1 ;;
+ start|stop|restart|status|health) shift && init && ${command} ${@} ;;
+ *) >&2 usage && exit 1 ;;
esac
}
diff --git a/package/conf/impala-env.sh b/package/conf/impala-env.sh
index c5bb78de6..39c1a06a0 100644
--- a/package/conf/impala-env.sh
+++ b/package/conf/impala-env.sh
@@ -36,8 +36,20 @@
# Specify JVM options.
export JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS:-}
-# Specify default pidfile directories.
+# Specify default pidfile.
: ${IMPALAD_PIDFILE:="/tmp/impalad.pid"}
: ${CATALOGD_PIDFILE:="/tmp/catalogd.pid"}
: ${ADMISSIOND_PIDFILE:="/tmp/admissiond.pid"}
: ${STATESTORED_PIDFILE:="/tmp/statestored.pid"}
+
+# Specify default stdout file.
+: ${IMPALAD_OUTFILE:="/tmp/impalad.out"}
+: ${CATALOGD_OUTFILE:="/tmp/catalogd.out"}
+: ${ADMISSIOND_OUTFILE:="/tmp/admissiond.out"}
+: ${STATESTORED_OUTFILE:="/tmp/statestored.out"}
+
+# Specify default stderr file.
+: ${IMPALAD_ERRFILE:="/tmp/impalad.err"}
+: ${CATALOGD_ERRFILE:="/tmp/catalogd.err"}
+: ${ADMISSIOND_ERRFILE:="/tmp/admissiond.err"}
+: ${STATESTORED_ERRFILE:="/tmp/statestored.err"}