Implement backuppable class
This commit is contained in:
parent
8b6f1dfe87
commit
ddd71d3b72
57
src/main/java/it/cavallium/dbengine/client/Backuppable.java
Normal file
57
src/main/java/it/cavallium/dbengine/client/Backuppable.java
Normal file
@ -0,0 +1,57 @@
|
||||
package it.cavallium.dbengine.client;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.publisher.SignalType;
|
||||
|
||||
public abstract class Backuppable implements IBackuppable {
|
||||
|
||||
public enum State {
|
||||
RUNNING, PAUSING, PAUSED, RESUMING, STOPPED
|
||||
}
|
||||
|
||||
private final AtomicInteger state = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public final Mono<Void> pauseForBackup() {
|
||||
return Mono.defer(() -> {
|
||||
if (state.compareAndSet(State.RUNNING.ordinal(), State.PAUSING.ordinal())) {
|
||||
return onPauseForBackup().doFinally(type -> state.compareAndSet(State.PAUSING.ordinal(),
|
||||
type == SignalType.ON_ERROR ? State.RUNNING.ordinal() : State.PAUSED.ordinal()
|
||||
));
|
||||
} else {
|
||||
return Mono.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Mono<Void> resumeAfterBackup() {
|
||||
return Mono.defer(() -> {
|
||||
if (state.compareAndSet(State.PAUSED.ordinal(), State.RESUMING.ordinal())) {
|
||||
return onResumeAfterBackup().doFinally(type -> state.compareAndSet(State.RESUMING.ordinal(),
|
||||
type == SignalType.ON_ERROR ? State.PAUSED.ordinal() : State.RUNNING.ordinal()
|
||||
));
|
||||
} else {
|
||||
return Mono.empty();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isPaused() {
|
||||
return state.get() == State.PAUSED.ordinal();
|
||||
}
|
||||
|
||||
public final State getState() {
|
||||
return State.values()[state.get()];
|
||||
}
|
||||
|
||||
protected abstract Mono<Void> onPauseForBackup();
|
||||
|
||||
protected abstract Mono<Void> onResumeAfterBackup();
|
||||
|
||||
public final void setStopped() {
|
||||
state.set(State.STOPPED.ordinal());
|
||||
}
|
||||
}
|
12
src/main/java/it/cavallium/dbengine/client/IBackuppable.java
Normal file
12
src/main/java/it/cavallium/dbengine/client/IBackuppable.java
Normal file
@ -0,0 +1,12 @@
|
||||
package it.cavallium.dbengine.client;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface IBackuppable {
|
||||
|
||||
Mono<Void> pauseForBackup();
|
||||
|
||||
Mono<Void> resumeAfterBackup();
|
||||
|
||||
boolean isPaused();
|
||||
}
|
@ -4,6 +4,7 @@ import com.google.common.primitives.Ints;
|
||||
import com.google.common.primitives.Longs;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.netty5.buffer.api.BufferAllocator;
|
||||
import it.cavallium.dbengine.client.IBackuppable;
|
||||
import it.cavallium.dbengine.client.MemoryStats;
|
||||
import it.cavallium.dbengine.database.collections.DatabaseInt;
|
||||
import it.cavallium.dbengine.database.collections.DatabaseLong;
|
||||
@ -14,7 +15,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface LLKeyValueDatabase extends LLSnapshottable, LLKeyValueDatabaseStructure, DatabaseProperties {
|
||||
public interface LLKeyValueDatabase extends LLSnapshottable, LLKeyValueDatabaseStructure, DatabaseProperties,
|
||||
IBackuppable {
|
||||
|
||||
Mono<? extends LLSingleton> getSingleton(byte[] singletonListColumnName, byte[] name, byte @Nullable[] defaultValue);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package it.cavallium.dbengine.database;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import it.cavallium.dbengine.client.IBackuppable;
|
||||
import it.cavallium.dbengine.client.query.current.data.NoSort;
|
||||
import it.cavallium.dbengine.client.query.current.data.Query;
|
||||
import it.cavallium.dbengine.client.query.current.data.QueryParams;
|
||||
@ -16,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface LLLuceneIndex extends LLSnapshottable, SafeCloseable {
|
||||
public interface LLLuceneIndex extends LLSnapshottable, IBackuppable, SafeCloseable {
|
||||
|
||||
String getLuceneIndexName();
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package it.cavallium.dbengine.database;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import it.cavallium.dbengine.client.IBackuppable;
|
||||
import it.cavallium.dbengine.rpc.current.data.IndicizerAnalyzers;
|
||||
import it.cavallium.dbengine.rpc.current.data.IndicizerSimilarities;
|
||||
import it.cavallium.dbengine.client.query.current.data.Query;
|
||||
@ -242,4 +244,24 @@ public class LLMultiLuceneIndex implements LLLuceneIndex {
|
||||
})
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return Mono.whenDelayError(Iterables.transform(this.luceneIndicesSet, IBackuppable::pauseForBackup));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return Mono.whenDelayError(Iterables.transform(this.luceneIndicesSet, IBackuppable::resumeAfterBackup));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
for (LLLuceneIndex llLuceneIndex : this.luceneIndicesSet) {
|
||||
if (llLuceneIndex.isPaused()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import io.micrometer.core.instrument.Timer;
|
||||
import io.netty5.buffer.api.BufferAllocator;
|
||||
import io.netty5.util.internal.PlatformDependent;
|
||||
import it.cavallium.data.generator.nativedata.NullableString;
|
||||
import it.cavallium.dbengine.client.Backuppable;
|
||||
import it.cavallium.dbengine.client.MemoryStats;
|
||||
import it.cavallium.dbengine.database.ColumnProperty;
|
||||
import it.cavallium.dbengine.database.ColumnUtils;
|
||||
@ -98,7 +99,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
||||
public class LLLocalKeyValueDatabase extends Backuppable implements LLKeyValueDatabase {
|
||||
|
||||
private static final boolean DELETE_LOG_FILES = false;
|
||||
private static final boolean FOLLOW_ROCKSDB_OPTIMIZATIONS = true;
|
||||
@ -687,6 +688,16 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
||||
}).subscribeOn(dbWScheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mono<Void> onPauseForBackup() {
|
||||
return pauseWrites();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mono<Void> onResumeAfterBackup() {
|
||||
return resumeWrites();
|
||||
}
|
||||
|
||||
private record RocksLevelOptions(CompressionType compressionType, CompressionOptions compressionOptions) {}
|
||||
private RocksLevelOptions getRocksLevelOptions(DatabaseLevel levelOptions, RocksDBRefs refs) {
|
||||
var compressionType = levelOptions.compression().getType();
|
||||
@ -1617,6 +1628,22 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
||||
.subscribeOn(dbWScheduler);
|
||||
}
|
||||
|
||||
private Mono<Void> pauseWrites() {
|
||||
return Mono.<Void>fromCallable(() -> {
|
||||
db.pauseBackgroundWork();
|
||||
db.disableFileDeletions();
|
||||
return null;
|
||||
}).subscribeOn(dbWScheduler);
|
||||
}
|
||||
|
||||
private Mono<Void> resumeWrites() {
|
||||
return Mono.<Void>fromCallable(() -> {
|
||||
db.continueBackgroundWork();
|
||||
db.enableFileDeletions(false);
|
||||
return null;
|
||||
}).subscribeOn(dbWScheduler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this method ONLY AFTER flushing completely a db and closing it!
|
||||
*/
|
||||
|
@ -14,6 +14,8 @@ import io.micrometer.core.instrument.Counter;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
import io.micrometer.core.instrument.Timer;
|
||||
import it.cavallium.dbengine.client.Backuppable;
|
||||
import it.cavallium.dbengine.client.IBackuppable;
|
||||
import it.cavallium.dbengine.client.query.QueryParser;
|
||||
import it.cavallium.dbengine.client.query.current.data.Query;
|
||||
import it.cavallium.dbengine.client.query.current.data.QueryParams;
|
||||
@ -82,7 +84,7 @@ import reactor.core.publisher.SignalType;
|
||||
import reactor.core.scheduler.Scheduler;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
public class LLLocalLuceneIndex extends SimpleResource implements LLLuceneIndex, LuceneCloseable {
|
||||
public class LLLocalLuceneIndex extends SimpleResource implements IBackuppable, LLLuceneIndex, LuceneCloseable {
|
||||
|
||||
protected static final Logger logger = LogManager.getLogger(LLLocalLuceneIndex.class);
|
||||
|
||||
@ -138,6 +140,7 @@ public class LLLocalLuceneIndex extends SimpleResource implements LLLuceneIndex,
|
||||
private final Similarity luceneSimilarity;
|
||||
private final LuceneRocksDBManager rocksDBManager;
|
||||
private final Directory directory;
|
||||
private final LuceneBackuppable backuppable;
|
||||
private final boolean lowMemory;
|
||||
|
||||
private final Phaser activeTasks = new Phaser(1);
|
||||
@ -280,6 +283,8 @@ public class LLLocalLuceneIndex extends SimpleResource implements LLLuceneIndex,
|
||||
var commitMillis = luceneOptions.commitDebounceTime().toMillis();
|
||||
luceneHeavyTasksScheduler.schedulePeriodically(this::scheduledCommit, commitMillis, commitMillis,
|
||||
TimeUnit.MILLISECONDS);
|
||||
|
||||
this.backuppable = new LuceneBackuppable();
|
||||
}
|
||||
|
||||
private Similarity getLuceneSimilarity() {
|
||||
@ -848,4 +853,42 @@ public class LLLocalLuceneIndex extends SimpleResource implements LLLuceneIndex,
|
||||
public int hashCode() {
|
||||
return shardName.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return backuppable.pauseForBackup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return backuppable.resumeAfterBackup();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return backuppable.isPaused();
|
||||
}
|
||||
|
||||
private class LuceneBackuppable extends Backuppable {
|
||||
|
||||
private LLSnapshot snapshot;
|
||||
|
||||
@Override
|
||||
protected Mono<Void> onPauseForBackup() {
|
||||
return LLLocalLuceneIndex.this.takeSnapshot().doOnSuccess(snapshot -> {
|
||||
if (snapshot == null) {
|
||||
logger.error("Can't pause index \"{}\" because snapshots are not enabled!", shardName);
|
||||
}
|
||||
this.snapshot = snapshot;
|
||||
}).then();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Mono<Void> onResumeAfterBackup() {
|
||||
if (snapshot == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return LLLocalLuceneIndex.this.releaseSnapshot(snapshot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,11 @@ package it.cavallium.dbengine.database.disk;
|
||||
import static it.cavallium.dbengine.client.UninterruptibleScheduler.uninterruptibleScheduler;
|
||||
import static it.cavallium.dbengine.lucene.LuceneUtils.luceneScheduler;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.netty5.util.Send;
|
||||
import it.cavallium.dbengine.client.IBackuppable;
|
||||
import it.cavallium.dbengine.client.query.QueryParser;
|
||||
import it.cavallium.dbengine.client.query.current.data.NoSort;
|
||||
import it.cavallium.dbengine.client.query.current.data.Query;
|
||||
@ -415,4 +417,24 @@ public class LLLocalMultiLuceneIndex extends SimpleResource implements LLLuceneI
|
||||
public boolean isLowMemoryMode() {
|
||||
return lowMemory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return Mono.whenDelayError(Iterables.transform(this.luceneIndicesSet, IBackuppable::pauseForBackup));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return Mono.whenDelayError(Iterables.transform(this.luceneIndicesSet, IBackuppable::resumeAfterBackup));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
for (LLLuceneIndex llLuceneIndex : this.luceneIndicesSet) {
|
||||
if (llLuceneIndex.isPaused()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -213,4 +213,19 @@ public class LLMemoryKeyValueDatabase implements LLKeyValueDatabase {
|
||||
.fromCallable(() -> snapshots.remove(snapshot.getSequenceNumber()))
|
||||
.then();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -231,6 +231,7 @@ public class LLQuicConnection implements LLDatabaseConnection {
|
||||
.cast(GeneratedEntityId.class)
|
||||
.map(GeneratedEntityId::id)
|
||||
.map(id -> new LLKeyValueDatabase() {
|
||||
|
||||
@Override
|
||||
public Mono<? extends LLSingleton> getSingleton(byte[] singletonListColumnName,
|
||||
byte[] name,
|
||||
@ -423,6 +424,21 @@ public class LLQuicConnection implements LLDatabaseConnection {
|
||||
public Mono<Void> releaseSnapshot(LLSnapshot snapshot) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -446,6 +462,7 @@ public class LLQuicConnection implements LLDatabaseConnection {
|
||||
.cast(GeneratedEntityId.class)
|
||||
.map(GeneratedEntityId::id)
|
||||
.map(id -> new LLLuceneIndex() {
|
||||
|
||||
@Override
|
||||
public String getLuceneIndexName() {
|
||||
return clusterName;
|
||||
@ -543,6 +560,21 @@ public class LLQuicConnection implements LLDatabaseConnection {
|
||||
public Mono<Void> releaseSnapshot(LLSnapshot snapshot) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> pauseForBackup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> resumeAfterBackup() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPaused() {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user