Code Monkey home page Code Monkey logo

simpledbm's Introduction

Java CI with Maven

SimpleDBM is an Open Source Transactional Database Engine in Java. It has a very small footprint and can be embedded in the address space of an application. It provides a simple programming API, which can be learned very quickly. A simple network API is available for remote access.

Features

SimpleDBM has the following features:

  1. Transactional - SimpleDBM fully supports ACID transactions. SimpleDBM uses a STEAL/NO-FORCE buffer management strategy for transactions; SimpleDBM's Transaction Manager implements the ARIES algorithm.
  2. Multi-threaded - SimpleDBM is multi-threaded and supports concurrent reads and writes of data.
  3. Write Ahead Log - SimpleDBM uses a write ahead log to ensure transaction recovery in the event of system crashes.
  4. Lock based concurrency - SimpleDBM uses shared, update and exclusive row locks to manage concurrency.
  5. Multiple Isolation Levels - SimpleDBM supports read-committed, repeatable-read, and serializable isolation levels.
  6. B-Tree Indexes - SimpleDBM implements B-Link/Plus Tree indexes, that fully support concurrent reads, inserts and deletes. SimpleDBM B-Trees continually re-balance themselves, and do not suffer from fragmentation.
  7. Tables - SimpleDBM supports tables, but for maximum flexibility, treats table rows as blobs of data. Table rows can have any internal structure as you like, and can span multiple disk pages. Standard table rows with multiple columns are supported via add-on modules.
  8. Latches and Locks - SimpleDBM uses latches for internal consistency, and locks for concurrency. Latches are more efficient locking mechanisms that do not suffer from deadlocks.
  9. Deadlock detection - SimpleDBM has support for deadlock detection. A background thread periodically checks the lock table for deadlocks and aborts transactions to resolve deadlocks.
  10. Network API - From release 1.0.18 a network client server implementation is included that allows SimpleDBM servers to run standalone and remote clients to connect via TCP/IP. Only Java bindings available right now.

Non Features

  1. SimpleDBM does not suport SQL.
  2. There is no support for distributed transactions (XA) yet.

Status

SimpleDBM is available via Maven Central. The latest release is 1.0.23. If you discover bugs please report as I will do my best to fix bugs. Enhancements are currently on hold due to lack of time.

News

  • 1 Aug 2014 - SimpleDBM 1.0.23 uploaded to maven central. From this release the primary license is Apache V2.0 - but GPL and LGPL continue to be options.
  • 22 May 2013 - SimpleDBM 1.0.22 uploaded to maven central
  • 3 June 2012 - SimpleDBM 1.0.19-ALPHA released. This is a bug fix release.
  • 19 April 2010 - SimpleDBM 1.0.18-ALPHA released. This contains a first implementation of the network client server.

License

SimpleDBM license has been changed to Apache License 2.0 from 1.0.23 onwards.

Getting Started with SimpleDBM

To start developing code with SimpleDBM, you need to include following maven dependencies:

Embedded Database

This option is where you want the database engine to be inside your application, deployed as part of the same JVM.

        <dependency>
            <groupId>org.simpledbm</groupId>
            <artifactId>simpledbm-common</artifactId>
            <version>1.0.23</version>
        </dependency>
        <dependency>
            <groupId>org.simpledbm</groupId>
            <artifactId>simpledbm-rss</artifactId>
            <version>1.0.23</version>
        </dependency>
        <dependency>
            <groupId>org.simpledbm</groupId>
            <artifactId>simpledbm-typesystem</artifactId>
            <version>1.0.23</version>
        </dependency>
        <dependency>
            <groupId>org.simpledbm</groupId>
            <artifactId>simpledbm-database</artifactId>
            <version>1.0.23</version>
        </dependency>

See the Database API documentation below.

Network Server

The Network Server allows a client / server deployment. Instructions to follow...

Documentation

For documentation, I recommend you start with:

For advanced stuff, read:

You can read the SimpleDBM Blog and other papers available in the downloads section. If you are interested in development, you should also read the literature referred to in the Bibliography.

