private boolean isStaleConfiguration(Configuration config) { String delimiter = "-"; String configId = config.getId(); // Bypasses item of "global" and folders of "version", just check db configurations. if (configId == null || configId.equals(Constants.GLOBAL_ID) || !configId.contains(delimiter)) { return false; } if (_serviceInfo.getId().endsWith(Constants.STANDALONE_ID)) { if (!configId.equals(_serviceInfo.getId())) { return true; } } else { CoordinatorClientInetAddressMap nodeMap = _coordinator.getInetAddessLookupMap(); int nodeCount = nodeMap.getControllerNodeIPLookupMap().size(); String nodeIndex = configId.split(delimiter)[1]; if (Constants.STANDALONE_ID.equalsIgnoreCase(nodeIndex) || Integer.parseInt(nodeIndex) > nodeCount) { return true; } } return false; }
/** Check offline event info to see if dbsvc/geodbsvc on this node could get started */ private void checkDBOfflineInfo() { Configuration config = _coordinator.queryConfiguration( _coordinator.getSiteId(), Constants.DB_DOWNTIME_TRACKER_CONFIG, _serviceInfo.getName()); DbOfflineEventInfo dbOfflineEventInfo = new DbOfflineEventInfo(config); String localNodeId = _coordinator.getInetAddessLookupMap().getNodeId(); Long lastActiveTimestamp = dbOfflineEventInfo.geLastActiveTimestamp(localNodeId); long zkTimeStamp = (lastActiveTimestamp == null) ? TimeUtils.getCurrentTime() : lastActiveTimestamp; File localDbDir = new File(dbDir); Date lastModified = getLastModified(localDbDir); boolean isDirEmpty = lastModified == null || localDbDir.list().length == 0; long localTimeStamp = (isDirEmpty) ? TimeUtils.getCurrentTime() : lastModified.getTime(); _log.info("Service timestamp in ZK is {}, local file is: {}", zkTimeStamp, localTimeStamp); long diffTime = (zkTimeStamp > localTimeStamp) ? (zkTimeStamp - localTimeStamp) : 0; if (diffTime >= MAX_SERVICE_OUTAGE_TIME) { String errMsg = String.format( "We detect database files on local disk are more than %s days older " + "than last time it was seen in the cluster. It may bring stale data into the database, " + "so the service cannot continue to boot. It may be the result of a VM snapshot rollback. " + "Please contact with EMC support engineer for solution.", diffTime / TimeUtils.DAYS); alertLog.error(errMsg); throw new IllegalStateException(errMsg); } Long offlineTime = dbOfflineEventInfo.getOfflineTimeInMS(localNodeId); if (!isDirEmpty && offlineTime != null && offlineTime >= MAX_SERVICE_OUTAGE_TIME) { String errMsg = String.format( "This node is offline for more than %s days. It may bring stale data into " + "database, so the service cannot continue to boot. Please poweroff this node and follow our " + "node recovery procedure to recover this node", offlineTime / TimeUtils.DAYS); alertLog.error(errMsg); throw new IllegalStateException(errMsg); } }
/** * Checks and registers db configuration information, this is one time when cluster is coming up * for the first time */ private Configuration checkConfiguration() { String configKind = _coordinator.getDbConfigPath(_serviceInfo.getName()); Configuration config = _coordinator.queryConfiguration(_coordinator.getSiteId(), configKind, _serviceInfo.getId()); if (config == null) { // check if it is upgraded from previous version to yoda - configuration may be stored in // zk global area /config. Since SeedProvider still need access that, so we remove the config // from global in migration callback after migration is done. config = _coordinator.queryConfiguration(configKind, _serviceInfo.getId()); if (config != null) { _log.info("Upgrade from pre-yoda release, move dbconfig to new location"); _coordinator.persistServiceConfiguration(_coordinator.getSiteId(), config); return config; } // this is a new node // 1. register its configuration with coordinator // 2. assume autobootstrap configuration // this means that when a node is added, it take 1/2 of biggest token rage and // copies its data over ConfigurationImpl cfg = new ConfigurationImpl(); cfg.setId(_serviceInfo.getId()); cfg.setKind(configKind); cfg.setConfig(DbConfigConstants.NODE_ID, _coordinator.getInetAddessLookupMap().getNodeId()); cfg.setConfig(DbConfigConstants.AUTOBOOT, Boolean.TRUE.toString()); // check other existing db nodes List<Configuration> configs = _coordinator.queryAllConfiguration(_coordinator.getSiteId(), configKind); if (configs.isEmpty()) { // we are the first node - turn off autobootstrap cfg.setConfig(DbConfigConstants.AUTOBOOT, Boolean.FALSE.toString()); } // persist configuration _coordinator.persistServiceConfiguration(_coordinator.getSiteId(), cfg); config = cfg; } return config; }