commit mariadb-image for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mariadb-image for openSUSE:Factory checked in at 2024-01-03 12:31:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mariadb-image (Old) and /work/SRC/openSUSE:Factory/.mariadb-image.new.28375 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "mariadb-image" Wed Jan 3 12:31:36 2024 rev:3 rq:1136342 version:unknown Changes: -------- --- /work/SRC/openSUSE:Factory/mariadb-image/mariadb-image.changes 2023-12-21 23:38:57.419289936 +0100 +++ /work/SRC/openSUSE:Factory/.mariadb-image.new.28375/mariadb-image.changes 2024-01-03 12:32:14.071363234 +0100 @@ -1,0 +2,5 @@ +Tue Jan 2 08:26:58 UTC 2024 - Dirk Mueller <dmueller@suse.com> + +- update year to 2024 + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ Dockerfile ++++++ --- /var/tmp/diff_new_pack.b9UV7G/_old 2024-01-03 12:32:15.515416046 +0100 +++ /var/tmp/diff_new_pack.b9UV7G/_new 2024-01-03 12:32:15.519416192 +0100 @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT -# Copyright (c) 2023 SUSE LLC +# Copyright (c) 2024 SUSE LLC # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed ++++++ docker-entrypoint.sh ++++++ --- /var/tmp/diff_new_pack.b9UV7G/_old 2024-01-03 12:32:15.555417509 +0100 +++ /var/tmp/diff_new_pack.b9UV7G/_new 2024-01-03 12:32:15.559417655 +0100 @@ -64,6 +64,8 @@ # process initializer files, based on file extensions docker_process_init_files() { # mysql here for backwards compatibility "${mysql[@]}" + # ShellCheck: mysql appears unused. Verify use (or export if used externally) + # shellcheck disable=SC2034 mysql=( docker_process_sql ) echo @@ -78,6 +80,8 @@ "$f" else mysql_note "$0: sourcing $f" + # ShellCheck can't follow non-constant source. Use a directive to specify location. + # shellcheck disable=SC1090 . "$f" fi ;; @@ -94,7 +98,6 @@ # arguments necessary to run "mysqld --verbose --help" successfully (used for testing configuration validity and for extracting default/configured values) _verboseHelpArgs=( --verbose --help - --log-bin-index="$(mktemp -u)" # https://github.com/docker-library/mysql/issues/136 ) mysql_check_config() { @@ -116,9 +119,13 @@ # Do a temporary startup of the MariaDB server, for init purposes docker_temp_server_start() { - "$@" --skip-networking --default-time-zone=SYSTEM --socket="${SOCKET}" --wsrep_on=OFF & + "$@" --skip-networking --default-time-zone=SYSTEM --socket="${SOCKET}" --wsrep_on=OFF \ + --expire-logs-days=0 \ + --loose-innodb_buffer_pool_load_at_startup=0 & + declare -g MARIADB_PID + MARIADB_PID=$! mysql_note "Waiting for server startup" - # only use the root password if the database has already been initializaed + # only use the root password if the database has already been initialized # so that it won't try to fill in a password file when it hasn't been set yet extraArgs=() if [ -z "$DATABASE_ALREADY_EXISTS" ]; then @@ -139,15 +146,48 @@ # Stop the server. When using a local socket file mysqladmin will block until # the shutdown is complete. docker_temp_server_stop() { - if ! MYSQL_PWD=$MARIADB_ROOT_PASSWORD mysqladmin shutdown -uroot --socket="${SOCKET}"; then - mysql_error "Unable to shut down server." - fi + kill "$MARIADB_PID" + wait "$MARIADB_PID" } # Verify that the minimally required password settings are set for new databases. docker_verify_minimum_env() { - if [ -z "$MARIADB_ROOT_PASSWORD" -a -z "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" -a -z "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then - mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MARIADB_ROOT_PASSWORD, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD and MARIADB_RANDOM_ROOT_PASSWORD' + # Restoring from backup requires no environment variables + declare -g DATABASE_INIT_FROM_BACKUP + for file in /docker-entrypoint-initdb.d/*.tar{.gz,.xz,.zst}; do + if [ -f "${file}" ]; then + DATABASE_INIT_FROM_BACKUP='true' + return + fi + done + if [ -z "$MARIADB_ROOT_PASSWORD" ] && [ -z "$MARIADB_ROOT_PASSWORD_HASH" ] && [ -z "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" ] && [ -z "$MARIADB_RANDOM_ROOT_PASSWORD" ]; then + mysql_error $'Database is uninitialized and password option is not specified\n\tYou need to specify one of MARIADB_ROOT_PASSWORD, MARIADB_ROOT_PASSWORD_HASH, MARIADB_ALLOW_EMPTY_ROOT_PASSWORD and MARIADB_RANDOM_ROOT_PASSWORD' + fi + # More preemptive exclusions of combinations should have been made before *PASSWORD_HASH was added, but for now we don't enforce due to compatibility. + if [ -n "$MARIADB_ROOT_PASSWORD" ] || [ -n "$MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" ] || [ -n "$MARIADB_RANDOM_ROOT_PASSWORD" ] && [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then + mysql_error "Cannot specify MARIADB_ROOT_PASSWORD_HASH and another MARIADB_ROOT_PASSWORD* option." + fi + if [ -n "$MARIADB_PASSWORD" ] && [ -n "$MARIADB_PASSWORD_HASH" ]; then + mysql_error "Cannot specify MARIADB_PASSWORD_HASH and MARIADB_PASSWORD option." + fi + if [ -n "$MARIADB_REPLICATION_USER" ]; then + if [ -z "$MARIADB_MASTER_HOST" ]; then + # its a master, we're creating a user + if [ -z "$MARIADB_REPLICATION_PASSWORD" ] && [ -z "$MARIADB_REPLICATION_PASSWORD_HASH" ]; then + mysql_error "MARIADB_REPLICATION_PASSWORD or MARIADB_REPLICATION_PASSWORD_HASH not found to create replication user for master" + fi + else + # its a replica + if [ -z "$MARIADB_REPLICATION_PASSWORD" ] ; then + mysql_error "MARIADB_REPLICATION_PASSWORD is mandatory to specify the replication on the replica image." + fi + if [ -n "$MARIADB_REPLICATION_PASSWORD_HASH" ] ; then + mysql_warn "MARIADB_REPLICATION_PASSWORD_HASH cannot be specified on a replica" + fi + fi + fi + if [ -n "$MARIADB_MASTER_HOST" ] && { [ -z "$MARIADB_REPLICATION_USER" ] || [ -z "$MARIADB_REPLICATION_PASSWORD" ] ; }; then + mysql_error "For a replica, MARIADB_REPLICATION_USER and MARIADB_REPLICATION is mandatory." fi } @@ -162,22 +202,31 @@ if [ "$user" = "0" ]; then # this will cause less disk access than `chown -R` - find "$DATADIR" \! -user mysql -exec chown mysql '{}' + + find "$DATADIR" \! -user mysql -exec chown mysql: '{}' + # See https://github.com/MariaDB/mariadb-docker/issues/363 - find "${SOCKET%/*}" -maxdepth 0 \! -user mysql -exec chown mysql '{}' \; + find "${SOCKET%/*}" -maxdepth 0 \! -user mysql -exec chown mysql: '{}' \; fi } +_mariadb_version() { + local mariaVersion="${MARIADB_VERSION##*:}" + mariaVersion="${mariaVersion%%[-+~]*}" + echo -n "${mariaVersion}-MariaDB" +} + # initializes the database directory docker_init_database_dir() { mysql_note "Initializing database files" installArgs=( --datadir="$DATADIR" --rpm --auth-root-authentication-method=normal ) - if { mysql_install_db --help || :; } | grep -q -- '--skip-test-db'; then - # 10.3+ - installArgs+=( --skip-test-db ) - fi # "Other options are passed to mysqld." (so we pass all "mysqld" arguments directly here) - mysql_install_db "${installArgs[@]}" "${@:2}" --default-time-zone=SYSTEM --enforce-storage-engine= + mysql_install_db "${installArgs[@]}" "${@:2}" \ + --skip-test-db \ + --old-mode='UTF8_IS_UTF8MB3' \ + --default-time-zone=SYSTEM --enforce-storage-engine= \ + --skip-log-bin \ + --expire-logs-days=0 \ + --loose-innodb_buffer_pool_load_at_startup=0 \ + --loose-innodb_buffer_pool_dump_at_shutdown=0 mysql_note "Database files initialized" } @@ -185,9 +234,10 @@ # This should be called after mysql_check_config, but before any other functions docker_setup_env() { # Get config - declare -g DATADIR SOCKET + declare -g DATADIR SOCKET PORT DATADIR="$(mysql_get_config 'datadir' "$@")" SOCKET="$(mysql_get_config 'socket' "$@")" + PORT="$(mysql_get_config 'port' "$@")" # Initialize values that might be stored in a file @@ -196,6 +246,16 @@ _mariadb_file_env 'MYSQL_USER' _mariadb_file_env 'MYSQL_PASSWORD' _mariadb_file_env 'MYSQL_ROOT_PASSWORD' + # No MYSQL_ compatibility needed for new variables + file_env 'MARIADB_PASSWORD_HASH' + file_env 'MARIADB_ROOT_PASSWORD_HASH' + # env variables related to replication + file_env 'MARIADB_REPLICATION_USER' + file_env 'MARIADB_REPLICATION_PASSWORD' + file_env 'MARIADB_REPLICATION_PASSWORD_HASH' + # env variables related to master + file_env 'MARIADB_MASTER_HOST' + file_env 'MARIADB_MASTER_PORT' 3306 # set MARIADB_ from MYSQL_ when it is unset and then make them the same value : "${MARIADB_ALLOW_EMPTY_ROOT_PASSWORD:=${MYSQL_ALLOW_EMPTY_PASSWORD:-}}" @@ -225,10 +285,9 @@ # ie: docker_process_sql --database=mydb <<<'INSERT ...' # ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql docker_process_sql() { - passfileArgs=() if [ '--dont-use-mysql-root-password' = "$1" ]; then shift - MYSQL_PWD= docker_exec_client "$@" + MYSQL_PWD='' docker_exec_client "$@" else MYSQL_PWD=$MARIADB_ROOT_PASSWORD docker_exec_client "$@" fi @@ -243,27 +302,28 @@ echo "${escaped//\'/\\\'}" } +# Creates replication user +create_replica_user() { + if [ -n "$MARIADB_REPLICATION_PASSWORD_HASH" ]; then + echo "CREATE USER '$MARIADB_REPLICATION_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_REPLICATION_PASSWORD_HASH';" + else + # SQL escape the user password, \ followed by ' + local userPasswordEscaped + userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_REPLICATION_PASSWORD}" ) + echo "CREATE USER '$MARIADB_REPLICATION_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';" + fi + echo "GRANT REPLICATION REPLICA ON *.* TO '$MARIADB_REPLICATION_USER'@'%';" +} + # Initializes database with timezone info and root password, plus optional extra db/user docker_setup_db() { # Load timezone info into database if [ -z "$MARIADB_INITDB_SKIP_TZINFO" ]; then - { - # Aria in 10.4+ is slow due to "transactional" (crash safety) - # https://jira.mariadb.org/browse/MDEV-23326 - # https://github.com/docker-library/mariadb/issues/262 - local tztables=( time_zone time_zone_leap_second time_zone_name time_zone_transition time_zone_transition_type ) - for table in "${tztables[@]}"; do - echo "/*!100400 ALTER TABLE $table TRANSACTIONAL=0 */;" - done - - # sed is for https://bugs.mysql.com/bug.php?id=20545 - mysql_tzinfo_to_sql /usr/share/zoneinfo \ - | sed 's/Local time zone must be set--see zic manual page/FCTY/' - - for table in "${tztables[@]}"; do - echo "/*!100400 ALTER TABLE $table TRANSACTIONAL=1 */;" - done - } | docker_process_sql --dont-use-mysql-root-password --database=mysql + # --skip-write-binlog usefully disables binary logging + # but also outputs LOCK TABLES to improve the IO of + # Aria (MDEV-23326) for 10.4+. + mysql_tzinfo_to_sql --skip-write-binlog /usr/share/zoneinfo \ + | docker_process_sql --dont-use-mysql-root-password --database=mysql # tell docker_process_sql to not use MYSQL_ROOT_PASSWORD since it is not set yet fi # Generate random root password @@ -272,63 +332,280 @@ export MARIADB_ROOT_PASSWORD MYSQL_ROOT_PASSWORD=$MARIADB_ROOT_PASSWORD mysql_note "GENERATED ROOT PASSWORD: $MARIADB_ROOT_PASSWORD" fi - # Sets root password and creates root users for non-localhost hosts + + # Creates root users for non-localhost hosts local rootCreate= - local rootPasswordEscaped - rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" ) + local rootPasswordEscaped= + if [ -n "$MARIADB_ROOT_PASSWORD" ]; then + # Sets root password and creates root users for non-localhost hosts + rootPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_ROOT_PASSWORD}" ) + fi # default root to listen for connections from anywhere if [ -n "$MARIADB_ROOT_HOST" ] && [ "$MARIADB_ROOT_HOST" != 'localhost' ]; then - # no, we don't care if read finds a terminating character in this heredoc + # ref "read -d ''", no, we don't care if read finds a terminating character in this heredoc # https://unix.stackexchange.com/questions/265149/why-is-set-o-errexit-breakin... - read -r -d '' rootCreate <<-EOSQL || true - CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; - GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; + if [ -n "$MARIADB_ROOT_PASSWORD_HASH" ]; then + read -r -d '' rootCreate <<-EOSQL || true + CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY PASSWORD '${MARIADB_ROOT_PASSWORD_HASH}' ; + GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; + GRANT PROXY ON ''@'%' TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION; + EOSQL + else + read -r -d '' rootCreate <<-EOSQL || true + CREATE USER 'root'@'${MARIADB_ROOT_HOST}' IDENTIFIED BY '${rootPasswordEscaped}' ; + GRANT ALL ON *.* TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION ; + GRANT PROXY ON ''@'%' TO 'root'@'${MARIADB_ROOT_HOST}' WITH GRANT OPTION; + EOSQL + fi + fi + + local mysqlAtLocalhost= + local mysqlAtLocalhostGrants= + # Install mysql@localhost user + if [ -n "$MARIADB_MYSQL_LOCALHOST_USER" ]; then + read -r -d '' mysqlAtLocalhost <<-EOSQL || true + CREATE USER mysql@localhost IDENTIFIED VIA unix_socket; EOSQL + if [ -n "$MARIADB_MYSQL_LOCALHOST_GRANTS" ]; then + if [ "$MARIADB_MYSQL_LOCALHOST_GRANTS" != USAGE ]; then + mysql_warn "Excessive privileges ON *.* TO mysql@localhost facilitates risks to the confidentiality, integrity and availability of data stored" + fi + mysqlAtLocalhostGrants="GRANT ${MARIADB_MYSQL_LOCALHOST_GRANTS} ON *.* TO mysql@localhost;"; + fi + fi + + local healthCheckUser + local healthCheckGrant=USAGE + local healthCheckConnectPass + local healthCheckConnectPassEscaped + healthCheckConnectPass="$(pwgen --numerals --capitalize --symbols --remove-chars="=#'\\" -1 32)" + healthCheckConnectPassEscaped=$( docker_sql_escape_string_literal "${healthCheckConnectPass}" ) + if [ -n "$MARIADB_HEALTHCHECK_GRANTS" ]; then + healthCheckGrant="$MARIADB_HEALTHCHECK_GRANTS" + fi + read -r -d '' healthCheckUser <<-EOSQL || true + CREATE USER healthcheck@'127.0.0.1' IDENTIFIED BY '$healthCheckConnectPassEscaped'; + CREATE USER healthcheck@'::1' IDENTIFIED BY '$healthCheckConnectPassEscaped'; + CREATE USER healthcheck@localhost IDENTIFIED BY '$healthCheckConnectPassEscaped'; + GRANT $healthCheckGrant ON *.* TO healthcheck@'127.0.0.1'; + GRANT $healthCheckGrant ON *.* TO healthcheck@'::1'; + GRANT $healthCheckGrant ON *.* TO healthcheck@localhost; + EOSQL + local maskPreserve + maskPreserve=$(umask -p) + umask 0077 + echo -e "[mariadb-client]\\nport=$PORT\\nsocket=$SOCKET\\nuser=healthcheck\\npassword=$healthCheckConnectPass\\nprotocol=tcp\\n" > "$DATADIR"/.my-healthcheck.cnf + $maskPreserve + + local rootLocalhostPass= + if [ -z "$MARIADB_ROOT_PASSWORD_HASH" ]; then + # handle MARIADB_ROOT_PASSWORD_HASH for root@localhost after /docker-entrypoint-initdb.d + rootLocalhostPass="SET PASSWORD FOR 'root'@'localhost'= PASSWORD('${rootPasswordEscaped}');" + fi + + local createDatabase= + # Creates a custom database and user if specified + if [ -n "$MARIADB_DATABASE" ]; then + mysql_note "Creating database ${MARIADB_DATABASE}" + createDatabase="CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\`;" + fi + + local createUser= + local userGrants= + if [ -n "$MARIADB_PASSWORD" ] || [ -n "$MARIADB_PASSWORD_HASH" ] && [ -n "$MARIADB_USER" ]; then + mysql_note "Creating user ${MARIADB_USER}" + if [ -n "$MARIADB_PASSWORD_HASH" ]; then + createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY PASSWORD '$MARIADB_PASSWORD_HASH';" + else + # SQL escape the user password, \ followed by ' + local userPasswordEscaped + userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" ) + createUser="CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped';" + fi + + if [ -n "$MARIADB_DATABASE" ]; then + mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}" + userGrants="GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%';" + fi + fi + + # To create replica user + local createReplicaUser= + local changeMasterTo= + local startReplica= + if [ -n "$MARIADB_REPLICATION_USER" ] ; then + if [ -z "$MARIADB_MASTER_HOST" ]; then + # on master + mysql_note "Creating user ${MARIADB_REPLICATION_USER}" + createReplicaUser=$(create_replica_user) + else + # on replica + local rplPasswordEscaped + rplPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_REPLICATION_PASSWORD}" ) + # SC cannot follow how MARIADB_MASTER_PORT is assigned a default value. + # shellcheck disable=SC2153 + changeMasterTo="CHANGE MASTER TO MASTER_HOST='$MARIADB_MASTER_HOST', MASTER_USER='$MARIADB_REPLICATION_USER', MASTER_PASSWORD='$rplPasswordEscaped', MASTER_PORT=$MARIADB_MASTER_PORT, MASTER_CONNECT_RETRY=10;" + startReplica="START REPLICA;" + fi fi + mysql_note "Securing system users (equivalent to running mysql_secure_installation)" # tell docker_process_sql to not use MARIADB_ROOT_PASSWORD since it is just now being set # --binary-mode to save us from the semi-mad users go out of their way to confuse the encoding. docker_process_sql --dont-use-mysql-root-password --database=mysql --binary-mode <<-EOSQL - -- What's done in this file shouldn't be replicated - -- or products like mysql-fabric won't work + -- Securing system users shouldn't be replicated + SET @orig_sql_log_bin= @@SESSION.SQL_LOG_BIN; SET @@SESSION.SQL_LOG_BIN=0; -- we need the SQL_MODE NO_BACKSLASH_ESCAPES mode to be clear for the password to be set SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); - DELETE FROM mysql.user WHERE user NOT IN ('mysql.sys', 'mariadb.sys', 'mysqlxsys', 'root') OR host NOT IN ('localhost') ; - SET PASSWORD FOR 'root'@'localhost'=PASSWORD('${rootPasswordEscaped}') ; - -- 10.1: https://github.com/MariaDB/server/blob/d925aec1c10cebf6c34825a7de50afe4e630a... - -- 10.5: https://github.com/MariaDB/server/blob/00c3a28820c67c37ebbca72691f4897b57f2e... - DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%' ; + DROP USER IF EXISTS root@'127.0.0.1', root@'::1'; + EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS root@\'', @@hostname,'\''); - GRANT ALL ON *.* TO 'root'@'localhost' WITH GRANT OPTION ; - FLUSH PRIVILEGES ; + ${rootLocalhostPass} ${rootCreate} - DROP DATABASE IF EXISTS test ; + ${mysqlAtLocalhost} + ${mysqlAtLocalhostGrants} + ${healthCheckUser} + -- end of securing system users, rest of init now... + SET @@SESSION.SQL_LOG_BIN=@orig_sql_log_bin; + -- create users/databases + ${createDatabase} + ${createUser} + ${createReplicaUser} + ${userGrants} + + ${changeMasterTo} + ${startReplica} EOSQL +} - # Creates a custom database and user if specified - if [ -n "$MARIADB_DATABASE" ]; then - mysql_note "Creating database ${MARIADB_DATABASE}" - docker_process_sql --database=mysql <<<"CREATE DATABASE IF NOT EXISTS \`$MARIADB_DATABASE\` ;" +# create a new installation +docker_mariadb_init() +{ + + # check dir permissions to reduce likelihood of half-initialized database + ls /docker-entrypoint-initdb.d/ > /dev/null + + if [ -n "$DATABASE_INIT_FROM_BACKUP" ]; then + shopt -s dotglob + for file in /docker-entrypoint-initdb.d/*.tar{.gz,.xz,.zst}; do + mkdir -p "$DATADIR"/.init + tar --auto-compress --extract --file "$file" --directory="$DATADIR"/.init + mariadb-backup --target-dir="$DATADIR"/.init --datadir="$DATADIR"/.restore --move-back + + mv "$DATADIR"/.restore/** "$DATADIR"/ + if [ -f "$DATADIR/.init/backup-my.cnf" ]; then + mv "$DATADIR/.init/backup-my.cnf" "$DATADIR/.my.cnf" + mysql_note "Adding startup configuration:" + my_print_defaults --defaults-file="$DATADIR/.my.cnf" --mysqld + fi + rm -rf "$DATADIR"/.init "$DATADIR"/.restore + if [ "$(id -u)" = "0" ]; then + # this will cause less disk access than `chown -R` + find "$DATADIR" \! -user mysql -exec chown mysql: '{}' + + fi + done + if _check_if_upgrade_is_needed; then + docker_mariadb_upgrade "$@" + fi + return fi + docker_init_database_dir "$@" - if [ -n "$MARIADB_USER" ] && [ -n "$MARIADB_PASSWORD" ]; then - mysql_note "Creating user ${MARIADB_USER}" - # SQL escape the user password, \ followed by ' - local userPasswordEscaped - userPasswordEscaped=$( docker_sql_escape_string_literal "${MARIADB_PASSWORD}" ) - docker_process_sql --database=mysql --binary-mode <<-EOSQL_USER - SET @@SESSION.SQL_MODE=REPLACE(@@SESSION.SQL_MODE, 'NO_BACKSLASH_ESCAPES', ''); - CREATE USER '$MARIADB_USER'@'%' IDENTIFIED BY '$userPasswordEscaped'; - EOSQL_USER + mysql_note "Starting temporary server" + docker_temp_server_start "$@" + mysql_note "Temporary server started." + + docker_setup_db + docker_process_init_files /docker-entrypoint-initdb.d/* + # Wait until after /docker-entrypoint-initdb.d is performed before setting + # root@localhost password to a hash we don't know the password for. + if [ -n "${MARIADB_ROOT_PASSWORD_HASH}" ]; then + mysql_note "Setting root@localhost password hash" + docker_process_sql --dont-use-mysql-root-password --binary-mode <<-EOSQL + SET @@SESSION.SQL_LOG_BIN=0; + SET PASSWORD FOR 'root'@'localhost'= '${MARIADB_ROOT_PASSWORD_HASH}'; + EOSQL + fi - if [ -n "$MARIADB_DATABASE" ]; then - mysql_note "Giving user ${MARIADB_USER} access to schema ${MARIADB_DATABASE}" - docker_process_sql --database=mysql <<<"GRANT ALL ON \`${MARIADB_DATABASE//_/\\_}\`.* TO '$MARIADB_USER'@'%' ;" + mysql_note "Stopping temporary server" + docker_temp_server_stop + mysql_note "Temporary server stopped" + + echo + mysql_note "MariaDB init process done. Ready for start up." + echo +} + +# backup the mysql database +docker_mariadb_backup_system() +{ + if [ -n "$MARIADB_DISABLE_UPGRADE_BACKUP" ] \ + && [ "$MARIADB_DISABLE_UPGRADE_BACKUP" = 1 ]; then + mysql_note "MariaDB upgrade backup disabled due to \$MARIADB_DISABLE_UPGRADE_BACKUP=1 setting" + return + fi + local backup_db="system_mysql_backup_unknown_version.sql.zst" + local oldfullversion="unknown_version" + if [ -r "$DATADIR"/mysql_upgrade_info ]; then + read -r -d '' oldfullversion < "$DATADIR"/mysql_upgrade_info || true + if [ -n "$oldfullversion" ]; then + backup_db="system_mysql_backup_${oldfullversion}.sql.zst" fi fi + + mysql_note "Backing up system database to $backup_db" + if ! mysqldump --skip-lock-tables --replace --databases mysql --socket="${SOCKET}" | zstd > "${DATADIR}/${backup_db}"; then + mysql_error "Unable backup system database for upgrade from $oldfullversion." + fi + mysql_note "Backing up complete" +} + +# perform mariadb-upgrade +# backup the mysql database if this is a major upgrade +docker_mariadb_upgrade() { + if [ -z "$MARIADB_AUTO_UPGRADE" ] \ + || [ "$MARIADB_AUTO_UPGRADE" = 0 ]; then + mysql_note "MariaDB upgrade (mysql_upgrade) required, but skipped due to \$MARIADB_AUTO_UPGRADE setting" + return + fi + mysql_note "Starting temporary server" + docker_temp_server_start "$@" --skip-grant-tables \ + --loose-innodb_buffer_pool_dump_at_shutdown=0 \ + --skip-slave-start + mysql_note "Temporary server started." + + docker_mariadb_backup_system + + mysql_note "Starting mariadb-upgrade" + mysql_upgrade --upgrade-system-tables + mysql_note "Finished mariadb-upgrade" + + mysql_note "Stopping temporary server" + docker_temp_server_stop + mysql_note "Temporary server stopped" +} + + +_check_if_upgrade_is_needed() { + if [ ! -f "$DATADIR"/mysql_upgrade_info ]; then + mysql_note "MariaDB upgrade information missing, assuming required" + return 0 + fi + local mariadbVersion + mariadbVersion="$(_mariadb_version)" + IFS='.-' read -ra newversion <<<"$mariadbVersion" + IFS='.-' read -ra oldversion < "$DATADIR"/mysql_upgrade_info || true + + if [[ ${#newversion[@]} -lt 2 ]] || [[ ${#oldversion[@]} -lt 2 ]] \ + || [[ ${oldversion[0]} -lt ${newversion[0]} ]] \ + || [[ ${oldversion[0]} -eq ${newversion[0]} && ${oldversion[1]} -lt ${newversion[1]} ]]; then + return 0 + fi + mysql_note "MariaDB upgrade not required" + return 1 } # check arguments for an option that would cause mysqld to stop @@ -351,6 +628,7 @@ set -- mysqld "$@" fi + #ENDOFSUBSTITUTIONS # skip setup if they aren't running mysqld or want an option that stops mysqld if [ "$1" = 'mariadbd' ] || [ "$1" = 'mysqld' ] && ! _mysql_want_help "$@"; then mysql_note "Entrypoint script for MariaDB Server ${MARIADB_VERSION} started." @@ -363,32 +641,18 @@ # If container is started as root user, restart as dedicated mysql user if [ "$(id -u)" = "0" ]; then mysql_note "Switching to dedicated user 'mysql'" - exec gosu mysql "$BASH_SOURCE" "$@" + exec gosu mysql "${BASH_SOURCE[0]}" "$@" fi # there's no database, so it needs to be initialized if [ -z "$DATABASE_ALREADY_EXISTS" ]; then docker_verify_minimum_env - # check dir permissions to reduce likelihood of half-initialized database - ls /docker-entrypoint-initdb.d/ > /dev/null - - docker_init_database_dir "$@" - - mysql_note "Starting temporary server" - docker_temp_server_start "$@" - mysql_note "Temporary server started." - - docker_setup_db - docker_process_init_files /docker-entrypoint-initdb.d/* - - mysql_note "Stopping temporary server" - docker_temp_server_stop - mysql_note "Temporary server stopped" - - echo - mysql_note "MariaDB init process done. Ready for start up." - echo + docker_mariadb_init "$@" + # MDEV-27636 mariadb_upgrade --check-if-upgrade-is-needed cannot be run offline + #elif mysql_upgrade --check-if-upgrade-is-needed; then + elif _check_if_upgrade_is_needed; then + docker_mariadb_upgrade "$@" fi fi exec "$@"
participants (1)
-
Source-Sync