If you find bugs, please raise Issues. You can also post questions in the discussion group.

simpledbm's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simpledbm's Issues

Implement a trace buffer facility for capturing runtime trace

To debug the concurrency errors we need a mechanism for tracing the complex
operations with low overhead. See the article in DDJ April 23, 2007,
Multi-threaded Debugging Techniques by Shameem Akhter and Jason Roberts.
This is an excerpt from the book Multi-Core Programming by the same authors.

Original issue reported on code.google.com by [email protected] on 26 Jul 2008 at 10:49

Out of memory errors cause SimpleDBM to hang

This is a symptom - the real issue is that if there is a catastrophic
failure, then SimpleDBM should immediately shutdown. At present, a
catastrophic failure in one component does not trigger a full shutdown.

Original issue reported on code.google.com by [email protected] on 30 Dec 2007 at 2:42

Add sanity checking (validation) code to BTree Manager

The BTree Manager is easily the most complex of the SimpleDBM modules. If
things go wrong it is very hard to pinpoint where the problem lies. 

Already several measures are present:

Trace messages have been added recently.
Node level validations are done if appropriate flag is set at run time.
Simple checks are performed when inserting new entries in a page - also
when a flag is set.
Number of assertions have been increasing.

But these measures are all ad-hoc. We need a more systematic approach so
that we get the maximum benefit at minimum overhead. For instance, it only
makes sense to validate stuff if things have changed.

Original issue reported on code.google.com by [email protected] on 2 Aug 2008 at 12:14

Transaction should not obtain a recursive lock on the global shared latch for Transaction Manager

During logical undos, a transactional module may generate new log records. 
As a result, during transaction aborts or rollbacks, it is possible to 
make an attempt to recursively acquire the shared latch for the 
transaction manager. However, the ReadWriteUpdateLatch implementation does 
not support recursive shared latch access because it does not maintain 
information about owners of shared latch. 



Original issue reported on code.google.com by [email protected] on 23 Dec 2006 at 3:06

Convert transaction's locklist to an arraylist

Using an ArrayList is now possible as the locklist is no longer consulted
when locks are released, acquired or searched for. The only use is to 
support the need to release all or some locks during rollbacks.

The offset within the arraylist can be used as lock position.

Original issue reported on code.google.com by [email protected] on 31 Dec 2006 at 3:41

Latch deadlock when inserting a tuple

When more than one thread is concurrently attempting to insert a tuple, a
latch deadlock occurs due to the order of locking:

a) First thread obtains exclusive locks on space map page and then data page.
b) The second thread obtains exclusive lock on data page followed by space
map page.

The deadlock can be avoided by ensuring that latches are always acquired in
the same order.

Original issue reported on code.google.com by [email protected] on 17 Jul 2008 at 7:58

Incorrect locking in READ_COMMITTED Isolation Mode

In the NOT FOUND case, the lock on next key should be for instant duration
only. However, at present, the scan does not detect the NOT FOUND scenario,
and therefore cannot release the lock immediately. Only the calling client
can determine whether the key was found or not.

Original issue reported on code.google.com by [email protected] on 30 Dec 2007 at 2:40

The deadlock detector thread causes the Lock Manager to hang due to latch deadlock

The deadlock detector must ensure that it has exclusive access to the Lock 
Manager data structures. To enable this, a global latch was introduced. 
All regular operations acquire the latch in shared mode, but the deadlock 
detector acquires the latch in exclusive mode.

It is however possible that the interaction between the deadlock detector 
and other threads to lead to a deadlock within the Lock Manager. This is 
because a request for shared latch is blocked if there is a pending 
request for exclusive access. 

To avoid the deadlock the deadlock detectory should use tryExclusiveLock() 
rather than exclusiveLock(). 

Original issue reported on code.google.com by [email protected] on 24 Dec 2006 at 2:17

Migrate from Checked to Unchecked exceptions

Except for lock exceptions, most other exceptions should be unchecked 
exceptions. This will not only simply the interfaces and the exception 
handling code, but also make it easier to pass on lock exceptions to the 
client.

