Coder Social home page Coder Social logo

lmdb-go's Introduction

lmdb-go releases/v1.9.2 C/v0.9.31 [Build Status]

Go bindings to the OpenLDAP Lightning Memory-Mapped Database (LMDB).

About this fork

This fork was created after the upstream repository bmatsuo/lmdb-go went without updates for 4 years. We would like to express our thanks to bmatsuo for creating and maintaining this repository until 2017.

We decided to rename this repository to allow usage without replace directives in the go.mod, as we do not expect this to be a temporary fork. This also makes it clear that new versions released here are different from any upstream versions.

To use this package, update all your import paths from github.com/bmatsuo/lmdb-go to github.com/PowerDNS/lmdb-go.

This affects all versions starting from 1.9.0.

Note that the experimental, never released exp/lmdbpool package has been removed in this fork.

Packages

Functionality is logically divided into several packages. Applications will usually need to import lmdb but may import other packages on an as needed basis.

Packages in the exp/ directory are not stable and may change without warning. That said, they are generally usable if application dependencies are managed and pinned by tag/commit.

Developers concerned with package stability should consult the documentation.

lmdb GoDoc stable

import "github.com/PowerDNS/lmdb-go/lmdb"

Core bindings allowing low-level access to LMDB.

lmdbscan GoDoc stable

import "github.com/PowerDNS/lmdb-go/lmdbscan"

A utility package for scanning database ranges. The API is inspired by bufio.Scanner and the python cursor implementation.

exp/lmdbsync GoDoc experimental

import "github.com/PowerDNS/lmdb-go/exp/lmdbsync"

An experimental utility package that provides synchronization necessary to change an environment's map size after initialization. The package provides error handlers to automatically manage database size and retry failed transactions.

The lmdbsync package is usable but the implementation of Handlers are unstable and may change in incompatible ways without notice. The use cases of dynamic map sizes and multiprocessing are niche and the package requires much more development driven by practical feedback before the Handler API and the provided implementations can be considered stable.

Key Features

Idiomatic API

API inspired by BoltDB with automatic commit/rollback of transactions. The goal of lmdb-go is to provide idiomatic database interactions without compromising the flexibility of the C API.

NOTE: While the lmdb package tries hard to make LMDB as easy to use as possible there are compromises, gotchas, and caveats that application developers must be aware of when relying on LMDB to store their data. All users are encouraged to fully read the documentation so they are aware of these caveats.

Where the lmdb package and its implementation decisions do not meet the needs of application developers in terms of safety or operational use the lmdbsync package has been designed to wrap lmdb and safely fill in additional functionality. Consult the documentation for more information about the lmdbsync package.

API coverage

The lmdb-go project aims for complete coverage of the LMDB C API (within reason). Some notable features and optimizations that are supported:

  • Idiomatic subtransactions ("sub-updates") that allow the batching of updates.

  • Batch IO on databases utilizing the MDB_DUPSORT and MDB_DUPFIXED flags.

  • Reserved writes than can save in memory copies converting/buffering into []byte.

For tracking purposes a list of unsupported features is kept in an issue.

Zero-copy reads

Applications with high performance requirements can opt-in to fast, zero-copy reads at the cost of runtime safety. Zero-copy behavior is specified at the transaction level to reduce instrumentation overhead.

err := lmdb.View(func(txn *lmdb.Txn) error {
    // RawRead enables zero-copy behavior with some serious caveats.
    // Read the documentation carefully before using.
    txn.RawRead = true

    val, err := txn.Get(dbi, []byte("largevalue"), 0)
    // ...
})

Documentation

Comprehensive documentation and examples are provided to demonstrate safe usage of lmdb. In addition to godoc documentation, implementations of the standand LMDB commands (mdb_stat, etc) can be found in the cmd/ directory and some simple experimental commands can be found in the exp/cmd/ directory. Aside from providing minor utility these programs are provided as examples of lmdb in practice.

