Continuous Backup

See Best Practices: Dev / Test / Prod for environment-specific recommendations.

By default, the continuous backup is disabled. If enabled the EclipseStore instance will clone all changes to another directory. The backup is identical to the primary EclipseStore storage.

To enable the continuous backup just set the backup directory:

With storage-embedded-configuration API:

Java
EmbeddedStorageManager storageManager = EmbeddedStorageConfigurationBuilder.New()
	.setBackupDirectory("A safe place")
	.createEmbeddedStorageFoundation()
	.createEmbeddedStorageManager();
XML
<properties>
	<property name="backup-directory" value ="/save/backup" />
	...
</properties>
INI
backupDirectory = backupDir

With EclipseStore foundation classes:

Java
NioFileSystem      fileSystem  = NioFileSystem.New();

StorageBackupSetup backupSetup = StorageBackupSetup.New(
	Storage.BackupFileProviderBuilder(fileSystem)
		.setDirectory(fileSystem.ensureDirectoryPath(BACKUPDIR))
		.setTruncationDirectory(fileSystem.ensureDirectoryPath(TRUNCATIONDIR))
		.setDeletionDirectory(fileSystem.ensureDirectoryPath(DELETIONDIR))
		.createFileProvider()
);

StorageConfiguration configuration = StorageConfiguration.Builder()
	.setBackupSetup(backupSetup)
	.setStorageFileProvider(StorageLiveFileProvider.New(
		fileSystem.ensureDirectoryPath(WORKINGDIR)
	))
	.createConfiguration()
;

Storage Targets

The continuous backup can be written to all supported storage targets.

foundation classes:
SQLiteDataSource dataSource = new SQLiteDataSource();
dataSource.setUrl("jdbc:sqlite:eclipsestore_bkup_db");

SqlFileSystem fileSystem = SqlFileSystem.New(
	SqlConnector.Caching(
		SqlProviderSqlite.New(dataSource)
	)
);

StorageBackupSetup backupSetup = StorageBackupSetup.New(
	Storage.BackupFileProviderBuilder(fileSystem)
		.setDirectory(fileSystem.ensureDirectoryPath(BACKUPDIR))
		.setTruncationDirectory(fileSystem.ensureDirectoryPath(TRUNCATIONDIR))
		.setDeletionDirectory(fileSystem.ensureDirectoryPath(DELETIONDIR))
		.createFileProvider()
);

StorageConfiguration configuration = StorageConfiguration.Builder()
	.setBackupSetup(backupSetup)
	.setStorageFileProvider(StorageLiveFileProvider.New(
		fileSystem.ensureDirectoryPath(WORKINGDIR)
	))
	.createConfiguration()
;

When using external configuration the specific target configuration must be applied to the backup-filesystem property:

external configuration:
storage-filesystem.aws.s3.credentials.type=static
storage-filesystem.aws.s3.credentials.access-key-id=my-access-key-id
storage-filesystem.aws.s3.credentials.secret-acces-key=my-secret-access-key
storage-filesystem.aws.s3.credentials.region=us-east-1

storage-directory=storageDir

backup-filesystem.sql.sqlite.data-source-provider=com.sample.MyDataSourceProvider
backup-filesystem.sql.sqlite.catalog=mycatalog
backup-filesystem.sql.sqlite.schema=myschema
backup-filesystem.sql.sqlite.url=jdbc:sqlite:eclipsestore_bkup_db_bkup_db

backup-directory=backupDir

Restore Consistency

The continuous backup is written asynchronously: committed stores are enqueued and copied to the backup target in commit order, after the fact. While the storage is running, the backup can therefore be behind the primary by the most recent stores.

Because the stores are copied in order, a lagging backup normally represents an older but self-consistent state of the storage — restoring it simply restores the data as it was some stores ago. Missing-entity errors (StorageExceptionConsistency: No entity found for objectId …​) can only arise from a lagging backup when an earlier store references an object that was persisted later — a forward reference across commits. Correct application store logic never produces this (every store persists the new objects it references); it indicates a gap such as splitting one logical graph change across multiple commits in the wrong order. Only in such rare application-logic gaps does backup lag turn into a restore-consistency problem.

A continuous backup is fully synchronized with the primary once the storage has been shut down cleanly: the shutdown processes the remaining backup queue before completing. Two situations fall outside that guarantee:

  • a storage that was stopped by an error (a registered disruption also ends the backup processing, possibly with items still queued);

  • a backup target copied while the storage is running — such a copy is a potentially lagging (older-state) snapshot.