Author: xedin
Date: Mon Dec 19 09:20:18 2011
New Revision: 1220663
URL: http://svn.apache.org/viewvc?rev=1220663&view=rev
Log:
fsync the directory after new sstable or commitlog segment are created
patch by Pavel Yaskevich; reviewed by Jonathan Ellis for CASSANDRA-3250
Modified:
cassandra/branches/cassandra-1.0/CHANGES.txt
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
Modified: cassandra/branches/cassandra-1.0/CHANGES.txt
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/CHANGES.txt?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/CHANGES.txt (original)
+++ cassandra/branches/cassandra-1.0/CHANGES.txt Mon Dec 19 09:20:18 2011
@@ -4,6 +4,8 @@
* CLibrary.createHardLinkWithExec() to check for errors (CASSANDRA-3101)
Merged from 0.8:
* prevent new nodes from thinking down nodes are up forever (CASSANDRA-3626)
+ * fsync the directory after new sstable or commitlog segment are created
(CASSANDRA-3250)
+
1.0.6
* (CQL) fix cqlsh support for replicate_on_write (CASSANDRA-3596)
Modified:
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
---
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
(original)
+++
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
Mon Dec 19 09:20:18 2011
@@ -39,6 +39,9 @@ public class SequentialWriter extends Ou
protected byte[] buffer;
private final boolean skipIOCache;
private final int fd;
+ private final int directoryFD;
+ // directory should be synced only after first file sync, in other words,
only once per file
+ private boolean directorySynced = false;
protected long current = 0, bufferOffset;
protected int validBufferBytes;
@@ -60,6 +63,7 @@ public class SequentialWriter extends Ou
buffer = new byte[bufferSize];
this.skipIOCache = skipIOCache;
fd = CLibrary.getfd(out.getFD());
+ directoryFD = CLibrary.tryOpenDirectory(file.getParent());
stream = new DataOutputStream(this);
}
@@ -148,6 +152,12 @@ public class SequentialWriter extends Ou
flushInternal();
out.getFD().sync();
+ if (!directorySynced)
+ {
+ CLibrary.trySync(directoryFD);
+ directorySynced = true;
+ }
+
syncNeeded = false;
}
}
@@ -288,6 +298,7 @@ public class SequentialWriter extends Ou
CLibrary.trySkipCache(fd, 0, 0);
out.close();
+ CLibrary.tryCloseFD(directoryFD);
}
/**
Modified:
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
---
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
(original)
+++
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
Mon Dec 19 09:20:18 2011
@@ -46,6 +46,7 @@ public final class CLibrary
private static final int F_SETFL = 4; /* set file status flags */
private static final int F_NOCACHE = 48; /* Mac OS X specific flag, turns
cache on/off */
private static final int O_DIRECT = 040000; /* fcntl.h */
+ private static final int O_RDONLY = 00000000; /* fcntl.h */
private static final int POSIX_FADV_NORMAL = 0; /* fadvise.h */
private static final int POSIX_FADV_RANDOM = 1; /* fadvise.h */
@@ -84,7 +85,11 @@ public final class CLibrary
// fadvice
public static native int posix_fadvise(int fd, long offset, int len, int
flag) throws LastErrorException;
-
+
+ public static native int open(String path, int flags) throws
LastErrorException;
+ public static native int fsync(int fd) throws LastErrorException;
+ public static native int close(int fd) throws LastErrorException;
+
private static int errno(RuntimeException e)
{
assert e instanceof LastErrorException;
@@ -261,6 +266,73 @@ public final class CLibrary
return result;
}
+ public static int tryOpenDirectory(String path)
+ {
+ int fd = -1;
+
+ try
+ {
+ return open(path, O_RDONLY);
+ }
+ catch (UnsatisfiedLinkError e)
+ {
+ // JNA is unavailable just skipping Direct I/O
+ }
+ catch (RuntimeException e)
+ {
+ if (!(e instanceof LastErrorException))
+ throw e;
+
+ logger.warn(String.format("open(%s, O_RDONLY) failed, errno
(%d).", path, CLibrary.errno(e)));
+ }
+
+ return fd;
+ }
+
+ public static void trySync(int fd)
+ {
+ if (fd == -1)
+ return;
+
+ try
+ {
+ fsync(fd);
+ }
+ catch (UnsatisfiedLinkError e)
+ {
+ // JNA is unavailable just skipping Direct I/O
+ }
+ catch (RuntimeException e)
+ {
+ if (!(e instanceof LastErrorException))
+ throw e;
+
+ logger.warn(String.format("fsync(%d) failed, errno (%d).", fd,
CLibrary.errno(e)));
+ }
+ }
+
+ public static void tryCloseFD(int fd)
+ {
+ if (fd == -1)
+ return;
+
+ try
+ {
+ close(fd);
+ }
+ catch (UnsatisfiedLinkError e)
+ {
+ // JNA is unavailable just skipping Direct I/O
+ }
+ catch (RuntimeException e)
+ {
+ if (!(e instanceof LastErrorException))
+ throw e;
+
+ logger.warn(String.format("close(%d) failed, errno (%d).", fd,
CLibrary.errno(e)));
+ }
+ }
+
/**
* Get system file descriptor from FileDescriptor object.
* @param descriptor - FileDescriptor objec to get fd from