use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FileWriteAheadLogManager method moveSegmentsToArchive.
/**
* Moving working segments to archive, if segments are more than {@link DataStorageConfiguration#getWalSegments()}
* or index of first segment is not 0. All segments will be moved except for last one,
* as well as all compressed segments.
*
* @throws StorageException If an error occurs while moving.
*/
private void moveSegmentsToArchive() throws StorageException {
assert isArchiverEnabled();
FileDescriptor[] workSegments = scan(walWorkDir.listFiles(WAL_SEGMENT_FILE_FILTER));
List<FileDescriptor> toMove = new ArrayList<>();
if (!F.isEmpty(workSegments) && (workSegments.length > dsCfg.getWalSegments() || workSegments[0].idx() != 0))
toMove.addAll(F.asList(workSegments).subList(0, workSegments.length - 1));
toMove.addAll(F.asList(scan(walWorkDir.listFiles(WAL_SEGMENT_FILE_COMPACTED_FILTER))));
if (!toMove.isEmpty()) {
log.warning("Content of WAL working directory needs rearrangement, some WAL segments will be moved to " + "archive: " + walArchiveDir.getAbsolutePath() + ". Segments from " + toMove.get(0).file().getName() + " to " + toMove.get(toMove.size() - 1).file().getName() + " will be moved, total number of files: " + toMove.size() + ". This operation may take some time.");
for (int i = 0, j = 0; i < toMove.size(); i++) {
FileDescriptor fd = toMove.get(i);
File tmpDst = new File(walArchiveDir, fd.file().getName() + TMP_SUFFIX);
File dst = new File(walArchiveDir, fd.file().getName());
try {
Files.copy(fd.file().toPath(), tmpDst.toPath());
Files.move(tmpDst.toPath(), dst.toPath());
Files.delete(fd.file().toPath());
if (log.isDebugEnabled()) {
log.debug("WAL segment moved [src=" + fd.file().getAbsolutePath() + ", dst=" + dst.getAbsolutePath() + ']');
}
// Batch output.
if (log.isInfoEnabled() && (i == toMove.size() - 1 || (i != 0 && i % 9 == 0))) {
log.info("WAL segments moved: " + toMove.get(j).file().getName() + (i == j ? "" : " - " + toMove.get(i).file().getName()));
j = i + 1;
}
} catch (IOException e) {
throw new StorageException("Failed to move WAL segment [src=" + fd.file().getAbsolutePath() + ", dst=" + dst.getAbsolutePath() + ']', e);
}
}
}
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FileWriteAheadLogManager method formatWorkSegments.
/**
* Formatting working segments to {@link DataStorageConfiguration#getWalSegmentSize()} for work in a mmap or fsync case.
*
* @throws StorageException If an error occurs when formatting.
*/
private void formatWorkSegments() throws StorageException {
assert isArchiverEnabled();
if (mode == WALMode.FSYNC || mmap) {
List<FileDescriptor> toFormat = Arrays.stream(scan(walWorkDir.listFiles(WAL_SEGMENT_FILE_FILTER))).filter(fd -> fd.file().length() < dsCfg.getWalSegmentSize()).collect(toList());
if (!toFormat.isEmpty()) {
if (log.isInfoEnabled()) {
log.info("WAL segments in working directory should have the same size: '" + U.humanReadableByteCount(dsCfg.getWalSegmentSize()) + "'. Segments that need reformat " + "found: " + F.viewReadOnly(toFormat, fd -> fd.file().getName()) + '.');
}
for (int i = 0, j = 0; i < toFormat.size(); i++) {
FileDescriptor fd = toFormat.get(i);
File tmpDst = new File(fd.file().getName() + TMP_SUFFIX);
try {
Files.copy(fd.file().toPath(), tmpDst.toPath());
if (log.isDebugEnabled()) {
log.debug("Start formatting WAL segment [filePath=" + tmpDst.getAbsolutePath() + ", fileSize=" + U.humanReadableByteCount(tmpDst.length()) + ", toSize=" + U.humanReadableByteCount(dsCfg.getWalSegmentSize()) + ']');
}
try (FileIO fileIO = ioFactory.create(tmpDst, CREATE, READ, WRITE)) {
int left = (int) (dsCfg.getWalSegmentSize() - tmpDst.length());
fileIO.position(tmpDst.length());
while (left > 0) left -= fileIO.writeFully(FILL_BUF, 0, Math.min(FILL_BUF.length, left));
fileIO.force();
}
Files.move(tmpDst.toPath(), fd.file().toPath(), REPLACE_EXISTING, ATOMIC_MOVE);
if (log.isDebugEnabled())
log.debug("WAL segment formatted: " + fd.file().getAbsolutePath());
// Batch output.
if (log.isInfoEnabled() && (i == toFormat.size() - 1 || (i != 0 && i % 9 == 0))) {
log.info("WAL segments formatted: " + toFormat.get(j).file().getName() + (i == j ? "" : " - " + fileName(i)));
j = i + 1;
}
} catch (IOException e) {
throw new StorageException("Failed to format WAL segment: " + fd.file().getAbsolutePath(), e);
}
}
}
}
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FileWriteAheadLogManager method createFile.
/**
* Creates a file atomically with temp file.
*
* @param file File to create.
* @throws StorageException If failed.
*/
private void createFile(File file) throws StorageException {
if (log.isDebugEnabled())
log.debug("Creating new file [exists=" + file.exists() + ", file=" + file.getAbsolutePath() + ']');
File tmp = new File(file.getParent(), file.getName() + TMP_SUFFIX);
formatFile(tmp);
try {
Files.move(tmp.toPath(), file.toPath());
} catch (IOException e) {
throw new StorageException("Failed to move temp file to a regular WAL segment file: " + file.getAbsolutePath(), e);
}
if (log.isDebugEnabled())
log.debug("Created WAL segment [file=" + file.getAbsolutePath() + ", size=" + file.length() + ']');
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FileWriteHandleImpl method close.
/**
* @return {@code true} If this thread actually closed the segment.
* @throws IgniteCheckedException If failed.
* @throws StorageException If failed.
*/
@Override
public boolean close(boolean rollOver) throws IgniteCheckedException, StorageException {
if (stop.compareAndSet(false, true)) {
lock.lock();
try {
flushOrWait(null);
try {
RecordSerializer backwardSerializer = new RecordSerializerFactoryImpl(cctx).createSerializer(serializerVer);
SwitchSegmentRecord segmentRecord = new SwitchSegmentRecord();
int switchSegmentRecSize = backwardSerializer.size(segmentRecord);
if (rollOver && written + switchSegmentRecSize < maxWalSegmentSize) {
segmentRecord.size(switchSegmentRecSize);
WALPointer segRecPtr = addRecord(segmentRecord);
if (segRecPtr != null) {
fsync(segRecPtr);
switchSegmentRecordOffset = segRecPtr.fileOffset() + switchSegmentRecSize;
} else {
if (log.isDebugEnabled())
log.debug("Not enough space in wal segment to write segment switch");
}
} else {
if (log.isDebugEnabled()) {
log.debug("Not enough space in wal segment to write segment switch, written=" + written + ", switchSegmentRecSize=" + switchSegmentRecSize);
}
}
// Unconditional flush (tail of the buffer)
flushOrWait(null);
if (mmap) {
List<SegmentedRingByteBuffer.ReadSegment> segs = buf.poll(maxWalSegmentSize);
if (segs != null) {
assert segs.size() == 1;
segs.get(0).release();
}
}
// Do the final fsync.
if (mode != WALMode.NONE) {
if (mmap)
((MappedByteBuffer) buf.buf).force();
else
fileIO.force();
lastFsyncPos = written;
}
if (mmap) {
try {
fileIO.close();
} catch (IOException ignore) {
// No-op.
}
} else {
walWriter.close();
if (!rollOver)
buf.free();
}
} catch (IOException e) {
throw new StorageException("Failed to close WAL write handle [idx=" + getSegmentId() + "]", e);
}
if (log.isDebugEnabled())
log.debug("Closed WAL write handle [idx=" + getSegmentId() + "]");
return true;
} finally {
if (mmap)
buf.free();
lock.unlock();
}
} else
return false;
}
use of org.apache.ignite.internal.processors.cache.persistence.StorageException in project ignite by apache.
the class FsyncFileWriteHandle method writeHeader.
/**
* Write serializer version to current handle. NOTE: Method mutates {@code fileIO} position, written and
* lastFsyncPos fields.
*
* @throws StorageException If fail to write serializer version.
*/
@Override
public void writeHeader() throws StorageException {
try {
assert fileIO.position() == 0 : "Serializer version can be written only at the begin of file " + fileIO.position();
long updatedPosition = writeSerializerVersion(fileIO, getSegmentId(), serializer.version(), mode);
written = updatedPosition;
lastFsyncPos = updatedPosition;
head.set(new FakeRecord(new WALPointer(getSegmentId(), (int) updatedPosition, 0), false));
} catch (IOException e) {
throw new StorageException("Unable to write serializer version for segment " + getSegmentId(), e);
}
}
Aggregations