Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.flink.runtime.state.gemini.engine.restore;
import org.apache.flink.api.common.typeutils.TypeSerializer;
import org.apache.flink.api.common.typeutils.base.IntSerializer;
import org.apache.flink.api.common.typeutils.base.LongSerializer;
import org.apache.flink.api.common.typeutils.base.MapSerializer;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.typeutils.runtime.TupleSerializer;
import org.apache.flink.core.fs.CloseableRegistry;
import org.apache.flink.core.fs.FSDataInputStream;
import org.apache.flink.core.fs.FSDataOutputStream;
import org.apache.flink.core.fs.FileStatus;
import org.apache.flink.core.fs.FileSystem;
import org.apache.flink.core.fs.Path;
import org.apache.flink.core.memory.DataInputView;
import org.apache.flink.core.memory.DataInputViewStreamWrapper;
import org.apache.flink.runtime.concurrent.FutureUtils;
import org.apache.flink.runtime.state.gemini.engine.GConfiguration;
import org.apache.flink.runtime.state.gemini.engine.GRegion;
import org.apache.flink.runtime.state.gemini.engine.GRegionContext;
import org.apache.flink.runtime.state.gemini.engine.GRegionID;
import org.apache.flink.runtime.state.gemini.engine.GRegionIDImpl;
import org.apache.flink.runtime.state.gemini.engine.GTable;
import org.apache.flink.runtime.state.gemini.engine.dbms.GContext;
import org.apache.flink.runtime.state.gemini.engine.dbms.Supervisor;
import org.apache.flink.runtime.state.gemini.engine.fs.FileManager;
import org.apache.flink.runtime.state.gemini.engine.fs.FileMeta;
import org.apache.flink.runtime.state.gemini.engine.page.PageAddress;
import org.apache.flink.runtime.state.gemini.engine.page.PageIndex;
import org.apache.flink.runtime.state.gemini.engine.page.PageIndexHashImpl;
import org.apache.flink.runtime.state.gemini.engine.snapshot.DBSnapshotMeta;
import org.apache.flink.runtime.state.gemini.engine.snapshot.SnapshotManager;
import org.apache.flink.runtime.state.gemini.engine.snapshot.SnapshotMetaFile;
import org.apache.flink.util.ExceptionUtils;
import org.apache.flink.util.FileUtils;
import org.apache.flink.util.FlinkRuntimeException;
import org.apache.flink.util.Preconditions;
import org.apache.flink.util.StringUtils;
import org.apache.flink.util.function.ThrowingRunnable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.apache.flink.runtime.concurrent.Executors.newDirectExecutorService;
/**
* Restore operation for Gemini.
*/
public class GeminiRestoreOperation {
private static final Logger LOG = LoggerFactory.getLogger(GeminiRestoreOperation.class);
private final GContext context;
private final GConfiguration configuration;
private final Supervisor supervisor;
private final CloseableRegistry closeableRegistry;
public GeminiRestoreOperation(GContext context, GConfiguration configuration, CloseableRegistry closeableRegistry) {
this.context = context;
this.configuration = configuration;
this.supervisor = this.context.getSupervisor();
this.closeableRegistry = closeableRegistry;
}
/**
* Restore from given snapshot metas and tables to restore.
*
* @param snapshotMetas Collection of restored snapshot metas, if size more than 1, means rescaling.
* @param restoredTables The tables to restore which recorded from snapshot handle's meta.
* @param startRegionId The start region id to restore (inclusive)
* @param endRegionId The end region id to restore (inclusive)
* @throws Exception
*/
@SuppressWarnings("unchecked")
public void restore(
Collection snapshotMetas,
Map restoredTables,
int startRegionId,
int endRegionId) throws Exception {
long startTime = System.currentTimeMillis();
MapSerializer>> fileMappingSerializer = getFileMappingSerializer();
long restoredCheckpointId = 0;
// dfs/local file mapping to restore for DB.
Set restoredDfsBasePaths = new HashSet<>(), restoredLocalBasePaths = new HashSet<>();
Map restoredDfsFileMetas = new HashMap<>(), restoredLocalFileMetas = new HashMap<>();
// {fileId -> {group, }}
Map>> dfsFileMapping = new HashMap<>(), localFileMapping = new HashMap<>();
// TODO #SR error handle.
LOG.info("Start to restore from snapshot for GeminiDB, snapshotMetas {}, tables {}, region from {} to {}.",
snapshotMetas, restoredTables, startRegionId, endRegionId);
boolean needToBreakLineage = false;
boolean needToFetchFiles = configuration.isEnableRestorePreFetch();
for (DBSnapshotMeta meta : snapshotMetas) {
restoredCheckpointId = meta.getCheckPointId();
long[] regionOffsets = meta.getRegionOffsets();
int metaStartRegionId = meta.getStartRegionId();
int metaEndRegionId = meta.getEndRegionId();
int startGroup = Math.max(startRegionId, metaStartRegionId);
int endGroup = Math.min(endRegionId, metaEndRegionId);
if (!needToBreakLineage) {
if (!supervisor.getSnapshotManager().getNameSpace().equals(meta.getNameSpace())) {
needToBreakLineage = true;
LOG.info("Current name space {} differs from previous snapshot's name space {}," +
" enforce the first snapshot to flush all pages out.", supervisor.getSnapshotManager().getNameSpace(), meta.getNameSpace());
}
}
Preconditions.checkArgument(startGroup <= endGroup,
String.format("Useless meta (key-group range [%s, %s]) should not be restored within this state-backend (key-group range [%s, %s])",
metaStartRegionId, metaEndRegionId, startRegionId, endRegionId));
try (SnapshotMetaFile.Reader reader = SnapshotMetaFile.getReader(new Path(meta.getSnapshotMetaPath()))) {
int tableSize = reader.readInt();
reader.seek(regionOffsets[startGroup - metaStartRegionId]);
for (int group = startGroup; group <= endGroup; group++) {
int writtenKeyGroupIndex = reader.readInt();
Preconditions.checkState(writtenKeyGroupIndex == group,
"Unexpected key-group in restore.");
for (int i = 0; i < tableSize; i++) {
// 1. restore table.
String tableName = reader.readUTF();
int expectedRegions = reader.readInt();
// 2. restore regions within this snapshot meta.
for (int j = 0; j < expectedRegions; j++) {
int regionCode = reader.readInt();
GRegionID gRegionId = new GRegionIDImpl(regionCode);
int regionId = gRegionId.getId();
long lastSeqId = reader.readLong();
long removeAllSeqId = reader.readLong();
GTable table = restoredTables.get(tableName);
GRegionContext regionContext = new GRegionContext(
context, tableName, gRegionId, table.getTableDescription().getPageSerde(), lastSeqId, removeAllSeqId);
// 3. restore logical page chains of this region.
PageIndex pageIndex = new PageIndexHashImpl.Builder(reader, regionContext).build();
// index 0 is data. now only support 1 index. TODO support more index.
if (gRegionId.getIndexID() == 0) {
// data region.
table.setRegion(regionId,
table.getTableDescription().createRegion(context, table, gRegionId, pageIndex));
} else {
// index region
table.setIndexRegion(regionId,
table.getIndexDescription().createRegion(context, table, gRegionId, pageIndex));
}
}
}
}
reader.seek(meta.getDfsFileMappingOffset());
// 4. restore dfs file mapping.
Tuple2