Original issue reported on code.google.com by [email protected] on 23 Dec 2006 at 12:44

Starvation when two threads attempt to acquire buffer in a single CPU machine

If all buffer pages are dirty and two threads are simultaneously trying to
fix a page, one of the threads may be starved and fail after 10 retries.
This appears to happen on single CPU machines. It seems that when the
buffer writer calls notifyAll() after a buffer write, it is possible for
one of threads to consistently fail to obtain the available buffer due to
the way the threads are awakened.

Original issue reported on code.google.com by [email protected] on 15 Aug 2008 at 10:46

Buffer unfix failed due to attempt to unfix and already unfixed buffer

Produced during database stress test - owing to the exception thrown by the
loop detection logic.

java.lang.IllegalStateException: SIMPLEDBM-EM0007: Latch mode in
inconsistent state
        at
org.simpledbm.rss.impl.bm.BufferManagerImpl$BufferAccessBlockImpl.unlatch(Buffer
ManagerImpl.java:1488)
        at
org.simpledbm.rss.impl.bm.BufferManagerImpl.unfix(BufferManagerImpl.java:908)
        at
org.simpledbm.rss.impl.bm.BufferManagerImpl$BufferAccessBlockImpl.unfix(BufferMa
nagerImpl.java:1532)
        at
org.simpledbm.rss.impl.tuple.TupleManagerImpl$TupleInserterImpl.doCompleteInsert
(TupleManagerImpl.java:1249)
        at
org.simpledbm.rss.impl.tuple.TupleManagerImpl$TupleInserterImpl.completeInsert(T
upleManagerImpl.java:1346)
        at
org.simpledbm.rss.impl.tuple.TupleManagerImpl$TupleContainerImpl.doUpdate(TupleM
anagerImpl.java:1768)
        at
org.simpledbm.rss.impl.tuple.TupleManagerImpl$TupleContainerImpl.update(TupleMan
agerImpl.java:1776)
        at
org.simpledbm.database.impl.TableScanImpl.updateCurrentRow(TableScanImpl.java:14
3)
        at
org.simpledbm.database.TestDatabase$TesterThread.testUpdate(TestDatabase.java:63
4)
        at
org.simpledbm.database.TestDatabase$TesterThread.run(TestDatabase.java:857)
        at java.lang.Thread.run(Thread.java:619)

Original issue reported on code.google.com by [email protected] on 26 Jul 2008 at 12:08

Rollback to savepoint must reacquire locks released since the savepoint

When rolling back to a savepoint, the transaction manager releases locks 
acquired since the rollback. However, it does not reacquire locks that 
were released after the savepoint. Locks can be released in situations 
where cursors are executing in cursor stabilty mode and have move from the 
cursor position at the time of rollback. When the transacion rolls back to 
a savepoint, the cursors must be restored to their position as at the time 
of savepoint, and the locks reacquired. 

The efficient way to resolve this issue appears to be to restore cusror 
position and reaquire locks. 


Original issue reported on code.google.com by [email protected] on 15 Nov 2006 at 10:55

BTree page split fails when there is no room for high key

The BTree split algorithm attempts to replace the high key in the left 
node before purging the items to the right of the high key. This is 
incorrect as the page may not have space for the high key if the new high 
key is larger than the old high key in size. The correct sequence is to 
purge the excess items first so that there is guaranteed space for the 
high key.

A related problem is that the slottedpage implementation does not report 
LOUDLY the failure to insert a slot due to lack of space. It reports the 
error condition by returning false - we need a more robust mechanism for 
reporting this; such as a runtime exception.

Original issue reported on code.google.com by [email protected] on 23 Dec 2006 at 12:36

Implement a network client and server

Currently SimpleDBM needs to be embedded in the application. It would be
nice to have the ability to run a SimpleDBM server and connect to it over TCP.

Original issue reported on code.google.com by [email protected] on 16 Aug 2008 at 12:45

When updating tuples, resize tuple segment to maximum length if possible

