… | |
… | |
27 | db_sync $db; |
27 | db_sync $db; |
28 | |
28 | |
29 | # when you also use Coro, management is easy: |
29 | # when you also use Coro, management is easy: |
30 | use Coro::BDB; |
30 | use Coro::BDB; |
31 | |
31 | |
32 | # automatic event loop intergration with AnyEvent: |
32 | # automatic event loop integration with AnyEvent: |
33 | use AnyEvent::BDB; |
33 | use AnyEvent::BDB; |
34 | |
34 | |
35 | # automatic result processing with EV: |
35 | # automatic result processing with EV: |
36 | my $WATCHER = EV::io BDB::poll_fileno, EV::READ, \&BDB::poll_cb; |
36 | my $WATCHER = EV::io BDB::poll_fileno, EV::READ, \&BDB::poll_cb; |
37 | |
37 | |
… | |
… | |
103 | |
103 | |
104 | =cut |
104 | =cut |
105 | |
105 | |
106 | package BDB; |
106 | package BDB; |
107 | |
107 | |
108 | no warnings; |
108 | use common::sense; |
109 | use strict 'vars'; |
|
|
110 | |
109 | |
111 | use base 'Exporter'; |
110 | use base 'Exporter'; |
112 | |
111 | |
113 | our $VERSION; |
112 | our $VERSION; |
114 | |
113 | |
115 | BEGIN { |
114 | BEGIN { |
116 | $VERSION = '1.82'; |
115 | $VERSION = '1.9'; |
117 | |
116 | |
118 | our @BDB_REQ = qw( |
117 | our @BDB_REQ = qw( |
119 | db_env_open db_env_close db_env_txn_checkpoint db_env_lock_detect |
118 | db_env_open db_env_close db_env_txn_checkpoint db_env_lock_detect |
120 | db_env_memp_sync db_env_memp_trickle db_env_dbrename db_env_dbremove |
119 | db_env_memp_sync db_env_memp_trickle db_env_dbrename db_env_dbremove |
121 | db_env_log_archive |
120 | db_env_log_archive |
122 | db_open db_close db_compact db_sync db_upgrade |
121 | db_open db_close db_compact db_sync db_verify db_upgrade |
123 | db_put db_exists db_get db_pget db_del db_key_range |
122 | db_put db_exists db_get db_pget db_del db_key_range |
124 | db_txn_commit db_txn_abort db_txn_finish |
123 | db_txn_commit db_txn_abort db_txn_finish |
125 | db_c_close db_c_count db_c_put db_c_get db_c_pget db_c_del |
124 | db_c_close db_c_count db_c_put db_c_get db_c_pget db_c_del |
126 | db_sequence_open db_sequence_close |
125 | db_sequence_open db_sequence_close |
127 | db_sequence_get db_sequence_remove |
126 | db_sequence_get db_sequence_remove |
… | |
… | |
192 | Functions in the BDB namespace, exported by default: |
191 | Functions in the BDB namespace, exported by default: |
193 | |
192 | |
194 | $env = db_env_create (U32 env_flags = 0) |
193 | $env = db_env_create (U32 env_flags = 0) |
195 | flags: RPCCLIENT |
194 | flags: RPCCLIENT |
196 | |
195 | |
197 | db_env_open (DB_ENV *env, bdb_filename db_home, U32 open_flags, int mode, SV *callback = &PL_sv_undef) |
196 | db_env_open (DB_ENV *env, bdb_filename db_home, U32 open_flags, int mode, SV *callback = 0) |
198 | open_flags: INIT_CDB INIT_LOCK INIT_LOG INIT_MPOOL INIT_REP INIT_TXN RECOVER RECOVER_FATAL USE_ENVIRON USE_ENVIRON_ROOT CREATE LOCKDOWN PRIVATE REGISTER SYSTEM_MEM |
197 | open_flags: INIT_CDB INIT_LOCK INIT_LOG INIT_MPOOL INIT_REP INIT_TXN RECOVER RECOVER_FATAL USE_ENVIRON USE_ENVIRON_ROOT CREATE LOCKDOWN PRIVATE REGISTER SYSTEM_MEM |
199 | db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = &PL_sv_undef) |
198 | db_env_close (DB_ENV *env, U32 flags = 0, SV *callback = 0) |
200 | db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = &PL_sv_undef) |
199 | db_env_txn_checkpoint (DB_ENV *env, U32 kbyte = 0, U32 min = 0, U32 flags = 0, SV *callback = 0) |
201 | flags: FORCE |
200 | flags: FORCE |
202 | db_env_lock_detect (DB_ENV *env, U32 flags = 0, U32 atype = DB_LOCK_DEFAULT, SV *dummy = 0, SV *callback = &PL_sv_undef) |
201 | db_env_lock_detect (DB_ENV *env, U32 flags = 0, U32 atype = DB_LOCK_DEFAULT, SV *dummy = 0, SV *callback = 0) |
203 | atype: LOCK_DEFAULT LOCK_EXPIRE LOCK_MAXLOCKS LOCK_MAXWRITE LOCK_MINLOCKS LOCK_MINWRITE LOCK_OLDEST LOCK_RANDOM LOCK_YOUNGEST |
202 | atype: LOCK_DEFAULT LOCK_EXPIRE LOCK_MAXLOCKS LOCK_MAXWRITE LOCK_MINLOCKS LOCK_MINWRITE LOCK_OLDEST LOCK_RANDOM LOCK_YOUNGEST |
204 | db_env_memp_sync (DB_ENV *env, SV *dummy = 0, SV *callback = &PL_sv_undef) |
203 | db_env_memp_sync (DB_ENV *env, SV *dummy = 0, SV *callback = 0) |
205 | db_env_memp_trickle (DB_ENV *env, int percent, SV *dummy = 0, SV *callback = &PL_sv_undef) |
204 | db_env_memp_trickle (DB_ENV *env, int percent, SV *dummy = 0, SV *callback = 0) |
206 | db_env_dbremove (DB_ENV *env, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, U32 flags = 0, SV *callback = &PL_sv_undef) |
205 | db_env_dbremove (DB_ENV *env, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, U32 flags = 0, SV *callback = 0) |
207 | db_env_dbrename (DB_ENV *env, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, bdb_filename newname, U32 flags = 0, SV *callback = &PL_sv_undef) |
206 | db_env_dbrename (DB_ENV *env, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, bdb_filename newname, U32 flags = 0, SV *callback = 0) |
208 | db_env_log_archive (DB_ENV *env, SV *listp, U32 flags = 0, SV *callback = &PL_sv_undef) |
207 | db_env_log_archive (DB_ENV *env, SV *listp, U32 flags = 0, SV *callback = 0) |
209 | |
208 | |
210 | $db = db_create (DB_ENV *env = 0, U32 flags = 0) |
209 | $db = db_create (DB_ENV *env = 0, U32 flags = 0) |
211 | flags: XA_CREATE |
210 | flags: XA_CREATE |
212 | |
211 | |
213 | db_open (DB *db, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, int type, U32 flags, int mode, SV *callback = &PL_sv_undef) |
212 | db_open (DB *db, DB_TXN_ornull *txnid, bdb_filename file, bdb_filename database, int type, U32 flags, int mode, SV *callback = 0) |
214 | flags: AUTO_COMMIT CREATE EXCL MULTIVERSION NOMMAP RDONLY READ_UNCOMMITTED THREAD TRUNCATE |
213 | flags: AUTO_COMMIT CREATE EXCL MULTIVERSION NOMMAP RDONLY READ_UNCOMMITTED THREAD TRUNCATE |
215 | db_close (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef) |
214 | db_close (DB *db, U32 flags = 0, SV *callback = 0) |
216 | flags: DB_NOSYNC |
215 | flags: DB_NOSYNC |
|
|
216 | db_verify (DB *db, bdb_filename file, bdb_filename database = 0, SV *dummy = 0, U32 flags = 0, SV *callback = 0) |
217 | db_upgrade (DB *db, bdb_filename file, U32 flags = 0, SV *callback = &PL_sv_undef) |
217 | db_upgrade (DB *db, bdb_filename file, U32 flags = 0, SV *callback = 0) |
218 | db_compact (DB *db, DB_TXN_ornull *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = &PL_sv_undef) |
218 | db_compact (DB *db, DB_TXN_ornull *txn = 0, SV *start = 0, SV *stop = 0, SV *unused1 = 0, U32 flags = DB_FREE_SPACE, SV *unused2 = 0, SV *callback = 0) |
219 | flags: FREELIST_ONLY FREE_SPACE |
219 | flags: FREELIST_ONLY FREE_SPACE |
220 | db_sync (DB *db, U32 flags = 0, SV *callback = &PL_sv_undef) |
220 | db_sync (DB *db, U32 flags = 0, SV *callback = 0) |
221 | db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = &PL_sv_undef) |
221 | db_key_range (DB *db, DB_TXN_ornull *txn, SV *key, SV *key_range, U32 flags = 0, SV *callback = 0) |
222 | db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
222 | db_put (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = 0) |
223 | flags: APPEND NODUPDATA NOOVERWRITE |
223 | flags: APPEND NODUPDATA NOOVERWRITE |
224 | db_exists (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = 0) (v4.6) |
224 | db_exists (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = 0) (v4.6) |
225 | db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
225 | db_get (DB *db, DB_TXN_ornull *txn, SV *key, SV *data, U32 flags = 0, SV *callback = 0) |
226 | flags: CONSUME CONSUME_WAIT GET_BOTH SET_RECNO MULTIPLE READ_COMMITTED READ_UNCOMMITTED RMW |
226 | flags: CONSUME CONSUME_WAIT GET_BOTH SET_RECNO MULTIPLE READ_COMMITTED READ_UNCOMMITTED RMW |
227 | db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
227 | db_pget (DB *db, DB_TXN_ornull *txn, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = 0) |
228 | flags: CONSUME CONSUME_WAIT GET_BOTH SET_RECNO MULTIPLE READ_COMMITTED READ_UNCOMMITTED RMW |
228 | flags: CONSUME CONSUME_WAIT GET_BOTH SET_RECNO MULTIPLE READ_COMMITTED READ_UNCOMMITTED RMW |
229 | db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef) |
229 | db_del (DB *db, DB_TXN_ornull *txn, SV *key, U32 flags = 0, SV *callback = 0) |
230 | db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef) |
230 | db_txn_commit (DB_TXN *txn, U32 flags = 0, SV *callback = 0) |
231 | flags: TXN_NOSYNC TXN_SYNC |
231 | flags: TXN_NOSYNC TXN_SYNC |
232 | db_txn_abort (DB_TXN *txn, SV *callback = &PL_sv_undef) |
232 | db_txn_abort (DB_TXN *txn, SV *callback = 0) |
233 | |
233 | |
234 | db_c_close (DBC *dbc, SV *callback = &PL_sv_undef) |
234 | db_c_close (DBC *dbc, SV *callback = 0) |
235 | db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = &PL_sv_undef) |
235 | db_c_count (DBC *dbc, SV *count, U32 flags = 0, SV *callback = 0) |
236 | db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
236 | db_c_put (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = 0) |
237 | flags: AFTER BEFORE CURRENT KEYFIRST KEYLAST NODUPDATA |
237 | flags: AFTER BEFORE CURRENT KEYFIRST KEYLAST NODUPDATA |
238 | db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
238 | db_c_get (DBC *dbc, SV *key, SV *data, U32 flags = 0, SV *callback = 0) |
239 | flags: CURRENT FIRST GET_BOTH GET_BOTH_RANGE GET_RECNO JOIN_ITEM LAST NEXT NEXT_DUP NEXT_NODUP PREV PREV_DUP PREV_NODUP SET SET_RANGE SET_RECNO READ_UNCOMMITTED MULTIPLE MULTIPLE_KEY RMW |
239 | flags: CURRENT FIRST GET_BOTH GET_BOTH_RANGE GET_RECNO JOIN_ITEM LAST NEXT NEXT_DUP NEXT_NODUP PREV PREV_DUP PREV_NODUP SET SET_RANGE SET_RECNO READ_UNCOMMITTED MULTIPLE MULTIPLE_KEY RMW |
240 | db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = &PL_sv_undef) |
240 | db_c_pget (DBC *dbc, SV *key, SV *pkey, SV *data, U32 flags = 0, SV *callback = 0) |
241 | db_c_del (DBC *dbc, U32 flags = 0, SV *callback = &PL_sv_undef) |
241 | db_c_del (DBC *dbc, U32 flags = 0, SV *callback = 0) |
242 | |
242 | |
243 | db_sequence_open (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, SV *key, U32 flags = 0, SV *callback = &PL_sv_undef) |
243 | db_sequence_open (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, SV *key, U32 flags = 0, SV *callback = 0) |
244 | flags: CREATE EXCL |
244 | flags: CREATE EXCL |
245 | db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = &PL_sv_undef) |
245 | db_sequence_close (DB_SEQUENCE *seq, U32 flags = 0, SV *callback = 0) |
246 | db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = &PL_sv_undef) |
246 | db_sequence_get (DB_SEQUENCE *seq, DB_TXN_ornull *txnid, int delta, SV *seq_value, U32 flags = DB_TXN_NOSYNC, SV *callback = 0) |
247 | flags: TXN_NOSYNC |
247 | flags: TXN_NOSYNC |
248 | db_sequence_remove (DB_SEQUENCE *seq, DB_TXN_ornull *txnid = 0, U32 flags = 0, SV *callback = &PL_sv_undef) |
248 | db_sequence_remove (DB_SEQUENCE *seq, DB_TXN_ornull *txnid = 0, U32 flags = 0, SV *callback = 0) |
249 | flags: TXN_NOSYNC |
249 | flags: TXN_NOSYNC |
250 | |
250 | |
251 | =head3 db_txn_finish (DB_TXN *txn, U32 flags = 0, SV *callback = &PL_sv_undef) |
251 | =head3 db_txn_finish (DB_TXN *txn, U32 flags = 0, SV *callback = 0) |
252 | |
252 | |
253 | This is not actually a Berkeley DB function but a BDB module |
253 | This is not actually a Berkeley DB function but a BDB module |
254 | extension. The background for this exytension is: It is very annoying to |
254 | extension. The background for this exytension is: It is very annoying to |
255 | have to check every single BDB function for error returns and provide a |
255 | have to check every single BDB function for error returns and provide a |
256 | codepath out of your transaction. While the BDB module still makes this |
256 | codepath out of your transaction. While the BDB module still makes this |
… | |
… | |
771 | |
771 | |
772 | =head2 Unexpected Crashes |
772 | =head2 Unexpected Crashes |
773 | |
773 | |
774 | Remember that, by default, BDB will execute requests in parallel, in |
774 | Remember that, by default, BDB will execute requests in parallel, in |
775 | somewhat random order. That means that it is easy to run a C<db_get> |
775 | somewhat random order. That means that it is easy to run a C<db_get> |
776 | request on thesa me database as a concurrent C<db_close> request, leading |
776 | request on the same database as a concurrent C<db_close> request, leading |
777 | to a crash, silent data corruption, eventually the next world war on |
777 | to a crash, silent data corruption, eventually the next world war on |
778 | terrorism. |
778 | terrorism. |
779 | |
779 | |
780 | If you only ever use foreground requests (without a callback), this will |
780 | If you only ever use foreground requests (without a callback), this will |
781 | not be an issue. |
781 | not be an issue (unless you use threads). |
782 | |
782 | |
783 | =head2 Unexpected Freezes or Deadlocks |
783 | =head2 Unexpected Freezes or Deadlocks |
784 | |
784 | |
785 | Remember that, by default, BDB will execute requests in parallel, which |
785 | Remember that, by default, BDB will execute requests in parallel, which |
786 | easily leads to deadlocks (even concurrent put's on the same database can |
786 | easily leads to deadlocks (even concurrent put's on the same database can |