LMDB compared to BoltDB

BoltDB is a quality database with a design similar to LMDB. Both store key-value data in a file and provide ACID transactions. So there are often questions of why to use one database or the other.

Advantages of BoltDB

  • Nested databases allow for hierarchical data organization.

  • Far more databases can be accessed concurrently.

  • Operating systems that do not support sparse files do not use up excessive space due to a large pre-allocation of file space. The exp/lmdbsync package is intended to resolve this problem with LMDB but it is not ready.

  • As a pure Go package bolt can be easily cross-compiled using the go toolchain and GOOS/GOARCH variables.

  • Its simpler design and implementation in pure Go mean it is free of many caveats and gotchas which are present using the lmdb package. For more information about caveats with the lmdb package, consult its documentation.

Advantages of LMDB

  • Keys can contain multiple values using the DupSort flag.

  • Updates can have sub-updates for atomic batching of changes.

  • Databases typically remain open for the application lifetime. This limits the number of concurrently accessible databases. But, this minimizes the overhead of database accesses and typically produces cleaner code than an equivalent BoltDB implementation.

  • Significantly faster than BoltDB. The raw speed of LMDB easily surpasses BoltDB. Additionally, LMDB provides optimizations ranging from safe, feature-specific optimizations to generally unsafe, extremely situational ones. Applications are free to enable any optimizations that fit their data, access, and reliability models.

  • LMDB allows multiple applications to access a database simultaneously. Updates from concurrent processes are synchronized using a database lock file.

  • As a C library, applications in any language can interact with LMDB databases. Mission critical Go applications can use a database while Python scripts perform analysis on the side.

Build

There is no dependency on shared libraries. So most users can simply install using go get.

go get github.com/PowerDNS/lmdb-go/lmdb

On FreeBSD 10, you must explicitly set CC (otherwise it will fail with a cryptic error), for example:

CC=clang go test -v ./...

Building commands and running tests can be done with go or with make

make bin
make test
make check
make all

On Linux, you can specify the pwritev build tag to reduce the number of syscalls required when committing a transaction. In your own package you can then do

go build -tags pwritev .

to enable the optimisation.

Documentation

Go doc

The go doc documentation available on godoc.org is the primary source of developer documentation for lmdb-go. It provides an overview of the API with a lot of usage examples. Where necessary the documentation points out differences between the semantics of methods and their C counterparts.

LMDB

The LMDB homepage and mailing list (archives) are the official source of documentation regarding low-level LMDB operation and internals.

Along with an API reference LMDB provides a high-level summary of the library. While lmdb-go abstracts many of the thread and transaction details by default the rest of the guide is still useful to compare with go doc.

Versioning and Stability

The lmdb-go project makes regular releases with IDs X.Y.Z. All packages outside of the exp/ directory are considered stable and adhere to the guidelines of semantic versioning.

Experimental packages (those packages in exp/) are not required to adhere to semantic versioning. However packages specifically declared to merely be "unstable" can be relied on more for long term use with less concern.

The API of an unstable package may change in subtle ways between minor release versions. But deprecations will be indicated at least one release in advance and all functionality will remain available through some method.

License

Except where otherwise noted files in the lmdb-go project are licensed under the BSD 3-clause open source license.

The LMDB C source is licensed under the OpenLDAP Public License.

Links

An experimental backend for github.com/hashicorp/raft forked from github.com/hashicorp/raft-mdb.

Experimental backend quad-store for github.com/google/cayley based off of the BoltDB implementation.

lmdb-go's People

Contributors

a-kr avatar benbjohnson avatar bmatsuo avatar burke avatar dinedal avatar docsavage avatar hyc avatar jvshahid avatar lmb avatar maximelenoir avatar mdennebaum avatar pieterlexis avatar shane-ns1 avatar szferi avatar thehydroimpulse avatar tysonmote avatar wojas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