At present during updates existing tuple segments are not resized even if
there is space available on the pages. This causes following inefficiency:
if a tuple grows beyond its original size, instead of resizing the tuple
segment, an additional tuple segment will be allocated (possibly on the
same page) and linked to the previous segment.

Original issue reported on code.google.com by [email protected] on 16 Aug 2008 at 12:14

Inserts into BTree failing with space error

org.simpledbm.rss.api.pm.PageException: SIMPLEDBM-EO0002: Cannot insert
item IndexItem(key=[[Blogg8072], [Joe8072]], isLeaf=false, isUnique=false,
Location=TupleId(ns=84, pageId=PageId(1,225), slot=1), ChildPage=207) of
size 58 into page at slot 137 due to lack of space: page contents = 
=========================================================================
PAGE DUMP : pageType=16, pageId=PageId(3,140), pageLsn=Lsn(3,2582669)
PageSize=8184
FIXED OVERHEAD=28
UsableSpace=8156
PageFlags=0
#Slots=139
#DeletedSlots=0
HighWaterMark=888
FreeSpace=54
SpaceMapPage=1
Slot#0=slot(offset=8136, length=20, flags=0)
Slot#1=slot(offset=8080, length=56, flags=0)
Slot#2=slot(offset=8024, length=56, flags=0)
Slot#3=slot(offset=7968, length=56, flags=0)
Slot#4=slot(offset=7912, length=56, flags=0)
...
Slot#137=slot(offset=888, length=48, flags=0)
Slot#138=slot(offset=936, length=16, flags=0)
Calculated PageSize=8184

        at
org.simpledbm.rss.impl.sp.SlottedPageImpl.insertAt(SlottedPageImpl.java:579)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl.redoLinkOperation(BTreeInd
exManagerImpl.java:491)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl.redo(BTreeIndexManagerImpl
.java:277)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl$BTreeImpl.doLink(BTreeInde
xManagerImpl.java:1461)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl$BTreeImpl.updateModeTraves
e(BTreeIndexManagerImpl.java:2270)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl$BTreeImpl.doInsertTraverse
(BTreeIndexManagerImpl.java:2357)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl$BTreeImpl.doInsert(BTreeIn
dexManagerImpl.java:2529)
        at
org.simpledbm.rss.impl.im.btree.BTreeIndexManagerImpl$BTreeImpl.insert(BTreeInde
xManagerImpl.java:2697)
        at org.simpledbm.database.impl.TableImpl.addRow(TableImpl.java:99)
        at
org.simpledbm.database.TestDatabase$TesterThread.testInsert(TestDatabase.java:52
5)
        at
org.simpledbm.database.TestDatabase$TesterThread.run(TestDatabase.java:814)
        at java.lang.Thread.run(Thread.java:613)

Original issue reported on code.google.com by [email protected] on 18 Jul 2008 at 12:12

Implement a simpler Database level API that supports data dictionary

SimpleDBM RSS module offers a low-level API to the database engine. It has no 
support for type-
system or data dictionary. For most users the level of abstraction is too low 
level.

We need two additional modules:

a) A Typesystem that supports different data types and row types.
b) A higher level Database API that uses the typesystem and also adds a data 
dictionary.

Original issue reported on code.google.com by [email protected] on 29 Jun 2008 at 10:37

With three or moe comcurrent threads, deadlocks can start forming in a chain

When running the database stress test with 3 or more threads, the test can
go into a state where every request starts to deadlock. This happens when
data is being deleted.

Example of this deadlock:

2008-07-25 23:56:02,851 [DeadlockDetector] WARN
org.simpledbm.rss.impl.locking SIMPLEDBM-WC0011: Detected deadlock cycle:

R1 LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION)
    (victim) waiting for
    R2 LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109095),
isolationMode=READ_COMMITTED), thread=Thread[Thread-2,5,main],
duration=MANUAL_DURATION)

R1 LockItem(
   target=TupleId(ns=84, pageId=PageId(1,394), slot=39),
   grantedMode=EXCLUSIVE,
   waiting=true,
   queue=[
      LockRequest(mode=EXCLUSIVE, convertMode=UPDATE, status=GRANTED,
count=2, owner=Transaction(trxId=TrxId(109095),
isolationMode=READ_COMMITTED), thread=Thread[Thread-2,5,main],
duration=COMMIT_DURATION),
      LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION)])

