Просмотр исходного кода

[MySQL] Optimize mysql upgrade logic

FreddleSpl0it 3 месяцев назад
Родитель
Сommit
9174a05af3
1 измененных файлов с 63 добавлено и 22 удалено
  1. 63 22
      data/Dockerfiles/bootstrap/modules/BootstrapMysql.py

+ 63 - 22
data/Dockerfiles/bootstrap/modules/BootstrapMysql.py

@@ -9,7 +9,22 @@ import subprocess
 
 class Bootstrap(BootstrapBase):
   def bootstrap(self):
-    self.upgrade_mysql()
+    dbuser = "root"
+    dbpass = os.getenv("MYSQL_ROOT_PASSWORD", "")
+    socket = "/var/run/mysqld/mysqld.sock"
+
+    print("Starting temporary mysqld for upgrade...")
+    self.start_temporary(socket)
+
+    self.connect_mysql()
+
+    print("Running mysql_upgrade...")
+    self.upgrade_mysql(dbuser, dbpass, socket)
+
+    print("Shutting down temporary mysqld...")
+    self.close_mysql()
+    self.stop_temporary(dbuser, dbpass, socket)
+
 
     # Setup Jinja2 Environment and load vars
     self.env = Environment(
@@ -28,27 +43,63 @@ class Bootstrap(BootstrapBase):
     print("Render config")
     self.render_config("my.cnf.j2", "/etc/mysql/conf.d/my.cnf")
 
-  def upgrade_mysql(self, max_retries=5, wait_interval=3):
-    """
-    Runs mysql_upgrade in a controlled way using run_command.
-    Starts mysqld in background, upgrades, shuts down, then restarts in foreground.
+  def start_temporary(self, socket):
     """
+    Starts a temporary mysqld process in the background using the given UNIX socket.
 
-    dbuser = "root"
-    dbpass = os.getenv("MYSQL_ROOT_PASSWORD", "")
-    socket = "/var/run/mysqld/mysqld.sock"
+    The server is started with networking disabled (--skip-networking).
 
-    print("Starting temporary mysqld for upgrade...")
-    temp_proc = subprocess.Popen([
+    Args:
+      socket (str): Path to the UNIX socket file for MySQL to listen on.
+
+    Returns:
+      subprocess.Popen: The running mysqld process object.
+    """
+
+    return subprocess.Popen([
       "mysqld",
       "--user=mysql",
       "--skip-networking",
       f"--socket={socket}"
     ])
 
-    self.connect_mysql()
+  def stop_temporary(self, dbuser, dbpass, socket):
+    """
+    Shuts down the temporary mysqld instance gracefully.
+
+    Uses mariadb-admin to issue a shutdown command to the running server.
+
+    Args:
+      dbuser (str): The MySQL username with shutdown privileges (typically 'root').
+      dbpass (str): The password for the MySQL user.
+      socket (str): Path to the UNIX socket the server is listening on.
+    """
+
+    self.run_command([
+      "mariadb-admin",
+      "shutdown",
+      f"--socket={socket}",
+      "-u", dbuser,
+      f"-p{dbpass}"
+    ])
+
+  def upgrade_mysql(self, dbuser, dbpass, socket, max_retries=5, wait_interval=3):
+    """
+    Executes mysql_upgrade to check and fix any schema or table incompatibilities.
+
+    Retries the upgrade command if it fails, up to a maximum number of attempts.
+
+    Args:
+      dbuser (str): MySQL username with privilege to perform the upgrade.
+      dbpass (str): Password for the MySQL user.
+      socket (str): Path to the MySQL UNIX socket for local communication.
+      max_retries (int): Maximum number of attempts before giving up. Default is 5.
+      wait_interval (int): Number of seconds to wait between retries. Default is 3.
+
+    Returns:
+      bool: True if upgrade succeeded, False if all attempts failed.
+    """
 
-    print("Running mysql_upgrade...")
     retries = 0
     while retries < max_retries:
       result = self.run_command([
@@ -67,14 +118,4 @@ class Bootstrap(BootstrapBase):
         time.sleep(wait_interval)
     else:
       print("mysql_upgrade failed after all retries.")
-      temp_proc.terminate()
       return False
-
-    print("Shutting down temporary mysqld...")
-    self.run_command([
-      "mariadb-admin",
-      "shutdown",
-      f"--socket={socket}",
-      "-u", dbuser,
-      f"-p{dbpass}"
-    ])