Skip to main content

Database Corruption

By default, CoreProtect makes use of a locally stored SQLite database to store the log data that it generates about your world. This file is subject to corruption if you mishandle it or if the server itself encounters an error. This will result in CoreProtect being unable to write or read data to or from the database and will print the following error to your server log:

Tested On...

The content covered in this article shouldn't change much between versions of Minecraft or CoreProtect, but the behavior and outputs of some commands might. So for reference, this article was tested and written on information gathered from a 1.20.4 Minecraft server running CoreProtect 22.2.

[18:48:34 WARN]: org.sqlite.SQLiteException: [SQLITE_CORRUPT] The database disk image is malformed (database disk image is malformed)
[18:48:34 WARN]: at org.sqlite.core.DB.newSQLException(DB.java:1179)
[18:48:34 WARN]: at org.sqlite.core.DB.newSQLException(DB.java:1190)
[18:48:34 WARN]: at org.sqlite.core.DB.throwex(DB.java:1150)
[18:48:34 WARN]: at org.sqlite.core.DB.executeBatch(DB.java:951)
[18:48:34 WARN]: at org.sqlite.core.DB.lambda$executeBatch$0(DB.java:916)
[18:48:34 WARN]: at org.sqlite.core.SafeStmtPtr.safeRun(SafeStmtPtr.java:128)
[18:48:34 WARN]: at org.sqlite.core.DB.executeBatch(DB.java:916)
[18:48:34 WARN]: at org.sqlite.core.CorePreparedStatement.lambda$executeLargeBatch$1(CorePreparedStatement.java:76)
[18:48:34 WARN]: at org.sqlite.jdbc3.JDBC3Statement.withConnectionTimeout(JDBC3Statement.java:454)
[18:48:34 WARN]: at org.sqlite.core.CorePreparedStatement.executeLargeBatch(CorePreparedStatement.java:72)
[18:48:34 WARN]: at org.sqlite.core.CorePreparedStatement.executeBatch(CorePreparedStatement.java:58)
[18:48:34 WARN]: at coreprotect-21_2.jar//net.coreprotect.consumer.process.Process.commit(Process.java:283)
[18:48:34 WARN]: at coreprotect-21_2.jar//net.coreprotect.consumer.process.Process.processConsumer(Process.java:248)
[18:48:34 WARN]: at coreprotect-21_2.jar//net.coreprotect.consumer.Consumer.run(Consumer.java:133)
[18:48:34 WARN]: at java.base/java.lang.Thread.run(Thread.java:840)

At this point, a significant portion of your data is probably lost, but you may be able to recover some of it by following the steps in this section. If you aren't worried about losing existing data, you can just delete your stored data by following the steps in this section.

Prevention is better than cure

If you haven't encountered this error yet, or want to avoid it in the future, you can prevent it under common circumstances by following the practices outlined in this section.

SQLite Error Codes

The error code in the log shown above, [SQLITE_CORRUPT], is part of the SQLite Error Code and has a very specific definition in the SQLite Result and Error Codes document. You can find the [SQLITE_CORRUPT] entry here, where it also links a detailed explanation on the general circumstances that can lead to database corruption.

Fixing

Whether or not you're able to recover any data from your database after it's been corrupted is a matter of your preparation, how the corruption presents itself, and where the actual corruption is within the file. Each of the sections below cover a different method of trying to remove the corruption from your database, with the final option being to delete the database to restore functionality to CoreProtect.

Precautions

Before you start trying to fix your database, you need to make sure you have done the following.

  1. Backed up your entire server
  2. Made a separate backup of your corrupted database
  3. Have moved both the server backup and database backup to a separate machine from the server

Doing the above steps ensures that if any of the below sections fail, you can try another one on a copy of the backed-up database, while also protecting your server from any potential damage that could happen during following the steps.

backup your server!

Follow the above recommendations and backup your server! Not doing so could result in more damage to your server!
If you aren't sure how, check out this article on server backups.

Purging corrupt data - simple

CoreProtect has a built-in method of fixing some basic corruption, and you might be able to easily fix small amounts by using it's purge command. The CoreProtect purge command copies each row to a new database after checking if it matches the parameters provided in the purge, if it's unable to read the row it wll try to fix the row and then discard the row if it can't. This will result in the corrupted rows being lost, and may not fix some types of corruption. The best way to avoid loosing data is to prevent the corruption in the first place.

After following the above steps for safely backing up your database, you can try running the /co purge command with a time greater than the age of your database. For example, if your database is a year old, you can run a purge for 400 days using the command /co purge t:400d.

