提交 88299ab9 authored 作者: Thomas Mueller's avatar Thomas Mueller

Documentation: added notranslate tags

上级 74d34875
......@@ -79,15 +79,19 @@ Before the result is returned to the application, all rows are read by the datab
Server side cursors are not supported currently.
If only the first few rows are interesting for the application, then the
result set size should be limited to improve the performance.
This can be done using LIMIT in a query (example: SELECT * FROM TEST LIMIT 100),
This can be done using <code class="notranslate">LIMIT</code> in a query
(example: <code class="notranslate">SELECT * FROM TEST LIMIT 100</code>),
or by using Statement.setMaxRows(max).
</p>
<h3>Large Result Sets and External Sorting</h3>
<p>
For large result set, the result is buffered to disk. The threshold can be defined using the statement SET MAX_MEMORY_ROWS.
If ORDER BY is used, the sorting is done using an external sort algorithm. In this case, each block of rows is sorted using
quick sort, then written to disk; when reading the data, the blocks are merged together.
For large result set, the result is buffered to disk. The threshold can be defined using the statement
<code class="notranslate">SET MAX_MEMORY_ROWS</code>.
If <code class="notranslate">ORDER BY</code> is used, the sorting is done using an
external sort algorithm.
In this case, each block of rows is sorted using quick sort, then written to disk;
when reading the data, the blocks are merged together.
</p>
<br />
......@@ -109,7 +113,7 @@ on the client side.
<p>
This database stores large LOB (CLOB and BLOB) objects as separate files.
Small LOB objects are stored in-place, the threshold can be set using
<a href="grammar.html#set_max_length_inplace_lob">MAX_LENGTH_INPLACE_LOB</a>,
<a href="grammar.html#set_max_length_inplace_lob" class="notranslate" >MAX_LENGTH_INPLACE_LOB</a>,
but there is still an overhead to use CLOB/BLOB. Because of this, BLOB and CLOB
should never be used for columns with a maximum size below about 200 bytes.
The best threshold depends on the use case; reading in-place objects is faster
......@@ -119,7 +123,8 @@ that don't involve this column.
<h3>Large Object Compression</h3>
<p>
CLOB and BLOB values can be compressed by using <a href="grammar.html#set_compress_lob">SET COMPRESS_LOB</a>.
CLOB and BLOB values can be compressed by using
<a href="grammar.html#set_compress_lob" class="notranslate" >SET COMPRESS_LOB</a>.
The LZF algorithm is faster but needs more disk space. By default compression is disabled, which usually speeds up write
operations. If you store many large compressible values such as XML, HTML, text, and uncompressed binary files,
then compressing can save a lot of disk space (sometimes more than 50%), and read operations may even be faster.
......@@ -129,9 +134,10 @@ then compressing can save a lot of disk space (sometimes more than 50%), and rea
<h2 id="linked_tables">Linked Tables</h2>
<p>
This database supports linked tables, which means tables that don't exist in the current database but
are just links to another database. To create such a link, use the CREATE LINKED TABLE statement:
are just links to another database. To create such a link, use the
<code class="notranslate">CREATE LINKED TABLE</code> statement:
</p>
<pre>
<pre class="notranslate">
CREATE LINKED TABLE LINK('org.postgresql.Driver', 'jdbc:postgresql:test', 'sa', 'sa', 'TEST');
</pre>
<p>
......@@ -147,10 +153,10 @@ To view the statements that are executed against the target table, set the trace
</p>
<p>
If multiple linked tables point to the same database (using the same database URL), the connection
is shared. To disable this, set the system property h2.shareLinkedConnections to false.
is shared. To disable this, set the system property <code class="notranslate">h2.shareLinkedConnections=false</code>.
</p>
<p>
The CREATE LINKED TABLE statement supports an optional schema name parameter.
The <code class="notranslate">CREATE LINKED TABLE</code> statement supports an optional schema name parameter.
See the grammar for details.
</p>
......@@ -232,24 +238,25 @@ for each connection.
The MVCC feature allows higher concurrency than using (table level or row level) locks.
When using MVCC in this database, delete, insert and update operations will only issue a
shared lock on the table. An exclusive lock is still used when adding or removing columns,
when dropping the table, and when using SELECT ... FOR UPDATE. Connections
only 'see' committed data, and own changes. That means, if connection A updates
when dropping the table, and when using <code class="notranslate">SELECT ... FOR UPDATE</code>.
Connections only 'see' committed data, and own changes. That means, if connection A updates
a row but doesn't commit this change yet, connection B will see the old value.
Only when the change is committed, the new value is visible by other connections
(read committed). If multiple connections concurrently try to update the same row, the
database waits until it can apply the change, but at most until the lock timeout expires.
</p>
<p>
To use the MVCC feature, append MVCC=TRUE to the database URL:
To use the MVCC feature, append <code class="notranslate">;MVCC=TRUE</code> to the database URL:
</p>
<pre>
<pre class="notranslate">
jdbc:h2:~/test;MVCC=TRUE
</pre>
<p>
The MVCC feature is not fully tested yet.
The limitations of the MVCC mode are: it can not be used at the same time as MULTI_THREADED;
The limitations of the MVCC mode are: it can not be used at the same time as
<code class="notranslate">MULTI_THREADED=TRUE</code>;
the complete undo log must fit in memory when using multi-version concurrency
(the setting MAX_MEMORY_UNDO has no effect).
(the setting <code class="notranslate">MAX_MEMORY_UNDO</code> has no effect).
</p>
<br />
......@@ -271,7 +278,8 @@ To initialize the cluster, use the following steps:
</p>
<ul>
<li>Create a database
</li><li>Use the CreateCluster tool to copy the database to another location and initialize the clustering.
</li><li>Use the <code class="notranslate">CreateCluster</code> tool to copy the database to
another location and initialize the clustering.
Afterwards, you have two databases containing the same data.
</li><li>Start two servers (one for each copy of the database)
</li><li>You are now ready to connect to the databases with the client application(s)
......@@ -288,7 +296,7 @@ databases will be on different servers.
Each directory will simulate a directory on a computer.
</li><li>Start a TCP server pointing to the first directory.
You can do this using the command line:
<pre>
<pre class="notranslate">
java org.h2.tools.Server
-tcp -tcpPort 9101
-baseDir server1
......@@ -296,12 +304,12 @@ java org.h2.tools.Server
</li><li>Start a second TCP server pointing to the second directory.
This will simulate a server running on a second (redundant) computer.
You can do this using the command line:
<pre>
<pre class="notranslate">
java org.h2.tools.Server
-tcp -tcpPort 9102
-baseDir server2
</pre>
</li><li>Use the CreateCluster tool to initialize clustering.
</li><li>Use the <code class="notranslate">CreateCluster</code> tool to initialize clustering.
This will automatically create a new, empty database if it does not exist.
Run the tool on the command line:
<pre class="notranslate">
......@@ -313,13 +321,13 @@ java org.h2.tools.CreateCluster
</pre>
</li><li>You can now connect to the databases using
an application or the H2 Console using the JDBC URL
jdbc:h2:tcp://localhost:9101,localhost:9102/~/test
<code class="notranslate">jdbc:h2:tcp://localhost:9101,localhost:9102/~/test</code>
</li><li>If you stop a server (by killing the process),
you will notice that the other machine continues to work,
and therefore the database is still accessible.
</li><li>To restore the cluster, you first need to delete the
database that failed, then restart the server that was stopped,
and re-run the CreateCluster tool.
and re-run the <code class="notranslate">CreateCluster</code> tool.
</li></ul>
<h3>Clustering Algorithm and Limitations</h3>
......@@ -327,9 +335,10 @@ and re-run the CreateCluster tool.
Read-only queries are only executed against the first cluster node, but all other statements are
executed against all nodes. There is currently no load balancing made to avoid problems with
transactions. The following functions may yield different results on different cluster nodes and must be
executed with care: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(),
CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should not be used
directly in modifying statements (for example INSERT, UPDATE, or MERGE). However, they can be used
executed with care: <code class="notranslate">RANDOM_UUID(), SECURE_RAND(), SESSION_ID(),
MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND()</code> [when not using a seed].
Those functions should not be used directly in modifying statements
(for example <code class="notranslate">INSERT, UPDATE, MERGE</code>). However, they can be used
in read-only statements and the result can then be used for modifying statements.
</p>
......@@ -373,12 +382,14 @@ Other database engines may commit the transaction in this case when the result s
There is a list of keywords that can't be used as identifiers (table names, column names and so on),
unless they are quoted (surrounded with double quotes). The list is currently:
</p><p>
<code class="notranslate">
CROSS, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, DISTINCT, EXCEPT, EXISTS, FALSE,
FOR, FROM, FULL, GROUP, HAVING, INNER, INTERSECT, IS, JOIN, LIKE, LIMIT, MINUS, NATURAL, NOT, NULL,
ON, ORDER, PRIMARY, ROWNUM, SELECT, SYSDATE, SYSTIME, SYSTIMESTAMP, TODAY, TRUE, UNION, WHERE
</code>
</p><p>
Certain words of this list are keywords because they are functions that can be used without '()' for compatibility,
for example CURRENT_TIMESTAMP.
for example <code class="notranslate">CURRENT_TIMESTAMP</code>.
</p>
<br />
......@@ -394,43 +405,43 @@ are not standardized. Whenever this is the case, this database tries to be compa
<h2 id="windows_service">Run as Windows Service</h2>
<p>
Using a native wrapper / adapter, Java applications can be run as a Windows Service.
There are various tools available to do that. The Java Service Wrapper from Tanuki Software, Inc.
(<a href="http://wrapper.tanukisoftware.org">http://wrapper.tanukisoftware.org</a>)
is included in the installation. Batch files are provided to install, start, stop and uninstall the H2 Database Engine Service.
This service contains the TCP Server and the H2 Console web application.
The batch files are located in the directory H2/service.
There are various tools available to do that. The Java Service Wrapper from
<a href="http://wrapper.tanukisoftware.org">Tanuki Software, Inc.</a>
is included in the installation. Batch files are provided to install, start, stop and uninstall the
H2 Database Engine Service. This service contains the TCP Server and the H2 Console web application.
The batch files are located in the directory <code class="notranslate">h2/service</code>.
</p>
<h3>Install the Service</h3>
<p>
The service needs to be registered as a Windows Service first.
To do that, double click on 1_install_service.bat.
To do that, double click on <code class="notranslate">1_install_service.bat</code>.
If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear.
</p>
<h3>Start the Service</h3>
<p>
You can start the H2 Database Engine Service using the service manager of Windows,
or by double clicking on 2_start_service.bat.
or by double clicking on <code class="notranslate">2_start_service.bat</code>.
Please note that the batch file does not print an error message if the service is not installed.
</p>
<h3>Connect to the H2 Console</h3>
<p>
After installing and starting the service, you can connect to the H2 Console application using a browser.
Double clicking on 3_start_browser.bat to do that. The
Double clicking on <code class="notranslate">3_start_browser.bat</code> to do that. The
default port (8082) is hard coded in the batch file.
</p>
<h3>Stop the Service</h3>
<p>
To stop the service, double click on 4_stop_service.bat.
To stop the service, double click on <code class="notranslate">4_stop_service.bat</code>.
Please note that the batch file does not print an error message if the service is not installed or started.
</p>
<h3>Uninstall the Service</h3>
<p>
To uninstall the service, double click on 5_uninstall_service.bat.
To uninstall the service, double click on <code class="notranslate">5_uninstall_service.bat</code>.
If successful, a command prompt window will pop up and disappear immediately. If not, a message will appear.
</p>
......@@ -463,7 +474,7 @@ The Windows version of the PostgreSQL ODBC driver is available at
<p>
After installing the ODBC driver, start the H2 Server using the command line:
</p>
<pre>
<pre class="notranslate">
java -cp h2*.jar org.h2.tools.Server
</pre>
<p>
......@@ -471,13 +482,13 @@ The PG Server (PG for PostgreSQL protocol) is started as well.
By default, databases are stored in the current working directory where the server is started.
Use -baseDir to save databases in another directory, for example the user home directory:
</p>
<pre>
<pre class="notranslate">
java -cp h2*.jar org.h2.tools.Server -baseDir ~
</pre>
<p>
The PG server can be started and stopped from within a Java application as follows:
</p>
<pre>
<pre class="notranslate">
Server server = Server.createPgServer("-baseDir", "~");
server.start();
...
......@@ -571,7 +582,7 @@ An implementation of the ADO.NET interface is available in the open source proje
If you want your C# application use H2, you need to add the h2.dll and the
IKVM.OpenJDK.ClassLibrary.dll to your C# solution. Here some sample code:
</p>
<pre>
<pre class="notranslate">
using System;
using java.sql;
......@@ -647,14 +658,15 @@ Making sure that committed transactions are not lost is more complicated than it
To guarantee complete durability, a database must ensure that the log record is on the hard drive
before the commit call returns. To do that, databases use different methods. One
is to use the 'synchronous write' file access mode. In Java, RandomAccessFile
supports the modes "rws" and "rwd":
supports the modes <code class="notranslate">"rws"</code> and <code class="notranslate">"rwd"</code>:
</p>
<ul>
<li>rwd: every update to the file's content is written synchronously to the underlying storage device.
</li><li>rws: in addition to rwd, every update to the metadata is written synchronously.</li>
<li><code class="notranslate">rwd</code>: every update to the file's content is written synchronously to the underlying storage device.
</li><li><code class="notranslate">rws</code>: in addition to rwd, every update to the metadata is written synchronously.</li>
</ul>
<p>
A test (org.h2.test.poweroff.TestWrite) with one of those modes achieves around 50 thousand write operations per second.
A test (<code class="notranslate">org.h2.test.poweroff.TestWrite</code>) with one of those modes achieves
around 50 thousand write operations per second.
Even when the operating system write buffer is disabled, the write rate is around 50 thousand operations per second.
This feature does not force changes to disk because it does not flush all buffers.
The test updates the same byte in the file again and again. If the hard drive was able to write at this rate,
......@@ -666,16 +678,18 @@ or about 120 revolutions per second. There is an overhead, so the maximum write
Calling fsync flushes the buffers. There are two ways to do that in Java:
</p>
<ul>
<li>FileDescriptor.sync(). The documentation says that this forces all system buffers to synchronize with the underlying device.
<li><code class="notranslate">FileDescriptor.sync()</code>. The documentation says that this forces all system
buffers to synchronize with the underlying device.
Sync is supposed to return after all in-memory modified copies of buffers associated with this FileDescriptor
have been written to the physical medium.
</li><li>FileChannel.force() (since JDK 1.4). This method is supposed to force any updates to this channel's file
to be written to the storage device that contains it.
</li><li><code class="notranslate">FileChannel.force()</code> (since JDK 1.4). This method is supposed
to force any updates to this channel's file to be written to the storage device that contains it.
</li></ul>
<p>
By default, MySQL calls fsync for each commit. When using one of those methods, only around 60 write operations
per second can be achieved, which is consistent with the RPM rate of the hard drive used.
Unfortunately, even when calling FileDescriptor.sync() or FileChannel.force(),
Unfortunately, even when calling <code class="notranslate">FileDescriptor.sync()</code> or
<code class="notranslate">FileChannel.force()</code>,
data is not always persisted to the hard drive, because most hard drives do not obey
fsync(): see
<a href="http://hardware.slashdot.org/article.pl?sid=05/05/13/0529252">Your Hard Drive Lies to You</a>.
......@@ -692,7 +706,8 @@ Because of those reasons, the default behavior of H2 is to delay writing committ
</p>
<p>
In H2, after a power failure, a bit more than one second of committed transactions may be lost.
To change the behavior, use SET WRITE_DELAY and CHECKPOINT SYNC.
To change the behavior, use <code class="notranslate">SET WRITE_DELAY</code> and
<code class="notranslate">CHECKPOINT SYNC</code>.
Most other databases support commit delay as well.
In the performance comparison, commit delay was used for all databases that support it.
</p>
......@@ -700,7 +715,8 @@ In the performance comparison, commit delay was used for all databases that supp
<h3>Running the Durability Test</h3>
<p>
To test the durability / non-durability of this and other databases, you can use the test application
in the package org.h2.test.poweroff. Two computers with network connection are required to run this test.
in the package <code class="notranslate">org.h2.test.poweroff</code>.
Two computers with network connection are required to run this test.
One computer just listens, while the test application is run (and power is cut) on the other computer.
The computer with the listener application opens a TCP/IP port and listens for an incoming connection.
The second computer first connects to the listener, and then created the databases and starts inserting
......@@ -719,7 +735,7 @@ The recover tool can be used to extract the contents of a data file, even if the
It also extracts the content of the log file or large objects (CLOB or BLOB).
To run the tool, type on the command line:
</p>
<pre>
<pre class="notranslate">
java -cp h2*.jar org.h2.tools.Recover
</pre>
<p>
......@@ -727,14 +743,14 @@ For each database in the current directory, a text file will be created.
This file contains raw insert statements (for the data) and data definition (DDL) statements to recreate
the schema of the database. This file can be executed using the RunScript tool or a
<code class="notranslate">RUNSCRIPT FROM</code> SQL statement. The script includes at least one
CREATE USER statement. If you run the script against a database that was created with the same
<code class="notranslate">CREATE USER</code> statement. If you run the script against a database that was created with the same
user, or if there are conflicting users, running the script will fail. Consider running the script
against a database that was created with a user name that is not in the script.
</p>
<p>
The recover tool creates a SQL script from the .data.db file. It also processes the transaction log file(s),
The recover tool creates a SQL script from database files. It also processes the transaction log file(s),
however it does not automatically apply those changes. Usually, many of those changes are already
applied in the .data.db file.
applied in the database.
</p>
<br />
......@@ -759,7 +775,8 @@ The two methods are 'file method' and 'socket methods'.
The default method for database file locking is the 'File Method'. The algorithm is:
</p>
<ul>
<li>If the lock file does not exist, it is created (using the atomic operation File.createNewFile).
<li>If the lock file does not exist, it is created (using the atomic operation
<code class="notranslate">File.createNewFile</code>).
Then, the process waits a little bit (20ms) and checks the file again. If the file was changed
during this time, the operation is aborted. This protects against a race condition
when one process deletes the lock file just after another one create it, and a third process creates
......@@ -827,16 +844,17 @@ This database engine provides a solution for the security vulnerability known as
Here is a short description of what SQL injection means.
Some applications build SQL statements with embedded user input such as:
</p>
<pre>
<pre class="notranslate">
String sql = "SELECT * FROM USERS WHERE PASSWORD='"+pwd+"'";
ResultSet rs = conn.createStatement().executeQuery(sql);
</pre>
<p>
If this mechanism is used anywhere in the application, and user input is not correctly filtered or encoded,
it is possible for a user to inject SQL functionality or statements by using specially built input
such as (in this example) this password: ' OR ''='. In this case the statement becomes:
such as (in this example) this password: <code class="notranslate">' OR ''='</code>.
In this case the statement becomes:
</p>
<pre>
<pre class="notranslate">
SELECT * FROM USERS WHERE PASSWORD='' OR ''='';
</pre>
<p>
......@@ -847,9 +865,9 @@ For more information about SQL Injection, see Glossary and Links.
<h3>Disabling Literals</h3>
<p>
SQL Injection is not possible if user input is not directly embedded in SQL statements.
A simple solution for the problem above is to use a PreparedStatement:
A simple solution for the problem above is to use a prepared statement:
</p>
<pre>
<pre class="notranslate">
String sql = "SELECT * FROM USERS WHERE PASSWORD=?";
PreparedStatement prep = conn.prepareStatement(sql);
prep.setString(1, pwd);
......@@ -860,28 +878,31 @@ This database provides a way to enforce usage of parameters when passing user in
to the database. This is done by disabling embedded literals in SQL statements.
To do this, execute the statement:
</p>
<pre>
<pre class="notranslate">
SET ALLOW_LITERALS NONE;
</pre>
<p>
Afterwards, SQL statements with text and number literals are not allowed any more.
That means, SQL statement of the form WHERE NAME='abc' or WHERE CustomerId=10 will fail.
It is still possible to use PreparedStatements and parameters as described above. Also, it is still possible to generate
That means, SQL statement of the form <code class="notranslate">WHERE NAME='abc'</code>
or <code class="notranslate">WHERE CustomerId=10</code> will fail.
It is still possible to use prepared statements and parameters as described above. Also, it is still possible to generate
SQL statements dynamically, and use the Statement API, as long as the SQL statements
do not include literals.
There is also a second mode where number literals are allowed: SET ALLOW_LITERALS NUMBERS.
To allow all literals, execute SET ALLOW_LITERALS ALL (this is the default setting).
Literals can only be enabled or disabled by an administrator.
There is also a second mode where number literals are allowed:
<code class="notranslate">SET ALLOW_LITERALS NUMBERS</code>.
To allow all literals, execute <code class="notranslate">SET ALLOW_LITERALS ALL</code>
(this is the default setting). Literals can only be enabled or disabled by an administrator.
</p>
<h3>Using Constants</h3>
<p>
Disabling literals also means disabling hard-coded 'constant' literals. This database supports
defining constants using the CREATE CONSTANT command. Constants can be defined only
defining constants using the <code class="notranslate">CREATE CONSTANT</code> command.
Constants can be defined only
when literals are enabled, but used even when literals are disabled. To avoid name clashes
with column names, constants can be defined in other schemas:
</p>
<pre>
<pre class="notranslate">
CREATE SCHEMA CONST AUTHORIZATION SA;
CREATE CONSTANT CONST.ACTIVE VALUE 'Active';
CREATE CONSTANT CONST.INACTIVE VALUE 'Inactive';
......@@ -895,9 +916,9 @@ time, the source code is easier to understand and change.
<h3>Using the ZERO() Function</h3>
<p>
It is not required to create a constant for the number 0 as there is already a built-in function ZERO():
It is not required to create a constant for the number 0 as there is already a built-in function <code class="notranslate">ZERO()</code>:
</p>
<pre>
<pre class="notranslate">
SELECT * FROM USERS WHERE LENGTH(PASSWORD)=ZERO();
</pre>
......@@ -906,8 +927,9 @@ SELECT * FROM USERS WHERE LENGTH(PASSWORD)=ZERO();
<p>
By default this database does not allow others to connect when starting the H2 Console,
the TCP server, or the PG server. Remote access can be enabled using the command line
options -webAllowOthers, -tcpAllowOthers, and -pgAllowOthers. If you enable remote
access, please also consider using the options -baseDir and -ifExists, so that remote
options <code class="notranslate">-webAllowOthers, -tcpAllowOthers, -pgAllowOthers</code>.
If you enable remote access, please also consider using the options
<code class="notranslate">-baseDir, -ifExists</code>, so that remote
users can not create new databases or access existing databases with weak passwords. Also,
ensure the existing accessible databases are protected using a strong password.
</p>
......@@ -916,9 +938,10 @@ ensure the existing accessible databases are protected using a strong password.
<h2 id="restricting_classes">Restricting Class Loading and Usage</h2>
<p>
By default there is no restriction on loading classes and executing Java code for admins.
That means an admin may call system functions such as System.setProperty by executing:
That means an admin may call system functions such as
<code class="notranslate">System.setProperty</code> by executing:
</p>
<pre>
<pre class="notranslate">
CREATE ALIAS SET_PROPERTY FOR "java.lang.System.setProperty";
CALL SET_PROPERTY('abc', '1');
CREATE ALIAS GET_PROPERTY FOR "java.lang.System.getProperty";
......@@ -926,11 +949,12 @@ CALL GET_PROPERTY('abc');
</pre>
<p>
To restrict users (including admins) from loading classes and executing code,
the list of allowed classes can be set in the system property h2.allowedClasses
the list of allowed classes can be set in the system property
<code class="notranslate">h2.allowedClasses</code>
in the form of a comma separated list of classes or patterns (items ending with '*').
By default all classes are allowed. Example:
</p>
<pre>
<pre class="notranslate">
java -Dh2.allowedClasses=java.lang.Math,com.acme.*
</pre>
<p>
......@@ -1028,8 +1052,8 @@ database operations take about 2.2 times longer when using XTEA, and 2.5 times l
<h3>Wrong Password / User Name Delay</h3>
<p>
To protect against remote brute force password attacks, the delay after each unsuccessful
login gets double as long. Use the system properties h2.delayWrongPasswordMin
and h2.delayWrongPasswordMax to change the minimum (the default is 250 milliseconds)
login gets double as long. Use the system properties <code class="notranslate">h2.delayWrongPasswordMin</code>
and <code class="notranslate">h2.delayWrongPasswordMax</code> to change the minimum (the default is 250 milliseconds)
or maximum delay (the default is 4000 milliseconds, or 4 seconds). The delay only
applies for those using the wrong password. Normally there is no delay for a user that knows the correct
password, with one exception: after using the wrong password, there is a delay of up to (randomly distributed)
......@@ -1045,7 +1069,7 @@ if the user name was wrong or the password.
<h3>HTTPS Connections</h3>
<p>
The web server supports HTTP and HTTPS connections using SSLServerSocket.
The web server supports HTTP and HTTPS connections using <code class="notranslate">SSLServerSocket</code>.
There is a default self-certified certificate to support an easy starting point, but
custom certificates are supported as well.
</p>
......@@ -1054,7 +1078,7 @@ custom certificates are supported as well.
<h2 id="ssl_tls_connections">SSL/TLS Connections</h2>
<p>
Remote SSL/TLS connections are supported using the Java Secure Socket Extension
(SSLServerSocket / SSLSocket). By default, anonymous SSL is enabled.
(<code class="notranslate">SSLServerSocket, SSLSocket</code>). By default, anonymous SSL is enabled.
The default cipher suite is <code class="notranslate">SSL_DH_anon_WITH_RC4_128_MD5</code>.
</p>
<p>
......@@ -1077,11 +1101,12 @@ With random UUIDs, the chance of two having the same value can be calculated
using the probability theory. See also 'Birthday Paradox'.
Standardized randomly generated UUIDs have 122 random bits.
4 bits are used for the version (Randomly generated UUID), and 2 bits for the variant (Leach-Salz).
This database supports generating such UUIDs using the built-in function RANDOM_UUID().
This database supports generating such UUIDs using the built-in function
<code class="notranslate">RANDOM_UUID()</code>.
Here is a small program to estimate the probability of having two identical UUIDs
after generating a number of values:
</p>
<pre>
<pre class="notranslate">
public class Test {
public static void main(String[] args) throws Exception {
double x = Math.pow(2, 122);
......@@ -1113,16 +1138,16 @@ that means the probability is about 0.000'000'000'06.
<h2 id="system_properties">Settings Read from System Properties</h2>
<p>
Some settings of the database can be set on the command line using
-DpropertyName=value. It is usually not required to change those settings manually.
<code class="notranslate">-DpropertyName=value</code>. It is usually not required to change those settings manually.
The settings are case sensitive.
Example:
</p>
<pre>
<pre class="notranslate">
java -Dh2.serverCachedObjects=256 org.h2.tools.Server
</pre>
<p>
The current value of the settings can be read in the table
INFORMATION_SCHEMA.SETTINGS.
<code class="notranslate">INFORMATION_SCHEMA.SETTINGS</code>.
</p>
<p>
For a complete list of settings, see
......@@ -1134,7 +1159,7 @@ For a complete list of settings, see
<p>
Usually server sockets accept connections on any/all local addresses.
This may be a problem on multi-homed hosts.
To bind only to one address, use the system property h2.bindAddress.
To bind only to one address, use the system property <code class="notranslate">h2.bindAddress</code>.
This setting is used for both regular server sockets and for SSL server sockets.
IPv4 and IPv6 address formats are supported.
</p>
......@@ -1145,20 +1170,20 @@ IPv4 and IPv6 address formats are supported.
This database supports a pluggable file system API. The file system implementation
is selected using a file name prefix. The following file systems are included:
</p>
<ul><li><b>zip:</b> read-only zip-file based file system. Format: zip:/zipFileName!/fileName.
</li><li><b>nio:</b> file system that uses FileChannel instead of RandomAccessFile (faster in some operating systems).
</li><li><b>nioMapped:</b> file system that uses memory mapped files (faster in some operating systems).
</li><li><b>split:</b> file system that splits files in 1 GB files (stackable with other file systems).
</li><li><b>memFS:</b> in-memory file system (experimental; used for testing).
</li><li><b>memLZF:</b> compressing in-memory file system (experimental; used for testing).
<ul><li><code class="notranslate">zip:</code> read-only zip-file based file system. Format: <code class="notranslate">zip:/zipFileName!/fileName</code>.
</li><li><code class="notranslate">nio:</code> file system that uses <code class="notranslate">FileChannel</code> instead of <code class="notranslate">RandomAccessFile</code> (faster in some operating systems).
</li><li><code class="notranslate">nioMapped:</code> file system that uses memory mapped files (faster in some operating systems).
</li><li><code class="notranslate">split:</code> file system that splits files in 1 GB files (stackable with other file systems).
</li><li><code class="notranslate">memFS:</code> in-memory file system (experimental; used for testing).
</li><li><code class="notranslate">memLZF:</code> compressing in-memory file system (experimental; used for testing).
</li></ul>
<p>
As an example, to use the the <b>nio</b> file system, use the following database URL:
As an example, to use the the <code class="notranslate">nio</code> file system, use the following database URL:
<code class="notranslate">jdbc:h2:nio:~/test</code>.
</p>
<p>
To register a new file system, extend the classes org.h2.store.fs.FileSystem and FileObject,
and call the method FileSystem.register before using it.
To register a new file system, extend the classes <code class="notranslate">org.h2.store.fs.FileSystem, FileObject</code>,
and call the method <code class="notranslate">FileSystem.register</code> before using it.
</p>
<br />
......@@ -1182,7 +1207,7 @@ files of 1 GB by default. An example database URL is:
With the page store (experimental), the minimum main memory required is much lower, around 1 MB for each 8 GB database file size.
</li><li>Limit on the complexity of SQL statements.
Statements of the following form will result in a stack overflow exception:
<pre>
<pre class="notranslate">
SELECT * FROM DUAL WHERE X = 1
OR X = 2 OR X = 2 OR X = 2 OR X = 2 OR X = 2
-- repeat previous line 500 times --
......
......@@ -67,9 +67,9 @@ Newer version or compatible software works too.
<h2 id="building">Building the Software</h2>
<p>
You need to install a JDK, for example the Sun JDK version 1.5 or 1.6.
Ensure that Java binary directory is included in the PATH environment variable, and that
the environment variable JAVA_HOME points to your Java installation.
On the command line, go to the directory h2 and execute the following command:
Ensure that Java binary directory is included in the <code class="notranslate">PATH</code> environment variable, and that
the environment variable <code class="notranslate">JAVA_HOME</code> points to your Java installation.
On the command line, go to the directory <code class="notranslate">h2</code> and execute the following command:
</p>
<pre class="notranslate">
build -?
......@@ -98,13 +98,18 @@ build switchSource
<p>
The build system can generate smaller jar files as well. The following targets are currently supported:
</p>
<ul><li>jarClient creates the h2client.jar. This only contains the JDBC client.
</li><li>jarSmall creates the file h2small.jar. This only contains the embedded database. Debug information is disabled.
</li><li>jarJaqu creates the file h2jaqu.jar. This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu.
</li><li>javadocImpl creates the Javadocs of the implementation.
<ul><li><code class="notranslate">jarClient</code>
creates the file <code class="notranslate">h2client.jar</code>. This only contains the JDBC client.
</li><li><code class="notranslate">jarSmall</code>
creates the file <code class="notranslate">h2small.jar</code>.
This only contains the embedded database. Debug information is disabled.
</li><li><code class="notranslate">jarJaqu</code>
creates the file <code class="notranslate">h2jaqu.jar</code>.
This only contains the JaQu (Java Query) implementation. All other jar files do not include JaQu.
</li><li><code class="notranslate">javadocImpl</code> creates the Javadocs of the implementation.
</li></ul>
<p>
To create the h2client.jar file, go to the directory h2 and execute the following command:
To create the file <code class="notranslate">h2client.jar</code>, go to the directory h2 and execute the following command:
</p>
<pre class="notranslate">
build jarClient
......@@ -132,7 +137,7 @@ they are available there.
<h3>Using Snapshot Version</h3>
<p>
To build a 'snapshot' H2 .jar file and upload it the to the local Maven 2 repository, execute the following command:
To build a 'snapshot' H2 jar file and upload it the to the local Maven 2 repository, execute the following command:
</p>
<pre class="notranslate">
build mavenInstallLocal
......@@ -154,14 +159,16 @@ Afterwards, you can include the database in your Maven 2 project as a dependency
The translation of this software is split into the following parts:
</p>
<ul>
<li>H2 Console: src/main/org/h2/server/web/res/_text_*.properties
</li><li>Error messages: src/main/org/h2/res/_messages_*.properties
</li><li>Web site: src/docsrc/text/_docs_*.utf8.txt
<li>H2 Console: <code class="notranslate">src/main/org/h2/server/web/res/_text_*.properties</code>
</li><li>Error messages: <code class="notranslate">src/main/org/h2/res/_messages_*.properties</code>
</li><li>Web site: <code class="notranslate">src/docsrc/text/_docs_*.utf8.txt</code>
</li></ul>
<p>
To translate the H2 Console, start it and select Preferences / Translate.
The conversion between UTF-8 and Java encoding (using the \u syntax), as well as the HTML entities (&amp;#..;)
is automated by running the tool PropertiesToUTF8. The web site translation is automated as well,
The conversion between UTF-8 and Java encoding (using the <code class="notranslate">\u</code> syntax),
as well as the HTML entities (<code class="notranslate">&amp;#..;</code>)
is automated by running the tool <code class="notranslate">PropertiesToUTF8</code>.
The web site translation is automated as well,
using <code class="notranslate">build docs</code>.
</p>
......@@ -176,18 +183,23 @@ If you like to provide patches, please consider the following guidelines to simp
The checkstyle configuration is in <code class="notranslate">src/installer/checkstyle.xml</code>.
</li><li>Please provide test cases and integrate them into the test suite.
For Java level tests, see <code class="notranslate">src/test/org/h2/test/TestAll.java</code>.
For SQL level tests, see <code class="notranslate">src/test/org/h2/test/test.in.txt</code> or <code class="notranslate">testSimple.in.txt</code>.
</li><li>The test cases should cover at least 90% of the changed and new code; use a code coverage tool to verify that (see above).
or use the build target 'coverage'.
</li><li>Verify that you did not break other features: run the test cases by executing <code class="notranslate">build test</code>.
For SQL level tests, see <code class="notranslate">src/test/org/h2/test/test.in.txt</code> or
<code class="notranslate">testSimple.in.txt</code>.
</li><li>The test cases should cover at least 90% of the changed and new code;
use a code coverage tool to verify that (see above).
or use the build target <code class="notranslate">coverage</code>.
</li><li>Verify that you did not break other features: run the test cases by executing
<code class="notranslate">build test</code>.
</li><li>Provide end user documentation if required (<code class="notranslate">src/docsrc/html/*</code>).
</li><li>Document grammar changes in <code class="notranslate">src/main/org/h2/res/help.csv</code>
</li><li>Provide a change log entry (<code class="notranslate">src/docsrc/html/changelog.html</code>).
</li><li>Verify the spelling using <code class="notranslate">build spellcheck</code>. If required
add the new words to <code class="notranslate">src/tools/org/h2/build/doc/dictionary.txt</code>.
</li><li>Run the src/installer/buildRelease to find and fix formatting errors.
</li><li>Verify the formatting using <code class="notranslate">build docs</code> and <code class="notranslate">build javadoc</code>.
</li><li>Submit patches as .patch files (compressed if big). To create a patch using Eclipse, use Team / Create Patch.
</li><li>Run the <code class="notranslate">src/installer/buildRelease</code> to find and fix formatting errors.
</li><li>Verify the formatting using <code class="notranslate">build docs</code> and
<code class="notranslate">build javadoc</code>.
</li><li>Submit patches as <code class="notranslate">.patch</code> files (compressed if big).
To create a patch using Eclipse, use Team / Create Patch.
</li></ul>
<p>
For legal reasons, patches need to be public in the form of an email to the
......
......@@ -18,7 +18,9 @@ Change Log
<h1>Change Log</h1>
<h2>Next Version (unreleased)</h2>
<ul><li>If a database in the old format exists, it is now used.
<ul><li>Better support GaeVFS (Google App Engine Virtual File System) thanks to Thanks to Vince Bonfanti.
</li><li>CSVREAD: the function didn't close the file. Thanks to Vince Bonfanti for the patch!
</li><li>If a database in the old format exists, it is now used.
The system property is used for new databases, or if databases exist
in both formats. In any case, the flag in the URL overrides this logic.
</li><li>Page store: large values in indexed columns could corrupt the index.
......
......@@ -47,18 +47,20 @@ Usually, bugs get fixes as they are found. There is a release every few weeks.
Here is the list of known and confirmed issues:
</p>
<ul><li>Tomcat and Glassfish 3 set most static fields (final or non-final) to null when
unloading a web application. This can cause a NullPointerException in H2 versions
unloading a web application. This can cause a <code class="notranslate">NullPointerException</code> in H2 versions
1.1.107 and older, and may still not work in newer versions. Please report it if you
run into this issue. In Tomcat >= 6.0 this behavior can be disabled by setting the
system property org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES
system property <code class="notranslate">org.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES</code>
to false, however Tomcat may then run out of memory. A known workaround is to
put the h2.jar file in a shared <code class="notranslate">lib</code> directory (common/lib).
put the h2.jar file in a shared <code class="notranslate">lib</code> directory
(<code class="notranslate">common/lib</code>).
</li><li>Some problems have been found with right outer join. Internally, it is converted
to left outer join, which does not always produce the same results as other databases
when used in combination with other joins.
</li><li>When using Install4j before 4.1.4 on Linux and enabling 'pack200',
the h2*.jar becomes corrupted by the install process, causing application failure.
A workaround is to add an empty file h2*.jar.nopack next to the h2*.jar file.
the <code class="notranslate">h2*.jar</code> becomes corrupted by the install process, causing application failure.
A workaround is to add an empty file <code class="notranslate">h2*.jar.nopack</code>
next to the <code class="notranslate">h2*.jar</code> file.
This problem is solved in Install4j 4.1.4.
</li></ul>
......@@ -72,13 +74,15 @@ See also under license.
<br />
<h3 id="query_slow">My Query is Slow</h3>
<p>
Slow SELECT (or DELETE, UPDATE, MERGE) statement can have multiple reasons.
Follow this checklist:
Slow <code class="notranslate">SELECT</code> (or <code class="notranslate">DELETE, UPDATE, MERGE</code>)
statement can have multiple reasons. Follow this checklist:
</p>
<ul>
<li>Run ANALYZE (see documentation for details).
</li><li>Run the query with EXPLAIN and check if indexes are used (see documentation for details).
</li><li>If required, create additional indexes and try again using ANALYZE and EXPLAIN.
<li>Run <code class="notranslate">ANALYZE</code> (see documentation for details).
</li><li>Run the query with <code class="notranslate">EXPLAIN</code> and check if indexes are used
(see documentation for details).
</li><li>If required, create additional indexes and try again using
<code class="notranslate">ANALYZE</code> and <code class="notranslate">EXPLAIN</code>.
</li><li>If it doesn't help please report the problem.
</li>
</ul>
......@@ -104,13 +108,18 @@ Connection conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "");
<br />
<h3 id="database_files">Where are the Database Files Stored?</h3>
<p>
When using database URLs like <code class="notranslate">jdbc:h2:~/test</code>, the database is stored in the user directory.
For Windows, this is usually C:\Documents and Settings\&lt;userName&gt;".
If the base directory is not set (as in <code class="notranslate">jdbc:h2:test</code>), the database files are stored in the directory where the application is started
(the current working directory). When using the H2 Console application from the start menu, this is "&lt;Installation Directory&gt;/bin".
When using database URLs like <code class="notranslate">jdbc:h2:~/test</code>,
the database is stored in the user directory.
For Windows, this is usually C:\Documents and Settings\&lt;userName&gt;.
If the base directory is not set (as in <code class="notranslate">jdbc:h2:test</code>),
the database files are stored in the directory where the application is started
(the current working directory). When using the H2 Console application from the start menu,
this is "&lt;Installation Directory&gt;/bin".
The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL
jdbc:h2:file:data/sample, the database is stored in the directory "data" (relative to the current working directory).
The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name).
<code class="notranslate">jdbc:h2:file:data/sample</code>, the database is stored in the directory
<code class="notranslate">data</code> (relative to the current working directory).
The directory is created automatically if it does not yet exist. It is also possible to use the
fully qualified directory name (and for Windows, drive name).
Example: <code class="notranslate">jdbc:h2:file:C:/data/test</code>
</p>
......@@ -125,9 +134,10 @@ See <a href="advanced.html#limits_limitations">Limits and Limitations</a>.
<p>
Some users have reported that after a power failure, the database can sometimes not be
opened because the index file is corrupt. In that case, the index file can be deleted
(it is automatically re-created). To avoid this, append ;LOG=2 to the database URL.
See also: <a href="grammar.html#set_log">SET LOG</a>. This problem will be solved
using the new 'page store' mechanism (currently experimental).
(it is automatically re-created). To avoid this, append
<code class="notranslate">;LOG=2</code> to the database URL.
See also: <a href="grammar.html#set_log" class="notranslate">SET LOG</a>. This problem will be solved
using the new 'page store' mechanism (currently beta).
</p>
<p>
That is not easy to say. It is still a quite new product. A lot of tests have been written,
......@@ -138,11 +148,13 @@ to be dangerous, they are only supported for situations where performance is mor
than reliability. Those dangerous features are:
</p>
<ul>
<li>Disabling the transaction log mechanism using SET LOG 0.
</li><li>Using the transaction isolation level READ_UNCOMMITTED (LOCK_MODE 0) while at the same time using multiple
<li>Disabling the transaction log mechanism using <code class="notranslate">SET LOG 0</code>.
</li><li>Using the transaction isolation level <code class="notranslate">READ_UNCOMMITTED</code>
(<code class="notranslate">LOCK_MODE 0</code>) while at the same time using multiple
connections.
</li><li>Disabling database file protection using FILE_LOCK=NO in the database URL.
</li><li>Disabling referential integrity using SET REFERENTIAL_INTEGRITY FALSE.
</li><li>Disabling database file protection using <code class="notranslate">FILE_LOCK=NO</code>
in the database URL.
</li><li>Disabling referential integrity using <code class="notranslate">SET REFERENTIAL_INTEGRITY FALSE</code>.
</li></ul>
<p>
In addition to that, running out of memory should be avoided.
......@@ -153,7 +165,8 @@ Areas that are not fully tested:
</p>
<ul>
<li>Platforms other than Windows XP, Linux, Mac OS X, or JVMs other than Sun 1.5 or 1.6
</li><li>The features AUTO_SERVER and AUTO_RECONNECT
</li><li>The features <code class="notranslate">AUTO_SERVER</code> and
<code class="notranslate">AUTO_RECONNECT</code>
</li><li>The MVCC (multi version concurrency) mode
</li><li>Cluster mode, 2-phase commit, savepoints
</li><li>24/7 operation
......@@ -164,12 +177,11 @@ Areas that are not fully tested:
</li></ul>
<p>
Areas considered Experimental:
Areas considered experimental are:
</p>
<ul>
<li>The PostgreSQL server
</li><li>The new page store
</li><li>Multi-threading within the engine using SET MULTI_THREADED=1
</li><li>Multi-threading within the engine using <code class="notranslate">SET MULTI_THREADED=1</code>
</li><li>Compatibility modes for other databases (only some features are implemented)
</li></ul>
......@@ -179,10 +191,12 @@ Areas considered Experimental:
If it takes a long time to open a database, in most cases it was not closed the last time.
This is specially a problem for larger databases.
To close a database, close all connections to it before the application ends, or execute
the command SHUTDOWN. The database is also closed when the virtual machine exits normally
the command <code class="notranslate">SHUTDOWN</code>.
The database is also closed when the virtual machine exits normally
by using a shutdown hook. However killing a Java process or calling Runtime.halt will prevent this.
The reason why opening is slow in this situations is that indexes are re-created.
If you can not guarantee the database is closed, consider using SET LOG 2 (see SQL Grammar).
If you can not guarantee the database is closed, consider using
<code class="notranslate">SET LOG 2</code> (see SQL Grammar).
</p>
<p>
To find out what the problem is, open the database in embedded mode using the H2 Console.
......
......@@ -65,33 +65,53 @@ After installing, you should get the following directory structure:
<th>Contents</th>
</tr>
<tr>
<td>bin</td>
<td class="notranslate">bin</td>
<td>JAR and batch files</td>
</tr>
<tr>
<td>docs</td>
<td class="notranslate">docs</td>
<td>Documentation</td>
</tr>
<tr>
<td>docs/html</td>
<td class="notranslate">docs/html</td>
<td>HTML pages</td>
</tr>
<tr>
<td>docs/javadoc</td>
<td class="notranslate">docs/javadoc</td>
<td>Javadoc files</td>
</tr>
<tr>
<td>ext</td>
<td class="notranslate">ext</td>
<td>External dependencies (downloaded when building)</td>
</tr>
<tr>
<td>service</td>
<td class="notranslate">service</td>
<td>Tools to run the database as a Windows Service</td>
</tr>
<tr>
<td>src</td>
<td class="notranslate">src</td>
<td>Source files</td>
</tr>
<tr>
<td class="notranslate">src/docsrc</td>
<td>Documentation sources</td>
</tr>
<tr>
<td class="notranslate">src/installer</td>
<td>Installer, shell, and release build script</td>
</tr>
<tr>
<td class="notranslate">src/main</td>
<td>Database engine source code</td>
</tr>
<tr>
<td class="notranslate">src/test</td>
<td>Test source code</td>
</tr>
<tr>
<td class="notranslate">src/tools</td>
<td>Tools and database adapters source code</td>
</tr>
</table>
<!-- [close] { --></div></td></tr></table><!-- } --><!-- analytics --></body></html>
......
......@@ -57,7 +57,7 @@ Click [Start], [All Programs], [H2], and [H2 Console (Command Line)]:<br />
<img class="screenshot" src="images/quickstart-1.png" alt="screenshot: start H2 Console" /><br />
A new console window appears:<br />
<img class="screenshot" src="images/quickstart-2.png" alt="screenshot: H2 running" /><br />
Also, a new browser page should open with the URL <a href="http://localhost:8082">http://localhost:8082</a>.
Also, a new browser page should open with the URL <a href="http://localhost:8082" class="notranslate">http://localhost:8082</a>.
You may get a security warning from the firewall. If you don't want other computers in the network to access the database
on your machine, you can let the firewall block these connections. Only local connections are required at this time.
</p>
......
......@@ -461,7 +461,13 @@ See also <a href="build.html#providing_patches">Providing Patches</a>.
</li><li>Fast scrambling (strong encryption doesn't help if the password is included in the application).
</li><li>Faster startup if there is a large number of LOB files.
</li><li>Support using system properties in database URLs (may be a security problem).
</li><li>The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number.
</li><li>Issue 126: The index name should be "IDX_" plus the constraint name unless there is a conflict, in which case append a number.
</li><li>Issue 127: Support activation/deactivation of triggers
</li><li>Issue 130: Custom log event listeners
</li><li>Issue 131: IBM DB2 compatibility: sysibm.sysdummy1
</li><li>Issue 132: Use Java enum trigger type.
</li><li>Issue 134: IBM DB2 compatibility: session global variables.
</li><li>FTL_SET_OPTION(keyString, valueString) with key stopWords at first.
</li></ul>
<h2>Not Planned</h2>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论