-
Notifications
You must be signed in to change notification settings - Fork 25.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Run CheckIndex on metadata index before loading #73239
Changes from 1 commit
fb88d31
02b05af
268fbd5
e619f05
9fb364c
95378d2
9e89fed
e28fdf4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ | |
import org.apache.lucene.document.Field; | ||
import org.apache.lucene.document.StoredField; | ||
import org.apache.lucene.document.StringField; | ||
import org.apache.lucene.index.CheckIndex; | ||
import org.apache.lucene.index.DirectoryReader; | ||
import org.apache.lucene.index.IndexNotFoundException; | ||
import org.apache.lucene.index.IndexWriter; | ||
|
@@ -46,6 +47,7 @@ | |
import org.elasticsearch.common.bytes.BytesReference; | ||
import org.elasticsearch.common.bytes.RecyclingBytesStreamOutput; | ||
import org.elasticsearch.common.io.Streams; | ||
import org.elasticsearch.common.io.stream.BytesStreamOutput; | ||
import org.elasticsearch.common.lease.Releasable; | ||
import org.elasticsearch.common.lease.Releasables; | ||
import org.elasticsearch.common.logging.Loggers; | ||
|
@@ -70,6 +72,8 @@ | |
import java.io.Closeable; | ||
import java.io.IOError; | ||
import java.io.IOException; | ||
import java.io.PrintStream; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
|
@@ -291,17 +295,45 @@ public static void overrideVersion(Version newVersion, Path... dataPaths) throws | |
* Loads the available on-disk cluster state. Returns {@link OnDiskState#NO_ON_DISK_STATE} if no such state was found. | ||
*/ | ||
public OnDiskState loadOnDiskState() throws IOException { | ||
return loadOnDiskState(true); | ||
} | ||
|
||
/** | ||
* Loads the available on-disk cluster state. Returns {@link OnDiskState#NO_ON_DISK_STATE} if no such state was found. | ||
* @param checkClean whether to check the index for corruption before loading, only for tests | ||
*/ | ||
OnDiskState loadOnDiskState(boolean checkClean) throws IOException { | ||
OnDiskState onDiskState = OnDiskState.NO_ON_DISK_STATE; | ||
|
||
final Path indexPath = dataPath.resolve(METADATA_DIRECTORY_NAME); | ||
if (Files.exists(indexPath)) { | ||
try (Directory directory = createDirectory(indexPath); | ||
DirectoryReader directoryReader = DirectoryReader.open(directory)) { | ||
onDiskState = loadOnDiskState(dataPath, directoryReader); | ||
try (Directory directory = createDirectory(indexPath)) { | ||
if (checkClean) { | ||
try (BytesStreamOutput outputStream = new BytesStreamOutput()) { | ||
final boolean isClean; | ||
try (PrintStream printStream = new PrintStream(outputStream, true, StandardCharsets.UTF_8); | ||
CheckIndex checkIndex = new CheckIndex(directory)) { | ||
checkIndex.setInfoStream(printStream); | ||
checkIndex.setChecksumsOnly(true); | ||
isClean = checkIndex.checkIndex().clean; | ||
} | ||
|
||
if (nodeId.equals(onDiskState.nodeId) == false) { | ||
throw new IllegalStateException("unexpected node ID in metadata, found [" + onDiskState.nodeId + | ||
"] in [" + dataPath + "] but expected [" + nodeId + "]"); | ||
if (isClean == false) { | ||
if (logger.isErrorEnabled()) { | ||
outputStream.bytes().utf8ToString().lines().forEach(l -> logger.error("checkIndex: {}", l)); | ||
} | ||
throw new IllegalStateException("metadata index at [" + indexPath + "] is unreadable"); | ||
} | ||
} | ||
} | ||
|
||
try (DirectoryReader directoryReader = DirectoryReader.open(directory)) { | ||
onDiskState = loadOnDiskState(dataPath, directoryReader); | ||
|
||
if (nodeId.equals(onDiskState.nodeId) == false) { | ||
throw new IllegalStateException("unexpected node ID in metadata, found [" + onDiskState.nodeId + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You had to be doing something pretty weird to hit this message anyway, and doubly so today since the node IDs that we're comparing both come from the user-data from the latest commit of this index. Harmonised with the other message in 9e89fed. |
||
"] in [" + dataPath + "] but expected [" + nodeId + "]"); | ||
} | ||
} | ||
} catch (IndexNotFoundException e) { | ||
logger.debug(new ParameterizedMessage("no on-disk state at {}", indexPath), e); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't great: we materialise all the bytes, then convert them to a string, and then split them into lines. A streaming implementation is definitely possible but doesn't seem worth the effort here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.