HBASE-1121 Cluster confused about where -ROOT- is

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hbase/trunk@737213 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Jim Kellerman 2009-01-23 22:37:01 +00:00
parent b634e6a3cb
commit 542abcf26d
12 changed files with 134 additions and 92 deletions

View File

@ -182,10 +182,10 @@
</property> </property>
<property> <property>
<name>hbase.regionserver.hlog.blocksize</name> <name>hbase.regionserver.hlog.blocksize</name>
<value>67108864</value> <value>1048576</value>
<description>Block size for HLog files. To minimize potential data loss, <description>Block size for HLog files. To minimize potential data loss,
the size should be (avg key length) * (avg value length) * flushlogentries. the size should be (avg key length) * (avg value length) * flushlogentries.
Default 64MB. Default 1MB.
</description> </description>
</property> </property>
<property> <property>
@ -232,12 +232,6 @@
Used as sleep interval by service threads such as META scanner and log roller. Used as sleep interval by service threads such as META scanner and log roller.
</description> </description>
</property> </property>
<property>
<name>hbase.regionserver.safemode.period</name>
<value>120000</value>
<description>Time to wait on regionserver startup before beginning
compactions and memcache flushes.</description>
</property>
<property> <property>
<name>hbase.hregion.memcache.flush.size</name> <name>hbase.hregion.memcache.flush.size</name>
<value>67108864</value> <value>67108864</value>

View File

@ -114,23 +114,7 @@ public class HMsg implements Writable {
private Type type = null; private Type type = null;
private HRegionInfo info = null; private HRegionInfo info = null;
private byte[] message = null; private byte[] message = null;
private boolean safeMode = false;
// Some useful statics. Use these rather than create a new HMsg each time.
//TODO: move the following to HRegionServer
public static final HMsg REPORT_EXITING = new HMsg(Type.MSG_REPORT_EXITING);
public static final HMsg REPORT_QUIESCED = new HMsg(Type.MSG_REPORT_QUIESCED);
//TODO: Move to o.a.h.h.master
public static final HMsg REGIONSERVER_QUIESCE =
new HMsg(Type.MSG_REGIONSERVER_QUIESCE);
//TODO: Move to o.a.h.h.master
public static final HMsg REGIONSERVER_STOP =
new HMsg(Type.MSG_REGIONSERVER_STOP);
//TODO: Move to o.a.h.h.master
public static final HMsg CALL_SERVER_STARTUP =
new HMsg(Type.MSG_CALL_SERVER_STARTUP);
//TODO: Move to o.a.h.h.master
public static final HMsg [] EMPTY_HMSG_ARRAY = new HMsg[0];
/** Default constructor. Used during deserialization */ /** Default constructor. Used during deserialization */
public HMsg() { public HMsg() {
@ -138,11 +122,11 @@ public class HMsg implements Writable {
} }
/** /**
* Construct a message with the specified message and HRegionInfo * Construct a message with the specified message and empty HRegionInfo
* @param type Message type * @param type Message type
*/ */
public HMsg(final HMsg.Type type) { public HMsg(final HMsg.Type type) {
this(type, new HRegionInfo(), null); this(type, new HRegionInfo(), null, false);
} }
/** /**
@ -151,7 +135,20 @@ public class HMsg implements Writable {
* @param hri Region to which message <code>type</code> applies * @param hri Region to which message <code>type</code> applies
*/ */
public HMsg(final HMsg.Type type, final HRegionInfo hri) { public HMsg(final HMsg.Type type, final HRegionInfo hri) {
this(type, hri, null); this(type, hri, null, false);
}
/**
* Constructor used by master to inform region servers if we are still in
* safe mode.
*
* @param type
* @param hri
* @param safeMode
*/
public HMsg(final HMsg.Type type, final HRegionInfo hri,
final boolean safeMode) {
this(type, hri, null, safeMode);
} }
/** /**
@ -163,6 +160,19 @@ public class HMsg implements Writable {
* @param msg Optional message (Stringified exception, etc.) * @param msg Optional message (Stringified exception, etc.)
*/ */
public HMsg(final HMsg.Type type, final HRegionInfo hri, final byte[] msg) { public HMsg(final HMsg.Type type, final HRegionInfo hri, final byte[] msg) {
this(type, hri, msg, false);
}
/**
* Used by the master to inform region servers if we are still in safe mode
*
* @param type
* @param hri
* @param msg
* @param safemode
*/
public HMsg(final HMsg.Type type, final HRegionInfo hri, final byte[] msg,
final boolean safemode) {
if (type == null) { if (type == null) {
throw new NullPointerException("Message type cannot be null"); throw new NullPointerException("Message type cannot be null");
} }
@ -172,6 +182,7 @@ public class HMsg implements Writable {
} }
this.info = hri; this.info = hri;
this.message = msg; this.message = msg;
this.safeMode = safemode;
} }
/** /**
@ -198,6 +209,11 @@ public class HMsg implements Writable {
public byte[] getMessage() { public byte[] getMessage() {
return this.message; return this.message;
} }
/** @return safe mode */
public boolean isInSafeMode() {
return this.safeMode;
}
@Override @Override
public String toString() { public String toString() {
@ -211,6 +227,7 @@ public class HMsg implements Writable {
if (this.message != null && this.message.length > 0) { if (this.message != null && this.message.length > 0) {
sb.append(": " + Bytes.toString(this.message)); sb.append(": " + Bytes.toString(this.message));
} }
sb.append(": safeMode=" + safeMode);
return sb.toString(); return sb.toString();
} }
@ -244,6 +261,7 @@ public class HMsg implements Writable {
out.writeBoolean(true); out.writeBoolean(true);
Bytes.writeByteArray(out, this.message); Bytes.writeByteArray(out, this.message);
} }
out.writeBoolean(this.safeMode);
} }
public void readFields(DataInput in) throws IOException { public void readFields(DataInput in) throws IOException {
@ -254,5 +272,6 @@ public class HMsg implements Writable {
if (hasMessage) { if (hasMessage) {
this.message = Bytes.readByteArray(in); this.message = Bytes.readByteArray(in);
} }
this.safeMode = in.readBoolean();
} }
} }

