@@ -453,7 +453,7 @@ public void check() {
453453
454454 // DB version 테이블의 latest 행 삭제
455455 final CloudStackVersion dbVersionInitial = CloudStackVersion .parse (_dao .getCurrentVersion ());
456- deleteCurrentVersionRowIfPresent (dbVersionInitial );
456+ enforceBaselineThenDeleteLastVersionIfNeeded (dbVersionInitial );
457457
458458 final String currentVersionValue = this .getClass ().getPackage ().getImplementationVersion ();
459459 if (StringUtils .isBlank (currentVersionValue )) return ;
@@ -495,6 +495,72 @@ public void check() {
495495 }
496496 }
497497
498+ private void enforceBaselineThenDeleteLastVersionIfNeeded (final CloudStackVersion dbVersionInitial ) {
499+ final String BASELINE_VERSION = "4.0.0" ;
500+ final String targetVersion = dbVersionInitial != null ? dbVersionInitial .toString () : null ;
501+
502+ final TransactionLegacy txn = TransactionLegacy .open ("enforce-baseline-then-delete-last" );
503+ txn .start ();
504+ try {
505+ final Connection conn = txn .getConnection ();
506+
507+ // 1) '4.0.0' 없으면 즉시 삽입(있으면 0 rows) → 한 턴에 끝
508+ final String insertIfMissingSql =
509+ "INSERT INTO `cloud`.`version` (`version`, `step`, `updated`) " +
510+ "SELECT ?, 'Complete', NOW() FROM DUAL " +
511+ "WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`version` WHERE `version` = ?)" ;
512+
513+ try (PreparedStatement ins = conn .prepareStatement (insertIfMissingSql )) {
514+ ins .setString (1 , BASELINE_VERSION );
515+ ins .setString (2 , BASELINE_VERSION );
516+ int inserted = ins .executeUpdate ();
517+ if (inserted > 0 ) {
518+ LOGGER .info ("Inserted baseline version row: {}" , BASELINE_VERSION );
519+ txn .commit ();
520+ return ; // 여기서 바로 종료
521+ }
522+ }
523+
524+ // 2) 삭제 대상: dbVersionInitial 의 최신 1건 (단, 베이스라인이면 삭제 금지)
525+ if (targetVersion != null && !BASELINE_VERSION .equals (targetVersion )) {
526+ // 최신 1건을 서브쿼리로 바로 삭제 (MySQL은 DELETE에서 서브쿼리 테이블 참조 시 래핑 필요)
527+ final String deleteLatestOneSql =
528+ "DELETE FROM `cloud`.`version` " +
529+ "WHERE `id` IN ( " +
530+ " SELECT id FROM ( " +
531+ " SELECT `id` " +
532+ " FROM `cloud`.`version` " +
533+ " WHERE `version` = ? AND (`step` IS NULL OR `step` = 'Complete') " +
534+ " ORDER BY COALESCE(`updated`, FROM_UNIXTIME(0)) DESC " +
535+ " LIMIT 1 " +
536+ " ) AS _x " +
537+ ")" ;
538+
539+ try (PreparedStatement delLatest = conn .prepareStatement (deleteLatestOneSql )) {
540+ delLatest .setString (1 , targetVersion );
541+ int deleted = delLatest .executeUpdate ();
542+ if (deleted > 0 ) {
543+ LOGGER .warn ("Deleted {} latest row for version {}" , deleted , targetVersion );
544+ txn .commit ();
545+ return ; // 목적(해당 버전 최신 1건 삭제) 달성 시 즉시 종료
546+ } else {
547+ LOGGER .info ("No deletable row found for targetVersion={}; skipping targeted delete." , targetVersion );
548+ }
549+ }
550+ } else {
551+ LOGGER .info ("Target version is baseline or null ({}). Skipping targeted delete." , targetVersion );
552+ }
553+
554+ txn .commit ();
555+ } catch (SQLException e ) {
556+ txn .rollback ();
557+ LOGGER .error ("Failed in enforceBaselineThenDeleteLastVersionIfNeeded" , e );
558+ throw new CloudRuntimeException ("Failed in enforceBaselineThenDeleteLastVersionIfNeeded" , e );
559+ } finally {
560+ txn .close ();
561+ }
562+ }
563+
498564 // Cloudstack DB 업데이트 전 Ablestack DB 업데이트 진행
499565 public void beforeUpgradeAblestack (String ablestackVersion ) {
500566 TransactionLegacy txn = TransactionLegacy .open ("Upgrade" );
@@ -530,27 +596,6 @@ public void beforeUpgradeAblestack (String ablestackVersion) {
530596 }
531597 }
532598
533- private void deleteCurrentVersionRowIfPresent (final CloudStackVersion currentVersion ) {
534- TransactionLegacy txn = TransactionLegacy .open ("delete-current-version-row" );
535- txn .start ();
536- try {
537- Connection conn = txn .getConnection ();
538- try (PreparedStatement ps = conn .prepareStatement (
539- "DELETE FROM `cloud`.`version` WHERE `version` = ? AND (`step` IS NULL OR `step` = 'Complete')" )) {
540- ps .setString (1 , currentVersion .toString ());
541- int deleted = ps .executeUpdate ();
542- LOGGER .warn ("Deleted {} row(s) from cloud.version for {}" , deleted , currentVersion );
543- }
544- txn .commit ();
545- } catch (SQLException e ) {
546- txn .rollback ();
547- LOGGER .error ("Unable to delete current version row" , e );
548- throw new CloudRuntimeException ("Unable to delete current version row" , e );
549- } finally {
550- txn .close ();
551- }
552- }
553-
554599 // Cloudstack DB 업데이트 후 Ablestack DB 업데이트 진행
555600 public void afterUpgradeAblestack (String ablestackVersion ) {
556601 TransactionLegacy txn = TransactionLegacy .open ("Upgrade" );
0 commit comments