You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by dm...@apache.org on 2016/12/09 13:32:30 UTC

ambari git commit: AMBARI-18990. Auto-fix common issues found by the DB consistency checker (dlysnichenko)

Repository: ambari
Updated Branches:
  refs/heads/branch-2.5 54da8c27c -> 6029846c9


AMBARI-18990. Auto-fix common issues found by the DB consistency checker (dlysnichenko)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6029846c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6029846c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6029846c

Branch: refs/heads/branch-2.5
Commit: 6029846c94d3b9aa00bee7282071270206781688
Parents: 54da8c2
Author: Lisnichenko Dmitro <dl...@hortonworks.com>
Authored: Fri Dec 9 15:29:20 2016 +0200
Committer: Lisnichenko Dmitro <dl...@hortonworks.com>
Committed: Fri Dec 9 15:29:20 2016 +0200

----------------------------------------------------------------------
 .../checks/DatabaseConsistencyCheckHelper.java  | 245 ++++++++++++++++++-
 .../checks/DatabaseConsistencyChecker.java      |   1 +
 .../ambari/server/controller/AmbariServer.java  |   3 +
 .../orm/entities/ClusterConfigEntity.java       |  17 ++
 ambari-server/src/main/python/ambari-server.py  |   2 +
 .../src/main/python/ambari_server_main.py       |   3 +
 .../server/controller/AmbariServerTest.java     |  26 ++
 7 files changed, 293 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
index 9c3ae5c..d40dfd2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyCheckHelper.java
@@ -20,23 +20,40 @@ package org.apache.ambari.server.checks;
 import java.io.File;
 import java.io.IOException;
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Scanner;
 import java.util.Set;
 
+import javax.inject.Provider;
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.DBAccessor;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
+import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
 import org.apache.ambari.server.orm.dao.MetainfoDAO;
+import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
+import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
+import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
 import org.apache.ambari.server.orm.entities.MetainfoEntity;
+import org.apache.ambari.server.state.SecurityState;
 import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.UpgradeState;
 import org.apache.ambari.server.utils.VersionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -46,6 +63,7 @@ import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
+import com.google.inject.persist.Transactional;
 
 public class DatabaseConsistencyCheckHelper {
 
@@ -103,8 +121,17 @@ public class DatabaseConsistencyCheckHelper {
     }
   }
 
+
+  public static void fixDatabaseConsistency() {
+    fixHostComponentStatesCountEqualsHostComponentsDesiredStates();
+    fixClusterConfigsNotMappedToAnyService();
+  }
+
   public static void runAllDBChecks() {
     LOG.info("******************************* Check database started *******************************");
+    checkSchemaName();
+    checkMySQLEngine();
+    checkForConfigsNotMappedToService();
     checkForNotMappedConfigsToCluster();
     checkForConfigsSelectedMoreThanOnce();
     checkForHostsWithoutState();
@@ -200,7 +227,7 @@ public class DatabaseConsistencyCheckHelper {
     }
   }
 
-  /*
+  /**
   * This method checks if any config type in clusterconfigmapping table, has
   * more than one versions selected. If config version is selected(in selected column = 1),
   * it means that this version of config is actual. So, if any config type has more
@@ -260,7 +287,7 @@ public class DatabaseConsistencyCheckHelper {
     }
   }
 
-  /*
+  /**
   * This method checks if all hosts from hosts table
   * has related host state info in hoststate table.
   * If not then we are showing error.
@@ -315,7 +342,7 @@ public class DatabaseConsistencyCheckHelper {
     }
   }
 
-  /*
+  /**
   * This method checks if count of host component states equals count
   * of desired host component states. According to ambari logic these
   * two tables should have the same count of rows. If not then we are
@@ -392,8 +419,218 @@ public class DatabaseConsistencyCheckHelper {
 
   }
 
+  /**
+  * Remove configs that are not mapped to any service.
+  */
+  @Transactional
+  public static void fixClusterConfigsNotMappedToAnyService() {
+    LOG.info("Checking for configs not mapped to any Service");
+    ClusterDAO clusterDAO = injector.getInstance(ClusterDAO.class);
+    List<ClusterConfigEntity> notMappedClusterConfigs = getNotMappedClusterConfigsToService();
+
+    for (ClusterConfigEntity clusterConfigEntity : notMappedClusterConfigs){
+      List<String> types = new ArrayList<>();
+      String type = clusterConfigEntity.getType();
+      types.add(type);
+      LOG.error("Removing cluster config mapping of type {} that is not mapped to any service", type);
+      clusterDAO.removeClusterConfigMappingEntityByTypes(clusterConfigEntity.getClusterId(),types);
+      LOG.error("Removing config that is not mapped to any service", clusterConfigEntity);
+      clusterDAO.removeConfig(clusterConfigEntity);
+    }
+  }
 
