nixos/services.mysql: fix wait for galera cluster sync to be done (#381333)

authored by Arne Keller and committed by GitHub e518fa23 00604c4f

+25 -6
+25 -6
nixos/modules/services/databases/mysql.nix
··· 433 done 434 ''} 435 436 if [ -f ${cfg.dataDir}/mysql_init ] 437 then 438 # While MariaDB comes with a 'mysql' super user account since 10.4.x, MySQL does not ··· 447 # Create initial databases 448 if ! test -e "${cfg.dataDir}/${database.name}"; then 449 echo "Creating initial database: ${database.name}" 450 - ( echo 'create database `${database.name}`;' 451 452 ${lib.optionalString (database.schema != null) '' 453 - echo 'use `${database.name}`;' 454 455 # TODO: this silently falls through if database.schema does not exist, 456 # we should catch this somehow and exit, but can't do it here because we're in a subshell. ··· 469 ${lib.optionalString (cfg.replication.role == "master") '' 470 # Set up the replication master 471 472 - ( echo "use mysql;" 473 echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;" 474 echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');" 475 echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';" ··· 479 ${lib.optionalString (cfg.replication.role == "slave") '' 480 # Set up the replication slave 481 482 - ( echo "stop slave;" 483 - echo "change master to master_host='${cfg.replication.masterHost}', master_user='${cfg.replication.masterUser}', master_password='${cfg.replication.masterPassword}';" 484 - echo "start slave;" 485 ) | ${cfg.package}/bin/mysql -u ${superUser} -N 486 ''} 487
··· 433 done 434 ''} 435 436 + ${lib.optionalString isMariaDB '' 437 + # If MariaDB is used in an Galera cluster, we have to check if the sync is done, 438 + # or it will fail to init the database while joining, so we get in an broken non recoverable state 439 + # so we wait until we have an synced state 440 + if ${cfg.package}/bin/mysql -u ${superUser} -N -e "SHOW VARIABLES LIKE 'wsrep_on'" 2>/dev/null | ${lib.getExe' pkgs.gnugrep "grep"} -q 'ON'; then 441 + echo "Galera cluster detected, waiting for node to be synced..." 442 + while true; do 443 + STATE=$(${cfg.package}/bin/mysql -u ${superUser} -N -e "SHOW STATUS LIKE 'wsrep_local_state_comment'" | ${lib.getExe' pkgs.gawk "awk"} '{print $2}') 444 + if [ "$STATE" = "Synced" ]; then 445 + echo "Node is synced" 446 + break 447 + else 448 + echo "Current state: $STATE - Waiting for 1 second..." 449 + sleep 1 450 + fi 451 + done 452 + fi 453 + ''} 454 + 455 if [ -f ${cfg.dataDir}/mysql_init ] 456 then 457 # While MariaDB comes with a 'mysql' super user account since 10.4.x, MySQL does not ··· 466 # Create initial databases 467 if ! test -e "${cfg.dataDir}/${database.name}"; then 468 echo "Creating initial database: ${database.name}" 469 + ( echo 'CREATE DATABASE IF NOT EXISTS `${database.name}`;' 470 471 ${lib.optionalString (database.schema != null) '' 472 + echo 'USE `${database.name}`;' 473 474 # TODO: this silently falls through if database.schema does not exist, 475 # we should catch this somehow and exit, but can't do it here because we're in a subshell. ··· 488 ${lib.optionalString (cfg.replication.role == "master") '' 489 # Set up the replication master 490 491 + ( echo "USE mysql;" 492 echo "CREATE USER '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' IDENTIFIED WITH mysql_native_password;" 493 echo "SET PASSWORD FOR '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}' = PASSWORD('${cfg.replication.masterPassword}');" 494 echo "GRANT REPLICATION SLAVE ON *.* TO '${cfg.replication.masterUser}'@'${cfg.replication.slaveHost}';" ··· 498 ${lib.optionalString (cfg.replication.role == "slave") '' 499 # Set up the replication slave 500 501 + ( echo "STOP SLAVE;" 502 + echo "CHANGE MASTER TO MASTER_HOST='${cfg.replication.masterHost}', MASTER_USER='${cfg.replication.masterUser}', MASTER_PASSWORD='${cfg.replication.masterPassword}';" 503 + echo "START SLAVE;" 504 ) | ${cfg.package}/bin/mysql -u ${superUser} -N 505 ''} 506