Identify corrupt region file data and self recover

If we identify an invalid offset (negative, or the header sectors),
then back up the region file and erase that specific chunks offset
data.

This will avoid crashing the server with AIOBB errors and also avoids
server owners having to consider the entire region file 'lost'.

I'm not sure what leads to this state, I can only assume write cut
off mid bits.

In this scenario, there is absolutely no way to know where the chunk
actually is in the data file without loading every
single chunk in the file. And even to do that, would be quite extreme
due to the fact the file isn't in some orderly fashion.

Since the file is backed up, the user can use a region fixer tool
externally to try to restore that single chunk. We could even
add a command to restore a chunk from a backup file in a different
commit later on. But this at least prevents the server from crashing.

The server will just generate a new chunk and move on,
after printing an error to the console about it.

Also fixed the case reported in this issue about the server
hanging when a corrupt chunk is encountered, so this issue
is now fully closed.

Resolves #1541
This commit is contained in:
Aikar
2018-10-10 21:28:12 -04:00
parent 7f7b6df9bd
commit ed0d75e389
2 changed files with 99 additions and 18 deletions

View File

@@ -904,7 +904,7 @@ index 98d182fdb8..487d98eb1b 100644
diff --git a/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java b/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java
new file mode 100644
index 0000000000..dabc4184e5
index 0000000000..2dfa59b204
--- /dev/null
+++ b/src/main/java/net/minecraft/server/PaperAsyncChunkProvider.java
@@ -0,0 +0,0 @@
@@ -1420,8 +1420,8 @@ index 0000000000..dabc4184e5
+ }
+ } catch (Exception ex) {
+ MinecraftServer.LOGGER.error("Couldn't load chunk (" +world.getWorld().getName() + ":" + x + "," + z + ")", ex);
+ if (!(ex instanceof IOException)) {
+ loadFinished(null);
+ if (ex instanceof IOException) {
+ generateFinished(null);
+ return;
+ }
+ }