-
-
Notifications
You must be signed in to change notification settings - Fork 4
Switch to MySQL 8 #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Switch to MySQL 8 #103
Changes from 1 commit
da4db23
0a74a23
101b3af
5cd7846
a24239d
061749e
2567a49
6e9bb8b
8a4a8eb
a53e8b8
ab9b7f5
e677c49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ package cmd | |
|
|
||
| import ( | ||
| "errors" | ||
| "fmt" | ||
| "os" | ||
| "path/filepath" | ||
| "strings" | ||
|
|
@@ -143,42 +144,134 @@ func setupLocalBeach() error { | |
| } | ||
|
|
||
| func migrateMariaDBToMySQL() error { | ||
| _, err := os.Stat(path.MariaDBDatabase) | ||
| if err == nil { | ||
| log.Info("Migrating MariaDB data from " + path.MariaDBDatabase + " to MySQL at " + path.MySQLDatabase) | ||
| log.Warn("Note: This may take a while, depending on DB size!") | ||
| migrationMarkerPath := filepath.Join(path.Base, ".mariadb-to-mysql-migration-complete") | ||
|
|
||
| if err = startMariaDB(); err != nil { | ||
| return err | ||
| // Check if migration has already been completed | ||
| if _, err := os.Stat(migrationMarkerPath); err == nil { | ||
| log.Debug("MariaDB to MySQL migration already completed, skipping") | ||
| return nil | ||
| } | ||
|
|
||
| // Check if MariaDB data exists | ||
| _, err := os.Stat(path.MariaDBDatabase) | ||
| if err != nil { | ||
| // No MariaDB data to migrate | ||
| if os.IsNotExist(err) { | ||
| log.Debug("No MariaDB data found, skipping migration") | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, yes. But that will be shown for every setup run ever after… and even for someone who never even had MariaDB in her Local Beach setup.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, let's remove that, it doesn't make sense. |
||
| return nil | ||
| } | ||
| return fmt.Errorf("failed to check MariaDB database path: %w", err) | ||
| } | ||
|
|
||
| log.Debug("dumping data from MariaDB to MySQL") | ||
| commandArgs := []string{"exec", "local_beach_mariadb", "bash", "-c"} | ||
| commandArgs = append(commandArgs, "mysql -h local_beach_mariadb -u root -ppassword --batch --skip-column-names -e \"SHOW DATABASES;\" | grep -E -v \"(information|performance)_schema|mysql|sys\"") | ||
| databases, err := exec.RunCommand("docker", commandArgs) | ||
| if err != nil { | ||
| log.Error(err) | ||
| return err | ||
| log.Info("Migrating MariaDB data from " + path.MariaDBDatabase + " to MySQL at " + path.MySQLDatabase) | ||
| log.Warn("This process may take several minutes depending on database size.") | ||
| log.Warn("Please do not interrupt this process!") | ||
|
|
||
| // Start both database servers | ||
| if err = startMariaDB(); err != nil { | ||
| return fmt.Errorf("failed to start database servers for migration: %w", err) | ||
| } | ||
|
|
||
| // Ensure cleanup happens on error | ||
| defer func() { | ||
| if stopErr := stopMariaDB(); stopErr != nil { | ||
| log.Error("Failed to stop MariaDB after migration: ", stopErr) | ||
| } | ||
| }() | ||
|
|
||
| for _, database := range strings.Split(strings.TrimSuffix(databases, "\n"), "\n") { | ||
| log.Debug("… " + database) | ||
| // Get list of databases to migrate | ||
| log.Info("Step 1/3: Discovering databases to migrate...") | ||
| commandArgs := []string{"exec", "local_beach_mariadb", "bash", "-c"} | ||
| commandArgs = append(commandArgs, "mysql -h local_beach_mariadb -u root -ppassword --batch --skip-column-names -e \"SHOW DATABASES;\" | grep -E -v \"(information|performance)_schema|mysql|sys\"") | ||
| databases, err := exec.RunCommand("docker", commandArgs) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to list databases from MariaDB: %w", err) | ||
| } | ||
|
|
||
| databaseList := strings.Split(strings.TrimSuffix(databases, "\n"), "\n") | ||
| if len(databaseList) == 0 || (len(databaseList) == 1 && databaseList[0] == "") { | ||
| log.Info("No databases found to migrate") | ||
| } else { | ||
| log.Info(fmt.Sprintf("Found %d database(s) to migrate", len(databaseList))) | ||
|
|
||
| // Migrate each database | ||
| log.Info("Step 2/3: Migrating databases...") | ||
| migratedCount := 0 | ||
| for i, database := range databaseList { | ||
| if database == "" { | ||
| continue | ||
| } | ||
| log.Info(fmt.Sprintf(" [%d/%d] Migrating database: %s", i+1, len(databaseList), database)) | ||
| commandArgs = []string{"exec", "local_beach_database", "bash", "-c"} | ||
| commandArgs = append(commandArgs, "mysqldump -h local_beach_mariadb -u root -ppassword --add-drop-trigger --compress --comments --dump-date --hex-blob --quote-names --routines --triggers --no-autocommit --no-tablespaces --skip-lock-tables --single-transaction --quick --databases "+database+" | sed -e \"s/DEFAULT '{}' COMMENT '(DC2Type:json)'/DEFAULT (JSON_OBJECT()) COMMENT '(DC2Type:json)'/\" | mysql -h local_beach_database -u root -ppassword") | ||
| _, err := exec.RunCommand("docker", commandArgs) | ||
| output, err := exec.RunCommand("docker", commandArgs) | ||
| if err != nil { | ||
| log.Error(err) | ||
| log.Error(fmt.Sprintf("Failed to migrate database %s: %v", database, err)) | ||
| if output != "" { | ||
| log.Error("Output: ", output) | ||
| } | ||
| return fmt.Errorf("migration failed for database %s: %w", database, err) | ||
| } | ||
| migratedCount++ | ||
| log.Info(fmt.Sprintf(" [%d/%d] Successfully migrated: %s", i+1, len(databaseList), database)) | ||
| } | ||
| log.Info(fmt.Sprintf("Successfully migrated %d database(s)", migratedCount)) | ||
| } | ||
|
|
||
| if err = stopMariaDB(); err != nil { | ||
| return err | ||
| } | ||
| // Verify migration | ||
| log.Info("Step 3/3: Verifying migration...") | ||
| if err = verifyMigration(); err != nil { | ||
| return fmt.Errorf("migration verification failed: %w", err) | ||
| } | ||
|
|
||
| log.Info("Done with migration to MySQL at " + path.MySQLDatabase) | ||
| log.Info("If all works as expected, remove " + path.MariaDBDatabase) | ||
| // Stop MariaDB | ||
| if err = stopMariaDB(); err != nil { | ||
| return fmt.Errorf("failed to stop MariaDB after migration: %w", err) | ||
| } | ||
|
|
||
| // Create migration marker file | ||
| markerFile, err := os.Create(migrationMarkerPath) | ||
| if err != nil { | ||
| log.Warn("Failed to create migration marker file: ", err) | ||
| log.Warn("Migration completed successfully, but may run again on next setup") | ||
| } else { | ||
| timestamp := time.Now().Format(time.RFC3339) | ||
| _, _ = markerFile.WriteString(fmt.Sprintf("Migration completed at: %s\n", timestamp)) | ||
| markerFile.Close() | ||
| } | ||
|
|
||
| log.Info("✓ Migration to MySQL completed successfully!") | ||
| log.Info("") | ||
| log.Info("Your MariaDB data has been preserved at: " + path.MariaDBDatabase) | ||
| log.Info("Once you've verified everything works correctly, you can safely remove it with:") | ||
| log.Info(" rm -rf " + path.MariaDBDatabase) | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func verifyMigration() error { | ||
| // Check that MySQL server is running and accessible | ||
| commandArgs := []string{"exec", "local_beach_database", "bash", "-c"} | ||
| commandArgs = append(commandArgs, "mysql -h local_beach_database -u root -ppassword --batch --skip-column-names -e \"SELECT 'OK';\"") | ||
| output, err := exec.RunCommand("docker", commandArgs) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to connect to MySQL: %w", err) | ||
| } | ||
| if !strings.Contains(output, "OK") { | ||
| return errors.New("MySQL connection test failed") | ||
| } | ||
|
|
||
| // Get database count from MySQL | ||
| commandArgs = []string{"exec", "local_beach_database", "bash", "-c"} | ||
| commandArgs = append(commandArgs, "mysql -h local_beach_database -u root -ppassword --batch --skip-column-names -e \"SHOW DATABASES;\" | grep -E -v \"(information|performance)_schema|mysql|sys\" | wc -l") | ||
| mysqlDbCount, err := exec.RunCommand("docker", commandArgs) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to count MySQL databases: %w", err) | ||
| } | ||
|
|
||
| mysqlDbCount = strings.TrimSpace(mysqlDbCount) | ||
| log.Info(fmt.Sprintf("Verification: Found %s database(s) in MySQL", mysqlDbCount)) | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe put that into the MariaDB folder, so it is gone when the source has been removed? Or move it into the block that is run when there is MariaDB data to (potentially) migrate…
Otherwise the setup will always say the migration was completed, until the marker is removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, good idea!