View File

@ -134,6 +134,7 @@ public class HConnectionManager implements HConstants {
private final Map<String, HRegionInterface> servers = private final Map<String, HRegionInterface> servers =
new ConcurrentHashMap<String, HRegionInterface>(); new ConcurrentHashMap<String, HRegionInterface>();
// Used by master and region servers during safe mode only
private volatile HRegionLocation rootRegionLocation; private volatile HRegionLocation rootRegionLocation;
private final Map<Integer, SoftValueSortedMap<byte [], HRegionLocation>> private final Map<Integer, SoftValueSortedMap<byte [], HRegionLocation>>
@ -177,10 +178,12 @@ public class HConnectionManager implements HConstants {
return this.pause * HConstants.RETRY_BACKOFF[ntries]; return this.pause * HConstants.RETRY_BACKOFF[ntries];
} }
// Used by master and region servers during safe mode only
public void unsetRootRegionLocation() { public void unsetRootRegionLocation() {
this.rootRegionLocation = null; this.rootRegionLocation = null;
} }
// Used by master and region servers during safe mode only
public void setRootRegionLocation(HRegionLocation rootRegion) { public void setRootRegionLocation(HRegionLocation rootRegion) {
if (rootRegion == null) { if (rootRegion == null) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
@ -445,7 +448,7 @@ public class HConnectionManager implements HConstants {
// second waits. The second thread will not do find. // second waits. The second thread will not do find.
if (!useCache || rootRegionLocation == null) { if (!useCache || rootRegionLocation == null) {
this.rootRegionLocation = locateRootRegion(); return locateRootRegion();
} }
return rootRegionLocation; return rootRegionLocation;
} }

View File

@ -61,7 +61,7 @@ class ProcessRegionClose extends ProcessRegionStatusChange {
Boolean result = null; Boolean result = null;
if (offlineRegion) { if (offlineRegion) {
result = result =
new RetryableMetaOperation<Boolean>(this.metaRegion, this.master) { new RetryableMetaOperation<Boolean>(getMetaRegion(), this.master) {
public Boolean call() throws IOException { public Boolean call() throws IOException {
LOG.info("region closed: " + regionInfo.getRegionNameAsString()); LOG.info("region closed: " + regionInfo.getRegionNameAsString());

View File

@ -64,7 +64,7 @@ class ProcessRegionOpen extends ProcessRegionStatusChange {
@Override @Override
protected boolean process() throws IOException { protected boolean process() throws IOException {
Boolean result = Boolean result =
new RetryableMetaOperation<Boolean>(this.metaRegion, this.master) { new RetryableMetaOperation<Boolean>(getMetaRegion(), this.master) {
private final RegionHistorian historian = RegionHistorian.getInstance(); private final RegionHistorian historian = RegionHistorian.getInstance();
public Boolean call() throws IOException { public Boolean call() throws IOException {

View File

@ -29,8 +29,8 @@ import org.apache.hadoop.hbase.HRegionInfo;
abstract class ProcessRegionStatusChange extends RegionServerOperation { abstract class ProcessRegionStatusChange extends RegionServerOperation {
protected final boolean isMetaTable; protected final boolean isMetaTable;
protected final HRegionInfo regionInfo; protected final HRegionInfo regionInfo;
protected final MetaRegion metaRegion; private volatile MetaRegion metaRegion = null;
protected final byte [] metaRegionName; protected volatile byte[] metaRegionName = null;
/** /**
* @param master * @param master
@ -40,15 +40,6 @@ abstract class ProcessRegionStatusChange extends RegionServerOperation {
super(master); super(master);
this.regionInfo = regionInfo; this.regionInfo = regionInfo;
this.isMetaTable = regionInfo.isMetaTable(); this.isMetaTable = regionInfo.isMetaTable();
if (isMetaTable) {
this.metaRegionName = HRegionInfo.ROOT_REGIONINFO.getRegionName();
this.metaRegion = new MetaRegion(master.getRootRegionLocation(),
this.metaRegionName, HConstants.EMPTY_START_ROW);
} else {
this.metaRegion =
master.regionManager.getFirstMetaRegionForRegion(regionInfo);
this.metaRegionName = this.metaRegion.getRegionName();
}
} }
protected boolean metaRegionAvailable() { protected boolean metaRegionAvailable() {
@ -71,4 +62,17 @@ abstract class ProcessRegionStatusChange extends RegionServerOperation {
} }
return available; return available;
} }
protected MetaRegion getMetaRegion() {
if (isMetaTable) {
this.metaRegionName = HRegionInfo.ROOT_REGIONINFO.getRegionName();
this.metaRegion = new MetaRegion(master.getRootRegionLocation(),
this.metaRegionName, HConstants.EMPTY_START_ROW);
} else {
this.metaRegion =
master.regionManager.getFirstMetaRegionForRegion(regionInfo);
this.metaRegionName = this.metaRegion.getRegionName();
}
return this.metaRegion;
}
} }

View File

@ -274,7 +274,8 @@ class RegionManager implements HConstants {
" to server " + serverName); " to server " + serverName);
s.setPendingOpen(serverName); s.setPendingOpen(serverName);
this.historian.addRegionAssignment(s.getRegionInfo(), serverName); this.historian.addRegionAssignment(s.getRegionInfo(), serverName);
returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_OPEN, s.getRegionInfo())); returnMsgs.add(
new HMsg(HMsg.Type.MSG_REGION_OPEN, s.getRegionInfo(), inSafeMode()));
if (--nregions <= 0) { if (--nregions <= 0) {
break; break;
} }
@ -401,7 +402,8 @@ class RegionManager implements HConstants {
" to the only server " + serverName); " to the only server " + serverName);
s.setPendingOpen(serverName); s.setPendingOpen(serverName);
this.historian.addRegionAssignment(s.getRegionInfo(), serverName); this.historian.addRegionAssignment(s.getRegionInfo(), serverName);
returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_OPEN, s.getRegionInfo())); returnMsgs.add(
new HMsg(HMsg.Type.MSG_REGION_OPEN, s.getRegionInfo(), inSafeMode()));
} }
} }
@ -440,7 +442,7 @@ class RegionManager implements HConstants {
currentRegion.getRegionNameAsString()); currentRegion.getRegionNameAsString());
// make a message to close the region // make a message to close the region
returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE, currentRegion, returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE, currentRegion,
OVERLOADED)); OVERLOADED, inSafeMode()));
// mark the region as closing // mark the region as closing
setClosing(serverName, currentRegion, false); setClosing(serverName, currentRegion, false);
setPendingClose(currentRegion.getRegionName()); setPendingClose(currentRegion.getRegionName());
@ -901,6 +903,7 @@ class RegionManager implements HConstants {
public boolean inSafeMode() { public boolean inSafeMode() {
if (safeMode) { if (safeMode) {
if(isInitialMetaScanComplete() && regionsInTransition.size() == 0) { if(isInitialMetaScanComplete() && regionsInTransition.size() == 0) {
master.connection.unsetRootRegionLocation();
safeMode = false; safeMode = false;
LOG.info("exiting safe mode"); LOG.info("exiting safe mode");
} else { } else {
@ -1065,7 +1068,7 @@ class RegionManager implements HConstants {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Sending " + msg + " " + pair.getFirst() + " to " + addr); LOG.debug("Sending " + msg + " " + pair.getFirst() + " to " + addr);
} }
returnMsgs.add(new HMsg(msg, pair.getFirst())); returnMsgs.add(new HMsg(msg, pair.getFirst(), inSafeMode()));
i.remove(); i.remove();
} }
} }

View File

@ -44,6 +44,7 @@ import org.apache.hadoop.hbase.Leases;
import org.apache.hadoop.hbase.LeaseListener; import org.apache.hadoop.hbase.LeaseListener;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HMsg.Type;
/** /**
* The ServerManager class manages info about region servers - HServerInfo, * The ServerManager class manages info about region servers - HServerInfo,
@ -52,6 +53,13 @@ import org.apache.hadoop.hbase.HRegionLocation;
class ServerManager implements HConstants { class ServerManager implements HConstants {
static final Log LOG = static final Log LOG =
LogFactory.getLog(ServerManager.class.getName()); LogFactory.getLog(ServerManager.class.getName());
private static final HMsg REGIONSERVER_QUIESCE =
new HMsg(Type.MSG_REGIONSERVER_QUIESCE);
private static final HMsg REGIONSERVER_STOP =
new HMsg(Type.MSG_REGIONSERVER_STOP);
private static final HMsg CALL_SERVER_STARTUP =
new HMsg(Type.MSG_CALL_SERVER_STARTUP);
private static final HMsg [] EMPTY_HMSG_ARRAY = new HMsg[0];
private final AtomicInteger quiescedServers = new AtomicInteger(0); private final AtomicInteger quiescedServers = new AtomicInteger(0);
@ -225,7 +233,7 @@ class ServerManager implements HConstants {
if (msgs.length > 0) { if (msgs.length > 0) {
if (msgs[0].isType(HMsg.Type.MSG_REPORT_EXITING)) { if (msgs[0].isType(HMsg.Type.MSG_REPORT_EXITING)) {
processRegionServerExit(serverName, msgs); processRegionServerExit(serverName, msgs);
return HMsg.EMPTY_HMSG_ARRAY; return EMPTY_HMSG_ARRAY;
} else if (msgs[0].isType(HMsg.Type.MSG_REPORT_QUIESCED)) { } else if (msgs[0].isType(HMsg.Type.MSG_REPORT_QUIESCED)) {
LOG.info("Region server " + serverName + " quiesced"); LOG.info("Region server " + serverName + " quiesced");
quiescedServers.incrementAndGet(); quiescedServers.incrementAndGet();
@ -245,10 +253,10 @@ class ServerManager implements HConstants {
msgs[0].isType(HMsg.Type.MSG_REPORT_QUIESCED)) { msgs[0].isType(HMsg.Type.MSG_REPORT_QUIESCED)) {
// Server is already quiesced, but we aren't ready to shut down // Server is already quiesced, but we aren't ready to shut down
// return empty response // return empty response
return HMsg.EMPTY_HMSG_ARRAY; return EMPTY_HMSG_ARRAY;
} }
// Tell the server to stop serving any user regions // Tell the server to stop serving any user regions
return new HMsg [] {HMsg.REGIONSERVER_QUIESCE}; return new HMsg [] {REGIONSERVER_QUIESCE};
} }
} }
@ -256,7 +264,7 @@ class ServerManager implements HConstants {
// Tell server to shut down if we are shutting down. This should // Tell server to shut down if we are shutting down. This should
// happen after check of MSG_REPORT_EXITING above, since region server // happen after check of MSG_REPORT_EXITING above, since region server
// will send us one of these messages after it gets MSG_REGIONSERVER_STOP // will send us one of these messages after it gets MSG_REGIONSERVER_STOP
return new HMsg [] {HMsg.REGIONSERVER_STOP}; return new HMsg [] {REGIONSERVER_STOP};
} }
HServerInfo storedInfo = serversToServerInfo.get(serverName); HServerInfo storedInfo = serversToServerInfo.get(serverName);
@ -267,7 +275,7 @@ class ServerManager implements HConstants {
// The HBaseMaster may have been restarted. // The HBaseMaster may have been restarted.
// Tell the RegionServer to start over and call regionServerStartup() // Tell the RegionServer to start over and call regionServerStartup()
return new HMsg[]{HMsg.CALL_SERVER_STARTUP}; return new HMsg[]{CALL_SERVER_STARTUP};
} else if (storedInfo.getStartCode() != serverInfo.getStartCode()) { } else if (storedInfo.getStartCode() != serverInfo.getStartCode()) {
// This state is reachable if: // This state is reachable if:
// //
@ -287,7 +295,7 @@ class ServerManager implements HConstants {
serversToServerInfo.notifyAll(); serversToServerInfo.notifyAll();
} }
return new HMsg[]{HMsg.REGIONSERVER_STOP}; return new HMsg[]{REGIONSERVER_STOP};
} else { } else {
return processRegionServerAllsWell(serverName, serverInfo, return processRegionServerAllsWell(serverName, serverInfo,
mostLoadedRegions, msgs); mostLoadedRegions, msgs);
@ -436,7 +444,8 @@ class ServerManager implements HConstants {
synchronized (master.regionManager) { synchronized (master.regionManager) {
// Tell the region server to close regions that we have marked for closing. // Tell the region server to close regions that we have marked for closing.
for (HRegionInfo i: master.regionManager.getMarkedToClose(serverName)) { for (HRegionInfo i: master.regionManager.getMarkedToClose(serverName)) {
returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE, i)); returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE, i,
master.regionManager.inSafeMode()));
// Transition the region from toClose to closing state // Transition the region from toClose to closing state
master.regionManager.setPendingClose(i.getRegionName()); master.regionManager.setPendingClose(i.getRegionName());
} }
@ -531,7 +540,8 @@ class ServerManager implements HConstants {
// Otherwise the HMaster will think the Region was closed on purpose, // Otherwise the HMaster will think the Region was closed on purpose,
// and then try to reopen it elsewhere; that's not what we want. // and then try to reopen it elsewhere; that's not what we want.
returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE_WITHOUT_REPORT, returnMsgs.add(new HMsg(HMsg.Type.MSG_REGION_CLOSE_WITHOUT_REPORT,
region, "Duplicate assignment".getBytes())); region, "Duplicate assignment".getBytes(),
master.regionManager.inSafeMode()));
} else { } else {
if (region.isRootRegion()) { if (region.isRootRegion()) {
// it was assigned, and it's not a duplicate assignment, so take it out // it was assigned, and it's not a duplicate assignment, so take it out
@ -540,8 +550,10 @@ class ServerManager implements HConstants {
// Store the Root Region location (in memory) // Store the Root Region location (in memory)
HServerAddress rootServer = serverInfo.getServerAddress(); HServerAddress rootServer = serverInfo.getServerAddress();
master.connection.setRootRegionLocation( if (master.regionManager.inSafeMode()) {
new HRegionLocation(region, rootServer)); master.connection.setRootRegionLocation(
new HRegionLocation(region, rootServer));
}
master.regionManager.setRootRegionLocation(rootServer); master.regionManager.setRootRegionLocation(rootServer);
} else { } else {
// Note that the table has been assigned and is waiting for the // Note that the table has been assigned and is waiting for the
@ -564,7 +576,6 @@ class ServerManager implements HConstants {
synchronized (master.regionManager) { synchronized (master.regionManager) {
if (region.isRootRegion()) { if (region.isRootRegion()) {
// Root region // Root region
master.connection.unsetRootRegionLocation();
master.regionManager.unsetRootRegion(); master.regionManager.unsetRootRegion();
if (region.isOffline()) { if (region.isOffline()) {
// Can't proceed without root region. Shutdown. // Can't proceed without root region. Shutdown.

View File

@ -173,7 +173,7 @@ public class HLog implements HConstants, Syncable {
this.flushlogentries = this.flushlogentries =
conf.getInt("hbase.regionserver.flushlogentries", 100); conf.getInt("hbase.regionserver.flushlogentries", 100);
this.blocksize = this.blocksize =
conf.getLong("hbase.regionserver.hlog.blocksize", 1024L * 1024L * 64L); conf.getLong("hbase.regionserver.hlog.blocksize", 1024L * 1024L);
this.optionalFlushInterval = this.optionalFlushInterval =
conf.getLong("hbase.regionserver.optionallogflushinterval", 10 * 1000); conf.getLong("hbase.regionserver.optionallogflushinterval", 10 * 1000);
this.threadWakeFrequency = conf.getLong(THREAD_WAKE_FREQUENCY, 10 * 1000); this.threadWakeFrequency = conf.getLong(THREAD_WAKE_FREQUENCY, 10 * 1000);

View File

@ -109,6 +109,8 @@ import org.apache.hadoop.util.StringUtils;
*/ */
public class HRegionServer implements HConstants, HRegionInterface, Runnable { public class HRegionServer implements HConstants, HRegionInterface, Runnable {
static final Log LOG = LogFactory.getLog(HRegionServer.class); static final Log LOG = LogFactory.getLog(HRegionServer.class);
private static final HMsg REPORT_EXITING = new HMsg(Type.MSG_REPORT_EXITING);
private static final HMsg REPORT_QUIESCED = new HMsg(Type.MSG_REPORT_QUIESCED);
// Set when a report to the master comes back with a message asking us to // Set when a report to the master comes back with a message asking us to
// shutdown. Also set by call to stop when debugging or running unit tests // shutdown. Also set by call to stop when debugging or running unit tests
@ -200,8 +202,8 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
final LogRoller logRoller; final LogRoller logRoller;
final LogFlusher logFlusher; final LogFlusher logFlusher;
// safemode processing // limit compactions while starting up
SafeModeThread safeModeThread; CompactionLimitThread compactionLimitThread;
// flag set after we're done setting up server threads (used for testing) // flag set after we're done setting up server threads (used for testing)
protected volatile boolean isOnline; protected volatile boolean isOnline;
@ -317,7 +319,7 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
haveRootRegion.set(true); haveRootRegion.set(true);
} }
} }
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
if (lastMsg != 0 && (now - lastMsg) >= serverLeaseTimeout) { if (lastMsg != 0 && (now - lastMsg) >= serverLeaseTimeout) {
// It has been way too long since we last reported to the master. // It has been way too long since we last reported to the master.
LOG.warn("unable to report to master for " + (now - lastMsg) + LOG.warn("unable to report to master for " + (now - lastMsg) +
@ -361,6 +363,15 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
!restart && !stopRequested.get() && i < msgs.length; !restart && !stopRequested.get() && i < msgs.length;
i++) { i++) {
LOG.info(msgs[i].toString()); LOG.info(msgs[i].toString());
if (safeMode.get()) {
if (!msgs[i].isInSafeMode()) {
this.connection.unsetRootRegionLocation();
synchronized (safeMode) {
safeMode.set(false);
safeMode.notifyAll();
}
}
}
switch(msgs[i].getType()) { switch(msgs[i].getType()) {
case MSG_CALL_SERVER_STARTUP: case MSG_CALL_SERVER_STARTUP:
// We the MSG_CALL_SERVER_STARTUP on startup but we can also // We the MSG_CALL_SERVER_STARTUP on startup but we can also
@ -503,7 +514,7 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
} }
try { try {
HMsg[] exitMsg = new HMsg[closedRegions.size() + 1]; HMsg[] exitMsg = new HMsg[closedRegions.size() + 1];
exitMsg[0] = HMsg.REPORT_EXITING; exitMsg[0] = REPORT_EXITING;
// Tell the master what regions we are/were serving // Tell the master what regions we are/were serving
int i = 1; int i = 1;
for (HRegion region: closedRegions) { for (HRegion region: closedRegions) {
@ -729,30 +740,24 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
/** /**
* Thread for toggling safemode after some configurable interval. * Thread for toggling safemode after some configurable interval.
*/ */
private class SafeModeThread extends Thread { private class CompactionLimitThread extends Thread {
@Override @Override
public void run() { public void run() {
// first, wait the required interval before turning off safemode // First wait until we exit safe mode
int safemodeInterval = synchronized (safeMode) {
conf.getInt("hbase.regionserver.safemode.period", 120 * 1000); while(safeMode.get()) {
try { LOG.debug("Waiting to exit safe mode");
Thread.sleep(safemodeInterval); try {
} catch (InterruptedException ex) { safeMode.wait();
// turn off safemode and limits on the way out due to some kind of } catch (InterruptedException e) {
// abnormal condition so we do not prevent such things as memcache // ignore
// flushes and worsen the situation }
safeMode.set(false);
compactSplitThread.setLimit(-1);
if (LOG.isDebugEnabled()) {
LOG.debug(this.getName() + " exiting on interrupt");
} }
return;
} }
LOG.info("leaving safe mode");
safeMode.set(false);
// now that safemode is off, slowly increase the per-cycle compaction // now that safemode is off, slowly increase the per-cycle compaction
// limit, finally setting it to unlimited (-1) // limit, finally setting it to unlimited (-1)
int compactionCheckInterval = int compactionCheckInterval =
conf.getInt("hbase.regionserver.thread.splitcompactcheckfrequency", conf.getInt("hbase.regionserver.thread.splitcompactcheckfrequency",
20 * 1000); 20 * 1000);
@ -1006,13 +1011,13 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
} }
// Set up the safe mode handler if safe mode has been configured. // Set up the safe mode handler if safe mode has been configured.
if (conf.getInt("hbase.regionserver.safemode.period", 0) < 1) { if (!conf.getBoolean("hbase.regionserver.safemode", true)) {
safeMode.set(false); safeMode.set(false);
compactSplitThread.setLimit(-1); compactSplitThread.setLimit(-1);
LOG.debug("skipping safe mode"); LOG.debug("skipping safe mode");
} else { } else {
this.safeModeThread = new SafeModeThread(); this.compactionLimitThread = new CompactionLimitThread();
Threads.setDaemonThreadRunning(this.safeModeThread, n + ".safeMode", Threads.setDaemonThreadRunning(this.compactionLimitThread, n + ".safeMode",
handler); handler);
} }
@ -1482,9 +1487,9 @@ public class HRegionServer implements HConstants, HRegionInterface, Runnable {
} }
this.quiesced.set(true); this.quiesced.set(true);
if (onlineRegions.size() == 0) { if (onlineRegions.size() == 0) {
outboundMsgs.add(HMsg.REPORT_EXITING); outboundMsgs.add(REPORT_EXITING);
} else { } else {
outboundMsgs.add(HMsg.REPORT_QUIESCED); outboundMsgs.add(REPORT_QUIESCED);
} }
} }

View File

@ -97,6 +97,14 @@
invoking an optional cache flush. Default 60,000. invoking an optional cache flush. Default 60,000.
</description> </description>
</property> </property>
<property>
<name>hbase.regionserver.safemode</name>
<value>false</value>
<description>
Turn on/off safe mode in region server. Always on for production, always off
for tests.
</description>
</property>
<property> <property>
<name>hbase.hregion.max.filesize</name> <name>hbase.hregion.max.filesize</name>
<value>67108864</value> <value>67108864</value>
@ -111,11 +119,4 @@
<name>hadoop.log.dir</name> <name>hadoop.log.dir</name>
<value>${user.dir}/../logs</value> <value>${user.dir}/../logs</value>
</property> </property>
<property>
<name>hbase.regionserver.safemode.period</name>
<value>0</value>
<description>Time to wait on regionserver startup before beginning
compactions and memcache flushes.
</description>
</property>
</configuration> </configuration>

View File

@ -33,10 +33,12 @@ import org.apache.hadoop.hbase.util.Writables;
*/ */
public class TestSerialization extends HBaseTestCase { public class TestSerialization extends HBaseTestCase {
@Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
} }
@Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
super.tearDown(); super.tearDown();
} }
@ -53,7 +55,7 @@ public class TestSerialization extends HBaseTestCase {
} }
public void testHMsg() throws Exception { public void testHMsg() throws Exception {
HMsg m = HMsg.REGIONSERVER_QUIESCE; HMsg m = new HMsg(HMsg.Type.MSG_REGIONSERVER_QUIESCE);
byte [] mb = Writables.getBytes(m); byte [] mb = Writables.getBytes(m);
HMsg deserializedHMsg = (HMsg)Writables.getWritable(mb, new HMsg()); HMsg deserializedHMsg = (HMsg)Writables.getWritable(mb, new HMsg());
assertTrue(m.equals(deserializedHMsg)); assertTrue(m.equals(deserializedHMsg));