[ 
https://issues.apache.org/jira/browse/HDFS-3004?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13240215#comment-13240215
 ] 

Todd Lipcon commented on HDFS-3004:
-----------------------------------

{code}
+    } catch (IOException e) {
+      return null;
{code}
This shows up a few places and makes me nervous. We should always at least 
LOG.warn an exception.

----
{code}
+            if (op.getTransactionId() > expectedTxId) { 
+              askOperator("There appears to be a gap in the edit log.  " +
+                  "We expected txid " + expectedTxId + ", but got txid " +
+                  op.getTransactionId() + ".", recovery, "skipping bad edit");
+            } else if (op.getTransactionId() < expectedTxId) { 
+              askOperator("There appears to be an out-of-order edit in " +
+                  "the edit log.  We expected txid " + expectedTxId +
+                  ", but got txid " + op.getTransactionId() + ".", recovery,
+                  "applying edits");
+              continue;
{code}
Am I reading this wrong, or is the logic backwards? It seems like the first 
prompt allows you to say "continue, skipping bad edit", but doesn't call 
continue (thus applying the bad edit). The second one gives you the choice 
"continue, applying edits" but *does* skip the bad one.

----
{code}
+          catch (Throwable e) {
+            askOperator("Failed to apply edit log operation " +
+              op.getTransactionIdStr() + ": error " + e.getMessage(),
+              recovery, "applying edits");
{code}
Here we no longer output the stack trace of the exception anywhere. That's 
often a big problem - we really need the exception trace to understand the root 
cause and to know whether we might be able to skip it.

- I would also recommend printing the op.toString() itself in all of these 
cases, not just the txids. That gives the operator something to base their 
decision on. I think we have a reasonable stringification of all ops nowdays.

----
{code}
-          LOG.info(String.format("Log begins at txid %d, but requested start "
-              + "txid is %d. Skipping %d edits.", elf.getFirstTxId(), fromTxId,
-              transactionsToSkip));
-          elfis.skipTransactions(transactionsToSkip);
+        // TODO: add recovery mode override here as part of edit log failover
+        if (elfis.skipUntil(fromTxId) == false) {
{code}
Please leave the log message in place here. Also, in the failure log message 
here, I think you should (a) throw EditLogInputException, and (b) include the 
file path here


----
{code}
+          /* Now that the operation has been successfully decoded and
+           * applied, update our bookkeeping. */
{code}
style: use // comments inline in code, not /* */ generally. There are a couple 
other places where you should make the same fix.

----
- There are still a few spurious whitespace changes unrelated to your code 
here. Not a big deal, but best to remove those hunks from your patch.

----

{code}
+   * Get the next valid operation from the stream storage
+   * 
+   * This is exactly like nextOp, except that we attempt to skip over damaged
+   * parts of the edit log
{code}
Please add '.'s at the end of the sentences in the docs. It's annoying, but the 
way JavaDoc gets formatted, all the sentences will run together without line 
breaks in many cases, so the punctuation's actually important for readability.
----

{code}
+   * @return        Returns true if we found a transaction ID greater than
+   *                'txid' in the log.
+   */
+  public boolean skipUntil(long txid) throws IOException {
{code}
The javadoc should say "greater than or equal to", right? Also, I think the doc 
should specify explicitly: "the next call to readOp() will usually return the 
transaction with the specified txid, unless the log contains a gap, in which 
case it may return a higher one."

----
{code}
+  private ThreadLocal <OpInstanceCache> cache = new 
ThreadLocal<OpInstanceCache>() {
{code}
Style: no space between "ThreadLocal" and '<'. Also the line's a bit long (we 
try to keep to 80 characters unless it's really hard not to)

----
{code}
+            if (op == null)
               break;
{code}
Style: we use {} braces even for one-line if statements. There are a few other 
examples of this too.

{code}
+          }
+          catch (Throwable e) {
{code}
catch clause goes on same line as '}'

----
{code}
+    if (txid == HdfsConstants.INVALID_TXID) {
+      throw new RuntimeException("operation has no txid");
{code}
Use {{Preconditions.checkState()}} here for better readability

----
{code}
+        LOG.error("automatically choosing " + firstChoice);
{code}
this should probably be INFO or WARN
----

Style: please add a blank line between functions in RecoveryContext.java

----
TestNameNodeRecovery:
- do we need data nodes in these tests? if it's just metadata ops, 0 DNs should 
be fine
- move the EditLogTestSetup interface down lower in the file, just above where 
you define the implementations
- extra space between {{interface}} and {{EditLogTestSetup}}
- please add blank lines between functions in that interface, and expand the 
javadoc out so the {{/**}} line is on its own, like the rest of the codebase
- removeFromArray -- really this is {{markTxnIdFound}} where {{-1}} is used as 
a mark, right? I think it might be much clearer to just use Set<Integer> here 
and remove the ints from the set -- that's essentially what you're doing?
- some funky indentation in a few places
- rather than catching, logging, and calling fail(), you can just let the 
Throwable pass out of the test case - that'll also fail the test case, with the 
advantage that the stack trace of the failure becomes clickable in IDEs
- tip: you can use StringUtils.stirngifyException to get an exception's stack 
trace into a String without StringWriter
- instead of the if (stream != null) checks, you can use IOUtils.closeStream, 
or IOUtils.cleanup, which takes care of that for you

                
> Implement Recovery Mode
> -----------------------
>
>                 Key: HDFS-3004
>                 URL: https://issues.apache.org/jira/browse/HDFS-3004
>             Project: Hadoop HDFS
>          Issue Type: New Feature
>          Components: tools
>            Reporter: Colin Patrick McCabe
>            Assignee: Colin Patrick McCabe
>         Attachments: HDFS-3004.010.patch, HDFS-3004.011.patch, 
> HDFS-3004.012.patch, HDFS-3004.013.patch, HDFS-3004.015.patch, 
> HDFS-3004.016.patch, HDFS-3004.017.patch, HDFS-3004.018.patch, 
> HDFS-3004.019.patch, HDFS-3004.020.patch, HDFS-3004.022.patch, 
> HDFS-3004.023.patch, HDFS-3004.024.patch, HDFS-3004.026.patch, 
> HDFS-3004.027.patch, HDFS-3004.029.patch, HDFS-3004.030.patch, 
> HDFS-3004.031.patch, HDFS-3004.032.patch, HDFS-3004.033.patch, 
> HDFS-3004__namenode_recovery_tool.txt
>
>
> When the NameNode metadata is corrupt for some reason, we want to be able to 
> fix it.  Obviously, we would prefer never to get in this case.  In a perfect 
> world, we never would.  However, bad data on disk can happen from time to 
> time, because of hardware errors or misconfigurations.  In the past we have 
> had to correct it manually, which is time-consuming and which can result in 
> downtime.
> Recovery mode is initialized by the system administrator.  When the NameNode 
> starts up in Recovery Mode, it will try to load the FSImage file, apply all 
> the edits from the edits log, and then write out a new image.  Then it will 
> shut down.
> Unlike in the normal startup process, the recovery mode startup process will 
> be interactive.  When the NameNode finds something that is inconsistent, it 
> will prompt the operator as to what it should do.   The operator can also 
> choose to take the first option for all prompts by starting up with the '-f' 
> flag, or typing 'a' at one of the prompts.
> I have reused as much code as possible from the NameNode in this tool.  
> Hopefully, the effort that was spent developing this will also make the 
> NameNode editLog and image processing even more robust than it already is.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to