-  /*
+
+  /**
+   * Find ClusterConfigs that are not mapped to Service
+   * @return ClusterConfigs that are not mapped to Service
+   */
+  private static List<ClusterConfigEntity> getNotMappedClusterConfigsToService() {
+    Provider<EntityManager> entityManagerProvider = injector.getProvider(EntityManager.class);
+    EntityManager entityManager = entityManagerProvider.get();
+
+    Query query = entityManager.createNamedQuery("ClusterConfigEntity.findNotMappedClusterConfigsToService",ClusterConfigEntity.class);
+
+    return (List<ClusterConfigEntity>) query.getResultList();
+  }
+
+  /**
+   * Look for configs that are not mapped to any service.
+   */
+  public static void checkForConfigsNotMappedToService() {
+    LOG.info("Checking for configs that are not mapped to any service");
+    List<ClusterConfigEntity> notMappedClasterConfigs = getNotMappedClusterConfigsToService();
+
+    if (!notMappedClasterConfigs.isEmpty()){
+      LOG.error("Found configs that are not mapped to any service!");
+      errorsFound = true;
+    }
+  }
+
+  /**
+  * This method checks if count of host component states equals count
+  * of desired host component states. According to ambari logic these
+  * two tables should have the same count of rows. If not then we are
+  * adding missed host components.
+  */
+  @Transactional
+  public static void fixHostComponentStatesCountEqualsHostComponentsDesiredStates() {
+    LOG.info("Checking that there are the same number of actual and desired host components");
+
+    HostComponentStateDAO hostComponentStateDAO = injector.getInstance(HostComponentStateDAO.class);
+    HostComponentDesiredStateDAO hostComponentDesiredStateDAO = injector.getInstance(HostComponentDesiredStateDAO.class);
+
+    List<HostComponentDesiredStateEntity> hostComponentDesiredStates = hostComponentDesiredStateDAO.findAll();
+    List<HostComponentStateEntity> hostComponentStates = hostComponentStateDAO.findAll();
+
+    Set<HostComponentDesiredStateEntity> missedHostComponentDesiredStates = new HashSet<>();
+    missedHostComponentDesiredStates.addAll(hostComponentDesiredStates);
+    Set<HostComponentStateEntity> missedHostComponentStates = new HashSet<>();
+    missedHostComponentStates.addAll(hostComponentStates);
+
+    for (Iterator<HostComponentStateEntity> stateIterator = missedHostComponentStates.iterator(); stateIterator.hasNext();){
+      HostComponentStateEntity hostComponentStateEntity = stateIterator.next();
+      for (Iterator<HostComponentDesiredStateEntity> desiredStateIterator = missedHostComponentDesiredStates.iterator(); desiredStateIterator.hasNext();) {
+        HostComponentDesiredStateEntity hostComponentDesiredStateEntity = desiredStateIterator.next();
+        if (hostComponentStateEntity.getComponentName().equals(hostComponentDesiredStateEntity.getComponentName()) &&
+            hostComponentStateEntity.getServiceName().equals(hostComponentDesiredStateEntity.getServiceName()) &&
+            hostComponentStateEntity.getHostId().equals(hostComponentDesiredStateEntity.getHostId())){
+          desiredStateIterator.remove();
+          stateIterator.remove();
+          break;
+        }
+      }
+    }
+
+    for (HostComponentDesiredStateEntity hostComponentDesiredStateEntity : missedHostComponentDesiredStates) {
+      HostComponentStateEntity stateEntity = new HostComponentStateEntity();
+      stateEntity.setClusterId(hostComponentDesiredStateEntity.getClusterId());
+      stateEntity.setComponentName(hostComponentDesiredStateEntity.getComponentName());
+      stateEntity.setServiceName(hostComponentDesiredStateEntity.getServiceName());
+      stateEntity.setVersion(State.UNKNOWN.toString());
+      stateEntity.setHostEntity(hostComponentDesiredStateEntity.getHostEntity());
+      stateEntity.setCurrentState(State.UNKNOWN);
+      stateEntity.setUpgradeState(UpgradeState.NONE);
+      stateEntity.setCurrentStack(hostComponentDesiredStateEntity.getDesiredStack());
+      stateEntity.setSecurityState(SecurityState.UNKNOWN);
+      stateEntity.setServiceComponentDesiredStateEntity(hostComponentDesiredStateEntity.getServiceComponentDesiredStateEntity());
+
+      LOG.error("Trying to add missing record in hostcomponentstate: {}", stateEntity);
+      hostComponentStateDAO.create(stateEntity);
+    }
+
+    for (HostComponentStateEntity missedHostComponentState : missedHostComponentStates) {
+
+      HostComponentDesiredStateEntity stateEntity = new HostComponentDesiredStateEntity();
+      stateEntity.setClusterId(missedHostComponentState.getClusterId());
+      stateEntity.setComponentName(missedHostComponentState.getComponentName());
+      stateEntity.setServiceName(missedHostComponentState.getServiceName());
+      stateEntity.setHostEntity(missedHostComponentState.getHostEntity());
+      stateEntity.setDesiredState(State.UNKNOWN);
+      stateEntity.setDesiredStack(missedHostComponentState.getCurrentStack());
+      stateEntity.setServiceComponentDesiredStateEntity(missedHostComponentState.getServiceComponentDesiredStateEntity());
+
+      LOG.error("Trying to add missing record in hostcomponentdesiredstate: {}", stateEntity);
+      hostComponentDesiredStateDAO.create(stateEntity);
+    }
+  }
+
+  /**
+  * This method checks db schema name for Postgres.
+  * */
+  public static void checkSchemaName () {
+    Configuration conf = injector.getInstance(Configuration.class);
+    if(conf.getDatabaseType()!=Configuration.DatabaseType.POSTGRES) {
+      return;
+    }
+    LOG.info("Ensuring that the schema set for Postgres is correct");
+    if (connection == null) {
+      if (dbAccessor == null) {
+        dbAccessor = injector.getInstance(DBAccessor.class);
+      }
+      connection = dbAccessor.getConnection();
+    }
+    ResultSet rs = null;
+    try {
+      DatabaseMetaData databaseMetaData = connection.getMetaData();
+
+      rs = databaseMetaData.getSchemas();
+
+      boolean ambariSchemaPresent = false;
+      if (rs != null) {
+        while (rs.next()) {
+          if(StringUtils.equals(rs.getString("TABLE_SCHEM"),conf.getDatabaseSchema())){
+            ambariSchemaPresent = true;
+            break;
+          }
+        }
+      }
+      if (!ambariSchemaPresent){
+        LOG.error("The schema %s defined for Ambari from ambari.properties has not been found in the database. " +
+          "This means that the Ambari tables are stored under the public schema which can lead to problems.", conf.getDatabaseSchema());
+        warningsFound = true;
+      }
+
+    } catch (SQLException e) {
+      LOG.error("Exception occurred during checking db schema name.: ", e);
+    } finally {
+      if (rs != null) {
+        try {
+          rs.close();
+        } catch (SQLException e) {
+          LOG.error("Exception occurred during result set closing procedure: ", e);
+        }
+      }
+    }
+  }
+
+  /**
+  * This method checks tables engine type to be innodb for MySQL.
+  * */
+  public static void checkMySQLEngine () {
+    Configuration conf = injector.getInstance(Configuration.class);
+    if(conf.getDatabaseType()!=Configuration.DatabaseType.MYSQL) {
+      return;
+    }
+    LOG.info("Checking to ensure that the MySQL DB engine type is set to InnoDB");
+    if (connection == null) {
+      if (dbAccessor == null) {
+        dbAccessor = injector.getInstance(DBAccessor.class);
+      }
+      connection = dbAccessor.getConnection();
+    }
+
+    String GET_INNODB_ENGINE_SUPPORT = "select TABLE_NAME, ENGINE from information_schema.tables where TABLE_SCHEMA = '%s' and LOWER(ENGINE) != 'innodb';";
+
+    ResultSet rs = null;
+    Statement statement;
+
+    try {
+      statement = connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
+      rs = statement.executeQuery(String.format(GET_INNODB_ENGINE_SUPPORT, conf.getDatabaseSchema()));
+      if (rs != null) {
+        List<String> tablesInfo = new ArrayList<>();
+        while (rs.next()) {
+          errorsFound = true;
+          tablesInfo.add(rs.getString("TABLE_NAME"));
+        }
+        if (!tablesInfo.isEmpty()){
+          LOG.error("Found tables with engine type that is not InnoDB : %s", StringUtils.join(tablesInfo, ','));
+        }
+      }
+    } catch (SQLException e) {
+      LOG.error("Exception occurred during checking MySQL engine to be innodb: ", e);
+    } finally {
+      if (rs != null) {
+        try {
+          rs.close();
+        } catch (SQLException e) {
+          LOG.error("Exception occurred during result set closing procedure: ", e);
+        }
+      }
+    }
+  }
+
+  /**
   * This method checks several potential problems for services:
   * 1) Check if we have services in cluster which doesn't have service config id(not available in serviceconfig table).
   * 2) Check if service has no mapped configs to it's service config id.

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java
index 6fa36d4..f12dd50 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/checks/DatabaseConsistencyChecker.java
@@ -134,6 +134,7 @@ public class DatabaseConsistencyChecker {
 
           if (DatabaseConsistencyCheckHelper.ifErrorsFound()) {
             System.out.print(String.format("DB configs consistency check failed. Run \"ambari-server start --skip-database-check\" to skip. " +
+                  "You may try --auto-fix-database flag to attempt to fix issues automatically. " +
                   "If you use this \"--skip-database-check\" option, do not make any changes to your cluster topology " +
                   "or perform a cluster upgrade until you correct the database consistency issues. See \"%s\" " +
                   "for more details on the consistency issues.", ambariDBConsistencyCheckLog));

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 1f2a694..23f9dcc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -663,6 +663,9 @@ public class AmbariServer {
       System.out.println("Database consistency check started");
       Logger DB_CHECK_LOG = LoggerFactory.getLogger(DatabaseConsistencyCheckHelper.class);
       try{
+        if (System.getProperty("fixDatabaseConsistency") != null ){
+          DatabaseConsistencyCheckHelper.fixDatabaseConsistency();
+        }
         DatabaseConsistencyCheckHelper.runAllDBChecks();
       } catch(Throwable e) {
         System.out.println("Database consistency check: failed");

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
index 937e872..f96db60 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterConfigEntity.java
@@ -18,6 +18,8 @@
 
 package org.apache.ambari.server.orm.entities;
 
+import com.google.common.base.Objects;
+
 import java.util.Collection;
 
 import javax.persistence.Basic;
@@ -52,6 +54,7 @@ import javax.persistence.UniqueConstraint;
     @NamedQuery(name = "ClusterConfigEntity.findNextConfigVersion", query = "SELECT COALESCE(MAX(clusterConfig.version),0) + 1 as nextVersion FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.type=:configType AND clusterConfig.clusterId=:clusterId"),
     @NamedQuery(name = "ClusterConfigEntity.findAllConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.stack=:stack"),
     @NamedQuery(name = "ClusterConfigEntity.findLatestConfigsByStack", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.clusterId=:clusterId AND clusterConfig.timestamp = (SELECT MAX(clusterConfig2.timestamp) FROM ClusterConfigEntity clusterConfig2 WHERE clusterConfig2.clusterId=:clusterId AND clusterConfig2.stack=:stack AND clusterConfig2.type = clusterConfig.type)"),
+    @NamedQuery(name = "ClusterConfigEntity.findNotMappedClusterConfigsToService", query = "SELECT clusterConfig FROM ClusterConfigEntity clusterConfig WHERE clusterConfig.serviceConfigEntities IS EMPTY AND clusterConfig.type != 'cluster-env'"),
     @NamedQuery(name = "ClusterConfigEntity.findClusterConfigMappingsByStack",
       query = "SELECT mapping FROM ClusterConfigMappingEntity mapping " +
         "JOIN ClusterConfigEntity config ON mapping.typeName = config.type AND mapping.tag = config.tag " +
@@ -266,4 +269,18 @@ public class ClusterConfigEntity {
   public void setServiceConfigEntities(Collection<ServiceConfigEntity> serviceConfigEntities) {
     this.serviceConfigEntities = serviceConfigEntities;
   }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public String toString() {
+    return Objects.toStringHelper(this)
+      .add("clusterId", clusterId)
+      .add("type", type)
+      .add("version", version)
+      .add("tag", tag)
+      .add("timestamp", timestamp)
+      .toString();
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/python/ambari-server.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari-server.py b/ambari-server/src/main/python/ambari-server.py
index ab26c0d..64962d3 100755
--- a/ambari-server/src/main/python/ambari-server.py
+++ b/ambari-server/src/main/python/ambari-server.py
@@ -397,6 +397,7 @@ def init_parser_options(parser):
                     help="Specifies the path to the JDBC driver JAR file")
   parser.add_option('--skip-properties-validation', action="store_true", default=False, help="Skip properties file validation", dest="skip_properties_validation")
   parser.add_option('--skip-database-check', action="store_true", default=False, help="Skip database consistency check", dest="skip_database_check")
+  parser.add_option('--auto-fix-database', action="store_true", default=False, help="Automatically fix database consistency issues", dest="fix_database_consistency")
   add_parser_options('--mpack',
       default=None,
       help="Specify the path for management pack to be installed/upgraded",
@@ -498,6 +499,7 @@ def init_parser_options(parser):
   parser.add_option('--version-display-name', default=None, help="Display name of desired repo version", dest="desired_repo_version")
   parser.add_option('--skip-properties-validation', action="store_true", default=False, help="Skip properties file validation", dest="skip_properties_validation")
   parser.add_option('--skip-database-check', action="store_true", default=False, help="Skip database consistency check", dest="skip_database_check")
+  parser.add_option('--auto-fix-database', action="store_true", default=False, help="Automatically fix database consistency issues", dest="fix_database_consistency")
   parser.add_option('--force-version', action="store_true", default=False, help="Force version to current", dest="force_repo_version")
   parser.add_option('--version', dest="stack_versions", default=None, action="append", type="string",
                     help="Specify stack version that needs to be enabled. All other stacks versions will be disabled")

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/main/python/ambari_server_main.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/python/ambari_server_main.py b/ambari-server/src/main/python/ambari_server_main.py
index 6c77522..a3fb08d 100644
--- a/ambari-server/src/main/python/ambari_server_main.py
+++ b/ambari-server/src/main/python/ambari_server_main.py
@@ -225,6 +225,7 @@ def wait_for_server_start(pidFile, scmStatus):
 
   if 'Database consistency check: failed' in open(configDefaults.SERVER_OUT_FILE).read():
     print "DB configs consistency check failed. Run \"ambari-server start --skip-database-check\" to skip. " \
+    "You may try --auto-fix-database flag to attempt to fix issues automatically. " \
     "If you use this \"--skip-database-check\" option, do not make any changes to your cluster topology " \
     "or perform a cluster upgrade until you correct the database consistency issues. See " + \
           configDefaults.DB_CHECK_LOG + "for more details on the consistency issues."
@@ -337,6 +338,8 @@ def server_process_main(options, scmStatus=None):
     properties.process_pair(CHECK_DATABASE_SKIPPED_PROPERTY, "true")
   else:
     print "Ambari database consistency check started..."
+    if options.fix_database_consistency:
+      jvm_args += " -DfixDatabaseConsistency"
     properties.process_pair(CHECK_DATABASE_SKIPPED_PROPERTY, "false")
 
   update_properties(properties)

http://git-wip-us.apache.org/repos/asf/ambari/blob/6029846c/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java
index 45e319a..d8af35a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java
@@ -19,12 +19,15 @@
 package org.apache.ambari.server.controller;
 
 import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
 import javax.servlet.DispatcherType;
 import javax.servlet.SessionCookieConfig;
 import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.anyString;
 import static org.easymock.EasyMock.createNiceMock;
 import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.partialMockBuilder;
 import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.verify;
 
@@ -34,6 +37,7 @@ import java.net.PasswordAuthentication;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.Statement;
+import java.util.ArrayList;
 import java.util.EnumSet;
 
 import org.apache.ambari.server.AmbariException;
@@ -220,6 +224,16 @@ public class AmbariServerTest {
     AmbariServer ambariServer = new AmbariServer();
 
 
+    final Configuration mockConfiguration = partialMockBuilder(Configuration.class).withConstructor()
+        .addMockedMethod("getDatabaseType").createMock();
+    final TypedQuery mockQuery = easyMockSupport.createNiceMock(TypedQuery.class);
+
+    expect(mockConfiguration.getDatabaseType()).andReturn(null).anyTimes();
+    expect(mockEntityManager.createNamedQuery(anyString(),anyObject(Class.class))).andReturn(mockQuery);
+    expect(mockQuery.getResultList()).andReturn(new ArrayList());
+
+    replay(mockConfiguration);
+
     final Injector mockInjector = Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
@@ -229,6 +243,7 @@ public class AmbariServerTest {
         bind(OsFamily.class).toInstance(mockOSFamily);
         bind(EntityManager.class).toInstance(mockEntityManager);
         bind(Clusters.class).toInstance(mockClusters);
+        bind(Configuration.class).toInstance(mockConfiguration);
       }
     });
 
@@ -281,6 +296,16 @@ public class AmbariServerTest {
     AmbariServer ambariServer = new AmbariServer();
 
 
+    final Configuration mockConfiguration = partialMockBuilder(Configuration.class).withConstructor()
+        .addMockedMethod("getDatabaseType").createMock();
+    final TypedQuery mockQuery = easyMockSupport.createNiceMock(TypedQuery.class);
+
+    expect(mockConfiguration.getDatabaseType()).andReturn(null).anyTimes();
+    expect(mockEntityManager.createNamedQuery(anyString(),anyObject(Class.class))).andReturn(mockQuery);
+    expect(mockQuery.getResultList()).andReturn(new ArrayList());
+
+    replay(mockConfiguration);
+
     final Injector mockInjector = Guice.createInjector(new AbstractModule() {
       @Override
       protected void configure() {
@@ -290,6 +315,7 @@ public class AmbariServerTest {
         bind(OsFamily.class).toInstance(mockOSFamily);
         bind(EntityManager.class).toInstance(mockEntityManager);
         bind(Clusters.class).toInstance(mockClusters);
+        bind(Configuration.class).toInstance(mockConfiguration);
       }
     });