提交 2a9fa06c authored 作者: Thomas Mueller's avatar Thomas Mueller

Documentation / formatting.

上级 18d0d751
...@@ -31,10 +31,10 @@ Change Log ...@@ -31,10 +31,10 @@ Change Log
This is still very experimental, and many features are not supported yet. This is still very experimental, and many features are not supported yet.
The data is stored in a file with the suffix ".mv.db". The data is stored in a file with the suffix ".mv.db".
</li><li>New connection setting "DEFAULT_TABLE_ENGINE" to use a specific </li><li>New connection setting "DEFAULT_TABLE_ENGINE" to use a specific
table engine if none is set explicitly. This is to simplify testing table engine if none is set explicitly. This is to simplify testing
the MVStore table engine. the MVStore table engine.
</li><li>MVStore: encrypted stores are now supported. </li><li>MVStore: encrypted stores are now supported.
Only standardized algorithms are used: PBKDF2, SHA-256, XTS-AES, AES-128. Only standardized algorithms are used: PBKDF2, SHA-256, XTS-AES, AES-128.
</li><li>MVStore: improved API thanks to Simo Tripodi. </li><li>MVStore: improved API thanks to Simo Tripodi.
</li><li>MVStore: maps can now be renamed. </li><li>MVStore: maps can now be renamed.
</li><li>MVStore: store the file header also at the end of each chunk, </li><li>MVStore: store the file header also at the end of each chunk,
...@@ -42,11 +42,11 @@ Change Log ...@@ -42,11 +42,11 @@ Change Log
</li><li>MVStore: a map implementation that supports concurrent operations. </li><li>MVStore: a map implementation that supports concurrent operations.
</li><li>MVStore: unified exception handling; the version is included in the messages. </li><li>MVStore: unified exception handling; the version is included in the messages.
</li><li>MVStore: old data is now retained for 45 seconds by default. </li><li>MVStore: old data is now retained for 45 seconds by default.
</ul><li>MVStore: compress is now disabled by default, and can be enabled on request. </li><li>MVStore: compress is now disabled by default, and can be enabled on request.
</ul><li>Support ALTER TABLE ADD ... AFTER. Patch from Andrew Gaul (argaul at gmail.com). Fixes issue 401. </li><li>Support ALTER TABLE ADD ... AFTER. Patch from Andrew Gaul (argaul at gmail.com). Fixes issue 401.
</ul><li>Improved OSGi support. H2 now registers itself as a DataSourceFactory service. Fixes issue 365. </li><li>Improved OSGi support. H2 now registers itself as a DataSourceFactory service. Fixes issue 365.
</ul><li>Add a DISK_SPACE_USED system function. Fixes issue 270. </li><li>Add a DISK_SPACE_USED system function. Fixes issue 270.
</ul><li>Fix a compile-time ambiguity when compiling with JDK7, thanks to a patch from Lukas Eder. </li><li>Fix a compile-time ambiguity when compiling with JDK7, thanks to a patch from Lukas Eder.
</li></ul> </li></ul>
<h2>Version 1.3.170 (2012-11-30)</h2> <h2>Version 1.3.170 (2012-11-30)</h2>
......
...@@ -243,20 +243,20 @@ as <code>store()</code> operates on a snapshot. ...@@ -243,20 +243,20 @@ as <code>store()</code> operates on a snapshot.
Caching is done on the page level. Caching is done on the page level.
The page cache is a concurrent LIRS cache, which should be resistant against scan operations. The page cache is a concurrent LIRS cache, which should be resistant against scan operations.
</p><p> </p><p>
The default map implementation does not support concurrent modification The default map implementation does not support concurrent modification
operations on a map (the same as <code>HashMap</code> and <code>TreeMap</code>). operations on a map (the same as <code>HashMap</code> and <code>TreeMap</code>).
</p><p> </p><p>
With the <code>MVMapConcurrent</code> implementation, With the <code>MVMapConcurrent</code> implementation,
read operations even on the newest version can happen concurrently with all other read operations even on the newest version can happen concurrently with all other
operations, without risk of corruption. operations, without risk of corruption.
This comes with slightly reduced speed in single threaded mode, This comes with slightly reduced speed in single threaded mode,
the same as with other <code>ConcurrentHashMap</code> implementations. the same as with other <code>ConcurrentHashMap</code> implementations.
Write operations first read the relevant area from disk to memory Write operations first read the relevant area from disk to memory
(this can happen concurrently), and only then modify the data. The in-memory part of write (this can happen concurrently), and only then modify the data. The in-memory part of write
operations is synchronized. operations is synchronized.
</p><p> </p><p>
For fully scalable concurrent write operations to a map (in-memory and to disk), For fully scalable concurrent write operations to a map (in-memory and to disk),
the map could be split into multiple maps in different stores ('sharding'). the map could be split into multiple maps in different stores ('sharding').
The plan is to add such a mechanism later when needed. The plan is to add such a mechanism later when needed.
</p> </p>
...@@ -265,7 +265,7 @@ The plan is to add such a mechanism later when needed. ...@@ -265,7 +265,7 @@ The plan is to add such a mechanism later when needed.
Currently, <code>store()</code> needs to be called explicitly to save changes. Currently, <code>store()</code> needs to be called explicitly to save changes.
Changes are buffered in memory, and once enough changes have accumulated Changes are buffered in memory, and once enough changes have accumulated
(for example 2 MB), all changes are written in one continuous disk write operation. (for example 2 MB), all changes are written in one continuous disk write operation.
(According to a test, write throughput of a common SSD gets higher the larger the block size, (According to a test, write throughput of a common SSD gets higher the larger the block size,
until a block size of 2 MB, and then does not further increase.) until a block size of 2 MB, and then does not further increase.)
But of course, if needed, changes can also be persisted if only little data was changed. But of course, if needed, changes can also be persisted if only little data was changed.
The estimated amount of unsaved changes is tracked. The estimated amount of unsaved changes is tracked.
...@@ -341,10 +341,10 @@ MVStore s = new MVStore.Builder(). ...@@ -341,10 +341,10 @@ MVStore s = new MVStore.Builder().
</p><p> </p><p>
The following algorithms and settings are used: The following algorithms and settings are used:
</p> </p>
<ul><li>The password char array is cleared after use, <ul><li>The password char array is cleared after use,
to reduce the risk that the password is stolen to reduce the risk that the password is stolen
even if the attacker has access to the main memory. even if the attacker has access to the main memory.
</li><li>The password is hashed according to the PBKDF2 standard, </li><li>The password is hashed according to the PBKDF2 standard,
using the SHA-256 hash algorithm. using the SHA-256 hash algorithm.
</li><li>The length of the salt is 64 bits, </li><li>The length of the salt is 64 bits,
so that an attacker can not use a pre-calculated password hash table (rainbow table). so that an attacker can not use a pre-calculated password hash table (rainbow table).
...@@ -364,27 +364,27 @@ There is a tool (<code>MVStoreTool</code>) to dump the contents of a file. ...@@ -364,27 +364,27 @@ There is a tool (<code>MVStoreTool</code>) to dump the contents of a file.
<h3>Exception Handling</h3> <h3>Exception Handling</h3>
<p> <p>
This tool does not throw checked exceptions. This tool does not throw checked exceptions.
Instead, unchecked exceptions are thrown if needed. Instead, unchecked exceptions are thrown if needed.
The error message always contains the version of the tool. The error message always contains the version of the tool.
The following exceptions can occur: The following exceptions can occur:
</p> </p>
<ul><li><code>IllegalStateException</code> if a map was already closed or <ul><li><code>IllegalStateException</code> if a map was already closed or
an IO exception occurred, for example if the file was locked, is already closed, an IO exception occurred, for example if the file was locked, is already closed,
could not be opened or closed, if reading or writing failed, could not be opened or closed, if reading or writing failed,
if the file is corrupt, or if there is an internal error in the tool. if the file is corrupt, or if there is an internal error in the tool.
</li><li><code>IllegalArgumentException</code> if a method was called with an illegal argument. </li><li><code>IllegalArgumentException</code> if a method was called with an illegal argument.
</li><li><code>UnsupportedOperationException</code> if a method was called that is not supported, </li><li><code>UnsupportedOperationException</code> if a method was called that is not supported,
for example trying to modify a read-only map or view. for example trying to modify a read-only map or view.
</ul> </li></ul>
<h2 id="differences">Similar Projects and Differences to Other Storage Engines</h2> <h2 id="differences">Similar Projects and Differences to Other Storage Engines</h2>
<p> <p>
Unlike similar storage engines like LevelDB and Kyoto Cabinet, Unlike similar storage engines like LevelDB and Kyoto Cabinet,
the MVStore is written in Java the MVStore is written in Java
and can easily be embedded in a Java and Android application. and can easily be embedded in a Java and Android application.
</p><p> </p><p>
The MVStore is somewhat similar to the Berkeley DB Java Edition The MVStore is somewhat similar to the Berkeley DB Java Edition
because it is also written in Java, because it is also written in Java,
and is also a log structured storage, but the H2 license is more liberal. and is also a log structured storage, but the H2 license is more liberal.
</p><p> </p><p>
......
...@@ -1411,7 +1411,7 @@ The workaround is to add the following XML file to the root of the classpath: ...@@ -1411,7 +1411,7 @@ The workaround is to add the following XML file to the root of the classpath:
<h2 id="osgi">OSGi</h2> <h2 id="osgi">OSGi</h2>
<p> <p>
The standard H2 jar can be dropped in as a bundle in an OSGi container. The standard H2 jar can be dropped in as a bundle in an OSGi container.
H2 implements the JDBC Service defined in OSGi Service Platform Release 4 Version 4.2 Enterprise Specification. H2 implements the JDBC Service defined in OSGi Service Platform Release 4 Version 4.2 Enterprise Specification.
The H2 Data Source Factory service is registered with the following properties: The H2 Data Source Factory service is registered with the following properties:
<code>OSGI_JDBC_DRIVER_CLASS=org.h2.Driver</code> <code>OSGI_JDBC_DRIVER_CLASS=org.h2.Driver</code>
...@@ -1420,9 +1420,9 @@ The <code>OSGI_JDBC_DRIVER_VERSION</code> ...@@ -1420,9 +1420,9 @@ The <code>OSGI_JDBC_DRIVER_VERSION</code>
property reflects the version of the driver as is. property reflects the version of the driver as is.
</p> </p>
<p> <p>
The following standard configuration properties are supported: The following standard configuration properties are supported:
<code>JDBC_USER, JDBC_PASSWORD, JDBC_DESCRIPTION, JDBC_DATASOURCE_NAME, JDBC_NETWORK_PROTOCOL, JDBC_URL, JDBC_SERVER_NAME, JDBC_PORT_NUMBER</code>. <code>JDBC_USER, JDBC_PASSWORD, JDBC_DESCRIPTION, JDBC_DATASOURCE_NAME, JDBC_NETWORK_PROTOCOL, JDBC_URL, JDBC_SERVER_NAME, JDBC_PORT_NUMBER</code>.
Any other standard property will be rejected. Any other standard property will be rejected.
Non-standard properties will be passed on to H2 in the connection URL. Non-standard properties will be passed on to H2 in the connection URL.
</p> </p>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.store; package org.h2.store;
import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -88,6 +89,8 @@ public class RecoverTester implements Recorder { ...@@ -88,6 +89,8 @@ public class RecoverTester implements Recorder {
new OutputStreamWriter( new OutputStreamWriter(
FileUtils.newOutputStream(fileName + ".log", true))); FileUtils.newOutputStream(fileName + ".log", true)));
testDatabase(fileName, out); testDatabase(fileName, out);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
} finally { } finally {
IOUtils.closeSilently(out); IOUtils.closeSilently(out);
testing = false; testing = false;
......
...@@ -216,7 +216,7 @@ public class FunctionTable extends Table { ...@@ -216,7 +216,7 @@ public class FunctionTable extends Table {
public long getRowCountApproximation() { public long getRowCountApproximation() {
return rowCount; return rowCount;
} }
public long getDiskSpaceUsed() { public long getDiskSpaceUsed() {
return 0; return 0;
} }
......
...@@ -724,7 +724,7 @@ public class RegularTable extends TableBase { ...@@ -724,7 +724,7 @@ public class RegularTable extends TableBase {
public long getRowCountApproximation() { public long getRowCountApproximation() {
return scanIndex.getRowCountApproximation(); return scanIndex.getRowCountApproximation();
} }
@Override @Override
public long getDiskSpaceUsed() { public long getDiskSpaceUsed() {
return scanIndex.getDiskSpaceUsed(); return scanIndex.getDiskSpaceUsed();
......
...@@ -294,7 +294,7 @@ public abstract class Table extends SchemaObjectBase { ...@@ -294,7 +294,7 @@ public abstract class Table extends SchemaObjectBase {
public abstract long getRowCountApproximation(); public abstract long getRowCountApproximation();
public abstract long getDiskSpaceUsed(); public abstract long getDiskSpaceUsed();
/** /**
* Get the row id column if this table has one. * Get the row id column if this table has one.
* *
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.tools; package org.h2.tools;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
...@@ -13,6 +14,7 @@ import java.sql.SQLException; ...@@ -13,6 +14,7 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.engine.Constants; import org.h2.engine.Constants;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
...@@ -147,6 +149,8 @@ public class CreateCluster extends Tool { ...@@ -147,6 +149,8 @@ public class CreateCluster extends Tool {
try { try {
scriptOut = FileUtils.newOutputStream(scriptFile, false); scriptOut = FileUtils.newOutputStream(scriptFile, false);
Script.process(connSource, scriptOut); Script.process(connSource, scriptOut);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
} finally { } finally {
IOUtils.closeSilently(scriptOut); IOUtils.closeSilently(scriptOut);
} }
......
...@@ -254,7 +254,11 @@ public class Recover extends Tool implements DataHandler { ...@@ -254,7 +254,11 @@ public class Recover extends Tool implements DataHandler {
fileName = fileName.substring(0, fileName.length() - 3); fileName = fileName.substring(0, fileName.length() - 3);
String outputFile = fileName + suffix; String outputFile = fileName + suffix;
trace("Created file: " + outputFile); trace("Created file: " + outputFile);
return new PrintWriter(IOUtils.getBufferedWriter(FileUtils.newOutputStream(outputFile, false))); try {
return new PrintWriter(IOUtils.getBufferedWriter(FileUtils.newOutputStream(outputFile, false)));
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
} }
private void writeDataError(PrintWriter writer, String error, byte[] data) { private void writeDataError(PrintWriter writer, String error, byte[] data) {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.tools; package org.h2.tools;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.sql.Connection; import java.sql.Connection;
...@@ -13,6 +14,7 @@ import java.sql.DriverManager; ...@@ -13,6 +14,7 @@ import java.sql.DriverManager;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.message.DbException;
import org.h2.store.fs.FileUtils; import org.h2.store.fs.FileUtils;
import org.h2.util.IOUtils; import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils; import org.h2.util.JdbcUtils;
...@@ -131,6 +133,8 @@ public class Script extends Tool { ...@@ -131,6 +133,8 @@ public class Script extends Tool {
try { try {
o = FileUtils.newOutputStream(fileName, false); o = FileUtils.newOutputStream(fileName, false);
execute(url, user, password, o); execute(url, user, password, o);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
} finally { } finally {
IOUtils.closeSilently(o); IOUtils.closeSilently(o);
} }
......
...@@ -104,6 +104,11 @@ public class MathUtils { ...@@ -104,6 +104,11 @@ public class MathUtils {
return cachedSecureRandom; return cachedSecureRandom;
} }
/**
* Generate a seed value, using as much unpredictable data as possible.
*
* @return the seed
*/
public static byte[] generateAlternativeSeed() { public static byte[] generateAlternativeSeed() {
try { try {
ByteArrayOutputStream bout = new ByteArrayOutputStream(); ByteArrayOutputStream bout = new ByteArrayOutputStream();
......
...@@ -265,7 +265,8 @@ public abstract class TestBase { ...@@ -265,7 +265,8 @@ public abstract class TestBase {
} else { } else {
url = name; url = name;
} }
// url = addOption(url, "DEFAULT_TABLE_ENGINE", "org.h2.mvstore.db.MVTableEngine"); // url = addOption(url, "DEFAULT_TABLE_ENGINE",
// "org.h2.mvstore.db.MVTableEngine");
if (!config.memory) { if (!config.memory) {
if (config.smallLog && admin) { if (config.smallLog && admin) {
url = addOption(url, "MAX_LOG_SIZE", "1"); url = addOption(url, "MAX_LOG_SIZE", "1");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论