Skip to content

Commit

Permalink
Updates to Console and SQL syntax.
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethpjdyer committed Apr 27, 2015
1 parent 58bcc49 commit ddf3f1d
Show file tree
Hide file tree
Showing 123 changed files with 2,055 additions and 1,613 deletions.
14 changes: 7 additions & 7 deletions Backup-and-Restore.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ For more information about [LVM](http://en.wikipedia.org/wiki/Logical_Volume_Man
### Using the console
You can also use the [console](Console-command-Backup.md) to execute a backup. Below the same backup like before, but using the console.
```sql
orientdb> connect plocal:../database/testdb admin admin
orientdb> backup database /dest/folder/backup.zip
orientdb> CONNECT plocal:../database/testdb admin admin
orientdb> BACKUP DATABASE /dest/folder/backup.zip
Backup executed in 0,52 seconds
```

## Restore database
Use the [console](Console-command-Restore.md) to restore a database. Example:

```
orientdb> restore database /backups/mydb.zip
orientdb> RESTORE DATABASE /backups/mydb.zip
Restore executed in 6,33 seconds
```

## See also
- [Backup Database](Console-command-Backup.md)
- [Restore Database](Console-command-Restore.md)
- [Export Database](Console-command-Export.md)
- [Import Database](Console-command-Import.md)
- [BACKUP DATABASE](Console-command-Backup.md)
- [RESTORE DATABASE](Console-command-Restore.md)
- [EXPORT DATABASE](Console-command-Export.md)
- [IMPORT DATABASE](Console-command-Import.md)
- [Console-Commands](Console-Commands.md)
5 changes: 4 additions & 1 deletion Caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ When the client application asks for a record OrientDB checks:
Local cache acts at database level. Each database instance has a Local cache enabled by default. This cache keeps the used records. Records will be removed from heap if 2 conditions will be satisfied:

1. There are no links to these records from outside of database
2. The Java Virtual Machine doesn't have enough memory to allocate for new data
1. The Java Virtual Machine doesn't have enough memory to allocate for new data

## Empty Local cache

Expand All @@ -51,10 +51,13 @@ Disabling of local cache may lead to situation when 2 different instances of the
and OConcurrentModificationException may be thrown during record update even in single thread mode.

To disable it use the system property <code>cache.local.enabled</code> by setting it at startup:

```java
java ... -Dcache.local.enabled=false ...
```

or via code before to open the database:

```java
OGlobalConfiguration.CACHE_LOCAL_ENABLED.setValue(false);
```
27 changes: 17 additions & 10 deletions Cluster-Selection.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Cluster Selection

When you create a new record specifying its [Class](Concepts.md#Class), OrientDB automatically selects the [Class](Concepts.md#Cluster) where to store the physical record, by using configurable strategies.
When you create a new record specifying its [Class](Concepts.md#Class), OrientDB automatically selects the [Cluster](Concepts.md#Cluster) where to store the physical record, by using configurable strategies.

The available strategies are:
- **default**, uses always the Class's ```defaultClusterId``` property. This was the default before 1.7
- **round-robin**, put the Class's configured clusters in a ring and returns a different cluster every time restarting from the first when the ring is completed
- **balanced**, checks the records in all the clusters and returns the smaller cluster. This allows the cluster to have all the underlying clusters balanced on size. On adding a new cluster to an existent class, the new empty cluster will be filled before the others because more empty then the others. Calculation of cluster size is made every 5 or more seconds to avoid to slow down insertion
- **local**. This is injected when OrientDB is running in distributed mode. With this strategy the cluster that is the master on current node is always preferred. This avoids conflicts and reduces network latency with remote calls between nodes.

- `default`, uses always the Class's ```defaultClusterId``` property. This was the default before 1.7
- `round-robin`, put the Class's configured clusters in a ring and returns a different cluster every time restarting from the first when the ring is completed
- `balanced`, checks the records in all the clusters and returns the smaller cluster. This allows the cluster to have all the underlying clusters balanced on size. On adding a new cluster to an existent class, the new empty cluster will be filled before the others because more empty then the others. Calculation of cluster size is made every 5 or more seconds to avoid to slow down insertion
- `local`. This is injected when OrientDB is running in distributed mode. With this strategy the cluster that is the master on current node is always preferred. This avoids conflicts and reduces network latency with remote calls between nodes.

## Create custom strategy

To create your custom strategy follow the following steps:

### 1) Create the implementation in Java
Expand All @@ -29,18 +31,21 @@ public class RandomSelectionStrategy implements OClusterSelectionStrategy {
}
```

Note that the method `getCluster()` receives also the ODocument to insert. This is useful if you want to assign the clusterId based on the Document content.
Note that the method `getCluster()` receives also the `ODocument` to insert. This is useful if you want to assign the `clusterId` based on the Document content.

### 2) Register the implementation as service
Create a new file under META-INF/services called `com.orientechnologies.orient.core.metadata.schema.clusterselection.OClusterSelectionStrategy` and write your class with full package.

Create a new file under `META-INF/services` called `com.orientechnologies.orient.core.metadata.schema.clusterselection.OClusterSelectionStrategy` and write your class with full package.

Example of the content:
```

``` java
mypackage.RandomSelectionStrategy
```

This is the default content in OrientDB core is:
```

``` java
com.orientechnologies.orient.core.metadata.schema.clusterselection.ORoundRobinClusterSelectionStrategy
com.orientechnologies.orient.core.metadata.schema.clusterselection.ODefaultClusterSelectionStrategy
com.orientechnologies.orient.core.metadata.schema.clusterselection.OBalancedClusterSelectionStrategy
Expand All @@ -50,5 +55,7 @@ com.orientechnologies.orient.core.metadata.schema.clusterselection.OBalancedClus

To assign your new strategy to a class, use the [ALTER CLASS](SQL-Alter-Class.md) command. Example:

ALTER CLASS Employee CLUSTERSELECTION random
``` sql
ALTER CLASS Employee CLUSTERSELECTION random
```

16 changes: 8 additions & 8 deletions Commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

| CRUD | Graph | Schema | Indexes | Database | Utility |
|----------|-------|--------|---------|-----------|---------|
| [Select](SQL-Query.md) | [Create Vertex](SQL-Create-Vertex.md) | [Create Class](SQL-Create-Class.md) | [Create Index](SQL-Create-Index.md)| [Create Cluster](SQL-Create-Cluster.md) | [Create Link](SQL-Create-Link.md) |
| [Insert](SQL-Insert.md) | [Create Edge](SQL-Create-Edge.md) |[Alter Class](SQL-Alter-Class.md) |[Rebuild Index](SQL-Rebuild-Index.md) |[Alter Cluster](SQL-Alter-Cluster.md) |[Find References](SQL-Find-References.md) |
| [Update](SQL-Update.md) | [Delete Vertex](SQL-Delete-Vertex.md) |[Drop Class](SQL-Drop-Class.md) |[Drop Index](SQL-Drop-Index.md) | [Drop Cluster](SQL-Drop-Cluster.md) | [Explain](SQL-Explain.md) |
| [Delete](SQL-Delete.md) | [Delete Edge](SQL-Delete-Edge.md) | [Create Property](SQL-Create-Property.md) | | [Alter Database](SQL-Alter-Database.md)| [Grant](SQL-Grant.md) |
| [Traverse](SQL-Traverse.md) | | [Alter Property](SQL-Alter-Property.md) | | [Create Database (console only)](Console-Command-Create-Database.md) | [Revoke](SQL-Revoke.md) |
| [Truncate Class](SQL-Truncate-Class.md) | | [Drop Property](SQL-Drop-Property.md) | | [Drop Database (console only)](Console-Command-Drop-Database.md) |[Create function](SQL-Create-Function.md)|
| [Truncate Cluster](SQL-Truncate-Cluster.md) | | | | | |
| [Truncate Record](SQL-Truncate-Record.md) | | | | | | |
| [SELECT](SQL-Query.md) | [CREATE VERTEX](SQL-Create-Vertex.md) | [CREATE CLASS](SQL-Create-Class.md) | [CREATE INDEX](SQL-Create-Index.md)| [CREATE CLUSTER](SQL-Create-Cluster.md) | [CREATE LINK](SQL-Create-Link.md) |
| [INSERT](SQL-Insert.md) | [CREATE EDGE](SQL-Create-Edge.md) |[ALTER CLASS](SQL-Alter-Class.md) |[REBUILD INDEX](SQL-Rebuild-Index.md) |[ALTER CLUSTER](SQL-Alter-Cluster.md) |[FIND REFERENCES](SQL-Find-References.md) |
| [UPDATE](SQL-Update.md) | [DELETE VERTEX](SQL-Delete-Vertex.md) |[DROP CLASS](SQL-Drop-Class.md) |[DROP INDEX](SQL-Drop-Index.md) | [DROP CLUSTER](SQL-Drop-Cluster.md) | [EXPLAIN](SQL-Explain.md) |
| [DELETE](SQL-Delete.md) | [DELETE EDGE](SQL-Delete-Edge.md) | [CREATE PROPERTY](SQL-Create-Property.md) | | [ALTER DATABASE](SQL-Alter-Database.md)| [GRANT](SQL-Grant.md) |
| [TRAVERSE](SQL-Traverse.md) | | [ALTER PROPERTY](SQL-Alter-Property.md) | | [CREATE DATABASE (console only)](Console-Command-Create-Database.md) | [REVOKE](SQL-Revoke.md) |
| [TRUNCATE CLASS](SQL-Truncate-Class.md) | | [DROP PROPERTY](SQL-Drop-Property.md) | | [DROP DATABASE (console only)](Console-Command-Drop-Database.md) |[CREATE FUNCTION](SQL-Create-Function.md)|
| [TRUNCATE CLUSTER](SQL-Truncate-Cluster.md) | | | | | |
| [TRUNCATE RECORD](SQL-Truncate-Record.md) | | | | | | |

38 changes: 23 additions & 15 deletions Concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,18 @@ OrientDB Documents support complex [relationships](Concepts.md#relationships). F
### RecordID

In OrientDB, each record has an auto assigned Unique ID. The RecordID (or RID) is composed in this way:

```
#[<cluster>:<position>]
```

Where:
- cluster is the cluster id. Positive numbers indicate persistent records. Negative numbers indicate temporary records, like those used in result sets for queries that use projections.
- position is the absolute position of the record inside a cluster.

*NOTE: The prefix character # is mandatory to recognize a RecordID.*
- `<cluster>` is the cluster id. Positive numbers indicate persistent records. Negative numbers indicate temporary records, like those used in result sets for queries that use projections.

- `<position>` is the absolute position of the record inside a cluster.

> **NOTE**: The prefix character `#` is mandatory to recognize a RecordID.
The record never loses its identity unless it is deleted. Once deleted its identity is never recycled (but with "local" storage). You can access a record directly by its RecordID. For this reason you don't need to create a field as a primary key like in a Relational DBMS.

Expand All @@ -76,22 +79,24 @@ When you create a new class by default a new [persistent cluster](Concepts.md#ph
### Abstract Class

If you know Object-Orientation you already know what an abstract class is. For all the rest:
- http://en.wikipedia.org/wiki/Abstract_type
- http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
- [Abstract Type](http://en.wikipedia.org/wiki/Abstract_type)
- [Abstract Methods and Classes](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html)
For our purpose, we can sum up an abstract class as:
- A class used as a foundation for defining other classes (eventually, concrete classes)
- A class that can't have instances

To create a new abstract class look at [SQL Create Class](SQL-Create-Class.md#abstract-class).
To create a new abstract class look at [CREATE CLASS](SQL-Create-Class.md#abstract-class).

Abstract classes are essential to support Object Orientation without the typical spamming of the database with always empty auto-created clusters.
_NOTE: available since 1.2.0_

> **NOTE**: Feature available since 1.2.0.
### When do you use a class or a cluster in queries?

Let's use an example: Let's assume you created a class "Invoice" and two clusters "invoice2011" and "invoice2012".

You can now query all the invoices by using the class as a target in the SQL select:

```sql
SELECT FROM Invoice
```
Expand Down Expand Up @@ -119,7 +124,9 @@ OrientDB supports two kinds of relationships: *referenced* and *embedded*. Orien
### Referenced relationships

Relationships in OrientDB are managed natively without computing costly JOINs, as in a Relational DBMS. In fact, OrientDB stores direct link(s) to the target objects of the relationship. This boosts up the load speed of the entire graph of connected objects like in Graph and Object DBMSs.
Example:

For example:

```
customer
Record A -------------> Record B
Expand Down Expand Up @@ -151,7 +158,8 @@ Embedded records, instead, are contained inside the record that embeds them. It'
CLASS=Account CLASS=Address
RID=5:23 NO RID!
```
<b>Record A</b> will contain the entire **Record B** in the property called "address". **Record B** can be reached only by traversing the container record.

**Record A** will contain the entire **Record B** in the property called "address". **Record B** can be reached only by traversing the container record.

Example:

Expand All @@ -167,9 +175,9 @@ These kinds of relationships are expressed using the **EMBEDDED** type.

These kinds of relationships are expressed using a collection of links such as:

- <b>EMBEDDEDLIST</b>, as an ordered list of records.
- <b>EMBEDDEDSET</b>, as an unordered set of records. It doesn't accept duplicates.
- <b>EMBEDDEDMAP</b>, as an ordered map of records as the value and a **String** as the key. It doesn't accept duplicate keys.
- **EMBEDDEDLIST**, as an ordered list of records.
- **EMBEDDEDSET**, as an unordered set of records. It doesn't accept duplicates.
- **EMBEDDEDMAP**, as an ordered map of records as the value and a **String** as the key. It doesn't accept duplicate keys.

### Inverse relationships

Expand Down Expand Up @@ -202,8 +210,8 @@ OrientDB has its own [URL](http://en.wikipedia.org/wiki/Uniform_Resource_Locator
```

Where:
- **db-name** is the database name and depends on the engine used (see below)
- **engine** can be:
- `<db-name>` is the database name and depends on the engine used (see below)
- `<engine>` can be:

|Engine|Description|Example|
|------|-----------|-------|
Expand All @@ -215,4 +223,4 @@ Where:

The database must always be closed once you've finished working with it.

NOTE: OrientDB automatically closes all opened databases when the process dies gracefully (not by killing it by force). This is assured if the Operating System allows a graceful shutdown.
> **NOTE**: OrientDB automatically closes all opened databases when the process dies gracefully (not by killing it by force). This is assured if the Operating System allows a graceful shutdown.
9 changes: 7 additions & 2 deletions Concurrency.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Concurrency

OrientDB has an [optimistic approach to concurrency](http://en.wikipedia.org/wiki/Optimistic_concurrency_control): "Optimistic Concurrency Control (OCC) assumes that multiple transactions can frequently complete without interfering with each other. While running, transactions use data resources without acquiring locks on those resources. Before committing, each transaction verifies that no other transaction has modified the data it has read. If the check reveals conflicting modifications, the committing transaction rolls back and can be restarted.
OrientDB has an optimistic approach to concurency: [Optimistic Concurrency Control (OCC)](http://en.wikipedia.org/wiki/Optimistic_concurrency_control) assumes that multiple transactions can frequently complete without interfering with each other. While running, transactions use data resources without acquiring locks on those resources. Before committing, each transaction verifies that no other transaction has modified the data it has read. If the check reveals conflicting modifications, the committing transaction rolls back and can be restarted.

OCC is generally used in environments with low data contention. When conflicts are rare, transactions can complete without the expense of managing locks and without having transactions wait for other transactions' locks to clear, leading to higher throughput than other concurrency control methods. However, if contention for data resources is frequent, the cost of repeatedly restarting transactions hurts performance significantly; it is commonly thought that other concurrency control methods have better performance under these conditions. However, locking-based ("pessimistic") methods also can deliver poor performance because locking can drastically limit effective concurrency even when deadlocks are avoided." - Wikipedia

OrientDB uses this approach on both **Atomic Operations** and **Transactions**.

## Atomic Operations

OrientDB supports [Multi Version Concurrency Control (MVCC)](http://en.wikipedia.org/wiki/Multiversion_concurrency_control) with atomic operations. This allows to avoid locking server side resources. At save time the version in database is checked. If it's equals to the record version contained in the operation, the operation succeed. If the version found in database is higher than the record version contained in the operation, then another thread/user already updated the same record in the meanwhile. In this case an `OConcurrentModificationException` exception is thrown.

Since this behavior is considered normal on Optimistic Systems, the developer should write a concurrency-proof code that retry X times before to report the error, by catching the exception, reloading the affected records and try updating them again. Below an example of saving a document.
Expand Down Expand Up @@ -35,6 +36,7 @@ for (int retry = 0; retry < maxRetries; ++retry) {
```

## Transactions

OrientDB supports optimistic transactions, so no lock is kept when a transaction is running, but at commit time each record (document, or graph element) version is checked to see if there has been an update by another client. This is the reason why you should write your code to be concurrency-proof by handling the concurrent updating case. Optimistic concurrency requires the transaction is retried in case of conflict. Example with connecting a new vertex to an existent one:

```java
Expand Down Expand Up @@ -68,16 +70,19 @@ In order to guarantee atomicity and consistency, OrientDB acquire an exclusive l
What happens when multiple clients add edges on the same vertex? OrientDB could throw the `OConcurrentModificationException` exception as well. Why? Because collection of edges are kept on vertices, so every time an edge is added or removed, both involved vertices are updated, and their versions incremented. To avoid this problem, you can use RIDBAG that are never embedded, so vertices will be never updated.

Set this configuration value at run-time before OrientDB is used:

```java
OGlobalConfiguration.INDEX_EMBEDDED_TO_SBTREEBONSAI_THRESHOLD.setValue(-1);
```

Or by setting the parameter at JVM level on startup (or even at run-time before OrientDB is used)
Or, by setting the parameter at JVM level on startup (or even at run-time before OrientDB is used)

```
java ... -Dindex.embeddedToSbtreeBonsaiThreshold=-1 ...
```

## Troubleshooting

### Reduce transaction size

`OConcurrentModificationException` can be thrown when even the first element has been update concurrently. This means that if you have thousands of record involved in the transaction, one changed record is enough to rollback it and throw `OConcurrentModificationException`. For this reason, if you plan to update many elements in the same transaction with high concurrency on the same vertices, a best practice is reducing the transaction size.
Loading

0 comments on commit ddf3f1d

Please sign in to comment.