You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafodion.apache.org by db...@apache.org on 2016/07/18 16:20:38 UTC
[13/16] incubator-trafodion git commit: Refactor and fix repository
upgrade code
Refactor and fix repository upgrade code
Project: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/commit/1cfc0ed8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/tree/1cfc0ed8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafodion/diff/1cfc0ed8
Branch: refs/heads/master
Commit: 1cfc0ed8bcaa9c3953d702429a406a8c4635b61c
Parents: a49afa1
Author: Dave Birdsall <db...@apache.org>
Authored: Wed Jul 13 18:42:53 2016 +0000
Committer: Dave Birdsall <db...@apache.org>
Committed: Wed Jul 13 18:42:53 2016 +0000
----------------------------------------------------------------------
core/sql/sqlcomp/CmpSeabaseDDL.h | 10 +-
core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp | 160 ++++++++++++++----
core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp | 225 +++++++++++++++++++++----
core/sql/sqlcomp/CmpSeabaseDDLupgrade.h | 193 ++++++++++++++++++++-
4 files changed, 517 insertions(+), 71 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/1cfc0ed8/core/sql/sqlcomp/CmpSeabaseDDL.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDL.h b/core/sql/sqlcomp/CmpSeabaseDDL.h
index 21f5cbe..a00a7ec 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDL.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDL.h
@@ -1286,10 +1286,18 @@ protected:
short createRepos(ExeCliInterface * cliInterface);
short dropRepos(ExeCliInterface * cliInterface,
- NABoolean oldRepos = FALSE, NABoolean dropSchema = TRUE);
+ NABoolean oldRepos = FALSE, NABoolean dropSchema = TRUE,
+ NABoolean inRecovery = FALSE);
short alterRenameRepos(ExeCliInterface * cliInterface, NABoolean newToOld);
short copyOldReposToNew(ExeCliInterface * cliInterface);
+
+public:
+
short upgradeRepos(ExeCliInterface * cliInterface, CmpDDLwithStatusInfo *mdui);
+ short upgradeReposComplete(ExeCliInterface * cliInterface, CmpDDLwithStatusInfo *mdui);
+ short upgradeReposUndo(ExeCliInterface * cliInterface, CmpDDLwithStatusInfo *mdui);
+
+protected:
void processRepository(NABoolean createR, NABoolean dropR, NABoolean upgradeR);
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/1cfc0ed8/core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp b/core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp
index bc39c8d..f4704ea 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLrepos.cpp
@@ -137,7 +137,8 @@ short CmpSeabaseDDL::createRepos(ExeCliInterface * cliInterface)
short CmpSeabaseDDL::dropRepos(ExeCliInterface * cliInterface,
NABoolean oldRepos,
- NABoolean dropSchema)
+ NABoolean dropSchema,
+ NABoolean inRecovery)
{
Lng32 cliRC = 0;
NABoolean xnWasStartedHere = FALSE;
@@ -147,6 +148,13 @@ short CmpSeabaseDDL::dropRepos(ExeCliInterface * cliInterface,
{
const MDUpgradeInfo &rti = allReposUpgradeInfo[i];
+ // If we are dropping the new repository as part of a recovery action,
+ // and there is no "old" table (because the table didn't change in this
+ // upgrade), then don't drop the new table. (If we did, we would be
+ // dropping the existing data.)
+ if (!oldRepos && inRecovery && !rti.oldName)
+ continue;
+
if ((oldRepos && !rti.oldName) || (NOT oldRepos && ! rti.newName))
continue;
@@ -361,7 +369,7 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
{
case 0:
{
- mdui->setMsg("Upgrade Repository: started");
+ mdui->setMsg("Upgrade Repository: Started");
mdui->subStep()++;
mdui->setEndStep(FALSE);
@@ -383,7 +391,10 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
{
// drop old repository
if (dropRepos(cliInterface, TRUE/*old repos*/, FALSE/*no schema drop*/))
- return -1;
+ return -3; // error, but no recovery needed (and in fact
+ // doing such things as dropping the *new* repository
+ // would just destroy the existing repository data
+ // that we wish to save)
mdui->setMsg(" End: Drop Old Repository");
mdui->subStep()++;
@@ -407,10 +418,7 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
{
// rename current repository tables to *_OLD_REPOS
if (alterRenameRepos(cliInterface, TRUE))
- {
- mdui->setSubstep(12); // label_error1
- break;
- }
+ return -2; // error, need to undo the rename only
mdui->setMsg(" End: Rename Current Repository");
mdui->subStep()++;
@@ -434,10 +442,7 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
{
// create new repository
if (createRepos(cliInterface))
- {
- mdui->setSubstep(13); // label_error2
- break;
- }
+ return -1; // error, need to drop new repository then undo rename
mdui->setMsg(" End: Create New Repository");
mdui->subStep()++;
@@ -461,10 +466,7 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
{
// copy old contents into new repository
if (copyOldReposToNew(cliInterface))
- {
- mdui->setSubstep(13); // label_error2
- break;
- }
+ return -1; // error, need to drop new repository then undo rename
mdui->setMsg(" End: Copy Old Repository Contents ");
mdui->subStep()++;
@@ -473,10 +475,38 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
return 0;
}
break;
-
+
case 9:
{
- mdui->setMsg(" Start: Drop Old Repository ");
+ mdui->setMsg("Upgrade Repository: Done except for cleaning up");
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+
+ return 0;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ } // while
+
+ return 0;
+}
+
+
+short CmpSeabaseDDL::upgradeReposComplete(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo *mdui)
+{
+ Lng32 cliRC = 0;
+
+ while (1) // exit via return stmt in switch
+ {
+ switch (mdui->subStep())
+ {
+ case 0:
+ {
+ mdui->setMsg("Upgrade Repository: Drop Old Repository");
mdui->subStep()++;
mdui->setEndStep(FALSE);
@@ -484,47 +514,105 @@ short CmpSeabaseDDL::upgradeRepos(ExeCliInterface * cliInterface,
}
break;
- case 10:
+ case 1:
{
- // drop old repository
+ // drop old repository; ignore errors
dropRepos(cliInterface, TRUE/*old repos*/, FALSE/*no schema drop*/);
- mdui->setMsg(" End: Drop Old Repository");
+ mdui->setMsg("Upgrade Repository: Drop Old Repository done");
+ mdui->setEndStep(TRUE);
+ mdui->setSubstep(0);
+
+ return 0;
+ }
+ break;
+
+ default:
+ return -1;
+ }
+ } // while
+
+ return 0;
+}
+
+short CmpSeabaseDDL::upgradeReposUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo *mdui)
+{
+ Lng32 cliRC = 0;
+
+ while (1) // exit via return stmt in switch
+ {
+ switch (mdui->subStep())
+ {
+ // error return codes from upgradeRepos can be mapped to
+ // the right recovery substep by this formula: substep = -(retcode + 1)
+ case 0: // corresponds to -1 return code from upgradeRepos (or
+ // to full recovery after some error after upgradeRepos)
+ case 1: // corresponds to -2 return code from upgradeRepos
+ case 2: // corresponds to -3 return code from upgradeRepos
+ {
+ mdui->setMsg("Upgrade Repository: Restoring Old Repository");
+ mdui->setSubstep(2*mdui->subStep()+3); // go to appropriate case
+ mdui->setEndStep(FALSE);
+
+ return 0;
+ }
+ break;
+
+ case 3:
+ {
+ mdui->setMsg(" Start: Drop New Repository");
mdui->subStep()++;
mdui->setEndStep(FALSE);
-
+
return 0;
}
break;
- case 11:
+ case 4:
{
- mdui->setMsg("Upgrade Repository: done");
+ // drop new repository; ignore errors
+ dropRepos(cliInterface, FALSE/*new repos*/, FALSE/*no schema drop*/,
+ TRUE /* don't drop new tables that haven't been upgraded */);
+ cliInterface->clearGlobalDiags();
+ mdui->setMsg(" End: Drop New Repository");
mdui->subStep()++;
- mdui->setEndStep(TRUE);
- mdui->setSubstep(0);
-
+ mdui->setEndStep(FALSE);
+
+ return 0;
+ }
+ break;
+
+ case 5:
+ {
+ mdui->setMsg(" Start: Rename Old Repository back to New");
+ mdui->subStep()++;
+ mdui->setEndStep(FALSE);
+
return 0;
}
break;
- case 12: // label_error1
+ case 6:
{
- // rename old repos to current
+ // rename old repos to current; ignore errors
alterRenameRepos(cliInterface, FALSE);
- return -1;
+ cliInterface->clearGlobalDiags();
+ mdui->setMsg(" End: Rename Old Repository back to New");
+ mdui->subStep()++;
+ mdui->setEndStep(FALSE);
+
+ return 0;
}
break;
- case 13: // label_error2
+ case 7:
{
- // drop new repository
- dropRepos(cliInterface, FALSE/*new repos*/, FALSE/*no schema drop*/);
-
- // rename old to new
- alterRenameRepos(cliInterface, FALSE);
+ mdui->setMsg("Upgrade Repository: Restore done");
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
- return -1;
+ return 0;
}
break;
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/1cfc0ed8/core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp b/core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp
index 1c058df..48ad516 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp
+++ b/core/sql/sqlcomp/CmpSeabaseDDLupgrade.cpp
@@ -310,15 +310,22 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
char msgBuf[1000];
char buf[10000];
+ // interfaces for upgrading subsystems; OK to create on stack for
+ // now as they are stateless
+ CmpSeabaseUpgradeRepository upgradeRepository;
+ CmpSeabaseUpgradePrivMgr upgradePrivMgr;
+
ExeCliInterface cliInterface(STMTHEAP, NULL, NULL,
CmpCommon::context()->sqlSession()->getParentQid());
ExpHbaseInterface * ehi = NULL;
while (1)
{
- // TODO: remove this debugging code
- cout << "mdui->step() is " << mdui->step() << ", mdui->subStep() is " << mdui->subStep() << endl;
- // TODO: remove the above debugging code
+ // The line below is useful when debugging upgrade; it shows the step progression
+ // through the upgrade state machine.
+ // cout << "mdui->step() is " << mdui->step()
+ // << ", mdui->subStep() is " << mdui->subStep() << endl;
+
switch (mdui->step())
{
case UPGRADE_START:
@@ -440,7 +447,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
case 2:
{
- str_sprintf(msgBuf, " Metadata need to be upgraded or reinitialized.");
+ str_sprintf(msgBuf, " Metadata needs to be upgraded or reinitialized.");
mdui->setMsg(msgBuf);
mdui->setEndStep(FALSE);
@@ -534,7 +541,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
else
{
if (retcode == -1395)
- str_sprintf(msgBuf, " Metadata need to be upgraded or reinitialized (Current Version %Ld.%Ld.%Ld, Expected Version %Ld.%Ld.%Ld).",
+ str_sprintf(msgBuf, " Metadata needs to be upgraded or reinitialized (Current Version %Ld.%Ld.%Ld, Expected Version %Ld.%Ld.%Ld).",
mdCurrMajorVersion, mdCurrMinorVersion, mdCurrUpdateVersion,
(Int64)METADATA_MAJOR_VERSION, (Int64)METADATA_MINOR_VERSION, (Int64)METADATA_UPDATE_VERSION);
else
@@ -577,7 +584,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
case 2:
{
- str_sprintf(msgBuf, " Metadata need to be updated with current software version. Run 'initialize trafodion, update software version' to update it.");
+ str_sprintf(msgBuf, " Metadata needs to be updated with current software version. Run 'initialize trafodion, update software version' to update it.");
mdui->setMsg(msgBuf);
mdui->setEndStep(FALSE);
@@ -666,17 +673,17 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
if (isMDUpgradeNeeded())
{
- upgItems += " Catalogs, ";
+ upgItems += " Catalogs,";
}
if (isViewsUpgradeNeeded())
{
upgItems += " Views,";
}
- if (isPrivsUpgradeNeeded())
+ if (upgradePrivMgr.needsUpgrade(this))
{
upgItems += " Privileges,";
}
- if (isReposUpgradeNeeded())
+ if (upgradeRepository.needsUpgrade(this))
{
upgItems += " Repository,";
}
@@ -686,7 +693,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
upgItems += ".";
}
}
- str_sprintf(msgBuf, " Metadata need to be upgraded from Version %Ld.%Ld.%Ld to %Ld.%Ld.%Ld.%s",
+ str_sprintf(msgBuf, " Metadata needs to be upgraded from Version %Ld.%Ld.%Ld to %Ld.%Ld.%Ld.%s",
mdCurrMajorVersion, mdCurrMinorVersion/10,
(mdCurrMinorVersion - (mdCurrMinorVersion/10)*10),
METADATA_MAJOR_VERSION, METADATA_MINOR_VERSION,
@@ -1426,7 +1433,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
if (NOT isViewsUpgradeNeeded())
{
- mdui->setStep(UPGRADE_PRIV_MGR);
+ mdui->setStep(UPGRADE_REPOS);
mdui->setSubstep(0);
break;
}
@@ -1492,7 +1499,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
}
mdui->setMsg("Update Metadata Views: done");
- mdui->setStep(UPGRADE_PRIV_MGR);
+ mdui->setStep(UPGRADE_REPOS);
mdui->setSubstep(0);
mdui->setEndStep(TRUE);
@@ -1506,13 +1513,20 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
case UPGRADE_PRIV_MGR:
{
+ // Note: We used to do this case before UPGRADE_REPOS, but
+ // that was changed in Trafodion 2.1 to do it afterwards instead.
+ // The reason is that the Privilege Manager does not adhere
+ // to the CmpSeabaseUpgradeSubsystem class contract; its drop
+ // and recovery logic is packaged in its upgrade method. So,
+ // we have to do the Privilege Manager upgrade last since there
+ // is no way to undo it if we have an error afterward.
switch (mdui->subStep())
{
case 0:
{
- if (NOT isPrivsUpgradeNeeded())
+ if (NOT upgradePrivMgr.needsUpgrade(this))
{
- mdui->setStep(UPGRADE_REPOS);
+ mdui->setStep(UPDATE_VERSION);
mdui->setSubstep(0);
break;
}
@@ -1527,12 +1541,11 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
case 1:
{
- NAString privMgrDoneMsg;
if (xnInProgress(&cliInterface))
{
*CmpCommon::diags() << DgSqlCode(-20123);
- mdui->setStep(UPGRADE_FAILED);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1543,16 +1556,16 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
- mdui->setStep(UPGRADE_FAILED);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
}
- cliRC = upgradePrivMgr(&cliInterface, ddlXns, privMgrDoneMsg);
+ cliRC = upgradePrivMgr.doUpgrade(&cliInterface,mdui,this,ddlXns);
if (cliRC != 0)
{
- mdui->setStep(UPGRADE_FAILED);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1563,14 +1576,14 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
- mdui->setStep(UPGRADE_FAILED);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
}
- mdui->setMsg(privMgrDoneMsg.data());
- mdui->setStep(UPGRADE_REPOS);
+ // mdui->setMsg() was called in upgradePrivMgr.doUpgrade()
+ mdui->setStep(UPDATE_VERSION);
mdui->setSubstep(0);
mdui->setEndStep(TRUE);
@@ -1586,7 +1599,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
if (NOT isReposUpgradeNeeded())
{
- mdui->setStep(UPDATE_VERSION);
+ mdui->setStep(UPGRADE_PRIV_MGR);
mdui->setSubstep(0);
break;
}
@@ -1601,18 +1614,18 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
break;
}
- cliRC = upgradeRepos(&cliInterface, mdui);
+ cliRC = upgradeRepository.doUpgrade(&cliInterface, mdui, this, ddlXns);
if (cliRC != 0)
{
- mdui->setStep(UPGRADE_FAILED);
- mdui->setSubstep(0);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
+ mdui->setSubstep(-(cliRC+1));
break;
}
if (mdui->endStep())
{
- mdui->setStep(UPDATE_VERSION);
+ mdui->setStep(UPGRADE_PRIV_MGR);
mdui->setSubstep(0);
}
@@ -1640,7 +1653,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
*CmpCommon::diags() << DgSqlCode(-20123);
- mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_MD);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1651,7 +1664,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
- mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_MD);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1660,7 +1673,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
cliRC = updateSeabaseVersions(&cliInterface, TRAFODION_SYSCAT_LIT);
if (cliRC < 0)
{
- mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_MD);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1674,7 +1687,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
{
cliInterface.retrieveSQLDiagnostics(CmpCommon::diags());
- mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_MD);
+ mdui->setStep(UPGRADE_FAILED_RESTORE_OLD_REPOS);
mdui->setSubstep(0);
break;
@@ -1686,7 +1699,7 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
(NOT isViewsUpgradeNeeded()))
mdui->setStep(METADATA_UPGRADED);
else
- mdui->setStep(OLD_MD_TABLES_HBASE_DELETE);
+ mdui->setStep(OLD_REPOS_DROP);
mdui->setSubstep(0);
mdui->setEndStep(TRUE);
@@ -1697,6 +1710,32 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
}
break;
+ case OLD_REPOS_DROP:
+ {
+ if (upgradeRepository.needsUpgrade(this))
+ {
+ if (upgradeRepository.doDrops(&cliInterface,mdui,this))
+ {
+ // no status message in this case so no return
+ cliInterface.clearGlobalDiags();
+ mdui->setStep(OLD_MD_TABLES_HBASE_DELETE);
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+ }
+ else
+ {
+ if (mdui->endStep())
+ {
+ mdui->setStep(OLD_MD_TABLES_HBASE_DELETE);
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+ }
+ return 0;
+ }
+ }
+ }
+ break;
+
case OLD_MD_TABLES_HBASE_DELETE:
{
switch (mdui->subStep())
@@ -1814,6 +1853,51 @@ short CmpSeabaseMDupgrade::executeSeabaseMDupgrade(CmpDDLwithStatusInfo *mdui,
}
break;
+ case UPGRADE_FAILED_RESTORE_OLD_REPOS:
+ {
+ // Note: We can't combine this case with UPGRADE_FAILED etc.
+ // below, because the subsystem code uses mdui->subStep()
+ // to keep track of its progress.
+
+ if (upgradeRepository.needsUpgrade(this))
+ {
+ if (xnInProgress(&cliInterface))
+ {
+ cliRC = rollbackXn(&cliInterface);
+ if (cliRC < 0)
+ {
+ // ignore errors
+ }
+ }
+
+ if (upgradeRepository.doUndo(&cliInterface,mdui,this))
+ {
+ // ignore errors; no status message so just continue on
+ cliInterface.clearGlobalDiags();
+ mdui->setStep(UPGRADE_FAILED_DROP_OLD_MD);
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+ }
+ else
+ {
+ if (mdui->endStep())
+ {
+ mdui->setStep(UPGRADE_FAILED_DROP_OLD_MD);
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+ }
+ return 0;
+ }
+ }
+ else
+ {
+ mdui->setStep(UPGRADE_FAILED_DROP_OLD_MD);
+ mdui->setSubstep(0);
+ mdui->setEndStep(TRUE);
+ }
+ }
+ break;
+
case UPGRADE_FAILED:
case UPGRADE_FAILED_RESTORE_OLD_MD:
case UPGRADE_FAILED_DROP_OLD_MD:
@@ -2414,6 +2498,83 @@ short CmpSeabaseMDupgrade::customizeNewMDv23tov30(CmpDDLwithStatusInfo *mdui,
}
// ----------------------------------------------------------------------------
+// Methods for class CmpSeabaseUpgradeRepository
+// ----------------------------------------------------------------------------
+NABoolean CmpSeabaseUpgradeRepository::needsUpgrade(CmpSeabaseMDupgrade * ddlState)
+{
+ return ddlState->isReposUpgradeNeeded();
+}
+
+short CmpSeabaseUpgradeRepository::doUpgrade(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState,
+ NABoolean /* ddlXns */)
+{
+ return ddlState->upgradeRepos(cliInterface,mdui);
+}
+
+short CmpSeabaseUpgradeRepository::doDrops(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui, CmpSeabaseMDupgrade * ddlState)
+{
+ return ddlState->upgradeReposComplete(cliInterface,mdui);
+}
+
+short CmpSeabaseUpgradeRepository::doUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui, CmpSeabaseMDupgrade * ddlState)
+{
+ return ddlState->upgradeReposUndo(cliInterface,mdui);
+}
+
+// ----------------------------------------------------------------------------
+// Methods for class CmpSeabaseUpgradePrivMgr
+// ----------------------------------------------------------------------------
+NABoolean CmpSeabaseUpgradePrivMgr::needsUpgrade(CmpSeabaseMDupgrade * ddlState)
+{
+ return ddlState->isPrivsUpgradeNeeded();
+}
+
+short CmpSeabaseUpgradePrivMgr::doUpgrade(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState,
+ NABoolean ddlXns)
+{
+ // If this is refactored in the future to return multiple messages
+ // then mdui will need to be passed in, and setEndStep called when
+ // we want to stop redriving this method.
+ NAString doneString;
+ short retcode = ddlState->upgradePrivMgr(cliInterface, ddlXns, doneString);
+ if (!retcode)
+ {
+ mdui->setMsg(doneString.data());
+ mdui->setEndStep(TRUE);
+ }
+ return retcode;
+}
+
+short CmpSeabaseUpgradePrivMgr::doDrops(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui, CmpSeabaseMDupgrade * ddlState)
+{
+ // At the moment, the privilege manager does not adhere to the contract.
+ // It does its drops inside the CmpSeabaseMDupgrade::upgradePrivMgr
+ // method. That is why the upgrade state machine above must do the
+ // privilege manager last. Because if there were an error afterward
+ // that required us to revert to previous state, we couldn't since
+ // the drops have already been done.
+ return 0; // stubbed, until Privilege Manager upgrade is refactored
+}
+
+short CmpSeabaseUpgradePrivMgr::doUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui, CmpSeabaseMDupgrade * ddlState)
+{
+ // At the moment, the privilege manager does not adhere to the contract.
+ // It does its recovery inside the CmpSeabaseMDupgrade::upgradePrivMgr
+ // method. That is why the upgrade state machine above must do the
+ // privilege manager last. Because if there were an error afterward
+ // that required us to revert to previous state, we couldn't since
+ // the drops have already been done.
+ return 0; // stubbed, until Privilege Manager upgrade is refactored
+}
+// ----------------------------------------------------------------------------
// method: upgradePrivMgr
//
// This method upgrades the privilege manager repository
http://git-wip-us.apache.org/repos/asf/incubator-trafodion/blob/1cfc0ed8/core/sql/sqlcomp/CmpSeabaseDDLupgrade.h
----------------------------------------------------------------------
diff --git a/core/sql/sqlcomp/CmpSeabaseDDLupgrade.h b/core/sql/sqlcomp/CmpSeabaseDDLupgrade.h
index 3fcc94b..4182a3d 100644
--- a/core/sql/sqlcomp/CmpSeabaseDDLupgrade.h
+++ b/core/sql/sqlcomp/CmpSeabaseDDLupgrade.h
@@ -60,6 +60,81 @@ CmpSeabaseDDLupgrade.cpp
-- modify CUSTOMIZE_NEW_MD case if something specified need to be done.
Ex: update new sql_data_type field in COLUMNS table
+Similar changes may be needed for subsystems that are upgraded as part
+of "initialize trafodion, upgrade", for example the Repository and the
+Privilege Manager. The Repository upgrade code is in CmpSeabaseDDLrepos.h/.cpp,
+while the Privilege Manager code is in the Priv* modules.
+
+The architecture of upgrade is as follows:
+
+Guiding principle:
+
+In the event of a failure, we do our best to put things back to their
+initial state. That allows the user to try again (for example, for a
+transient HBase difficulty), or to reinstall the old software if desired.
+
+Control flow:
+
+First we upgrade the metadata tables ("_MD_" schema). This has to be done
+using bootstrapping techniques. We rename the existing metadata tables
+to an old name, using HBase primitives. We then create the new metadata
+tables, and copy the data from the old tables to the new, transforming it
+as needed. The copy is done using a vanilla UPSERT/SELECT. We can do this
+because at process startup time, the NATable cache is bootstrapped with
+both the old and new metadata table definitions. We don't drop the old
+metadata tables yet, because we want to be able to revert to our initial
+state should an error occur.
+
+Subsystems are upgraded after the metadata table upgrade succeeds. The
+subsystems are not self-referencing from a metadata point of view. So,
+for example, it is possible to rename a subsystem table using a SQL
+ALTER TABLE RENAME statement, which is not true for a metadata table.
+
+Subsystems go through basically the same steps: Rename the existing table
+to old, create the new, copy the data in. Again, the old tables are not
+dropped yet, so we can revert in the event of an error (in the next
+subsystem for example).
+
+Once all the subsystems have been upgraded, we update the version in
+the VERSIONS table.
+
+Finally, we drop all the old tables. We can ignore errors at this point
+because we have good new tables.
+
+If there is an error, we undo the upgrade for each subsystem, then undo
+the upgrade for the metadata tables. Again, we can use vanilla SQL for
+the subsystems, but must use low level HBase primitives for the metadata
+tables.
+
+The CmpSeabaseUpgradeSubsystem class defines the contract that a subsystem
+must implement in order to be called from "initialize trafodion, upgrade".
+Briefly, each subsystem must implement the following:
+
+-- a method that says whether an upgrade is needed for that subsystem
+-- a method that does the upgrade, but leaves the old tables around
+ so that they can be recovered in case we have to undo the upgrade
+-- a method that drops the old tables, called when we have decided that
+ the upgrade has succeeded
+-- a method that undoes the upgrade, called when an error is detected
+ in "initialize trafodion, upgrade".
+
+These are packaged in separate methods because, as mentioned above,
+processing is interleaved. We do all the subsystem upgrades. If they are
+all successful, we do the drops. But if there was an error, we do the undo's.
+
+Data flow:
+
+The "initialize trafodion, upgrade" statement is a DDL statement that returns
+rows. The rows are status messages, which if displayed immediately (as they
+would be, say, in sqlci or trafci), give a real time status of the operation.
+
+As such, the upgrade methods are redriven after each row is returned. The
+upgrade processing occurs in a tdm_arkcmp process. All state is kept in the
+message objects communicated between it and its invoker. For this reason,
+the classes used for the upgrade methods are stateless. Instead, state
+consists of state-machine step information which is stored in a
+CmpDDLwithStatusInfo object.
+
***************************************************************************************/
// structure containing information on old and new MD tables
@@ -501,13 +576,14 @@ class CmpSeabaseMDupgrade : public CmpSeabaseDDL
OLD_TABLES_MD_DELETE,
OLD_MD_TABLES_HBASE_DELETE,
UPDATE_MD_VIEWS,
- UPGRADE_PRIV_MGR,
UPGRADE_REPOS,
+ UPGRADE_PRIV_MGR,
UPDATE_VERSION,
- OLD_MD_DROP_POST,
+ OLD_REPOS_DROP,
METADATA_UPGRADED,
UPGRADE_DONE,
UPGRADE_FAILED,
+ UPGRADE_FAILED_RESTORE_OLD_REPOS,
UPGRADE_FAILED_RESTORE_OLD_MD,
UPGRADE_FAILED_DROP_OLD_MD,
GET_MD_VERSION,
@@ -553,5 +629,118 @@ class CmpSeabaseMDupgrade : public CmpSeabaseDDL
};
+
+// abstract class defining the contract that a subsystem must implement
+// in order to be called from "initialize trafodion, upgrade"
+class CmpSeabaseUpgradeSubsystem
+{
+ public:
+
+ CmpSeabaseUpgradeSubsystem(void) { } ;
+ ~CmpSeabaseUpgradeSubsystem(void) { } ;
+
+ // Returns TRUE if an upgrade is needed, FALSE if not
+ virtual NABoolean needsUpgrade(CmpSeabaseMDupgrade * ddlState) = 0;
+
+ // The next three methods have the same return interface:
+ //
+ // returns 0 if successful or not done yet, a negative value
+ // if not. ("Not done yet" means call again. This allows
+ // the method to return status text messages to the user as
+ // it progresses in its processing.) To signal successful
+ // completion, the method should return 0, and call
+ // mdui->setEndStep(TRUE). Any state needed across calls
+ // should be kept in the CmpDDLwithStatusInfo object,
+ // e.g., via its setStep and setSubstep methods.
+ //
+ // The negative value can be used to signal what sort of
+ // recovery is needed.
+
+ // Does the upgrade, but leaves old tables there in case we
+ // need to undo.
+ virtual short doUpgrade(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState,
+ NABoolean ddlXns) = 0;
+
+ // Drops the old tables left behind by doUpgrade; errors
+ // are typically ignored as at this point upgrade is
+ // done except for dropping old tables.
+ virtual short doDrops(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState) = 0;
+
+ // Undoes the upgrade by putting the old tables back to
+ // their original names.
+ virtual short doUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState) = 0;
+
+ private:
+
+ // for now, avoid having any state; the upgrade mainline
+ // keeps most of its state in the CmpDDLwithStatusInfo message
+};
+
+// Repository specialization
+
+class CmpSeabaseUpgradeRepository : public CmpSeabaseUpgradeSubsystem
+{
+ public:
+
+ CmpSeabaseUpgradeRepository(void) { } ;
+ ~CmpSeabaseUpgradeRepository(void) { } ;
+
+ NABoolean needsUpgrade(CmpSeabaseMDupgrade * ddlState);
+
+ short doUpgrade(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState,
+ NABoolean ddlXns);
+
+ short doDrops(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState);
+
+ short doUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState);
+
+ private:
+
+ // avoid having state for now
+
+};
+
+// Privilege Manager specialization
+
+class CmpSeabaseUpgradePrivMgr : public CmpSeabaseUpgradeSubsystem
+{
+ public:
+
+ CmpSeabaseUpgradePrivMgr(void) { } ;
+ ~CmpSeabaseUpgradePrivMgr(void) { } ;
+
+ NABoolean needsUpgrade(CmpSeabaseMDupgrade * ddlState);
+
+ short doUpgrade(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState,
+ NABoolean ddlXns);
+
+ short doDrops(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState);
+
+ short doUndo(ExeCliInterface * cliInterface,
+ CmpDDLwithStatusInfo * mdui,
+ CmpSeabaseMDupgrade * ddlState);
+
+ private:
+
+ // avoid having state for now
+
+};
+
#endif