Skip to content

Commit a28cae5

Browse files
committed
설치시 업그레드 오류 테스트 1
1 parent e7fabe6 commit a28cae5

File tree

2 files changed

+52
-36
lines changed

2 files changed

+52
-36
lines changed

engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -451,23 +451,26 @@ public void check() {
451451
try {
452452
initializeDatabaseEncryptors();
453453

454-
// DB version 테이블의 latest 행 삭제
455-
final CloudStackVersion dbVersionInitial = CloudStackVersion.parse(_dao.getCurrentVersion());
456-
enforceBaselineThenDeleteLastVersionIfNeeded(dbVersionInitial);
457-
454+
// 1) 코드(설치될) 버전 먼저 파싱
458455
final String currentVersionValue = this.getClass().getPackage().getImplementationVersion();
459456
if (StringUtils.isBlank(currentVersionValue)) return;
460457
final CloudStackVersion currentVersion = CloudStackVersion.parse(currentVersionValue);
461458

459+
// 2) DB 최신 버전 읽기
460+
final CloudStackVersion dbLatestVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
461+
462+
// 3) 베이스라인 보장 + (db==code) 같으면 삭제 스킵
463+
enforceBaselineThenDeleteLastVersionIfNeeded(dbLatestVersion, currentVersion);
464+
462465
///////////////////// Ablestack 업그레이드 //////////////////////////
463466
beforeUpgradeAblestack("Bronto");
464467
beforeUpgradeAblestack("Cerato");
465468
beforeUpgradeAblestack("Diplo");
466469
///////////////////// Ablestack 업그레이드 //////////////////////////
467470

468-
// 삭제 후 DB 버전 재조회
471+
// 4) 재조회 후 본 업그레이드 진행
469472
final CloudStackVersion dbVersion = CloudStackVersion.parse(_dao.getCurrentVersion());
470-
LOGGER.info("After deletion, DB version = {} , Code version = {}", dbVersion, currentVersion);
473+
LOGGER.info("After enforcement, DB version = {} , Code version = {}", dbVersion, currentVersion);
471474

472475
String csVersion = SystemVmTemplateRegistration.parseMetadataFile();
473476
final CloudStackVersion sysVmVersion = CloudStackVersion.parse(csVersion);
@@ -495,67 +498,80 @@ public void check() {
495498
}
496499
}
497500

498-
private void enforceBaselineThenDeleteLastVersionIfNeeded(final CloudStackVersion dbVersionInitial) {
501+
private void enforceBaselineThenDeleteLastVersionIfNeeded(final CloudStackVersion dbLatestVersion,
502+
final CloudStackVersion currentVersion) {
499503
final String BASELINE_VERSION = "4.0.0";
500-
final String targetVersion = dbVersionInitial != null ? dbVersionInitial.toString() : null;
501-
502504
final TransactionLegacy txn = TransactionLegacy.open("enforce-baseline-then-delete-last");
503505
txn.start();
504506
try {
505507
final Connection conn = txn.getConnection();
506508

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` = ?)";
509+
// 0) DB 최신버전 == 코드버전이면 삭제/삽입 모두 스킵
510+
final boolean sameAsCode = (dbLatestVersion != null
511+
&& currentVersion != null
512+
&& dbLatestVersion.compareTo(currentVersion) == 0);
513+
if (sameAsCode) {
514+
LOGGER.info("DB latest version equals code version (db={}, code={}). Skipping baseline insert and deletion.",
515+
dbLatestVersion, currentVersion);
516+
txn.commit();
517+
return;
518+
}
512519

520+
// 1) sameAsCode == false 인 경우에만 베이스라인 보장 (없으면 삽입)
521+
final String insertIfMissingSql =
522+
"INSERT INTO `cloud`.`version` (`version`, `step`, `updated`) " +
523+
"SELECT ?, 'Complete', NOW() FROM DUAL " +
524+
"WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`version` WHERE `version` = ?)";
513525
try (PreparedStatement ins = conn.prepareStatement(insertIfMissingSql)) {
514526
ins.setString(1, BASELINE_VERSION);
515527
ins.setString(2, BASELINE_VERSION);
516528
int inserted = ins.executeUpdate();
517529
if (inserted > 0) {
518530
LOGGER.info("Inserted baseline version row: {}", BASELINE_VERSION);
519531
txn.commit();
520-
return; // 여기서 바로 종료
532+
return; // 여기서 종료
521533
}
522534
}
523535

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-
")";
536+
// 2) 삭제 대상: dbLatestVersion 의 최신 1건 (단, 베이스라인이면 삭제 금지)
537+
if (dbLatestVersion != null
538+
&& currentVersion != null
539+
&& dbLatestVersion.compareTo(currentVersion) != 0
540+
&& !BASELINE_VERSION.equals(dbLatestVersion.toString())) {
538541

542+
final String deleteLatestOneSql =
543+
"DELETE FROM `cloud`.`version` " +
544+
"WHERE `id` IN ( " +
545+
" SELECT id FROM ( " +
546+
" SELECT `id` " +
547+
" FROM `cloud`.`version` " +
548+
" WHERE `version` = ? AND (`step` IS NULL OR `step` = 'Complete') " +
549+
" ORDER BY COALESCE(`updated`, FROM_UNIXTIME(0)) DESC " +
550+
" LIMIT 1 " +
551+
" ) AS _x " +
552+
")";
539553
try (PreparedStatement delLatest = conn.prepareStatement(deleteLatestOneSql)) {
540-
delLatest.setString(1, targetVersion);
554+
delLatest.setString(1, dbLatestVersion.toString());
541555
int deleted = delLatest.executeUpdate();
542556
if (deleted > 0) {
543-
LOGGER.warn("Deleted {} latest row for version {}", deleted, targetVersion);
557+
LOGGER.warn("Deleted {} latest row for version {}", deleted, dbLatestVersion.toString());
544558
txn.commit();
545-
return; // 목적(해당 버전 최신 1건 삭제) 달성 시 즉시 종료
559+
return;
546560
} else {
547-
LOGGER.info("No deletable row found for targetVersion={}; skipping targeted delete.", targetVersion);
561+
LOGGER.info("No deletable row found for targetVersion={}; skipping targeted delete.",
562+
dbLatestVersion.toString());
548563
}
549564
}
550565
} else {
551-
LOGGER.info("Target version is baseline or null ({}). Skipping targeted delete.", targetVersion);
566+
// null-safe 로깅
567+
LOGGER.info("Target version is baseline or null ({}). Skipping targeted delete.",
568+
String.valueOf(dbLatestVersion));
552569
}
553570

554571
txn.commit();
555572
} catch (SQLException e) {
556573
txn.rollback();
557574
LOGGER.error("Failed in enforceBaselineThenDeleteLastVersionIfNeeded", e);
558-
throw new CloudRuntimeException("Failed in enforceBaselineThenDeleteLastVersionIfNeeded", e);
559575
} finally {
560576
txn.close();
561577
}

engine/schema/src/main/resources/META-INF/db/schema-41720to41800.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ CALL `cloud`.`ADD_GUEST_OS_AND_HYPERVISOR_MAPPING` (1, 'Red Hat Enterprise Linux
4343
CALL `cloud`.`ADD_GUEST_OS_AND_HYPERVISOR_MAPPING` (1, 'Rocky Linux 9', 'VMware', '7.0.3.0', 'otherLinux64Guest');
4444

4545
-- Add support for VMware 8.0 and 8.0a (8.0.0.1)
46-
`cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0', 1024, 0, 59, 64, 1, 1);
46+
INSERT IGNORE INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0', 1024, 0, 59, 64, 1, 1);
4747
INSERT IGNORE INTO `cloud`.`hypervisor_capabilities` (uuid, hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_data_volumes_limit, max_hosts_per_cluster, storage_motion_supported, vm_snapshot_enabled) values (UUID(), 'VMware', '8.0.0.1', 1024, 0, 59, 64, 1, 1);
4848
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'VMware', '8.0', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='VMware' AND hypervisor_version='7.0.3.0';
4949
INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid,hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created, is_user_defined) SELECT UUID(),'VMware', '8.0.0.1', guest_os_name, guest_os_id, utc_timestamp(), 0 FROM `cloud`.`guest_os_hypervisor` WHERE hypervisor_type='VMware' AND hypervisor_version='7.0.3.0';

0 commit comments

Comments
 (0)