lmdb-go's Issues

go vet has issues

I followed the instructions for a PR in CONTRIBUTING.md, and when I ran go vet it raised a few issues.

These are:

# github.com/PowerDNS/lmdb-go/lmdbscan
lmdbscan/scanner_test.go:88:3: *github.com/PowerDNS/lmdb-go/internal/lmdbtest.SimpleItem struct literal uses unkeyed fields

This for like 50 lines.

And:

# github.com/PowerDNS/lmdb-go/cmd/lmdb_stat
cmd/lmdb_stat/main.go:245:44: possible misuse of reflect.SliceHeader

Incorrect file mode in lmdb_cat

Since I was looking at go vet output, I figured that I should also try staticcheck, which is useful in catching all kinds of errors. Mostly problems were in test code, but it did spot one issue in non-test code:

exp/cmd/lmdb_cat/main.go:181:43: file mode '644' evaluates to 01204; did you mean '0644'? (SA9002)

This seems to be an actual problem. PR incoming.

Mysterious error: "cgo argument has Go pointer to unpinned Go pointer"

I'm very confused about this and even asked this question on StackOverflow, but I figured I would repeat it here in case someone has any incredible insight: https://stackoverflow.com/questions/77608920/mysterious-error-cgo-argument-has-go-pointer-to-unpinned-go-pointer

I was using bmatsuo's version but recently have switched to this fork and the problem persists unchanged and that has me very confused.

I am even more confused because I'm using bmatsuo's library in another project in which looks like to me the exact same way, but there I don't see this issue and here I do.

Anyway, I'm just looking for some hint in case anyone knows anything about what is going on.

Warnings on build

We're seeing warnings on the build:

mdb.c: In function 'mdb_env_cwalk':
mdb.c:9273:7: warning: writing 8 bytes into a region of size 1 [-Wstringop-overflow=]
 9273 |       memcpy(NODEDATA(ni), &my->mc_next_pgno, sizeof(pgno_t));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mdb.c:941:8: note: at offset 0 to object 'mn_data' with size 1 declared here
  941 |  char  mn_data[1];   /**< key and data are appended here */
      |        ^~~~~~~
mdb.c: In function 'mdb_node_add':
mdb.c:7412:4: warning: writing 8 bytes into a region of size 1 [-Wstringop-overflow=]
 7412 |    memcpy(ndata, &ofp->mp_pgno, sizeof(pgno_t));
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mdb.c:7406:5: warning: writing 8 bytes into a region of size 1 [-Wstringop-overflow=]
 7406 |     memcpy(ndata, data->mv_data, sizeof(pgno_t));
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Since our Go version trusts our C coders to have figured out stuff like this, we can just ignore these (a quick inspection reveals that they are almost certainly false positives). PR incoming.

many warnings on go run or go build

Hi guys, want to replace bmatsuo/lmdb-go on yours that is more fresh, but have many warnings on start or build an application.

go version go1.21.5 darwin/arm64

go get github.com/PowerDNS/lmdb-go/lmdb
go: downloading github.com/PowerDNS/lmdb-go v1.9.2
go: added github.com/PowerDNS/lmdb-go v1.9.2

go build cmd/main.go           
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
go run cmd/main.go -f configs/dev_copy.json 
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]
# github.com/PowerDNS/lmdb-go/lmdb
warning: unknown warning option '-Wno-stringop-overflow'; did you mean '-Wno-shift-overflow'? [-Wunknown-warning-option]

staticcheck reports issues in tests

The staticcheck tool reports numerous issues in the tests.

These include:

  • Unused types
  • Unused functions
  • Unused variables
  • Empty branches
  • Missing error checks
  • Style complaints (apparently 0 != id0 is not ideomatic Go)

Except for missing error checks, none of these are super important. But fixing them will tidy up the code a bit, and open the way for using staticcheck for all commits (which is probably a good idea).

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.