This method won't always work and will result in some rows being removed. If it doesn't work, try one of the methods below.

SQLite CLI - complex

The SQLite library provides a CLI (Command Line Interface) utility that includes a recovery tool for corrupted databases. This tool is more robust than the one built into CoreProtect and has a better chance of restoring your database to at least a functioning state.
As a result of the way corruption affects SQLite databases, there's no guarantee that this will result in a database with data that makes sense, but it should at least be readable by CoreProtect. Depending on how the corruption presents itself, IE what exactly in the structure of the database was corrupted, you may end up with a complete restoration of the data or with some of the data being jumbled, misplaced, or incoherent. The best way to avoid this outcome is to prevent the corruption in the first place.

To use the tool you'll need to follow the steps under the Precautions section, where you'll make a backup of your server and database, then you'll want to download a copy of your corrupted database to your PC. With the backup complete and a copy of the database downloaded locally, you'll need to download the SQLite CLI from their website here, where you'll be looking for the file prefixed sqlite-tools- and then your operating system, IE for Windows it's sqlite-tools-win-x64-####.zip under the header "Precompiled Binaries for Windows".
It'll be a .zip file, so you'll need to extract it to get the executable file for the CLI. Within the extracted .zip folder, the executable file will be named sqlite3 and should be moved into the same directory as your database.

After extracting the precompiled binaries and moving the sqlite3 file into a directory with your database.db file, you'll want to open a command prompt window inside of that directory. On Windows, you can do this by clicking inside of the Address Bar, typing cmd, then pressing the enter key.

Inside the command window, you'll want to type a command similar to this one, sqlite3 database.db .recover >database-output.sql. This will generate a .sql file that contains instructions to rebuild your database and will be at least twice the current size of your database.

disk space

These SQLite commands will use a lot of disk space! Plan to store at least 4 times the size of your database!

When that command finishes you'll want to rebuild the database using the following command, sqlite3 recovered.db <database-output.sql. This will build a new .db file named recovered.db that you can upload to your server under the /plugins/coreprotect/ folder, rename back to database.db and check if it works.

If this doesn't, your final option is to delete the database.

Deleting the database

If none of the above steps work then your data is most likely lost, so you'll need to delete the database so that CoreProtect can log new data. Since CoreProtect uses the database to store all of the logs it collects about your world, you won't be able to rollback anything that happened before now, but it will start tracking new events that take place on the server.

You'll need to stop your server and delete the database file located at /plugins/CoreProtect/database.db then follow the steps outlined in the section on prevention below.

Prevention

Recovering from a corrupted database is no sure thing, and will always result in some lost data. The best method of dealing with a corrupted database is to prevent it, and the second best is to restore to a backup. You can find information on both of these below.

When making a backup

The most common way of corrupting an SQLite database is by modifying it while it's in use, and since CoreProtect V21 (available for Minecraft 1.14+), CoreProtect provides a way to pause it's database access, otherwise known as a consumer. You can use this to take backups of your CoreProtect database so that you're prepared when another error might occur.

If you take a backup of your CoreProtect database while the server is online and CoreProtect is writing to or reading from the database then the copy of the database will be corrupted. As a result, you won't have a working CoreProtect database when you restore your server from a backup.

V21+

In CoreProtect version 21 and higher, you can tell CoreProtect to stop interacting with the database using the /co consumer command.

Pausing the consumer will tell CoreProtect to not write to the database and will let you back up the SQLite database file as part of your normal backup process without corrupting the backed up file. You can then restore to the backed up database without worrying about data loss.

pre-V21

Prior to CoreProtect version 21, you need to stop the server before backing up the database. Taking any backup of the SQLite database while the server is online will result in the backup's database being corrupted and unusable.

When upgrading/updating/transferring your server

The biggest mistake you can make while messing with your server files as part of an upgrade, update, or transfer, is to do it while the server is online. Moving around server files, especially world and plugin data files while they're being written to, will inevitably result in corruption. The easiest way to avoid this is to stop the server before you download or change any files on your server.

When a general server error is encountered

If an unexpected error has occurred, like your disk filling up, a server crash, or complete loss of your server data, your only respite will be your backup. You should always take backups of your server, and this section provides information on how to take a backup of the CoreProtect database. If you aren't sure how to take backups, check out our articles on DriveBackupV2 and our Game Server backup script example.

Reach Out!

Have Questions? Need Help? Feel free to reach out!

Join our Discord