R2 LockItem(
   target=TupleId(ns=84, pageId=PageId(1,394), slot=35),
   grantedMode=EXCLUSIVE,
   waiting=true,
   queue=[
      LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=GRANTED,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION),
      LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109094),
isolationMode=READ_COMMITTED), thread=Thread[Thread-3,5,main],
duration=COMMIT_DURATION),
      LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109095),
isolationMode=READ_COMMITTED), thread=Thread[Thread-2,5,main],
duration=MANUAL_DURATION)])

2008-07-25 23:56:02,852 [DeadlockDetector] WARN
org.simpledbm.rss.impl.locking SIMPLEDBM-WC0011: Detected deadlock cycle:

R1 LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109094),
isolationMode=READ_COMMITTED), thread=Thread[Thread-3,5,main],
duration=COMMIT_DURATION)
   (victim) waiting for
   R2 LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=DENIED,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION)

R1 LockItem(
   target=TupleId(ns=84, pageId=PageId(1,394), slot=35),
   grantedMode=EXCLUSIVE,
   waiting=true,
   queue=[
       LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=GRANTED,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION),
       LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109094),
isolationMode=READ_COMMITTED), thread=Thread[Thread-3,5,main],
duration=COMMIT_DURATION),
       LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=WAITING,
count=1, owner=Transaction(trxId=TrxId(109095),
isolationMode=READ_COMMITTED), thread=Thread[Thread-2,5,main],
duration=MANUAL_DURATION)])

R2 LockItem(
   target=TupleId(ns=84, pageId=PageId(1,394), slot=39),
   grantedMode=EXCLUSIVE,
   waiting=true,
   queue=[
       LockRequest(mode=EXCLUSIVE, convertMode=UPDATE, status=GRANTED,
count=2, owner=Transaction(trxId=TrxId(109095),
isolationMode=READ_COMMITTED), thread=Thread[Thread-2,5,main],
duration=COMMIT_DURATION),
       LockRequest(mode=EXCLUSIVE, convertMode=EXCLUSIVE, status=DENIED,
count=1, owner=Transaction(trxId=TrxId(109093),
isolationMode=READ_COMMITTED), thread=Thread[Thread-1,5,main],
duration=COMMIT_DURATION)])


It seems that this may be due to the COMMIT_DURATION request being
victimised instead of the MANUAL_DURATION request. 

Original issue reported on code.google.com by [email protected] on 25 Jul 2008 at 11:45

Update documentation regarding the additional RSS server properties that are now exposed.

Some newly exposed properties include:

log.disableFlushRequests - if true, performs log flush less frequently
bufferpool.writerSleepInterval - changes the interval between write scans
transaction.ckpt.interval - changes the interval between checkpoints
lock.deadlock.detection.interval - changes the interval between deadlock checks
storage.flushMode - changes the way data is flushed to disk (noforce)

Original issue reported on code.google.com by [email protected] on 1 Aug 2008 at 11:28

Expose additional properties to modify behaviour of RSS

Some additional properties worth exposing are:

log.disableFlushRequests - if true, performs log flush less frequently
bufferpool.writerSleepInterval - changes the interval between write scans
transaction.ckpt.interval - changes the interval between checkpoints
lock.deadlock.detection.interval - changes the interval between deadlock checks

Original issue reported on code.google.com by [email protected] on 30 Jul 2008 at 11:01

The Latch implementation using ReentrantReadWriteLock should emulate update mode using exclusive mode

At present the ReadWriteLatch implementation uses Java's 
ReentrantReadWriteLock. It throws NotSupportedException if any of the 
methods that support update mode lock are invoked. Instead of throwing an 
exception, treat update locks as exclusive ones. 

This improvement will allow the use of these latches where the 
ReadWriteUpdateLatch is used - this is good for testing.

Original issue reported on code.google.com by [email protected] on 23 Dec 2006 at 12:41

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.