diff --git a/Dockerfile b/Dockerfile index f41f3bb78..4efc1e87d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,6 +13,8 @@ ARG TARGETPLATFORM ARG TARGETARCH ARG TARGETVARIANT +ARG EXTRA_PACKAGES + ARG OPEN_SSL_VERSION=1.1.1s RUN echo "Running on $BUILDPLATFORM, building for $TARGETPLATFORM" @@ -22,6 +24,7 @@ RUN --mount=type=cache,target=/var/cache/apt,id=ubuntu22-apt \ --mount=type=cache,target=/var/lib/apt/lists,id=ubuntu22-apt-lists \ apt-get update -y \ && apt-get install -y wget tar gzip \ + $EXTRA_PACKAGES \ libncurses5 libnuma-dev \ bc \ sudo diff --git a/README.md b/README.md index a1b06fbe7..dd5a5d57e 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,27 @@ It may be the case that the benchmarks require more resources than are configure To execute a benchmark on a bigger machine to get better numbers one needs to increase the settings in docker.env and resources/config_templates/config.ini. +## Instrumentation for mysqld + +Instrumenting `mysqld` is recommended only for advanced debugging scenarios. +The `--mysqld-instrumentation` argument is used to prepend the command line that starts `mysqld`. +Use the `--extra-packages` argument to list the packages you need installed for this purpose. +Example: + +```bash +# Use valgrind to check for memory leaks during a benchmark run. Since we use the +# --volumes-in-local-dir flag, the memcheck output will be saved under +# `autogenerated_files/*/volumes/mysqlFilesDir_mysqld_*/`. +./build_run_docker.sh \ + --rondb-tarball-is-local \ + -ruri ./rondb-21.04.9-linux-glibc2.35-arm64_v8.tar.gz \ + -v 21.04.9 -m 1 -g 1 -r 2 -my 1 -a 1 \ + --mysqld-instrumentation "valgrind --log-file=/srv/hops/mysql-cluster/mysql-files/memcheck.log" \ + --extra-packages valgrind \ + --volumes-in-local-dir \ + --run-benchmark sysbench_single +``` + ## Goals of this repository 1. Create an image with RonDB installed "hopsworks/rondb-standalone:21.04.9" diff --git a/build_run_docker.sh b/build_run_docker.sh index ab9a939f5..b9a00815a 100755 --- a/build_run_docker.sh +++ b/build_run_docker.sh @@ -53,6 +53,8 @@ Usage: $0 [-lv --volumes-in-local-dir ] [-sf --save-sample-files ] [-d --detached ] + [-mi --mysqld-instrumentation ] + [-ep --extra-packages ] EOF } @@ -76,6 +78,8 @@ RUN_BENCHMARK= VOLUME_TYPE=docker SAVE_SAMPLE_FILES= DETACHED= +MYSQLD_INSTRUMENTATION= +EXTRA_PACKAGES= POSITIONAL=() while [[ $# -gt 0 ]]; do @@ -147,6 +151,18 @@ while [[ $# -gt 0 ]]; do shift # past argument ;; + -mi | --mysqld-instrumentation) + MYSQLD_INSTRUMENTATION="$2" + shift # past argument + shift # past value + ;; + + -ep | --extra-packages) + EXTRA_PACKAGES="$2" + shift # past argument + shift # past value + ;; + *) # unknown option POSITIONAL+=("$1") # save it in an array for later shift # past argument @@ -173,6 +189,8 @@ print-parsed-arguments() { echo "Volume type docker/local = ${VOLUME_TYPE}" echo "Save sample files = ${SAVE_SAMPLE_FILES}" echo "Run detached = ${DETACHED}" + echo "Instrumentation mysqld = ${MYSQLD_INSTRUMENTATION}" + echo "Extra packages = ${EXTRA_PACKAGES}" echo } print-parsed-arguments @@ -249,12 +267,23 @@ fi # We use this for the docker-compose project name, which will not allow "." RONDB_VERSION_NO_DOT=$(echo "$RONDB_VERSION" | tr -d '.') +# We can't put an arbitrary command line or arbitrary list of packages as part +# of a filename, so hash them. User can refer to parsed_arguments.txt for full +# context. +MYSQLD_INSTRUMENTATION_INDICATOR= +if [ -n "$MYSQLD_INSTRUMENTATION" ]; then + MYSQLD_INSTRUMENTATION_INDICATOR="$(echo "$MYSQLD_INSTRUMENTATION" | sha256sum | sed -r 's/^(.{4}).*$/_mi-\1/')" +fi +EXTRA_PACKAGES_INDICATOR= +if [ -n "$EXTRA_PACKAGES" ]; then + EXTRA_PACKAGES_INDICATOR="$(echo "$EXTRA_PACKAGES" | sha256sum | sed -r 's/^(.{4}).*$/_ep-\1/')" +fi ## Uncomment this for quicker testing # yes | docker container prune # yes | docker volume prune -FILE_SUFFIX="v${RONDB_VERSION_NO_DOT}_m${NUM_MGM_NODES}_g${NODE_GROUPS}_r${REPLICATION_FACTOR}_my${NUM_MYSQL_NODES}_api${NUM_API_NODES}" +FILE_SUFFIX="v${RONDB_VERSION_NO_DOT}_m${NUM_MGM_NODES}_g${NODE_GROUPS}_r${REPLICATION_FACTOR}_my${NUM_MYSQL_NODES}_api${NUM_API_NODES}${MYSQLD_INSTRUMENTATION_INDICATOR}${EXTRA_PACKAGES_INDICATOR}" AUTOGENERATED_FILES_DIR="$SCRIPT_DIR/autogenerated_files/$FILE_SUFFIX" rm -rf $AUTOGENERATED_FILES_DIR @@ -305,11 +334,12 @@ BENCH_DIR="/home/mysql/benchmarks" echo "Building RonDB Docker image for local platform" -RONDB_IMAGE_NAME="rondb-standalone:$RONDB_VERSION" +RONDB_IMAGE_NAME="rondb-standalone:$RONDB_VERSION${MYSQLD_INSTRUMENTATION_INDICATOR}${EXTRA_PACKAGES_INDICATOR}" docker buildx build . \ --tag "$RONDB_IMAGE_NAME" \ --build-arg RONDB_VERSION="$RONDB_VERSION" \ --build-arg RONDB_TARBALL_LOCAL_REMOTE=$RONDB_TARBALL_LOCAL_REMOTE \ + --build-arg "EXTRA_PACKAGES=$EXTRA_PACKAGES" \ --build-arg RONDB_TARBALL_URI="$RONDB_TARBALL_URI" ####################### @@ -530,6 +560,10 @@ if [ "$NUM_MYSQL_NODES" -gt 0 ]; then # Only need one mysqld to setup databases, users, etc. template+="$(printf "$ENV_VAR_TEMPLATE" "MYSQL_SETUP_APP" "1")" fi + if [ -n "$MYSQLD_INSTRUMENTATION" ]; then + env_var="$(printf "$ENV_VAR_TEMPLATE" "MYSQLD_INSTRUMENTATION" "$MYSQLD_INSTRUMENTATION")" + template+="$env_var" + fi BASE_DOCKER_COMPOSE_FILE+="$template" diff --git a/resources/entrypoints/mysqld.sh b/resources/entrypoints/mysqld.sh index a5677dbc6..805e3274e 100755 --- a/resources/entrypoints/mysqld.sh +++ b/resources/entrypoints/mysqld.sh @@ -74,8 +74,8 @@ echo '[entrypoints/mysqld.sh] Database initialized' export MYSQLD_PARENT_PID=$$ if [ -z "$MYSQL_SETUP_APP" ]; then echo '[entrypoints/mysqld.sh] Not setting up app here; going straight to execution of mysqld' - echo "[entrypoints/mysqld.sh] Running: $*" - exec "$@" + echo "[entrypoints/mysqld.sh] Running: $MYSQLD_INSTRUMENTATION $*" + exec $MYSQLD_INSTRUMENTATION "$@" fi echo '[entrypoints/mysqld.sh] Executing mysqld as daemon with no networking allowed...' @@ -175,5 +175,5 @@ mysqladmin -uroot --password="$MYSQL_ROOT_PASSWORD" shutdown --socket="$SOCKET" echo "[entrypoints/mysqld.sh] Successfully shut down MySQLd" echo '[entrypoints/mysqld.sh] MySQL init process done. Ready for start up.' -echo "[entrypoints/mysqld.sh] Running: $*" -exec "$@" +echo "[entrypoints/mysqld.sh] Running: $MYSQLD_INSTRUMENTATION $*" +exec $MYSQLD_INSTRUMENTATION "$@"