diff --git a/README b/README index 6cd73919..367ffaa5 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Berkeley DB 11g Release 2, library version 11.2.5.2.28: (June 10, 2011) +Berkeley DB 11g Release 2, library version 11.2.5.3.21: (May 11, 2012) This is Berkeley DB 11g Release 2 from Oracle. To view release and installation documentation, load the distribution file docs/index.html diff --git a/dist/ChangeLog b/dist/ChangeLog index 23a44691..8ed93de7 100644 --- a/dist/ChangeLog +++ b/dist/ChangeLog @@ -1,426 +1,318 @@ -= Berkeley DB 5.2 Changelog = += Berkeley DB 5.3 Changelog = + +== Changes between 11.2.5.3.15 and 11.2.5.3.21 == + +Fixed incompatibility problems of Java DPL with JDK7, so DPL will now +work with JDK7. [#20586] + +Added a flag to allow database locking to be disabled from the SQL +API. [#20928] + +Fixed a bug that could allocate a heap data page in a region after the +region creation has been undone. [#20939] + +Redundant whitespaces are now ignored in DB_CONFIG lines pertaining to +directories, e.g. set_data_dir. [#20158] + +Fixed a bug that caused DB_ENV->backup to stop early if DB_BACKUP_FILES was +not set and a non-DB file was in the data directory. [#21076] + +Fixed a rare race condition that could cause a crash if two processes opened +the same database at the same time. [#21041] + +Fixed missing cross compiling capability for the JDBC driver. [#21101] + +Allow the same system/machine to host both a master and a replica +database through the use of relative pathnames. [#21105] + +Fixed a bug in the Java API where EnvironmentConfig.setCreateDir would fail +to configure the environment. [#21127] + +Fixed an assert failure in btreeCompare when allocating memory +in the wrong thread was causing a memory leak. [#21232] + +Fixed a bug in the Java API where concurrent operations that change the +database schema could lead to a hang. [#21265] + +Added JDBC code to the code base and updated the windows build files +to include the JDBC solution. [#21294] + +Fixed a bug where the heap's region size was not getting swapped correctly +in mixed-endian environments. [#21295] + +Fixed a bug in the db_sql_jdbc project file for vs2010 that was preventing +it from building correctly. [#21332] == Database or Log File On-Disk Format Changes == -Existing database file formats were unchanged in library version 11.2.5.2. -However, a new database file format, "heap", was introduced. +Existing database file formats were unchanged in library version 11.2.5.3. -The log file format changed in library version 11.2.5.2. +The log file format changed in library version 11.2.5.3. == New Features == -Replication Manager now manages Group Membership. This allows sites to be added to -and removed from the replication group dynamically. Replication Manager -also now automatically keeps track of the group size (nsites). [#14778] +Added support for verifying named in-memory dbs. [#16941] -Initial allocations for various non-pagebuffer (mpool) system resources -may now be specified, as well as a total maximum of memory to use, rather than -specifying a maximum value for each resource. [#16334] +Added an integer key comparison function to improve performance through +the SQL API. [#19609] -Implemented Berkeley DB globalization support architecture to enable localized -and stripped error and output messages. [#16863] +Support build on the platforms where pthread_t is a struct. [#19876] -Added a new access method, DB_HEAP. Heap aims for efficient use (and re-use) -of disk space. Keys in a heap database are automatically generated by BDB, it -is recommended that one or more secondary indexes be used with a heap -database. For full details on DB_HEAP, see the Programmer's Reference -Guide. [#17627] +Added an API call so the user can specify the size of the region in a +heap db. [#19914] -Added a compatible mode for 32bit and 64bit Windows environment. [#18225] +Improved Replication Manager's ability to recover from the (perhaps +rare) phenomenon of two sites trying to connect to each other +simultaneously, which used to result in loss of both connections, +requiring a retry after the CONNECTION_RETRY timeout period. [#19980] -For the SQL API, concurrency between read and write transactions can now be -enabled using "PRAGMA multiversion". Added several pragmas that can be -used to configure the Berkeley DB datastore. [#18521] +Enhanced the interface for copying databases for a hot backup. Added configure +support for --enable-atomicfileread. [#20129] -Add several new pragmas to provide in-process support for replication in -the SQL API. [#18528] +Enhaced the log reading routine to detect that a log file is missing rather +than returning that a zero length record was found. [#20130] -The Berkeley DB X/open compliant XA resource manager has been restored, -including support for multi-threaded servers. [#18701] +Added pragma bdbsql_shared_resources to set or report the maximum amount of +memory to be used by shared structures in the main environment region and +bdbsql_lock_tablesize to set or report the number of buckets in +the lock object hash table. These are advanced tuning features for +applications with large number of tables or needs to reduce locking on +concurrent long running transactions. [#20156] -Improved the ability to recover from an application crash on connections -through the SQL API. Berkeley DB will try to automatically clean up locks, -mutexes and transactions from the failed process. [#18713] +Added set_metadata_dir() and get_metadata_dir() to enable storage of +persistent metadata files in a location other than the environment +home directory. [#20174] -Add support for sequence usage in the SQL API using SQLite custom -functions. [#19007] +Improved the error handling through the SQL API. Errors can be sent to a +file with the use of the BDBSQL_ERROR_FILE pragma. [#20213] -Add a pragma in the SQL API to allow execution of a cache trickle -command. [#19202] +Database handles can now be configured to give exclusive access to +the database. [#20331] -Add a pragma in the SQL API to allow configuration of DB_SYSTEM_MEM -environments. [#19249] +XA transactions will now use transaction snapshots if the XA databases +they operate on were configured with DB_MULTIVERSION. [#20332] -The new db_env_set_win_security(SECURITY_ATTRIBUTES *) function allows an -application to specify the particular Microsoft Windows security attributes -to be used by Berkeley DB. This helps support applications which reduce their -privileges after opening the environment. [#19529] +Added additional stats fields into the C# API [#20693] +Added pragma bdbsql_single_process to keep the Berkeley DB environment +information on the heap instead of in shared memory. This option cannot +be used if the database is accessed from multiple processes. [#20789] + +Improved the ability of DB->compact to move DB_HASH database pages to the +begining of the file. [#20815] == Database Environment Changes == -None +Fixed a bug that could cause a segmentation violation when closing +an environment handle which has open database handles on partition +databases. [#20281] -== Concurrent Data Store Changes == +Fixed a bug that could cause a segmentation violation if a region was +extended leaving a very small fragment at the end. [#20414] -None +Changed the behavior of the DB_REGISTER | DB_RECOVER flag combination, so +that recovery is always run if the environment panic bit is set. [#20767] == Access Method Changes == -Modified the queue access method so that it only uses latches on the metadata -page rather than a latch and a lock. This was done to improve -performance. [#18749] +Fixed a bug were database configuration settings could be lost when the +database was opened if the open operation was blocked for any amount +of time. [#20860] -Fixed several bugs that could cause an update running with MVCC to get the -wrong version of a page or improperly update the metadata last page -number. [#19063] +Fixed a bug that bulk update operations did not work correctly on +compressed databases. [#19017] -The database open code will no longer log the open and close of the master -database in a file when opening a sub database in that file. [#19071] +Improved the log flushing performance when ftruncate() is not available +on a system. [#19725] -Fixed a bug where an error during an update to a hash database with -DB_NOOVERWRITE set could return DB_KEYEXIST rather than the correct -error. [#19077] +When performing partial puts in a heap database, empty pieces will no longer +be left in a split record chain. [#20052] -Fixed a bug that could cause the wrong page number to be on a root or metadata -page if DB->compact moved the page and the operation was later rolled -forward. [#19167] +Fixed a bug where, on systems without FTRUNCATE, db_verify will return an +error for truncated heap databases. [#20195] -Fixed a bug that could cause the close of a secondary index database to fail -if the transaction doing the open aborted. [#19169] +Fixed a bug where BDB could run out of mutexes when many databases are +renamed. [#20228] -Fixed a bug that could prevent an update to a primary recno or queue database -with DB_NOOVERWITE set. [#19230] +Fixed a bug where the metadata page in hash databases would not be flushed +to disk. [#20265] -Fixed a bug when an update to a database with DB_NOOVERWRITE set could -incorrectly return DB_KEYEXIST rather than the correct error -(e.g., DB_LOCK_DEADLOCK). [#19345] +Fixed a bug that could leave deleted pages from a HEAP database in the +buffer cache. [#20309] -Fixed a bug preventing the use of the set_re_len and set_re_pad methods with -a RECNO database when configuring with --disable-queue. [#19367] +Fixed a bug where the library would fail to put records with overflow keys +into hash duplicate database. [#20329] + +Fixed a bug in DB->compact of btrees that could cause a bad pointer +reference. [#20360] -Fixed a bug in DB->compact on BTREE databases that did not check if the last -page in the database could be moved to a lower numbered page. [#19394] +Fixed a bug that could cause the last page number stored on the metadata +page to be wrong after rolling forward a db->compact operation that freed +more pages than will fit in a single log record. [#20646] -Fixed a bug that could cause a Log Sequence Error when recovering the -deallocation of a multiple page overflow chain. [#19474] +Fixed a bug that could cause DB->stat to block on a mutex while holding a +lock on the metadata page. [#20770] -Fixed a bug that could cause a diagnostic assertion if MVCC was in use -and multiple levels of a btree needed to be split. [#19481] +Fixed a bug that could cause DB->compact of a DB_HASH database to fail to +mark a page it updated as dirty. [#20778] -Fixed a few error paths that could cause a Panic with an "unpinned page -returned" error. [#19493] +Fixed a bug where internal HEAP structures were not rebuilt during database +handle refresh. [#20821] -Fixed a bug that closed a race condition that under heavy mult-threaded -appending to a queue database could cause some records to be lost. [#19498] +Fixed a bug with secondary indices, off-page duplicates and +DB_READ_COMMITTED which could erroneously release the lock on the page +holding a returned record. [#20853] -Fixed a bug that might cause DB->compact to mis-estimate the size of an -overflow record when merging two pages. This may cause the page to have more -data than desired. [#19562] +Fixed a bug that could cause a hang or improperly report an empty queue when +the queue record numbers wrapped around at 2^32. [#20956] -Fixed a bug in DB_ENV->fileid_reset that did not update the fileid's on the -metadata pages of subdatabases if the database file was not in native -byte order. [#19608] - -Fixed a bug that caused the first directory specified in the create of -a partitioned database to get too many partitions. [#20041] +Fixed a bug on Linux or Windows that could generate a checksum error +if a database file was being opened while the meta data page happened +to be flushed from the cache. [#20996] == SQL API Changes == -Fixed a race condition that would cause a corruption error in one process when -two processes created the same SQL database. [#18929] +Fixed several memory leaks in the Online Backup API. [#19850] -Fixed a bug that would cause a constraint violation when updating the -primary key with the same value. [#18976] +Fixed a bug in the SQL API when using large blob items and multiple concurrent +connections. [#19945] -Overwriting an old backup with a new backup using the SQL online backup API -will no longer double the size of the database. [#19021] +To avoid a race condition that could cause a snapshot reader to see a wrong +version it is now not permitted to open a DB handle specifying DB_MULTIVERSION +if that database is currently opened by a handle which did not specify +DB_MULTIVERSION. [#19940] -Implemented index optimizations for indexes on large values. [#19094] +Pragma replication=on can now enable replication on an existing database. +Turning replication off is now permanent. [#20180] -Fixed a bug that could cause an undetected deadlock between a -thread which moved a metadata or root page via a DB->compact operation and -another thread trying to open the database if the old page was being removed -from the file. [#19186] +Fixed a bug in the SQL API where it was possible for a schema update to be +ignored when accessing a database from multiple processes. [#20319] -Fix a bug in the BDBSQL_FILE_PER_TABLE option, to allow absolute -path names. [#19190] +Fixed a bug where aborting an exclusive transaction followed by an +auto-commit read operation causes an assert failure. [#20567] -Add a pragma to allow configuration of DB_SYSTEM_MEM environments. [#19249] +Fixed a bug in the SQL API where using the journal_mode pragma could cause a +crash when used as the first operation in a connection on an existing +database. [#20620] -Exclusive transactions will now block new transactions and will prevent -existing transactions from making forward progress. [#19256] +Turn off the DBSQL encryption option on Windows/WinCE by default to match the +behavior on the other platforms. [#20671] -Fixed a bug that would cause assert error when opening an in-memory hash -database with thread count configured when compiled with ---enable-diagnostic. [#19357] +Renamed the BDBSQL_OMIT_SHARING preprocessor flag to +BDBSQL_SINGLE_PROCESS. [#20789] -Upgrade the bundled version of SQLite to 3.7.6.2 [#19376] +Fixed a bug dealing with handle lock modes not reflecting the correct state +which was causing a deadlock in the SQL API. [#20862] -Fixed a performance bug with the cache victim selection algorithm when there -were multiple cache regions. [#19385] +== Java-specific API changes == -Fixed a bug which could cause two SQL threads to have an undetected deadlock -when opening or closing tables. [#19386] +Added ReplicationManagerConnectionStatus class and +ReplicationManagerSiteInfo.getConnectionStatus(). Deprecated +ReplicationManagerSiteInfo.isConnected(). [#18068] -Fix a bug that could cause a hang when deleting a table if there are multiple -connections to a database from different processes. [#19419] +Updated EID_MASTER to be "public static final" so that it would be exposed +in Java docs. [#20184] -Fixed a bug which could cause multiple threads performing DB->compact on -the same database file to overrun the in-memory freelist, which could -potentially lead to memory corruption. [#19571] - -Fixed a bug in DB->compact that could cause a loop if an attempt to move a -sub-database meta data page deadlocked. [#20028] - -== C API Changes == - -Fixed a bug where encryption could not be enabled for individual databases -in an encrypted environment. [#18891] - -Removed two unused error codes, DB_NOSERVER_HOME and DB_NOSERVER_ID. [#18978] - -Added a DB_DBT_READONLY flag so that users can pass in a non-usermem key -(DB_DBT_USERMEM) for get operations. [#19360] - -Fixed a bug in DB/DBC->get/pget that the partial flags are silently ignored -with positional flags and return inconsistent DBT. [#19540] - -Fixed a bug which prevented items from being deleted on a secondary -database. [#19573] - -Fixed a bug to correctly handle the DB_BUFFER_SMALL case on delete -operations when compression is enabled. [#19660] +Fixed a bug where calls that return Stat objects could cause a +segfault. [#20377] -== Tcl-specific API Changes == - -None. - - -== C#-specific API Changes == - -Added support for partial put/get in the C# API. [#18795] - -Fixed a bug in compare delegate for secondary db. [#18935] - == Replication Changes == -Replication Manager now allows differing ack policies at different -sites throughout the group, and supports dynamic changes to the ack -policy. (The ack policy in force is determined by the current -master.) [#14993] +Fixed quorum computation when most sites are unelectable. [#15251] -Replication Manager "channels" feature allows applications to -share repmgr's communication facilities. [#17228] +Made Replication more resilient to random input on its port. [#15712] -Add example program for RepMgr "channels" feature: ex_rep_chan. [#17387] +Fixed a bug where the datadir structure was not maintained during an +internal init. [#19041] -Replication Manager now allows dynamic changes to a site's -"electability" (changes between zero and non-zero priority). This -feature should be used with care, because electability changes can in -boundary cases invalidate durability guarantees granted for previous -transactions. [#17497] +Fixed a repmgr memory leak when using DB_PRIVATE. [#19363] -Changed election criteria so that later group transactions -won't get overwritten by earlier generations with more log. [#17815] +Fixed a minor bug to handle ENOMEM when using an in-memory +temp database. [#20197] -Added changes to master lease checks that result in improved -performance when using master leases. [#18960] +Fixed a bug where multiple long running transactions across +checkpoints could cause Log Sequence errors on client systems. [#20421] -A log write failure on a replication master will now cause -a panic since the transaction may be committed on some clients. [#19054] - -Fixed a few memory leak conditions on error paths. [#19131] - -Change lease code so that zero priority sites do not count -in lease guarantees since they cannot be elected. [#19154] - -Repmgr rerequest processing is moved from a dedicated thread to heartbeat -messages. Repmgr clients using heartbeats can now detect and rerequest -missing final master log records without master activity. [#19197] - -Repmgr statistics are now included in full statistics output for -an environment. [#19198] - -Fix an inefficiency in mixed version elections. We now check -if an election is won via the EID instead of priority. [#19254] - -Changed election LSNs to use the last txn commit LSN instead -of the end of the log. [#19278] - -Create replication internal database files in the environment -home directory rather than the data directory so that they are in the -same location as the other internal replication files. [#19403] - -Fix a bug that was preventing repmgr from calling an election -when starting a site with the DB_REP_ELECTION flag. [#19546] - -Fixed a bug which could cause a segfault at a replication master if a -named in-memory database was being created around the same time as a -client site were synchronizing (in "internal init") with the master. -[#19583] - -Adjust lease code to consider timeout length when retrying. [#19705] - -Fixed a bug that could cause a crash in replication groups of more -than 10 sites, with multiple processes sharing each DB environment -concurrently. [#19818] - -Fix a bug where an assertion failure could happen if pages in a database -were deallocated during a client internal initialization.[#19851] - -Fix a bug where an internal initialization of a queue database with -non-contiguous extent files could return an error. [#19925] - -The 2SITE_STRICT replication configuration parameter is now turned on -by default. It can be turned off via a call to -DB_ENV->rep_set_config(). [#19937] - -Repmgr heartbeats can now help detect a duplicate master without the -need for application activity. [#19950] +Fixed a bug where multiple Replication Manager processes would sometimes +not all conform to replication-group-aware log archiving. [#20342] == Locking Subsystem Changes == -Fixed a bug where an updater supporting DB_READ_UNCOMMITED might downgrade -its lock too soon if there was an error during the update. [#19155] - -Fixed a bug where transaction timeouts could have been specified in a -database environment where the locking subsystem was disabled. [#19582] - -Fixed a bug in a diagnostic assertion that was improperly triggered by the -removal of a sub-database. [#19683] - -Fixed a bug that would cause DB_ENV->failcheck to free locks for a locker -associated with a database handle after the thread that opened the handle -exited. [#19881] +Fixed a bug that could cause an early lock timeout if a previous error +left a lock timeout value set. [#19973] == Logging Subsystem Changes == -Enhanced recovery so that it will not output extra checkpoint or transaction -id recycle log records if there was no activity since the last -checkpoint. [#15330] +Fixed a bug which could cause an incompletely written log record to be +recognized as valid, resulting in recovery failing with the message "Illegal +record type in log". [#17851] -Log checksums can now be disabled using the compile argument ---disable-log-checksum. This will give a performance increase at the risk -of undetectable corruption in the log records, which would make recovery -impossible. [#19143] - -Fixed a bug that could cause a page that should have been removed from the -end of a file still be in the copy of the file in a hot backup. [#19996] +Fixed a bug where printlog would fail on in-memory heap databases. [#20269] == Memory Pool Subsystem Changes == -Fixed a bug in MPOOLFILE->get that did not permit the DB_MPOOL_DIRTY flag -to be used with other flags. [#19421] +Fixed a bug which overstated the number of clean and dirty pages evicted from +the cache. [#20410] + +Fixed a bug that left a small fragment at the end of a region when +extending. [#20414] + +Fixed a bug where the file bucket was always zero when creating a mpoolfile +using the mpool API. [#20468] + +Fixed a bug with multiversion concurrency control which could cause +versions of pages to remain in the cache even though they are no longer +needed. [#20570] + +The memory pool allocator will now start freezing MVCC versions of buffers +if it sees more than 1/4 of the available buffers are taken up by +versions. [#20836] == Mutex Subsystem Changes == -Fixed a bug when the mutex region needs to be larger than 4GB, the region size -was incorrectly adjusted to be slightly too small to fit the mutexes. [#18968] - -Fixed a performance problem with hybrid shared latches in which a request for -exclusive access would busy-wait (rather than put itself to sleep) if the latch -were held by a shared reader. This also fixed the timeout handling of hybrid -mutexes. In some cases the timeout would not be honored, resulting in delays -for the replication "read your writes" feature which were longer than requested. -[#18982] - -Fixed the timeout handling of the pthreads mutexes used by the replication -"read your writes" feature. When a timeout occurred there was a race condition -which might result in a hang. [#19047] +Fixed a bug in which DB_ENV->mutex_set_align() could cause +DB_ENV->mutex_stat_print(dbenv, DB_STAT_ALL) to display only the +first mutex. [#20522] +Fixed a bug with DB_ENV->mutex_stat_print() in which the information on +some mutexes would not be displayed, if any mutex had been freed and not +yet reallocated. [#20533] == Transaction Subsystem Changes == -Fixed a leak of log file ids when a database is closed before the end of a -transaction that references it. [#15957] - -Fixed a bug that would cause a panic if a child transaction performed a database -rename, then aborted, and then the parent transaction committed. [#18069] - -Fixed a bug where we released the metadata page lock too early if a -non-transactional update was being done. [#19036] - -Removed the possibility that checkpoints will overlap in the log, decreasing -the time to recover. [#19062] - - -== Test Suite Changes == - -Require Tcl 8.5 or greater. +Fixed a bug where a malloc failure could result in a segfault +when doing a put on a database with secondaries. [#20641] == Utility Changes == -Added a new utility, db_tuner, which analyzes the data in a btree database, -and suggests a reasonable pagesize. [#18910] +Fixed a bug that would cause verify to call the wrong compare function if +there are user defined compare functions used and the database has multilevel +off page sorted duplicate trees. [#20284] -Fixed some bugs in log_verify when there are in-memory database logs and subdb -logs. [#19157] +Fixed a bug that could cause recovery to fail if DB->compact moved the meta +data page of a HASH subdatabase. [#20708] -Modified db_hotbackup to not read from the file system as required on non-UNIX -systems. Also provided the db_copy function for this purpose. [#19863] - -Fixed db_hotbackup so that when -d/-l or -D is not specified, DB_CONFIG is -used to determine the locations of the databases and logs in the source -environment. [#19994] +Fixed two problems with db_hotbackup's handling of transaction logs. A hotbackup +would always try to open the logs in the environment home, even if a log +directory had been specified. The second fix corrected an error path, in which +the memory was freed by the wrong function, possibly causing a guard byte error. +[#21313] == Configuration, Documentation, Sample Apps, Portability and Build Changes == -Changed SQL API library built on *nix to link with libpthreads when -necessary. [#19098] - -Added CPPFLAGS into our --enable-jdbc configuration. [#19234] - -Added encryption support into the Windows CE build project for SQL API. [#19632] - -Fixed a bug in the STAT_INC_VERB() dtrace probe that was causing compiler -warnings. [#19707] - -Fixed a bug that could cause a trap in db_dump using salvage mode if a -page was found that was not associated with any database in the file. [#19974] - -On Cygwin, circumvented a bug in libtool that is exposed when building the -BDB SQL API in a directory path containing whitespace characters. [#19812] - -== Example Changes == - -Update repmgr C, C#, C++, Java examples(ex_rep_mgr, ex_rep_gsg_repmgr, -ex_rep_chan, excs_repquote, excxx_repquote, excxx_epquote_gsg, repquote, -repquote_gsg) with their related API changes for group -membership. [#19586][#19622] - -Port ex_rep_chan, ex_rep_gsg_repmgr,ex_rep_gsg_simple, -excxx_repquote_gsg_repmgr, excxx_repquote_gsg_simple to Window.[#19890] - -== Miscellaneous Bug Fixes == - -Fixed a bug where memory copied from the Java API could leak if flags were not -correctly configured. [#19152] - -== Deprecated Features == - -None +The DB_CONFIG configuration commands which specify directory pathnames +("set_data_dir", "set_lg_dir", and "set_tmp_dir") now accept names containing +whitespace characters. [#20158] == Known Bugs == -The SQL API has a known issue when using a blob field with a lot of content -and multiple concurrent connections to the database. [#19945] +If two SQL processes are concurrently altering the schema of the same tables +in a database, there is a race condition that can cause the application +to hang. [#20513] -Rollback of a dropped table in the SQL layer contains a mutex leak, which -can consume all mutex resources if enough rollbacks of table drops are -performed. [#20077] - -The DB_CONFIG configuration parameters which specify path names currently -do not support names containing any whitespace characters. [#20158] - -The BFile module has a known crash issue when using BFile handle for SQL -expressions interface on 64bit platforms. [#20193] - -On systems without FTRUNCATE, db_verify will return an error for truncated -heap databases. This is a bug in db_verify, the database has been truncated -correctly and can be used in the future. [#20195] - -An application using queue extents which is append mostly could see a -decrease in the buffer pool hit rate due to the failure to remove pages -from closed extents from the buffer pool. [#20217] +Replication groups including machines of different endianness do +not support the heap access method. [#21016] +If a txn that is attempting to remove a region page from a heap database is +aborted and another txn is trying to update that same page then it can +cause the original txn to abort. This is timing dependant. [#20939] diff --git a/dist/Makefile.in b/dist/Makefile.in index 1ee35140..0d319707 100644 --- a/dist/Makefile.in +++ b/dist/Makefile.in @@ -223,8 +223,8 @@ HASH_OBJS=\ HASH_VRFY_OBJS=\ hash_verify@o@ HEAP_OBJS=\ - heap@o@ heap_auto@o@ heap_conv@o@ heap_method@o@ heap_open@o@ \ - heap_rec@o@ heap_reclaim@o@ heap_stat@o@ + heap@o@ heap_auto@o@ heap_backup@o@ heap_conv@o@ heap_method@o@ \ + heap_open@o@ heap_rec@o@ heap_reclaim@o@ heap_stat@o@ HEAP_VRFY_OBJS=\ heap_verify@o@ QUEUE_OBJS=\ @@ -263,39 +263,41 @@ XA_OBJS=\ # object files in order to generate the additional objects in @FINAL_OBJS@. DTRACE_OBJS= @ADDITIONAL_OBJS@ @REPLACEMENT_OBJS@ @CRYPTO_OBJS@ \ - clock@o@ crdel_auto@o@ crdel_rec@o@ db@o@ db_am@o@ \ - db_auto@o@ db_byteorder@o@ db_cam@o@ db_cds@o@ db_compact@o@ \ - db_compint@o@ db_conv@o@ db_copy@o@ db_dispatch@o@ db_dup@o@ db_err@o@ \ - db_getlong@o@ db_idspace@o@ db_iface@o@ db_join@o@ db_log2@o@ \ - db_meta@o@ db_method@o@ db_open@o@ db_overflow@o@ db_pr@o@ db_rec@o@ \ - db_reclaim@o@ db_remove@o@ db_rename@o@ db_ret@o@ db_setid@o@ \ - db_setlsn@o@ db_shash@o@ db_sort_multiple@o@ db_stati@o@ \ - db_truncate@o@ db_upg@o@ db_upg_opd@o@ dbreg@o@ dbreg_stat@o@ \ - dbreg_auto@o@ dbreg_rec@o@ dbreg_util@o@ dbt@o@ env_alloc@o@ \ - env_config@o@ env_failchk@o@ env_file@o@ env_globals@o@ env_open@o@ \ - env_method@o@ env_name@o@ env_recover@o@ env_region@o@ env_register@o@ \ - env_sig@o@ env_stat@o@ fileops_auto@o@ fop_basic@o@ fop_rec@o@ \ - fop_util@o@ hash_func@o@ hmac@o@ log@o@ log_archive@o@ \ - log_compare@o@ log_debug@o@ log_get@o@ log_method@o@ log_print@o@ \ - log_put@o@ log_stat@o@ mkpath@o@ mp_alloc@o@ mp_bh@o@ mp_fget@o@ \ + clock@o@ crdel_auto@o@ crdel_rec@o@ db@o@ db_am@o@ db_auto@o@ \ + db_backup@o@ db_byteorder@o@ db_cam@o@ db_cds@o@ db_compact@o@ \ + db_compint@o@ db_conv@o@ db_copy@o@ db_dispatch@o@ db_dup@o@ \ + db_err@o@ db_getlong@o@ db_idspace@o@ db_iface@o@ db_join@o@ \ + db_log2@o@ db_meta@o@ db_method@o@ db_open@o@ db_overflow@o@ \ + db_pr@o@ db_rec@o@ db_reclaim@o@ db_remove@o@ db_rename@o@ \ + db_ret@o@ db_setid@o@ db_setlsn@o@ db_shash@o@ db_sort_multiple@o@ \ + db_stati@o@ db_truncate@o@ db_upg@o@ db_upg_opd@o@ dbreg@o@ \ + dbreg_stat@o@ dbreg_auto@o@ dbreg_rec@o@ dbreg_util@o@ \ + dbt@o@ env_alloc@o@ env_config@o@ env_backup@o@ env_failchk@o@ \ + env_file@o@ env_globals@o@ env_open@o@ env_method@o@ env_name@o@ \ + env_recover@o@ env_region@o@ env_register@o@ env_sig@o@ \ + env_stat@o@ fileops_auto@o@ fop_basic@o@ fop_rec@o@ fop_util@o@ \ + hash_func@o@ hmac@o@ log@o@ log_archive@o@ log_compare@o@ \ + log_debug@o@ log_get@o@ log_method@o@ log_print@o@ log_put@o@ \ + log_stat@o@ mkpath@o@ mp_alloc@o@ mp_backup@o@ mp_bh@o@ mp_fget@o@ \ mp_fmethod@o@ mp_fopen@o@ mp_fput@o@ mp_fset@o@ mp_method@o@ \ mp_mvcc@o@ mp_region@o@ mp_register@o@ mp_resize@o@ mp_stat@o@ \ mp_sync@o@ mp_trickle@o@ openflags@o@ os_abort@o@ os_abs@o@ \ os_alloc@o@ os_clock@o@ os_cpu@o@ os_ctime@o@ os_config@o@ \ os_dir@o@ os_errno@o@ os_fid@o@ os_flock@o@ os_fsync@o@ \ os_getenv@o@ os_handle@o@ os_map@o@ os_method@o@ os_mkdir@o@ \ - os_open@o@ os_pid@o@ os_rename@o@ os_root@o@ os_rpath@o@ \ - os_rw@o@ os_seek@o@ os_stack@o@ os_stat@o@ os_tmpdir@o@ \ - os_truncate@o@ os_uid@o@ os_unlink@o@ os_yield@o@ partition@o@ \ - seq_stat@o@ sequence@o@ sha1@o@ snprintf@o@ txn@o@ txn_auto@o@ \ - txn_chkpt@o@ txn_failchk@o@ txn_method@o@ txn_rec@o@ txn_recover@o@ \ - txn_region@o@ txn_stat@o@ txn_util@o@ xa@o@ xa_map@o@ zerofill@o@ + os_open@o@ os_path@o@ os_pid@o@ os_rename@o@ os_root@o@ \ + os_rpath@o@ os_rw@o@ os_seek@o@ os_stack@o@ os_stat@o@ \ + os_tmpdir@o@ os_truncate@o@ os_uid@o@ os_unlink@o@ os_yield@o@ \ + partition@o@ seq_stat@o@ sequence@o@ sha1@o@ snprintf@o@ txn@o@ \ + txn_auto@o@ txn_chkpt@o@ txn_failchk@o@ txn_method@o@ txn_rec@o@ \ + txn_recover@o@ txn_region@o@ txn_stat@o@ txn_util@o@ xa@o@ \ + xa_map@o@ zerofill@o@ \ C_OBJS= $(DTRACE_OBJS) @FINAL_OBJS@ CUTEST_OBJS=\ - CuTest@o@ CuTests@o@ Runner@o@ TestChannel@o@ TestDbTuner@o@ \ - TestEncryption@o@ TestEnvConfig@o@ TestEnvMethod@o@ \ + CuTest@o@ CuTests@o@ Runner@o@ TestChannel@o@ TestDbHotBackup@o@ \ + TestDbTuner@o@ TestEncryption@o@ TestEnvConfig@o@ TestEnvMethod@o@ \ TestKeyExistErrorReturn@o@ TestPartial@o@ TestQueue@o@ \ CXX_OBJS=\ @@ -315,13 +317,14 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/asm/AnnotationWriter.java \ $(JAVA_SLEEPYCAT)/asm/Attribute.java \ $(JAVA_SLEEPYCAT)/asm/ByteVector.java \ - $(JAVA_SLEEPYCAT)/asm/ClassAdapter.java \ $(JAVA_SLEEPYCAT)/asm/ClassReader.java \ $(JAVA_SLEEPYCAT)/asm/ClassVisitor.java \ $(JAVA_SLEEPYCAT)/asm/ClassWriter.java \ $(JAVA_SLEEPYCAT)/asm/Edge.java \ $(JAVA_SLEEPYCAT)/asm/FieldVisitor.java \ $(JAVA_SLEEPYCAT)/asm/FieldWriter.java \ + $(JAVA_SLEEPYCAT)/asm/Frame.java \ + $(JAVA_SLEEPYCAT)/asm/Handle.java \ $(JAVA_SLEEPYCAT)/asm/Handler.java \ $(JAVA_SLEEPYCAT)/asm/Item.java \ $(JAVA_SLEEPYCAT)/asm/Label.java \ @@ -401,6 +404,8 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/collections/TransactionWorker.java \ $(JAVA_SLEEPYCAT)/collections/TupleSerialFactory.java \ $(JAVA_SLEEPYCAT)/compat/DbCompat.java \ + $(JAVA_SLEEPYCAT)/db/BackupHandler.java \ + $(JAVA_SLEEPYCAT)/db/BackupOptions.java \ $(JAVA_SLEEPYCAT)/db/BtreeCompressor.java \ $(JAVA_SLEEPYCAT)/db/BtreePrefixCalculator.java \ $(JAVA_SLEEPYCAT)/db/BtreeStats.java \ @@ -478,6 +483,7 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/db/ReplicationLeaseExpiredException.java \ $(JAVA_SLEEPYCAT)/db/ReplicationLockoutException.java \ $(JAVA_SLEEPYCAT)/db/ReplicationManagerAckPolicy.java \ + $(JAVA_SLEEPYCAT)/db/ReplicationManagerConnectionStatus.java \ $(JAVA_SLEEPYCAT)/db/ReplicationManagerMessageDispatch.java \ $(JAVA_SLEEPYCAT)/db/ReplicationManagerSite.java \ $(JAVA_SLEEPYCAT)/db/ReplicationManagerSiteConfig.java \ @@ -539,6 +545,7 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/persist/PrimaryKeyValueAdapter.java \ $(JAVA_SLEEPYCAT)/persist/SecondaryIndex.java \ $(JAVA_SLEEPYCAT)/persist/StoreConfig.java \ + $(JAVA_SLEEPYCAT)/persist/StoreConfigBeanInfo.java \ $(JAVA_SLEEPYCAT)/persist/StoreExistsException.java \ $(JAVA_SLEEPYCAT)/persist/StoreNotFoundException.java \ $(JAVA_SLEEPYCAT)/persist/SubIndex.java \ @@ -550,6 +557,7 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/persist/evolve/Deleter.java \ $(JAVA_SLEEPYCAT)/persist/evolve/EntityConverter.java \ $(JAVA_SLEEPYCAT)/persist/evolve/EvolveConfig.java \ + $(JAVA_SLEEPYCAT)/persist/evolve/EvolveConfigBeanInfo.java \ $(JAVA_SLEEPYCAT)/persist/evolve/EvolveEvent.java \ $(JAVA_SLEEPYCAT)/persist/evolve/EvolveInternal.java \ $(JAVA_SLEEPYCAT)/persist/evolve/EvolveListener.java \ @@ -627,6 +635,8 @@ JAVA_DBSRCS=\ $(JAVA_SLEEPYCAT)/persist/raw/RawObject.java \ $(JAVA_SLEEPYCAT)/persist/raw/RawStore.java \ $(JAVA_SLEEPYCAT)/persist/raw/RawType.java \ + $(JAVA_SLEEPYCAT)/util/ClassResolver.java \ + $(JAVA_SLEEPYCAT)/util/ConfigBeanInfoBase.java \ $(JAVA_SLEEPYCAT)/util/ErrorBuffer.java \ $(JAVA_SLEEPYCAT)/util/ExceptionUnwrapper.java \ $(JAVA_SLEEPYCAT)/util/ExceptionWrapper.java \ @@ -1306,10 +1316,12 @@ CuTests@o@: $(testdir)/c/cutest/CuTests.c $(CC) $(CUTEST_FLAGS) $? Runner@o@: $(testdir)/c/cutest/Runner.c $(CC) $(CUTEST_FLAGS) $? -TestDbTuner@o@: $(testdir)/c/suites/TestDbTuner.c - $(CC) $(CUTEST_FLAGS) $? TestChannel@o@: $(testdir)/c/suites/TestChannel.c $(CC) $(CUTEST_FLAGS) $? +TestDbHotBackup@o@: $(testdir)/c/suites/TestDbHotBackup.c + $(CC) $(CUTEST_FLAGS) $? +TestDbTuner@o@: $(testdir)/c/suites/TestDbTuner.c + $(CC) $(CUTEST_FLAGS) $? TestEncryption@o@: $(testdir)/c/suites/TestEncryption.c $(CC) $(CUTEST_FLAGS) $? TestEnvConfig@o@: $(testdir)/c/suites/TestEnvConfig.c @@ -1899,6 +1911,8 @@ db_autop@o@: $(srcdir)/db/db_autop.c $(CC) $(CFLAGS) $? db_byteorder@o@: $(srcdir)/common/db_byteorder.c $(CC) $(CFLAGS) $? +db_backup@o@: $(srcdir)/db/db_backup.c + $(CC) $(CFLAGS) $? db_cam@o@: $(srcdir)/db/db_cam.c $(CC) $(CFLAGS) $? db_cds@o@: $(srcdir)/db/db_cds.c @@ -1991,6 +2005,8 @@ env_alloc@o@: $(srcdir)/env/env_alloc.c $(CC) $(CFLAGS) $? env_config@o@: $(srcdir)/env/env_config.c $(CC) $(CFLAGS) $? +env_backup@o@: $(srcdir)/env/env_backup.c + $(CC) $(CFLAGS) $? env_failchk@o@: $(srcdir)/env/env_failchk.c $(CC) $(CFLAGS) $? env_file@o@: $(srcdir)/env/env_file.c @@ -2063,6 +2079,8 @@ heap_auto@o@: $(srcdir)/heap/heap_auto.c $(CC) $(CFLAGS) $? heap_autop@o@: $(srcdir)/heap/heap_autop.c $(CC) $(CFLAGS) $? +heap_backup@o@: $(srcdir)/heap/heap_backup.c + $(CC) $(CFLAGS) $? heap_conv@o@: $(srcdir)/heap/heap_conv.c $(CC) $(CFLAGS) $? heap_method@o@: $(srcdir)/heap/heap_method.c @@ -2141,6 +2159,8 @@ mp_alloc@o@: $(srcdir)/mp/mp_alloc.c $(CC) $(CFLAGS) $? mp_bh@o@: $(srcdir)/mp/mp_bh.c $(CC) $(CFLAGS) $? +mp_backup@o@: $(srcdir)/mp/mp_backup.c + $(CC) $(CFLAGS) $? mp_fget@o@: $(srcdir)/mp/mp_fget.c $(CC) $(CFLAGS) $? mp_fmethod@o@: $(srcdir)/mp/mp_fmethod.c @@ -2229,6 +2249,8 @@ os_mkdir@o@: $(srcdir)/@OSDIR@/os_mkdir.c $(CC) $(CFLAGS) $? os_open@o@: $(srcdir)/@OSDIR@/os_open.c $(CC) $(CFLAGS) $? +os_path@o@: $(srcdir)/os/os_path.c + $(CC) $(CFLAGS) $? os_pid@o@: $(srcdir)/os/os_pid.c $(CC) $(CFLAGS) $? os_qnx_fsync@o@: $(srcdir)/os_qnx/os_qnx_fsync.c diff --git a/dist/RELEASE b/dist/RELEASE index 61670208..54896523 100644 --- a/dist/RELEASE +++ b/dist/RELEASE @@ -4,13 +4,13 @@ DB_VERSION_FAMILY=11 DB_VERSION_LETTER="g" DB_VERSION_RELEASE=2 DB_VERSION_MAJOR=5 -DB_VERSION_MINOR=2 -DB_VERSION_PATCH=28 +DB_VERSION_MINOR=3 +DB_VERSION_PATCH=21 DB_VERSION="$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH" DB_VERSION_FULL="$DB_VERSION_FAMILY.$DB_VERSION_RELEASE.$DB_VERSION_MAJOR.$DB_VERSION_MINOR.$DB_VERSION_PATCH" DB_VERSION_UNIQUE_NAME=`printf "_%d%03d" $DB_VERSION_MAJOR $DB_VERSION_MINOR` -DB_RELEASE_DATE="June 10, 2011" +DB_RELEASE_DATE="May 11, 2012" DB_VERSION_STRING="Berkeley DB $DB_VERSION: ($DB_RELEASE_DATE)" DB_VERSION_FULL_STRING="Berkeley DB $DB_VERSION_FAMILY$DB_VERSION_LETTER Release $DB_VERSION_RELEASE, library version $DB_VERSION_FULL: ($DB_RELEASE_DATE)" diff --git a/dist/aclocal/mmap.m4 b/dist/aclocal/mmap.m4 index bb0256aa..727c6c35 100644 --- a/dist/aclocal/mmap.m4 +++ b/dist/aclocal/mmap.m4 @@ -1,4 +1,4 @@ -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # Detect mmap capability: If the file underlying an mmap is extended, # does the addressable memory grow too? diff --git a/dist/aclocal/mutex.m4 b/dist/aclocal/mutex.m4 index 3963796b..81f1ea8d 100644 --- a/dist/aclocal/mutex.m4 +++ b/dist/aclocal/mutex.m4 @@ -156,7 +156,8 @@ if test "$db_cv_mingw" = yes; then fi if test "$db_cv_mutex" = no; then - # User-specified POSIX or UI mutexes. + # Check for the availability of POSIX or UI mutexes; also check + # whether the user has specified POSIX with --enable-posixmutexes. # # There are two different reasons to specify mutexes: First, the # application is already using one type of mutex and doesn't want @@ -178,21 +179,35 @@ if test "$db_cv_mutex" = no; then # POSIX.1 pthreads: pthread_XXX # - # If the user specified we use POSIX pthreads mutexes, and we fail to - # find the full interface, try and configure for just intra-process - # support. - if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then - LIBS="$LIBS -lpthread" - AM_PTHREADS_SHARED(POSIX/pthreads/library) - AM_PTHREADS_CONDVAR_DUPINITCHK - AM_PTHREADS_RWLOCKVAR_DUPINITCHK - LIBS="$orig_libs" - fi - if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then - AM_PTHREADS_SHARED(POSIX/pthreads) - AM_PTHREADS_CONDVAR_DUPINITCHK - AM_PTHREADS_RWLOCKVAR_DUPINITCHK - fi + # If we find POSIX pthreads mutexes but not the full interface, + # try to configure for just intra-process support. + case "$host_os" in + darwin*) + # Mac OS 10.7 Lion has broken pthread_*_setpshared() calls. + # Most BSD-like operating systems have pointers in their mutex + # and condition variables, and cannot be shared between + # proceses. Earlier Mac OS releases correctly returned EINVAL + # from *_setpshared(PTHREAD_PROCESS_SHARED), but 10.7 returns + # success. Since we can't trust those calls anymore we now + # avoid these probes for multiprocess pthreads. + ;; + *) + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + LIBS="$LIBS -lpthread" + AM_PTHREADS_SHARED(POSIX/pthreads/library) + AM_PTHREADS_CONDVAR_DUPINITCHK + AM_PTHREADS_RWLOCKVAR_DUPINITCHK + LIBS="$orig_libs" + fi + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + AM_PTHREADS_SHARED(POSIX/pthreads) + AM_PTHREADS_CONDVAR_DUPINITCHK + AM_PTHREADS_RWLOCKVAR_DUPINITCHK + fi + ;; + esac + # We probe for private pthreads only when the user has asked for posix + # mutexes and we don't have a multiprocess pthreads library available. if test "$db_cv_mutex" = posix_only; then AM_PTHREADS_PRIVATE(POSIX/pthreads/private) AM_PTHREADS_CONDVAR_DUPINITCHK diff --git a/dist/aclocal/options.m4 b/dist/aclocal/options.m4 index 1fd93342..c007fba6 100644 --- a/dist/aclocal/options.m4 +++ b/dist/aclocal/options.m4 @@ -368,6 +368,26 @@ AC_ARG_ENABLE(umrw, [db_cv_umrw="$enable_umrw"], [db_cv_umrw="no"]) AC_MSG_RESULT($db_cv_umrw) +# Solaris, AI/X, OS/X and other BSD-derived systems default to POSIX-conforming +# disk i/o: A single read or write call is atomic. Other systems do not +# guarantee atomicity; in particular Linux and Microsoft Windows. +atomicfileread="no" +case "$host_os" in +solaris* | aix* | bsdi3* | freebsd* | darwin*) + atomicfileread="yes";; +esac +AC_MSG_CHECKING(if --enable-atomicfileread option specified) +AC_ARG_ENABLE(atomicfileread, + [AC_HELP_STRING([--enable-atomicfileread], + [Indicate that the platform reads and writes files atomically.])], + [db_cv_atomicfileread="$enable_atomicfileread"], [db_cv_atomicfileread=$atomicfileread]) +AC_MSG_RESULT($db_cv_atomicfileread) +if test "$db_cv_atomicfileread" = "yes"; then + AC_DEFINE(HAVE_ATOMICFILEREAD) + AH_TEMPLATE(HAVE_ATOMICFILEREAD, + [Define to 1 if platform reads and writes files atomically.]) +fi + # Cryptography support. # Until Berkeley DB 5.0, this was a simple yes/no decision. # With the addition of support for Intel Integrated Performance Primitives (ipp) diff --git a/dist/aclocal/tcl.m4 b/dist/aclocal/tcl.m4 index 0aba9b5b..3403954c 100644 --- a/dist/aclocal/tcl.m4 +++ b/dist/aclocal/tcl.m4 @@ -87,10 +87,10 @@ AC_DEFUN(SC_LOAD_TCLCONFIG, [ AC_MSG_RESULT([file not found]) fi - # DB requires at least version 8.4. + # DB requires at least version 8.5. if test ${TCL_MAJOR_VERSION} -lt 8 \ - -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then - AC_MSG_ERROR([Berkeley DB requires Tcl version 8.4 or better.]) + -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 5; then + AC_MSG_ERROR([Berkeley DB requires Tcl version 8.5 or better.]) fi # The eval is required to do substitution (for example, the TCL_DBGX diff --git a/dist/api_flags b/dist/api_flags index cb6008c5..9d606670 100644 --- a/dist/api_flags +++ b/dist/api_flags @@ -1,6 +1,16 @@ db_env_create DB_CXX_NO_EXCEPTIONS # C++: return error values +DbEnv.backup + # Remove all files from the target directory tree first. + DB_BACKUP_CLEAN + DB_BACKUP_FILES # Copy plain files too. + DB_BACKUP_NO_LOGS # Don't backup log files. + DB_BACKUP_SINGLE_DIR # All files go to a single directory. + DB_BACKUP_UPDATE # Incremental backup. + DB_CREATE # Create the target directories. + DB_EXCL # Error if a target file exists. + DbEnv.close # Sync database when automatically closing its db handles. DB_FORCESYNC @@ -68,6 +78,7 @@ DbEnv.lock_stat_print DbEnv.lock_vec DB_LOCK_CHECK # UNDOC: check for a lock + DB_LOCK_IGNORE_REC # UNDOC: get lock during recovery DB_LOCK_NOWAIT # Don't wait for an unavailable lock DB_LOCK_RECORD # UNDOC: record lock DB_LOCK_SET_TIMEOUT # UNDOC: set lock timeout @@ -231,6 +242,7 @@ DbEnv.set_timeout DB_SET_REG_TIMEOUT # Set dbregister timeout DbEnv.set_verbose + DB_VERB_BACKUP # Backup information DB_VERB_DEADLOCK # Deadlock detection information DB_VERB_FILEOPS # Major file operations DB_VERB_FILEOPS_ALL # All file operations @@ -289,6 +301,7 @@ DbLogc.get DbMpoolFile.close DB_MPOOL_DISCARD # UNDOC: Discard file + DB_FLUSH # UNDOC: opened to flush a page DB_MPOOL_NOLOCK # UNDOC: Already have mpf locked DbMpoolFile.get @@ -305,6 +318,7 @@ DbMpoolFile.open DB_DIRECT # Don't buffer the file in the OS DB_DURABLE_UNKNOWN # UNDOC: Durability on open DB_EXTENT # UNDOC: dealing with an extent + DB_FLUSH # UNDOC: opened to flush a page DB_MULTIVERSION # Multiversion concurrency control DB_NOMMAP # Don't mmap underlying file DB_ODDFILESIZE # Truncate file to N * pgsize @@ -435,7 +449,8 @@ Db.open # The following flags aren't actually part of the Db.open method # API, but they are accepted by the underlying __db_open function. DB_DURABLE_UNKNOWN # UNDOC: Durability on open - DB_INTERNAL_DB # UNDOC: Open db in env dir + DB_INTERNAL_PERSISTENT_DB # UNDOC: Open db in metadata dir + DB_INTERNAL_TEMPORARY_DB # UNDOC: Open db in env home dir DB_NOERROR # UNDOC: Don't raise errors. DB_ODDFILESIZE # UNDOC: Truncate file to N * pgsize DB_WRITEOPEN # UNDOC: open with write lock diff --git a/dist/api_flags.c b/dist/api_flags.c index 70e21602..a546a0c0 100644 --- a/dist/api_flags.c +++ b/dist/api_flags.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ #include diff --git a/dist/buildpkg b/dist/buildpkg index aa1b07cd..a7a4385c 100644 --- a/dist/buildpkg +++ b/dist/buildpkg @@ -57,8 +57,8 @@ START_DIR=`pwd` D=`pwd`/../release R="$D/db-${VERSION}" RNC="$D/db-$VERSION.NC" -DOCS=`pwd`/../../docs_books -DB_ADDONS=`pwd`/../../db_addons +DOCS=`pwd`/../../docs_books-5.3 +DB_ADDONS=`pwd`/../../db_addons-5.3 if [ ! -d $DB_ADDONS ]; then echo "buildpkg requires a db_addons repository at the same level as the db repository." diff --git a/dist/config.guess b/dist/config.guess index 187cd54e..8152efd6 100755 --- a/dist/config.guess +++ b/dist/config.guess @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. -timestamp='2011-02-02' +timestamp='2011-11-11' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -792,13 +792,12 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -807,6 +806,9 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 @@ -882,7 +884,13 @@ EOF then echo ${UNAME_MACHINE}-unknown-linux-gnu else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi fi exit ;; avr32*:Linux:*:*) @@ -897,6 +905,9 @@ EOF frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; + hexagon:Linux:*:*) + echo hexagon-unknown-linux-gnu + exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build @@ -972,7 +983,7 @@ EOF echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-tilera-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu diff --git a/dist/config.hin b/dist/config.hin index 7644e1a0..50e00a05 100644 --- a/dist/config.hin +++ b/dist/config.hin @@ -36,6 +36,9 @@ /* Define to 1 if you have the `atol' function. */ #undef HAVE_ATOL +/* Define to 1 if platform reads and writes files atomically. */ +#undef HAVE_ATOMICFILEREAD + /* Define to 1 to use Solaris library routes for atomic operations. */ #undef HAVE_ATOMIC_SOLARIS diff --git a/dist/config.sub b/dist/config.sub index 30fdca81..e76eaf47 100755 --- a/dist/config.sub +++ b/dist/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # 2011 Free Software Foundation, Inc. -timestamp='2011-03-23' +timestamp='2011-11-11' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -251,13 +251,17 @@ case $basic_machine in | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ + | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ + | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ @@ -291,7 +295,7 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ - | rx \ + | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ @@ -300,7 +304,7 @@ case $basic_machine in | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ - | v850 | v850e \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -357,6 +361,7 @@ case $basic_machine in | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ + | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | clipper-* | craynv-* | cydra-* \ @@ -365,8 +370,10 @@ case $basic_machine in | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ + | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ @@ -400,7 +407,7 @@ case $basic_machine in | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ - | romp-* | rs6000-* | rx-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ @@ -408,10 +415,11 @@ case $basic_machine in | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile-* | tilegx-* \ + | tile*-* \ | tron-* \ | ubicom32-* \ - | v850-* | v850e-* | vax-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -808,10 +816,18 @@ case $basic_machine in ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; + msys) + basic_machine=i386-pc + os=-msys + ;; mvs) basic_machine=i370-ibm os=-mvs ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 @@ -1120,13 +1136,8 @@ case $basic_machine in basic_machine=t90-cray os=-unicos ;; - # This must be matched before tile*. - tilegx*) - basic_machine=tilegx-unknown - os=-linux-gnu - ;; tile*) - basic_machine=tile-unknown + basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) @@ -1336,7 +1347,7 @@ case $os in | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ diff --git a/dist/configure b/dist/configure index e28f2a38..db718de0 100755 --- a/dist/configure +++ b/dist/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for Berkeley DB 5.2.28. +# Generated by GNU Autoconf 2.68 for Berkeley DB 5.3.21. # # Report bugs to . # @@ -569,15 +569,15 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Berkeley DB' -PACKAGE_TARNAME='db-5.2.28' -PACKAGE_VERSION='5.2.28' -PACKAGE_STRING='Berkeley DB 5.2.28' +PACKAGE_TARNAME='db-5.3.21' +PACKAGE_VERSION='5.3.21' +PACKAGE_STRING='Berkeley DB 5.3.21' PACKAGE_BUGREPORT='Oracle Technology Network Berkeley DB forum' PACKAGE_URL='' ac_unique_file="../src/db/db.c" enable_option_checking=no -ac_default_prefix=/usr/local/BerkeleyDB.5.2 +ac_default_prefix=/usr/local/BerkeleyDB.5.3 # Factoring default headers for most tests. ac_includes_default="\ #include @@ -867,6 +867,7 @@ enable_systemtap enable_perfmon_statistics enable_uimutexes enable_umrw +enable_atomicfileread enable_cryptography with_cryptography with_mutex @@ -1439,7 +1440,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Berkeley DB 5.2.28 to adapt to many kinds of systems. +\`configure' configures Berkeley DB 5.3.21 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1488,7 +1489,7 @@ Fine tuning of the installation directories: --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root - [DATAROOTDIR/doc/db-5.2.28] + [DATAROOTDIR/doc/db-5.3.21] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] @@ -1510,7 +1511,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Berkeley DB 5.2.28:";; + short | recursive ) echo "Configuration of Berkeley DB 5.3.21:";; esac cat <<\_ACEOF @@ -1564,6 +1565,8 @@ Optional Features: statistics values [default=no]. --enable-uimutexes Force use of Unix International mutexes. --enable-umrw Mask harmless uninitialized memory read/writes. + --enable-atomicfileread Indicate that the platform reads and writes files + atomically. --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] @@ -1668,7 +1671,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Berkeley DB configure 5.2.28 +Berkeley DB configure 5.3.21 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2447,7 +2450,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Berkeley DB $as_me 5.2.28, which was +It was created by Berkeley DB $as_me 5.3.21, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3009,13 +3012,13 @@ DB_VERSION_RELEASE="2" DB_VERSION_MAJOR="5" -DB_VERSION_MINOR="2" +DB_VERSION_MINOR="3" -DB_VERSION_PATCH="28" +DB_VERSION_PATCH="21" -DB_VERSION_STRING='"Berkeley DB 5.2.28: (June 10, 2011)"' +DB_VERSION_STRING='"Berkeley DB 5.3.21: (May 11, 2012)"' -DB_VERSION_FULL_STRING='"Berkeley DB 11g Release 2, library version 11.2.5.2.28: (June 10, 2011)"' +DB_VERSION_FULL_STRING='"Berkeley DB 11g Release 2, library version 11.2.5.3.21: (May 11, 2012)"' # Process all options before using them. @@ -3621,6 +3624,31 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_umrw" >&5 $as_echo "$db_cv_umrw" >&6; } +# Solaris, AI/X, OS/X and other BSD-derived systems default to POSIX-conforming +# disk i/o: A single read or write call is atomic. Other systems do not +# guarantee atomicity; in particular Linux and Microsoft Windows. +atomicfileread="no" +case "$host_os" in +solaris* | aix* | bsdi3* | freebsd* | darwin*) + atomicfileread="yes";; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-atomicfileread option specified" >&5 +$as_echo_n "checking if --enable-atomicfileread option specified... " >&6; } +# Check whether --enable-atomicfileread was given. +if test "${enable_atomicfileread+set}" = set; then : + enableval=$enable_atomicfileread; db_cv_atomicfileread="$enable_atomicfileread" +else + db_cv_atomicfileread=$atomicfileread +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_atomicfileread" >&5 +$as_echo "$db_cv_atomicfileread" >&6; } +if test "$db_cv_atomicfileread" = "yes"; then + $as_echo "#define HAVE_ATOMICFILEREAD 1" >>confdefs.h + + +fi + # Cryptography support. # Until Berkeley DB 5.0, this was a simple yes/no decision. # With the addition of support for Intel Integrated Performance Primitives (ipp) @@ -3729,7 +3757,7 @@ $as_echo "$with_uniquename" >&6; } else db_cv_uniquename="yes" if test "$with_uniquename" = "yes"; then - DB_VERSION_UNIQUE_NAME="_5002" + DB_VERSION_UNIQUE_NAME="_5003" else DB_VERSION_UNIQUE_NAME="$with_uniquename" fi @@ -17857,7 +17885,7 @@ else JAVA_TEST=Test.java CLASS_TEST=Test.class cat << \EOF > $JAVA_TEST -/* #line 17860 "configure" */ +/* #line 17888 "configure" */ public class Test { } EOF @@ -18120,7 +18148,7 @@ EOF if uudecode$EXEEXT Test.uue; then ac_cv_prog_uudecode_base64=yes else - echo "configure: 18123: uudecode had trouble decoding base 64 file 'Test.uue'" >&5 + echo "configure: 18151: uudecode had trouble decoding base 64 file 'Test.uue'" >&5 echo "configure: failed file was:" >&5 cat Test.uue >&5 ac_cv_prog_uudecode_base64=no @@ -18238,7 +18266,7 @@ else JAVA_TEST=Test.java CLASS_TEST=Test.class cat << \EOF > $JAVA_TEST -/* #line 18241 "configure" */ +/* #line 18269 "configure" */ public class Test { } EOF @@ -18273,7 +18301,7 @@ JAVA_TEST=Test.java CLASS_TEST=Test.class TEST=Test cat << \EOF > $JAVA_TEST -/* [#]line 18276 "configure" */ +/* [#]line 18304 "configure" */ public class Test { public static void main (String args[]) { System.exit (0); @@ -20501,7 +20529,8 @@ if test "$db_cv_mingw" = yes; then fi if test "$db_cv_mutex" = no; then - # User-specified POSIX or UI mutexes. + # Check for the availability of POSIX or UI mutexes; also check + # whether the user has specified POSIX with --enable-posixmutexes. # # There are two different reasons to specify mutexes: First, the # application is already using one type of mutex and doesn't want @@ -20523,11 +20552,21 @@ if test "$db_cv_mutex" = no; then # POSIX.1 pthreads: pthread_XXX # - # If the user specified we use POSIX pthreads mutexes, and we fail to - # find the full interface, try and configure for just intra-process - # support. - if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then - LIBS="$LIBS -lpthread" + # If we find POSIX pthreads mutexes but not the full interface, + # try to configure for just intra-process support. + case "$host_os" in + darwin*) + # Mac OS 10.7 Lion has broken pthread_*_setpshared() calls. + # Most BSD-like operating systems have pointers in their mutex + # and condition variables, and cannot be shared between + # proceses. Earlier Mac OS releases correctly returned EINVAL + # from *_setpshared(PTHREAD_PROCESS_SHARED), but 10.7 returns + # success. Since we can't trust those calls anymore we now + # avoid these probes for multiprocess pthreads. + ;; + *) + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + LIBS="$LIBS -lpthread" if test "$cross_compiling" = yes; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20699,9 +20738,9 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - LIBS="$orig_libs" - fi - if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then + LIBS="$orig_libs" + fi + if test "$db_cv_mutex" = no -o "$db_cv_mutex" = posix_only; then if test "$cross_compiling" = yes; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -20873,7 +20912,11 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - fi + fi + ;; + esac + # We probe for private pthreads only when the user has asked for posix + # mutexes and we don't have a multiprocess pthreads library available. if test "$db_cv_mutex" = posix_only; then if test "$cross_compiling" = yes; then : @@ -24056,10 +24099,10 @@ $as_echo "loading" >&6; } $as_echo "file not found" >&6; } fi - # DB requires at least version 8.4. + # DB requires at least version 8.5. if test ${TCL_MAJOR_VERSION} -lt 8 \ - -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 4; then - as_fn_error $? "Berkeley DB requires Tcl version 8.4 or better." "$LINENO" 5 + -o ${TCL_MAJOR_VERSION} -eq 8 -a ${TCL_MINOR_VERSION} -lt 5; then + as_fn_error $? "Berkeley DB requires Tcl version 8.5 or better." "$LINENO" 5 fi # The eval is required to do substitution (for example, the TCL_DBGX @@ -24439,7 +24482,7 @@ if test "$db_cv_build_replication" = "yes"; then # replication manager. - if test "$ac_cv_header_pthread_h" = yes; then + if test "$ac_cv_header_pthread_h" = yes -a "$db_cv_mingw" != "yes"; then $as_echo "#define HAVE_REPLICATION_THREADS 1" >>confdefs.h @@ -24529,6 +24572,8 @@ ac_cv_lib_socket=ac_cv_lib_socket_main esac ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)" else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Replication manager is not supported." >&5 +$as_echo "$as_me: WARNING: Replication manager is not supported." >&2;} ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}" fi else @@ -25211,7 +25256,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Berkeley DB $as_me 5.2.28, which was +This file was extended by Berkeley DB $as_me 5.3.21, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25277,7 +25322,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Berkeley DB config.status 5.2.28 +Berkeley DB config.status 5.3.21 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -27307,6 +27352,7 @@ if test "$db_cv_jdbc" != "no"; then test "$prefix" != "" && jdbc_args="--prefix=$prefix --with-jardir=$prefix/jar" test "$enable_shared" != "" && jdbc_args="$jdbc_args --enable-shared=$enable_shared" test "$enable_static" != "" && jdbc_args="$jdbc_args --enable-static=$enable_static" + test "$cross_compiling" = "yes" && jdbc_args="$jdbc_args --build=$build --host=$host " # 1. The build directory is build_unix/jdbc, so the include paths are relative # to that. diff --git a/dist/configure.ac b/dist/configure.ac index 1608c3b2..b1e49a3f 100644 --- a/dist/configure.ac +++ b/dist/configure.ac @@ -936,7 +936,7 @@ if test "$db_cv_build_replication" = "yes"; then AH_TEMPLATE(HAVE_REPLICATION_THREADS, [Define to 1 if building the Berkeley DB replication framework.]) - if test "$ac_cv_header_pthread_h" = yes; then + if test "$ac_cv_header_pthread_h" = yes -a "$db_cv_mingw" != "yes"; then AC_DEFINE(HAVE_REPLICATION_THREADS) if test "$with_stacksize" != "no"; then @@ -955,6 +955,7 @@ if test "$db_cv_build_replication" = "yes"; then esac ADDITIONAL_OBJS="$ADDITIONAL_OBJS \$(REPMGR_OBJS)" else + AC_MSG_WARN([Replication manager is not supported.]) ADDITIONAL_OBJS="$ADDITIONAL_OBJS repmgr_stub${o}" fi else diff --git a/dist/db_provider.d b/dist/db_provider.d index 3d1ba3a6..06e966ce 100644 --- a/dist/db_provider.d +++ b/dist/db_provider.d @@ -8,21 +8,23 @@ provider bdb { /* * * dist/events.in - This description of Oracle Berkeley DB's internal - * events hierarchy is processes by dist/s_perfmon to generate the - * platform-specific files needed by the configured operating system. + * events hierarchy is processed by 'dist/s_include' to generate the + * platform-independant file dist/db_provider.d. The 'configure' step on the + * target operating system generate platform-specific include file. * - * The entries starting in the first column are event class names, and consist - * of a single word. The class's individual function-like events follow. + * s_include -> dist/db_provider.d + * configure -> /db_provider.h * - * Some of these are included to enhance consistency; thse calls could be - * supported by pid$target:::entry (DTrace) or - * probe process("$LIB").function("").call (SystemTap) probes. + * There are two kinds of entries in events.in, describing either an event class + * or an individual event. The entries starting in the first column are class + * names, consisting of a single word. The class's individual events follow, + * described as if they were an ANSI C function signature; * - * For DTrace - * dist/bdb_provider.d - * util/dtrace/dbdefs.d - * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Events are listed grouped by their relation to one another, rather than + * alphabetically. For instance allocation and free events are adjacent. + * New, unrelated events are placed at the end of their event class. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * */ @@ -228,6 +230,19 @@ provider bdb { probe mpool__alloc_max_pages(unsigned max, unsigned region_id); probe mpool__alloc_pages(unsigned count, unsigned region_id); + probe mpool__backup_spins(unsigned spins, char *file, unsigned pgno); + + /* + * The aggressiveness of a buffer cache allocation increases as more + * involved methods are needed in order to free up the requested space + * in the cache with the indicated region_id. + * aggressive: the agressiveness of an allocation request was increased. + * max_aggressive: the agressiveness of an allocation request was increased + * to a new maximum. + */ + probe mpool__aggressive(unsigned st_alloc_aggressive, unsigned region_id); + probe mpool__max_aggressive(unsigned st_alloc_max_aggr, unsigned region_id); + /* * The mutex category monitors includes shared latches. The alloc_id value * is one of the MTX_XXX definitions from dbinc/mutex.h diff --git a/dist/events.in b/dist/events.in index 6953fa2f..49436a72 100644 --- a/dist/events.in +++ b/dist/events.in @@ -1,20 +1,22 @@ # # dist/events.in - This description of Oracle Berkeley DB's internal -# events hierarchy is processes by dist/s_perfmon to generate the -# platform-specific files needed by the configured operating system. +# events hierarchy is processed by 'dist/s_include' to generate the +# platform-independant file dist/db_provider.d. The 'configure' step on the +# target operating system generate platform-specific include file. # -# The entries starting in the first column are event class names, and consist -# of a single word. The class's individual function-like events follow. +# s_include -> dist/db_provider.d +# configure -> /db_provider.h # -# Some of these are included to enhance consistency; thse calls could be -# supported by pid$target:::entry (DTrace) or -# probe process("$LIB").function("").call (SystemTap) probes. +# There are two kinds of entries in events.in, describing either an event class +# or an individual event. The entries starting in the first column are class +# names, consisting of a single word. The class's individual events follow, +# described as if they were an ANSI C function signature; # -# For DTrace -# dist/bdb_provider.d -# util/dtrace/dbdefs.d -# -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Events are listed grouped by their relation to one another, rather than +# alphabetically. For instance allocation and free events are adjacent. +# New, unrelated events are placed at the end of their event class. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # The alloc class covers the allocation of "on disk" database pages. @@ -170,6 +172,17 @@ mpool alloc_max_pages(unsigned max, unsigned region_id); alloc_pages(unsigned count, unsigned region_id); + backup_spins(unsigned spins, char *file, unsigned pgno);` + + # The aggressiveness of a buffer cache allocation increases as more + # involved methods are needed in order to free up the requested space + # in the cache with the indicated region_id. + # aggressive: the agressiveness of an allocation request was increased. + # max_aggressive: the agressiveness of an allocation request was increased + # to a new maximum. + aggressive(unsigned st_alloc_aggressive, unsigned region_id); + max_aggressive(unsigned st_alloc_max_aggr, unsigned region_id); + # The mutex category monitors includes shared latches. The alloc_id value # is one of the MTX_XXX definitions from dbinc/mutex.h mutex diff --git a/dist/gen_msg.awk b/dist/gen_msg.awk index 0f08d3d0..72820995 100644 --- a/dist/gen_msg.awk +++ b/dist/gen_msg.awk @@ -1,7 +1,7 @@ # # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -404,7 +404,10 @@ function emit_unmarshal() } printf("\tDB_NTOHL_COPYIN(env, argp->%s.size, bp);\n", \ vars[i]) >> CFILE; - printf("\targp->%s.data = bp;\n", vars[i]) >> CFILE; + printf("\tif (argp->%s.size == 0)\n", vars[i]) >> CFILE; + printf("\t\targp->%s.data = NULL;\n", vars[i]) >> CFILE; + printf("\telse\n") >> CFILE; + printf("\t\targp->%s.data = bp;\n", vars[i]) >> CFILE; printf("\tneeded += (size_t)argp->%s.size;\n", \ vars[i]) >> CFILE; printf("\tif (max < needed)\n") >> CFILE; diff --git a/dist/gen_rec.awk b/dist/gen_rec.awk index 5c788361..129c978f 100644 --- a/dist/gen_rec.awk +++ b/dist/gen_rec.awk @@ -2,7 +2,7 @@ # # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/dist/pubdef.in b/dist/pubdef.in index aef8b298..266f3aec 100644 --- a/dist/pubdef.in +++ b/dist/pubdef.in @@ -28,6 +28,7 @@ DB_AM_IN_RENAME * I * * DB_AM_NOT_DURABLE * I * * DB_AM_OPEN_CALLED * I * * DB_AM_PAD * I * * +DB_AM_PARTDB * I * * DB_AM_PGDEF * I * * DB_AM_RDONLY * I * * DB_AM_READ_UNCOMMITTED * I * * @@ -49,6 +50,15 @@ DB_ARCH_REMOVE D I J C DB_ASSOC_IMMUTABLE_KEY * I J C DB_ASSOC_CREATE * I J C DB_AUTO_COMMIT D I J C +DB_BACKUP_CLEAN D I J C +DB_BACKUP_FILES D I J C +DB_BACKUP_NO_LOGS D I J C +DB_BACKUP_READ_COUNT D I J C +DB_BACKUP_READ_SLEEP D I J C +DB_BACKUP_SINGLE_DIR D I J C +DB_BACKUP_SIZE D I J C +DB_BACKUP_UPDATE D I J C +DB_BACKUP_WRITE_DIRECT D I J C DB_BEFORE D I J C DB_BOOTSTRAP_HELPER D I J C DB_BTREE D I J C @@ -186,7 +196,8 @@ DB_INIT_MUTEX * I * * DB_INIT_REP D I J C DB_INIT_TXN D I J C DB_INORDER D I J C -DB_INTERNAL_DB * I * * +DB_INTERNAL_PERSISTENT_DB * I * * +DB_INTERNAL_TEMPORARY_DB * I * * DB_JOINENV * I J C DB_JOIN_ITEM D I J C DB_JOIN_NOSORT D I J C @@ -206,6 +217,7 @@ DB_LOCK_DUMP * I * * DB_LOCK_EXPIRE D I J C DB_LOCK_GET D I J C DB_LOCK_GET_TIMEOUT D I J C +DB_LOCK_IGNORE_REC * I * * DB_LOCK_INHERIT * I * * DB_LOCK_IREAD D I J C DB_LOCK_IWR D I J C @@ -510,6 +522,7 @@ DB_UPDATE_SECONDARY * I * * DB_UPGRADE D I J C DB_USE_ENVIRON D I J C DB_USE_ENVIRON_ROOT D I J C +DB_VERB_BACKUP D I J C DB_VERB_DEADLOCK D I J C DB_VERB_FILEOPS D I J C DB_VERB_FILEOPS_ALL D I J C @@ -543,3 +556,6 @@ DB_WRITELOCK * I * * DB_WRITEOPEN * I * * DB_XA_CREATE D I * * DB_YIELDCPU D I J C +DB2_AM_EXCL * I * * +DB2_AM_INTEXCL * I * * +DB2_AM_NOWAIT * I * * \ No newline at end of file diff --git a/dist/s_test b/dist/s_test index d0abc1b6..e12b34e5 100755 --- a/dist/s_test +++ b/dist/s_test @@ -19,6 +19,7 @@ trap 'rm -f $t; exit 0' 0 1 2 3 13 15 echo "set src_root @srcdir@/.." && \ echo "set test_path @srcdir@/../test/tcl" && \ echo "set je_root @srcdir@/../../je" && \ + echo "set tcl_utils @srcdir@/../test/tcl_utils" && \ echo "" && \ echo "global testdir" && \ echo "set testdir ./TESTDIR" && \ @@ -54,6 +55,7 @@ cmp $t $f > /dev/null 2>&1 || echo "set src_root .." && \ echo "set test_path ../test/tcl" && \ echo "set je_root ../../je" && \ + echo "set tcl_utils ../test/tcl_utils" && \ echo "" && \ echo "global testdir" && \ echo "set testdir ./TESTDIR" && \ diff --git a/dist/srcfiles.in b/dist/srcfiles.in index b9d8a37a..e3465f12 100644 --- a/dist/srcfiles.in +++ b/dist/srcfiles.in @@ -113,6 +113,7 @@ src/db/db.c android vx vxsmall src/db/db_am.c android vx vxsmall src/db/db_auto.c android vx vxsmall src/db/db_autop.c vx6 +src/db/db_backup.c android vx vxsmall src/db/db_cam.c android vx vxsmall src/db/db_cds.c android vx vxsmall src/db/db_compact.c android vx vxsmall @@ -152,6 +153,7 @@ src/dbreg/dbreg_rec.c android vx vxsmall src/dbreg/dbreg_stat.c android vx vxsmall src/dbreg/dbreg_util.c android vx vxsmall src/env/env_alloc.c android vx vxsmall +src/env/env_backup.c android vx vxsmall src/env/env_config.c android vx vxsmall src/env/env_failchk.c android vx vxsmall src/env/env_file.c android vx vxsmall @@ -188,6 +190,7 @@ src/hash/hash_upgrade.c vx src/hash/hash_verify.c vx src/heap/heap_auto.c vx src/heap/heap_autop.c vx +src/heap/heap_backup.c vx src/heap/heap.c vx src/heap/heap_conv.c vx src/heap/heap_method.c vx @@ -224,6 +227,7 @@ src/log/log_verify_auto.c vx src/log/log_verify_int.c vx src/log/log_verify_stub.c android vxsmall src/mp/mp_alloc.c android vx vxsmall +src/mp/mp_backup.c android vx vxsmall src/mp/mp_bh.c android vx vxsmall src/mp/mp_fget.c android vx vxsmall src/mp/mp_fmethod.c android vx vxsmall @@ -264,6 +268,7 @@ src/os/os_handle.c android vx vxsmall src/os/os_map.c android src/os/os_mkdir.c android vx vxsmall src/os/os_open.c android vx vxsmall +src/os/os_path.c android vx vxsmall src/os/os_pid.c android vx vxsmall src/os/os_rename.c android vx vxsmall src/os/os_root.c android vx vxsmall diff --git a/dist/validate/s_chk_build_configs b/dist/validate/s_chk_build_configs index 56579a7e..e93cc913 100644 --- a/dist/validate/s_chk_build_configs +++ b/dist/validate/s_chk_build_configs @@ -113,6 +113,6 @@ r r "--disable-static" r "--enable-cxx" r "--enable-java" -r "--with-tcl=/usr/local/lib/tcl8.4" -r "--enable-test --with-tcl=/usr/local/lib/tcl8.4" -r "--enable-cxx --enable-java --with-tcl=/usr/local/lib/tcl8.4" +r "--with-tcl=/usr/local/lib/tcl8.5" +r "--enable-test --with-tcl=/usr/local/lib/tcl8.5" +r "--enable-cxx --enable-java --with-tcl=/usr/local/lib/tcl8.5" diff --git a/dist/validate/s_chk_comma.c b/dist/validate/s_chk_comma.c index 4a41bddc..d14219f8 100644 --- a/dist/validate/s_chk_comma.c +++ b/dist/validate/s_chk_comma.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. */ #include diff --git a/dist/validate/s_chk_flags.c b/dist/validate/s_chk_flags.c index bcc3c8b0..54645e40 100644 --- a/dist/validate/s_chk_flags.c +++ b/dist/validate/s_chk_flags.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. */ #include diff --git a/dist/validate/s_chk_logverify.c b/dist/validate/s_chk_logverify.c index dc6faf69..e1134ca5 100644 --- a/dist/validate/s_chk_logverify.c +++ b/dist/validate/s_chk_logverify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/dist/validate/s_chk_pubdef b/dist/validate/s_chk_pubdef index db767bec..cc4515b2 100644 --- a/dist/validate/s_chk_pubdef +++ b/dist/validate/s_chk_pubdef @@ -64,6 +64,7 @@ END_OF_TEXT cat $d/src/dbinc/db.in $d/src/dbinc_auto/api_flags.in | sed -n \ -e 's/^#.*[ ]\(DB_[A-Z_0-9][A-Z_0-9]*\).*/\1/p' \ + -e 's/^#.*[ ]\(DB2_[A-Z_0-9][A-Z_0-9]*\).*/\1/p' \ -e 's/[ ]\(DB_[A-Z_]*\)=[0-9].*/\1/p' \ -e d | while read name; do diff --git a/examples/c/csv/DbRecord.c b/examples/c/csv/DbRecord.c index cbfbd5e9..b25aeadc 100644 --- a/examples/c/csv/DbRecord.c +++ b/examples/c/csv/DbRecord.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/README b/examples/c/csv/README index 00e9e1f7..6d5eb878 100644 --- a/examples/c/csv/README +++ b/examples/c/csv/README @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/code.c b/examples/c/csv/code.c index 54cef6c1..24aaac81 100644 --- a/examples/c/csv/code.c +++ b/examples/c/csv/code.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/csv.h b/examples/c/csv/csv.h index 5f5eab5c..ac9fac2a 100644 --- a/examples/c/csv/csv.h +++ b/examples/c/csv/csv.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/csv_extern.h b/examples/c/csv/csv_extern.h index 36581708..a541bb5c 100644 --- a/examples/c/csv/csv_extern.h +++ b/examples/c/csv/csv_extern.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/db.c b/examples/c/csv/db.c index 71086c25..dc72f0d8 100644 --- a/examples/c/csv/db.c +++ b/examples/c/csv/db.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/load.c b/examples/c/csv/load.c index 5f7212b3..74fadfe0 100644 --- a/examples/c/csv/load.c +++ b/examples/c/csv/load.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/load_main.c b/examples/c/csv/load_main.c index 0353bfee..1caeda00 100644 --- a/examples/c/csv/load_main.c +++ b/examples/c/csv/load_main.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/query.c b/examples/c/csv/query.c index e08c023f..f41dc560 100644 --- a/examples/c/csv/query.c +++ b/examples/c/csv/query.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/query_main.c b/examples/c/csv/query_main.c index 0e223115..ed22283e 100644 --- a/examples/c/csv/query_main.c +++ b/examples/c/csv/query_main.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/csv/util.c b/examples/c/csv/util.c index 81196475..c8cfa6c0 100644 --- a/examples/c/csv/util.c +++ b/examples/c/csv/util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_access.c b/examples/c/ex_access.c index e4aca821..67d248fe 100644 --- a/examples/c/ex_access.c +++ b/examples/c/ex_access.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_apprec/ex_apprec.c b/examples/c/ex_apprec/ex_apprec.c index 5d3b4ac8..0c19341f 100644 --- a/examples/c/ex_apprec/ex_apprec.c +++ b/examples/c/ex_apprec/ex_apprec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_apprec/ex_apprec.h b/examples/c/ex_apprec/ex_apprec.h index e0702426..b7e0da03 100644 --- a/examples/c/ex_apprec/ex_apprec.h +++ b/examples/c/ex_apprec/ex_apprec.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_apprec/ex_apprec.src b/examples/c/ex_apprec/ex_apprec.src index d332133a..91618c00 100644 --- a/examples/c/ex_apprec/ex_apprec.src +++ b/examples/c/ex_apprec/ex_apprec.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_apprec/ex_apprec_rec.c b/examples/c/ex_apprec/ex_apprec_rec.c index 43f3fed6..70eab4a5 100644 --- a/examples/c/ex_apprec/ex_apprec_rec.c +++ b/examples/c/ex_apprec/ex_apprec_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_btrec.c b/examples/c/ex_btrec.c index 42540eaf..85a910d9 100644 --- a/examples/c/ex_btrec.c +++ b/examples/c/ex_btrec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id: ex_btrec.c,v 0f73af5ae3da 2010/05/10 05:38:40 alexander $ */ diff --git a/examples/c/ex_bulk.c b/examples/c/ex_bulk.c index 3212d4df..bc3ec26e 100644 --- a/examples/c/ex_bulk.c +++ b/examples/c/ex_bulk.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_env.c b/examples/c/ex_env.c index 2bdc79c5..dfc436d6 100644 --- a/examples/c/ex_env.c +++ b/examples/c/ex_env.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_heap.c b/examples/c/ex_heap.c index a6711408..990c9365 100644 --- a/examples/c/ex_heap.c +++ b/examples/c/ex_heap.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ * @@ -24,7 +24,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif #define BUFFER_LEN 30 /* Buffer size to hold data */ @@ -90,13 +90,13 @@ main(argc, argv) DB *dbp; u_int32_t cachesize, ghpsize, hpsize, pgsize; char *home; - int ch, ret, set_ghpsize, set_hpsize, test_btree, test_var_data; + int ch, ret, ret_t, set_ghpsize, set_hpsize, test_btree, test_var_data; int recs_per_rep, repeats; dbenv = NULL; dbp = NULL; cachesize = 0; - ret = set_ghpsize = set_hpsize = test_btree = 0; + ret = ret_t = set_ghpsize = set_hpsize = test_btree = 0; home = NULL; recs_per_rep = DEF_RECS_PER_REP; @@ -200,13 +200,15 @@ main(argc, argv) } } err: - if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) - dbenv->err(dbenv, ret, "DB->close"); - dbp = NULL; + if (dbp != NULL && (ret_t = dbp->close(dbp, 0)) != 0) { + dbenv->err(dbenv, ret_t, "DB->close"); + ret = (ret == 0 ? ret_t : ret); + } - if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { + if (dbenv != NULL && (ret_t = dbenv->close(dbenv, 0)) != 0) { fprintf(stderr, "%s: dbenv->close: %s", progname, - db_strerror(ret)); + db_strerror(ret_t)); + ret = (ret == 0 ? ret_t : ret); } return (ret); @@ -456,7 +458,7 @@ generate_data(buf, rec_no, test_var) int rec_no, test_var; { const char *str = "abcdefghijklmnopqrst"; - size_t len = strlen(str); + int len = (int)strlen(str); /* * Default use the fix-length data, diff --git a/examples/c/ex_lock.c b/examples/c/ex_lock.c index 83665398..32e22b0e 100644 --- a/examples/c/ex_lock.c +++ b/examples/c/ex_lock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_mpool.c b/examples/c/ex_mpool.c index 18befdf7..c7a24283 100644 --- a/examples/c/ex_mpool.c +++ b/examples/c/ex_mpool.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/base/rep_base.c b/examples/c/ex_rep/base/rep_base.c index 93556ad0..c9443e4d 100644 --- a/examples/c/ex_rep/base/rep_base.c +++ b/examples/c/ex_rep/base/rep_base.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/base/rep_base.h b/examples/c/ex_rep/base/rep_base.h index fbc45bcd..27901349 100644 --- a/examples/c/ex_rep/base/rep_base.h +++ b/examples/c/ex_rep/base/rep_base.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/base/rep_msg.c b/examples/c/ex_rep/base/rep_msg.c index 51826e84..8ed45f7f 100644 --- a/examples/c/ex_rep/base/rep_msg.c +++ b/examples/c/ex_rep/base/rep_msg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -342,7 +342,7 @@ connect_all(args) goto err; } - if (nsites > 0 && (hm_thr = calloc(nsites, sizeof(int))) == NULL) { + if (nsites > 0 && (hm_thr = calloc(nsites, sizeof(thread_t))) == NULL) { dbenv->err(dbenv, errno, "connect_all"); ret = 1; goto err; diff --git a/examples/c/ex_rep/base/rep_net.c b/examples/c/ex_rep/base/rep_net.c index 08ac5da7..29012536 100644 --- a/examples/c/ex_rep/base/rep_net.c +++ b/examples/c/ex_rep/base/rep_net.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/common/rep_common.c b/examples/c/ex_rep/common/rep_common.c index 0ecca3ed..a091adda 100644 --- a/examples/c/ex_rep/common/rep_common.c +++ b/examples/c/ex_rep/common/rep_common.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/common/rep_common.h b/examples/c/ex_rep/common/rep_common.h index a8d9881c..edf3b67d 100644 --- a/examples/c/ex_rep/common/rep_common.h +++ b/examples/c/ex_rep/common/rep_common.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep/mgr/rep_mgr.c b/examples/c/ex_rep/mgr/rep_mgr.c index 62ebf745..0eaf1971 100644 --- a/examples/c/ex_rep/mgr/rep_mgr.c +++ b/examples/c/ex_rep/mgr/rep_mgr.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep_chan/rep_chan.c b/examples/c/ex_rep_chan/rep_chan.c index 1742ed38..f5638264 100644 --- a/examples/c/ex_rep_chan/rep_chan.c +++ b/examples/c/ex_rep_chan/rep_chan.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_rep_chan/rep_chan.h b/examples/c/ex_rep_chan/rep_chan.h index 96647cab..9eff740d 100644 --- a/examples/c/ex_rep_chan/rep_chan.h +++ b/examples/c/ex_rep_chan/rep_chan.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * $Id$ */ diff --git a/examples/c/ex_rep_chan/rep_chan_util.c b/examples/c/ex_rep_chan/rep_chan_util.c index ade6bec4..07758152 100644 --- a/examples/c/ex_rep_chan/rep_chan_util.c +++ b/examples/c/ex_rep_chan/rep_chan_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_sequence.c b/examples/c/ex_sequence.c index 3d3fb136..28f0e199 100644 --- a/examples/c/ex_sequence.c +++ b/examples/c/ex_sequence.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_stream.c b/examples/c/ex_stream.c index 2e30404e..209d6279 100644 --- a/examples/c/ex_stream.c +++ b/examples/c/ex_stream.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_thread.c b/examples/c/ex_thread.c index 8d851915..7b39c8eb 100644 --- a/examples/c/ex_thread.c +++ b/examples/c/ex_thread.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/c/ex_tpcb.c b/examples/c/ex_tpcb.c index 041a3ef4..16807d2c 100644 --- a/examples/c/ex_tpcb.c +++ b/examples/c/ex_tpcb.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/AccessExample.cpp b/examples/cxx/AccessExample.cpp index 2cf38d2e..48683188 100644 --- a/examples/cxx/AccessExample.cpp +++ b/examples/cxx/AccessExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/BtRecExample.cpp b/examples/cxx/BtRecExample.cpp index 5cf5fb79..807b46f5 100644 --- a/examples/cxx/BtRecExample.cpp +++ b/examples/cxx/BtRecExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/EnvExample.cpp b/examples/cxx/EnvExample.cpp index b83d07e0..4cece0af 100644 --- a/examples/cxx/EnvExample.cpp +++ b/examples/cxx/EnvExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/LockExample.cpp b/examples/cxx/LockExample.cpp index 11d5adbf..3aa8c362 100644 --- a/examples/cxx/LockExample.cpp +++ b/examples/cxx/LockExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/MpoolExample.cpp b/examples/cxx/MpoolExample.cpp index 5cf35b4d..1b4133bd 100644 --- a/examples/cxx/MpoolExample.cpp +++ b/examples/cxx/MpoolExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/SequenceExample.cpp b/examples/cxx/SequenceExample.cpp index 52984340..d1347a59 100644 --- a/examples/cxx/SequenceExample.cpp +++ b/examples/cxx/SequenceExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/TpcbExample.cpp b/examples/cxx/TpcbExample.cpp index 28fa4691..ba4b135b 100644 --- a/examples/cxx/TpcbExample.cpp +++ b/examples/cxx/TpcbExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote/RepConfigInfo.cpp b/examples/cxx/excxx_repquote/RepConfigInfo.cpp index 45195d57..867226f6 100644 --- a/examples/cxx/excxx_repquote/RepConfigInfo.cpp +++ b/examples/cxx/excxx_repquote/RepConfigInfo.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote/RepConfigInfo.h b/examples/cxx/excxx_repquote/RepConfigInfo.h index ba12fd94..2d3a25da 100644 --- a/examples/cxx/excxx_repquote/RepConfigInfo.h +++ b/examples/cxx/excxx_repquote/RepConfigInfo.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote/RepQuoteExample.cpp b/examples/cxx/excxx_repquote/RepQuoteExample.cpp index f06f1c90..1f4b2d2b 100644 --- a/examples/cxx/excxx_repquote/RepQuoteExample.cpp +++ b/examples/cxx/excxx_repquote/RepQuoteExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote/dbc_auto.h b/examples/cxx/excxx_repquote/dbc_auto.h index fc8518d5..3672d252 100644 --- a/examples/cxx/excxx_repquote/dbc_auto.h +++ b/examples/cxx/excxx_repquote/dbc_auto.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote_gsg/RepConfigInfo.h b/examples/cxx/excxx_repquote_gsg/RepConfigInfo.h index e9bdcc3c..06b5015b 100644 --- a/examples/cxx/excxx_repquote_gsg/RepConfigInfo.h +++ b/examples/cxx/excxx_repquote_gsg/RepConfigInfo.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote_gsg/RepMgrGSG.cpp b/examples/cxx/excxx_repquote_gsg/RepMgrGSG.cpp index a13eea6d..43a6e6ea 100644 --- a/examples/cxx/excxx_repquote_gsg/RepMgrGSG.cpp +++ b/examples/cxx/excxx_repquote_gsg/RepMgrGSG.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote_gsg/SimpleConfigInfo.h b/examples/cxx/excxx_repquote_gsg/SimpleConfigInfo.h index 7198b526..e04bf5b1 100644 --- a/examples/cxx/excxx_repquote_gsg/SimpleConfigInfo.h +++ b/examples/cxx/excxx_repquote_gsg/SimpleConfigInfo.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/excxx_repquote_gsg/SimpleTxn.cpp b/examples/cxx/excxx_repquote_gsg/SimpleTxn.cpp index 1c219ffb..a44c91b5 100644 --- a/examples/cxx/excxx_repquote_gsg/SimpleTxn.cpp +++ b/examples/cxx/excxx_repquote_gsg/SimpleTxn.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/getting_started/MyDb.cpp b/examples/cxx/getting_started/MyDb.cpp index 4a04023f..a1ced76f 100644 --- a/examples/cxx/getting_started/MyDb.cpp +++ b/examples/cxx/getting_started/MyDb.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/getting_started/MyDb.hpp b/examples/cxx/getting_started/MyDb.hpp index d1f54c24..3ca72231 100644 --- a/examples/cxx/getting_started/MyDb.hpp +++ b/examples/cxx/getting_started/MyDb.hpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/getting_started/excxx_example_database_load.cpp b/examples/cxx/getting_started/excxx_example_database_load.cpp index 446e686e..2a66c575 100644 --- a/examples/cxx/getting_started/excxx_example_database_load.cpp +++ b/examples/cxx/getting_started/excxx_example_database_load.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/getting_started/excxx_example_database_read.cpp b/examples/cxx/getting_started/excxx_example_database_read.cpp index c00d65d9..9ac26b12 100644 --- a/examples/cxx/getting_started/excxx_example_database_read.cpp +++ b/examples/cxx/getting_started/excxx_example_database_read.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/getting_started/gettingStartedCommon.hpp b/examples/cxx/getting_started/gettingStartedCommon.hpp index cbf7a6d8..be9ea4e5 100644 --- a/examples/cxx/getting_started/gettingStartedCommon.hpp +++ b/examples/cxx/getting_started/gettingStartedCommon.hpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/txn_guide/TxnGuide.cpp b/examples/cxx/txn_guide/TxnGuide.cpp index 89bee1fb..580b2c94 100644 --- a/examples/cxx/txn_guide/TxnGuide.cpp +++ b/examples/cxx/txn_guide/TxnGuide.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/cxx/txn_guide/TxnGuideInMemory.cpp b/examples/cxx/txn_guide/TxnGuideInMemory.cpp index ed684535..e10fd474 100644 --- a/examples/cxx/txn_guide/TxnGuideInMemory.cpp +++ b/examples/cxx/txn_guide/TxnGuideInMemory.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/StlAccessExample.cpp b/examples/stl/StlAccessExample.cpp index 97d2b5fa..c533c63f 100644 --- a/examples/stl/StlAccessExample.cpp +++ b/examples/stl/StlAccessExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/StlAdvancedFeatures.cpp b/examples/stl/StlAdvancedFeatures.cpp index 79b6b065..ae4e6f4d 100644 --- a/examples/stl/StlAdvancedFeatures.cpp +++ b/examples/stl/StlAdvancedFeatures.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/StlAdvancedFeatures.h b/examples/stl/StlAdvancedFeatures.h index ae9c312b..36eba519 100644 --- a/examples/stl/StlAdvancedFeatures.h +++ b/examples/stl/StlAdvancedFeatures.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/StlTpcbExample.cpp b/examples/stl/StlTpcbExample.cpp index 30b1afca..785f7011 100644 --- a/examples/stl/StlTpcbExample.cpp +++ b/examples/stl/StlTpcbExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/StlTransactionGuideExample.cpp b/examples/stl/StlTransactionGuideExample.cpp index 08e180ce..85b681cf 100644 --- a/examples/stl/StlTransactionGuideExample.cpp +++ b/examples/stl/StlTransactionGuideExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/repquote/StlRepConfigInfo.cpp b/examples/stl/repquote/StlRepConfigInfo.cpp index 35d268e5..13ded886 100644 --- a/examples/stl/repquote/StlRepConfigInfo.cpp +++ b/examples/stl/repquote/StlRepConfigInfo.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/repquote/StlRepConfigInfo.h b/examples/stl/repquote/StlRepConfigInfo.h index cec996d2..2a1a6883 100644 --- a/examples/stl/repquote/StlRepConfigInfo.h +++ b/examples/stl/repquote/StlRepConfigInfo.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/examples/stl/repquote/StlRepQuoteExample.cpp b/examples/stl/repquote/StlRepQuoteExample.cpp index 80ead3fd..5e7f4210 100644 --- a/examples/stl/repquote/StlRepQuoteExample.cpp +++ b/examples/stl/repquote/StlRepQuoteExample.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_channel.cpp b/lang/cxx/cxx_channel.cpp index 280ed4c4..72127112 100644 --- a/lang/cxx/cxx_channel.cpp +++ b/lang/cxx/cxx_channel.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_db.cpp b/lang/cxx/cxx_db.cpp index 6d3674dc..366f707a 100644 --- a/lang/cxx/cxx_db.cpp +++ b/lang/cxx/cxx_db.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -92,7 +92,7 @@ Db::Db(DbEnv *dbenv, u_int32_t flags) , construct_flags_(flags) , append_recno_callback_(0) , associate_callback_(0) -, associate_foreign_callback_(0) +, associate_foreign_callback_(0) , bt_compare_callback_(0) , bt_compress_callback_(0) , bt_decompress_callback_(0) @@ -305,6 +305,26 @@ DB_METHOD(key_range, (DbTxn *txnid, Dbt *key, DB_KEY_RANGE *results, u_int32_t flags), (db, unwrap(txnid), key, results, flags), DB_RETOK_STD) +int Db::get_lk_exclusive(bool *onoff, bool *nowait) +{ + DB *db = (DB *)unwrapConst(this); + int on, on_nowait, ret; + + ret = db->get_lk_exclusive(db, &on, &on_nowait); + + *onoff = (on ? true : false); + *nowait = (on_nowait ? true : false); + return (ret); +} +int Db::set_lk_exclusive(bool nowait) +{ + DB *db = (DB *)unwrapConst(this); + int on_nowait; + + on_nowait = (nowait ? 1 : 0); + return (db->set_lk_exclusive(db, on_nowait)); +} + // If an error occurred during the constructor, report it now. // Otherwise, call the underlying DB->open method. // @@ -659,6 +679,10 @@ DB_METHOD(get_heapsize, (u_int32_t *gbytesp, u_int32_t *bytesp), (db, gbytesp, bytesp), DB_RETOK_STD) DB_METHOD(set_heapsize, (u_int32_t gbytes, u_int32_t bytes), (db, gbytes, bytes, 0), DB_RETOK_STD) +DB_METHOD(get_heap_regionsize, (u_int32_t *npagesp), + (db, npagesp), DB_RETOK_STD) +DB_METHOD(set_heap_regionsize, (u_int32_t npages), + (db, npages), DB_RETOK_STD) DB_METHOD(set_h_compare, (h_compare_fcn_type func), (db, func), DB_RETOK_STD) DB_METHOD(get_h_ffactor, (u_int32_t *h_ffactorp), diff --git a/lang/cxx/cxx_dbc.cpp b/lang/cxx/cxx_dbc.cpp index ae36eea9..642327d0 100644 --- a/lang/cxx/cxx_dbc.cpp +++ b/lang/cxx/cxx_dbc.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_dbt.cpp b/lang/cxx/cxx_dbt.cpp index 82820234..722764f1 100644 --- a/lang/cxx/cxx_dbt.cpp +++ b/lang/cxx/cxx_dbt.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_env.cpp b/lang/cxx/cxx_env.cpp index 5f0d85d8..aae95bec 100644 --- a/lang/cxx/cxx_env.cpp +++ b/lang/cxx/cxx_env.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -150,6 +150,27 @@ char *_thread_id_string_intercept_c(DB_ENV *dbenv, pid_t pid, return (DbEnv::_thread_id_string_intercept(dbenv, pid, thrid, buf)); } +extern "C" +int _backup_close_intercept_c(DB_ENV *dbenv, const char *dbname, void *handle) +{ + return (DbEnv::_backup_close_intercept(dbenv, dbname, handle)); +} + +extern "C" +int _backup_open_intercept_c(DB_ENV *dbenv, + const char *dbname, const char *target, void **handle) +{ + return (DbEnv::_backup_open_intercept(dbenv, dbname, target, handle)); +} + +extern "C" +int _backup_write_intercept_c(DB_ENV *dbenv, u_int32_t off_gbytes, + u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle) +{ + return (DbEnv::_backup_write_intercept( + dbenv, off_gbytes, off_bytes, size, buf, handle)); +} + void DbEnv::_feedback_intercept(DB_ENV *dbenv, int opcode, int pct) { DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); @@ -287,6 +308,58 @@ char *DbEnv::_thread_id_string_intercept(DB_ENV *dbenv, return (cxxenv->thread_id_string_callback_(cxxenv, pid, thrid, buf)); } +int DbEnv::_backup_close_intercept( + DB_ENV *dbenv, const char *dbname, void *handle) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::backup_close_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + if (cxxenv->backup_close_callback_ == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_close_callback", + EINVAL, cxxenv->error_policy()); + return (EINVAL); + } + return (*cxxenv->backup_close_callback_)(cxxenv, dbname, handle); +} + +int DbEnv::_backup_open_intercept(DB_ENV *dbenv, + const char *dbname, const char *target, void **handle) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::backup_open_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + if (cxxenv->backup_open_callback_ == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_open_callback", + EINVAL, cxxenv->error_policy()); + return (EINVAL); + } + return (*cxxenv->backup_open_callback_)(cxxenv, dbname, target, handle); +} + +int DbEnv::_backup_write_intercept(DB_ENV *dbenv, u_int32_t off_gbytes, + u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle) +{ + DbEnv *cxxenv = DbEnv::get_DbEnv(dbenv); + if (cxxenv == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), + "DbEnv::backup_write_callback", EINVAL, ON_ERROR_UNKNOWN); + return (EINVAL); + } + if (cxxenv->backup_write_callback_ == 0) { + DB_ERROR(DbEnv::get_DbEnv(dbenv), "DbEnv::backup_write_callback", + EINVAL, cxxenv->error_policy()); + return (EINVAL); + } + return (*cxxenv->backup_write_callback_)( + cxxenv, off_gbytes, off_bytes, size, buf, handle); +} + // A truism for the DbEnv object is that there is a valid // DB_ENV handle from the constructor until close(). // After the close, the DB_ENV handle is invalid and @@ -750,6 +823,8 @@ char *DbEnv::strerror(int error) // We keep these alphabetical by field name, // for comparison with Java's list. // +DBENV_METHOD(get_backup_config, (DB_BACKUP_CONFIG type, u_int32_t *valuep), (dbenv, type, valuep)) +DBENV_METHOD(set_backup_config, (DB_BACKUP_CONFIG type, u_int32_t value), (dbenv, type, value)) DBENV_METHOD(set_data_dir, (const char *dir), (dbenv, dir)) DBENV_METHOD(get_encrypt_flags, (u_int32_t *flagsp), (dbenv, flagsp)) @@ -795,6 +870,8 @@ DBENV_METHOD(get_memory_init, (DB_MEM_CONFIG type, u_int32_t *count), (dbenv, ty DBENV_METHOD(set_memory_init, (DB_MEM_CONFIG type, u_int32_t count), (dbenv, type, count)) DBENV_METHOD(get_memory_max, (u_int32_t *gbytes, u_int32_t *bytes), (dbenv, gbytes, bytes)) DBENV_METHOD(set_memory_max, (u_int32_t gbytes, u_int32_t bytes), (dbenv, gbytes, bytes)) +DBENV_METHOD(get_metadata_dir, (const char **dirp), (dbenv, dirp)) +DBENV_METHOD(set_metadata_dir, (const char *dir), (dbenv, dir)) DBENV_METHOD(get_mp_max_openfd, (int *maxopenfdp), (dbenv, maxopenfdp)) DBENV_METHOD(set_mp_max_openfd, (int maxopenfd), (dbenv, maxopenfd)) DBENV_METHOD(get_mp_max_write, (int *maxwritep, db_timeout_t *maxwrite_sleepp), @@ -1066,6 +1143,43 @@ int DbEnv::set_thread_id_string( return (ret); } +int DbEnv::get_backup_callbacks( + int (**open_funcp)(DbEnv *, const char *, const char *, void **), + int (**write_funcp)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + int (**close_funcp)(DbEnv *, const char *, void *)) +{ + if (open_funcp != NULL) + *open_funcp = backup_open_callback_; + if (write_funcp != NULL) + *write_funcp = backup_write_callback_; + if (close_funcp != NULL) + *close_funcp = backup_close_callback_; + + return 0; +} + +int DbEnv::set_backup_callbacks( + int (*open_func)(DbEnv *, const char *, const char *, void **), + int (*write_func)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + int (*close_func)(DbEnv *, const char *, void *)) +{ + DB_ENV *dbenv = unwrap(this); + int ret; + + backup_open_callback_ = open_func; + backup_write_callback_ = write_func; + backup_close_callback_ = close_func; + + if ((ret = dbenv->set_backup_callbacks(dbenv, + open_func == 0 ? 0 : _backup_open_intercept_c, + write_func == 0 ? 0 : _backup_write_intercept_c, + close_func == 0 ? 0 : _backup_close_intercept_c)) != 0) + DB_ERROR(this, "DbEnv::set_backup_callbacks", ret, + error_policy()); + + return (ret); +} + DBENV_METHOD(add_data_dir, (const char *dir), (dbenv, dir)) int DbEnv::cdsgroup_begin(DbTxn **tid) @@ -1333,6 +1447,12 @@ DBENV_METHOD(set_timeout, (db_timeout_t timeout, u_int32_t flags), (dbenv, timeout, flags)) +DBENV_METHOD(backup, + (const char *target, u_int32_t flags), (dbenv, target, flags)) +DBENV_METHOD(dbbackup, + (const char *dbfile, const char *target, u_int32_t flags), + (dbenv, dbfile, target, flags)) + // static method char *DbEnv::version(int *major, int *minor, int *patch) { diff --git a/lang/cxx/cxx_except.cpp b/lang/cxx/cxx_except.cpp index 63c8377c..dd095bbd 100644 --- a/lang/cxx/cxx_except.cpp +++ b/lang/cxx/cxx_except.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_lock.cpp b/lang/cxx/cxx_lock.cpp index 4ee11fdd..8f367df8 100644 --- a/lang/cxx/cxx_lock.cpp +++ b/lang/cxx/cxx_lock.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_logc.cpp b/lang/cxx/cxx_logc.cpp index 95b1766b..28fd1fc1 100644 --- a/lang/cxx/cxx_logc.cpp +++ b/lang/cxx/cxx_logc.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_mpool.cpp b/lang/cxx/cxx_mpool.cpp index ec9ebcd0..7255e30d 100644 --- a/lang/cxx/cxx_mpool.cpp +++ b/lang/cxx/cxx_mpool.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_multi.cpp b/lang/cxx/cxx_multi.cpp index 11a197c2..04eb0ece 100644 --- a/lang/cxx/cxx_multi.cpp +++ b/lang/cxx/cxx_multi.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_rid.cpp b/lang/cxx/cxx_rid.cpp index 23ad8ca8..3ea0b0b9 100644 --- a/lang/cxx/cxx_rid.cpp +++ b/lang/cxx/cxx_rid.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_seq.cpp b/lang/cxx/cxx_seq.cpp index e6569572..5cd1b4ec 100644 --- a/lang/cxx/cxx_seq.cpp +++ b/lang/cxx/cxx_seq.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_site.cpp b/lang/cxx/cxx_site.cpp index 6c8d602d..fca5c9ba 100644 --- a/lang/cxx/cxx_site.cpp +++ b/lang/cxx/cxx_site.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/cxx_txn.cpp b/lang/cxx/cxx_txn.cpp index 2a95cf24..c5368b74 100644 --- a/lang/cxx/cxx_txn.cpp +++ b/lang/cxx/cxx_txn.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_base_iterator.h b/lang/cxx/stl/dbstl_base_iterator.h index e2cce74f..ebe4c565 100644 --- a/lang/cxx/stl/dbstl_base_iterator.h +++ b/lang/cxx/stl/dbstl_base_iterator.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_container.cpp b/lang/cxx/stl/dbstl_container.cpp index b187b26a..bf5f527d 100644 --- a/lang/cxx/stl/dbstl_container.cpp +++ b/lang/cxx/stl/dbstl_container.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -174,7 +174,8 @@ int db_container::construct_db_file_name(string &filename) const // avoid name clash len = _snprintf(name, 64, "tmpdb_db_map_%lu_%d_%u.db", - (u_long)((uintptr_t)tid + ts.tv_nsec), rand(), g_db_file_suffix_++); + (u_long)((uintptr_t)&tid + ts.tv_nsec), + rand(), g_db_file_suffix_++); filename = name; return 0; diff --git a/lang/cxx/stl/dbstl_container.h b/lang/cxx/stl/dbstl_container.h index 3690862a..4b6ed701 100644 --- a/lang/cxx/stl/dbstl_container.h +++ b/lang/cxx/stl/dbstl_container.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_dbc.h b/lang/cxx/stl/dbstl_dbc.h index 7304af77..c8bdd3b9 100644 --- a/lang/cxx/stl/dbstl_dbc.h +++ b/lang/cxx/stl/dbstl_dbc.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_dbt.h b/lang/cxx/stl/dbstl_dbt.h index 43c5a190..3480b3a6 100644 --- a/lang/cxx/stl/dbstl_dbt.h +++ b/lang/cxx/stl/dbstl_dbt.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -408,7 +408,9 @@ public: else sz = sizeof(dt); - if (onstack) { + copyf = EM::instance()->get_copy_function(); + + if (onstack && copyf == NULL) { freemem(); pdbt->data = ((void*)&dt); // We have to set DB_DBT_USERMEM for DB_THREAD to work. @@ -432,7 +434,7 @@ public: } else pdbt->size = (sz); - if ((copyf = EM::instance()->get_copy_function()) != NULL) + if (copyf != NULL) copyf(pdbt->data, dt); else memcpy(pdbt->data, &dt, sz); @@ -650,16 +652,16 @@ protected: template void make_dbt_internal(const T*t, bool onstack) { + typedef DbstlElemTraits EM; u_int32_t i, sz, totalsz, sql; DBT *pdbt = (DBT *)&dbt_; - typename DbstlElemTraits::ElemSizeFunct szf = NULL; - typename DbstlElemTraits::SequenceLenFunct - seqlenf = NULL; + typename EM::ElemSizeFunct szf = NULL; + typename EM::SequenceLenFunct seqlenf = NULL; + typename EM::SequenceCopyFunct seqcopyf = NULL; - szf = DbstlElemTraits::instance()-> - get_size_function(); - seqlenf = DbstlElemTraits::instance()-> - get_sequence_len_function(); + szf = EM::instance()->get_size_function(); + seqlenf = EM::instance()->get_sequence_len_function(); + seqcopyf = EM::instance()->get_sequence_copy_function(); assert(seqlenf != NULL); sql = sz = (u_int32_t)seqlenf(t); @@ -671,7 +673,7 @@ protected: sz = totalsz; - if (onstack) { + if (onstack && seqcopyf == NULL) { freemem(); pdbt->data = (void *)t; pdbt->size = sz; @@ -687,9 +689,7 @@ protected: } pdbt->size = sz; - DbstlElemTraits::instance()-> - get_sequence_copy_function() - ((T *)pdbt->data, t, sql); + EM::instance()->copy((T *)pdbt->data, t, sql); } } diff --git a/lang/cxx/stl/dbstl_element_ref.h b/lang/cxx/stl/dbstl_element_ref.h index 992d0052..d680901b 100644 --- a/lang/cxx/stl/dbstl_element_ref.h +++ b/lang/cxx/stl/dbstl_element_ref.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_exception.h b/lang/cxx/stl/dbstl_exception.h index a0ae4acb..4f8c2f8b 100644 --- a/lang/cxx/stl/dbstl_exception.h +++ b/lang/cxx/stl/dbstl_exception.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_inner_utility.h b/lang/cxx/stl/dbstl_inner_utility.h index 7c1b82b2..01c072c1 100644 --- a/lang/cxx/stl/dbstl_inner_utility.h +++ b/lang/cxx/stl/dbstl_inner_utility.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_map.h b/lang/cxx/stl/dbstl_map.h index b118403e..6828787d 100644 --- a/lang/cxx/stl/dbstl_map.h +++ b/lang/cxx/stl/dbstl_map.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_resource_manager.cpp b/lang/cxx/stl/dbstl_resource_manager.cpp index cd664d3d..81c131e1 100644 --- a/lang/cxx/stl/dbstl_resource_manager.cpp +++ b/lang/cxx/stl/dbstl_resource_manager.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_resource_manager.h b/lang/cxx/stl/dbstl_resource_manager.h index 16869b99..6fc968fb 100644 --- a/lang/cxx/stl/dbstl_resource_manager.h +++ b/lang/cxx/stl/dbstl_resource_manager.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_set.h b/lang/cxx/stl/dbstl_set.h index 4832afbc..5f3be103 100644 --- a/lang/cxx/stl/dbstl_set.h +++ b/lang/cxx/stl/dbstl_set.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_utility.h b/lang/cxx/stl/dbstl_utility.h index fe8f8b78..63b661e9 100644 --- a/lang/cxx/stl/dbstl_utility.h +++ b/lang/cxx/stl/dbstl_utility.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/cxx/stl/dbstl_vector.h b/lang/cxx/stl/dbstl_vector.h index 6e28ee10..968b7427 100644 --- a/lang/cxx/stl/dbstl_vector.h +++ b/lang/cxx/stl/dbstl_vector.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/docs/db.html b/lang/tcl/docs/db.html index cbcbbda4..6c5bcecf 100644 --- a/lang/tcl/docs/db.html +++ b/lang/tcl/docs/db.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/env.html b/lang/tcl/docs/env.html index 9a1f34bf..f790cab0 100644 --- a/lang/tcl/docs/env.html +++ b/lang/tcl/docs/env.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/historic.html b/lang/tcl/docs/historic.html index 9904a830..9345208e 100644 --- a/lang/tcl/docs/historic.html +++ b/lang/tcl/docs/historic.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/index.html b/lang/tcl/docs/index.html index f7d62d7d..ad08b3ae 100644 --- a/lang/tcl/docs/index.html +++ b/lang/tcl/docs/index.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/library.html b/lang/tcl/docs/library.html index 91cae9c0..fab4ff2f 100644 --- a/lang/tcl/docs/library.html +++ b/lang/tcl/docs/library.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/lock.html b/lang/tcl/docs/lock.html index ada94dc7..d9b7599c 100644 --- a/lang/tcl/docs/lock.html +++ b/lang/tcl/docs/lock.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/log.html b/lang/tcl/docs/log.html index af14df1c..7df38f80 100644 --- a/lang/tcl/docs/log.html +++ b/lang/tcl/docs/log.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/mpool.html b/lang/tcl/docs/mpool.html index 1f75abd3..42d38e27 100644 --- a/lang/tcl/docs/mpool.html +++ b/lang/tcl/docs/mpool.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/rep.html b/lang/tcl/docs/rep.html index 83ca4f38..60c074e1 100644 --- a/lang/tcl/docs/rep.html +++ b/lang/tcl/docs/rep.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/sequence.html b/lang/tcl/docs/sequence.html index ab669514..8d608d31 100644 --- a/lang/tcl/docs/sequence.html +++ b/lang/tcl/docs/sequence.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/test.html b/lang/tcl/docs/test.html index 551d4710..ff591b7b 100644 --- a/lang/tcl/docs/test.html +++ b/lang/tcl/docs/test.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/docs/txn.html b/lang/tcl/docs/txn.html index a79062c6..061a221a 100644 --- a/lang/tcl/docs/txn.html +++ b/lang/tcl/docs/txn.html @@ -1,4 +1,4 @@ - + diff --git a/lang/tcl/tcl_compat.c b/lang/tcl/tcl_compat.c index 36e26566..57c0b9bc 100644 --- a/lang/tcl/tcl_compat.c +++ b/lang/tcl/tcl_compat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_db.c b/lang/tcl/tcl_db.c index 6276f996..afe431b8 100644 --- a/lang/tcl/tcl_db.c +++ b/lang/tcl/tcl_db.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -120,6 +120,7 @@ db_Cmd(clientData, interp, objc, objv) "get_env", "get_errpfx", "get_flags", + "get_heap_regionsize", "get_h_ffactor", "get_h_nelem", "get_join", @@ -134,6 +135,7 @@ db_Cmd(clientData, interp, objc, objv) "get_type", "is_byteswapped", "join", + "get_lk_exclusive", "put", "stat", "stat_print", @@ -163,6 +165,7 @@ db_Cmd(clientData, interp, objc, objv) DBGETENV, DBGETERRPFX, DBGETFLAGS, + DBGETHEAPREGIONSIZE, DBGETHFFACTOR, DBGETHNELEM, DBGETJOIN, @@ -177,6 +180,7 @@ db_Cmd(clientData, interp, objc, objv) DBGETTYPE, DBSWAPPED, DBJOIN, + DBGETLKEXCLUSIVE, DBPUT, DBSTAT, DBSTATPRINT, @@ -189,7 +193,7 @@ db_Cmd(clientData, interp, objc, objv) DBTCL_INFO *dbip, *ip; DBTYPE type; Tcl_Obj *res, *myobjv[3]; - int cmdindex, intval, ncache, result, ret; + int cmdindex, intval, ncache, result, ret, onoff, nowait; char newname[MSG_SIZE]; u_int32_t bytes, gbytes, value; const char *strval, *filename, *dbname, *envid; @@ -454,6 +458,16 @@ db_Cmd(clientData, interp, objc, objv) case DBGETFLAGS: result = tcl_DbGetFlags(interp, objc, objv, dbp); break; + case DBGETHEAPREGIONSIZE: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = dbp->get_heap_regionsize(dbp, &value); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "db get_heap_regionsize")) == TCL_OK) + res = Tcl_NewIntObj((int)value); + break; case DBGETHFFACTOR: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); @@ -552,6 +566,19 @@ db_Cmd(clientData, interp, objc, objv) "db get_re_source")) == TCL_OK) res = NewStringObj(strval, strlen(strval)); break; + case DBGETLKEXCLUSIVE: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = dbp->get_lk_exclusive(dbp, &onoff, &nowait); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "db get_lk_exclusive")) == TCL_OK) { + myobjv[0] = Tcl_NewIntObj((int)onoff); + myobjv[1] = Tcl_NewIntObj((int)nowait); + res = Tcl_NewListObj(2, myobjv); + } + break; case DBTRUNCATE: result = tcl_DbTruncate(interp, objc, objv, dbp); break; @@ -697,6 +724,9 @@ tcl_DbStat(interp, objc, objv, dbp) MAKE_STAT_LIST("Page size", hpsp->heap_pagesize); MAKE_STAT_LIST("Page count", hpsp->heap_pagecnt); MAKE_STAT_LIST("Number of records", hpsp->heap_nrecs); + MAKE_STAT_LIST("Number of regions", hpsp->heap_nregions); + MAKE_STAT_LIST("Number of pages in a region", + hpsp->heap_regionsize); } else if (type == DB_QUEUE) { qsp = (DB_QUEUE_STAT *)sp; MAKE_STAT_LIST("Magic", qsp->qs_magic); @@ -833,23 +863,26 @@ tcl_DbClose(interp, objc, objv, dbp, dbip) DBTCL_INFO *dbip; /* Info pointer */ { static const char *dbclose[] = { - "-nosync", "--", NULL + "-handle_only", "-nosync", "--", NULL }; enum dbclose { + TCL_DBCLOSE_HANDLEONLY, TCL_DBCLOSE_NOSYNC, TCL_DBCLOSE_ENDARG }; DB *recdbp, *secdbp; DBTCL_INFO *rdbip, *sdbip; u_int32_t flag; - int endarg, i, optindex, result, ret; + int endarg, handle_only, i, optindex, result, ret; char *arg; result = TCL_OK; endarg = 0; flag = 0; + handle_only = 0; + if (objc > 4) { - Tcl_WrongNumArgs(interp, 2, objv, "?-nosync?"); + Tcl_WrongNumArgs(interp, 2, objv, "?-nosync | -handle_only?"); return (TCL_ERROR); } @@ -864,6 +897,9 @@ tcl_DbClose(interp, objc, objv, dbp, dbip) break; } switch ((enum dbclose)optindex) { + case TCL_DBCLOSE_HANDLEONLY: + handle_only = 1; + break; case TCL_DBCLOSE_NOSYNC: flag = DB_NOSYNC; break; @@ -881,38 +917,52 @@ tcl_DbClose(interp, objc, objv, dbp, dbip) break; } - /* If it looks like there might be aux dbs, try to close them. */ - recdbp = ((DBTCL_INFO *)dbp->api_internal)->hrdbp; - secdbp = ((DBTCL_INFO *)dbp->api_internal)->hsdbp; + /* + * If it looks like there might be aux dbs, free the DBTCL_INFOs, + * and try to close the dbs if we want. + */ + recdbp = dbip->hrdbp; + secdbp = dbip->hsdbp; if (recdbp != NULL && secdbp != NULL) { - rdbip = recdbp->api_internal; + rdbip = _PtrToInfo(recdbp); _DbInfoDelete(interp, rdbip); - recdbp->api_internal = NULL; - ret = recdbp->close(recdbp, flag); - - sdbip = secdbp->api_internal; + sdbip = _PtrToInfo(secdbp); _DbInfoDelete(interp, sdbip); - secdbp->api_internal = NULL; - ret = secdbp->close(secdbp, flag); - result = _ReturnSetup(interp, - ret, DB_RETOK_STD(ret), "db close"); + + if (handle_only == 0) { + recdbp->api_internal = NULL; + ret = recdbp->close(recdbp, flag); + result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "db close"); + + secdbp->api_internal = NULL; + ret = secdbp->close(secdbp, flag); + if (result == TCL_OK) + result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "db close"); + } } if (dbip->i_cdata != NULL) - __os_free(dbp->env, dbip->i_cdata); + __os_free(handle_only ? NULL : dbp->env, dbip->i_cdata); _DbInfoDelete(interp, dbip); _debug_check(); - /* Paranoia. */ - dbp->api_internal = NULL; + /* Close the db handle if we want. */ + if (handle_only == 0) { + /* Paranoia. */ + dbp->api_internal = NULL; + ret = (dbp)->close(dbp, flag); + + /* + * As long as the first two close(s) above were ok, + * then we check this one. + */ + if (result == TCL_OK) + result = _ReturnSetup(interp, + ret, DB_RETOK_STD(ret), "db close"); + } - ret = (dbp)->close(dbp, flag); - - /* As long as the 1st close above was ok, then we check this one. */ - if (result == TCL_OK) - result = _ReturnSetup(interp, - ret, DB_RETOK_STD(ret), "db close"); - return (result); } @@ -936,6 +986,7 @@ tcl_DbPut(interp, objc, objv, dbp) "-nooverwrite", "-overwritedup", "-partial", + "-sort_multiple", "-txn", NULL }; @@ -949,6 +1000,7 @@ tcl_DbPut(interp, objc, objv, dbp) DBPUT_NOOVER, DBPUT_OVER, DBPUT_PART, + DBPUT_SORT_MULTIPLE, DBPUT_TXN }; static const char *dbputapp[] = { @@ -957,7 +1009,7 @@ tcl_DbPut(interp, objc, objv, dbp) NULL }; enum dbputapp { DBPUT_APPEND0, DBPUT_MULTIPLE_KEY0 }; - DBT data, hkey, key; + DBT data, hkey, key, rkey; DBTYPE type; DB *recdbp; DB_HEAP_RID rid; @@ -966,15 +1018,15 @@ tcl_DbPut(interp, objc, objv, dbp) void *dtmp, *ktmp, *ptr; db_recno_t recno; u_int32_t flag, hflag, multiflag; - int delemc, elemc, end, freekey, freedata, skiprecno; + int delemc, elemc, end, freekey, freedata, skiprecno, sort_multiple; int dlen, klen, i, optindex, result, ret; char *arg, msg[MSG_SIZE]; txn = NULL; result = TCL_OK; - flag = hflag = multiflag = 0; - if (objc <= 2) { - Tcl_WrongNumArgs(interp, 2, objv, "?-args? ?key? data"); + flag = hflag = multiflag = sort_multiple = 0; + if (objc <= 3) { + Tcl_WrongNumArgs(interp, 3, objv, "?-args? key data"); return (TCL_ERROR); } @@ -1055,20 +1107,10 @@ tcl_DbPut(interp, objc, objv, dbp) case DBPUT_MULTIPLE: FLAG_CHECK(multiflag); multiflag = DB_MULTIPLE; - if (type == DB_HEAP) { - Tcl_SetResult(interp, - "-multiple not supported", TCL_STATIC); - result = TCL_ERROR; - } break; case DBPUT_MULTIPLE_KEY: FLAG_CHECK(multiflag); multiflag = DB_MULTIPLE_KEY; - if (type == DB_HEAP) { - Tcl_SetResult(interp, - "-multiple_key not supported", TCL_STATIC); - result = TCL_ERROR; - } break; case DBPUT_NOOVER: FLAG_CHECK(flag); @@ -1109,11 +1151,26 @@ tcl_DbPut(interp, objc, objv, dbp) * lines above and copy that.) */ break; + case DBPUT_SORT_MULTIPLE: + sort_multiple = 1; + break; } if (result != TCL_OK) break; } + if (sort_multiple != 0 && multiflag == 0) { + Tcl_SetResult(interp, + "-sort_multiple must be used with -multiple and -multiple_key", + TCL_STATIC); + result = TCL_ERROR; + } else if (sort_multiple != 0 && type != DB_BTREE) { + Tcl_SetResult(interp, + "-sort_multiple must be used on btree database", + TCL_STATIC); + result = TCL_ERROR; + } + if (result == TCL_ERROR) return (result); @@ -1141,8 +1198,14 @@ tcl_DbPut(interp, objc, objv, dbp) elemc = delemc; memset(&key, 0, sizeof(key)); - key.ulen = DB_ALIGN((u_int32_t)klen + - (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + if (type == DB_HEAP) + key.ulen = DB_ALIGN( + (u_int32_t)elemc * sizeof(DB_HEAP_RID) + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + else + key.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + key.flags = DB_DBT_USERMEM | DB_DBT_BULK; if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0) return (ret); @@ -1164,6 +1227,46 @@ tcl_DbPut(interp, objc, objv, dbp) dtmp, 0); DB_ASSERT(dbp->env, ptr != NULL); } + } else if (type == DB_HEAP) { + /* + * For heap we need to translate each record number in + * the passed in array into an RID. Bulk put can only + * be used to update existing heap records, so we don't + * need to worry about writing to the aux recno db. + */ + memset(&hkey, 0, sizeof(hkey)); + hkey.data = &rid; + hkey.ulen = hkey.size = sizeof(DB_HEAP_RID); + hkey.flags = DB_DBT_USERMEM; + rid.pgno = 0; + rid.indx = 0; + + /* set up key for recno auxiliary db */ + memset(&rkey, 0, sizeof(rkey)); + rkey.data = &recno; + rkey.ulen = rkey.size = sizeof(db_recno_t); + rkey.flags = DB_DBT_USERMEM; + + /* Set up the DB ptr for the recno db */ + recdbp = ((DBTCL_INFO *)dbp->api_internal)->hrdbp; + + /* The records must exist, don't need the recno put. */ + skiprecno = 1; + + DB_MULTIPLE_WRITE_INIT(ptr, &key); + for (i = 0; i < elemc; i++) { + result = _GetUInt32(interp, elemv[i], &recno); + ret = recdbp->get(recdbp, txn, &rkey, &hkey, 0); + if (ret == 0) + DB_MULTIPLE_WRITE_NEXT(ptr, + &key, hkey.data, hkey.size); + else { + result = _ReturnSetup(interp, ret, + DB_RETOK_DBPUT(ret), + "db put heap bulk"); + goto out; + } + } } else { DB_MULTIPLE_WRITE_INIT(ptr, &key); for (i = 0; i < elemc; i++) { @@ -1180,6 +1283,13 @@ tcl_DbPut(interp, objc, objv, dbp) &data, dtmp, (u_int32_t)dlen); DB_ASSERT(dbp->env, ptr != NULL); } + if (sort_multiple != 0) { + ret = dbp->sort_multiple(dbp, &key, &data, multiflag); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "sort_multiple"); + if (ret != 0) + goto out; + } } else if (multiflag == DB_MULTIPLE_KEY) { /* * To work out how big a buffer is needed, we first need to @@ -1193,8 +1303,16 @@ tcl_DbPut(interp, objc, objv, dbp) return (result); memset(&key, 0, sizeof(key)); - key.ulen = DB_ALIGN((u_int32_t)klen + - (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + if (type == DB_HEAP) { + /* Need to make sure there's room for RIDs. */ + key.ulen = DB_ALIGN( + (u_int32_t)klen + + (u_int32_t)elemc * sizeof(DB_HEAP_RID) + + (u_int32_t)elemc * sizeof(u_int32_t) * 4, 1024UL); + } else { + key.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + } key.flags = DB_DBT_USERMEM | DB_DBT_BULK; if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0) return (ret); @@ -1210,6 +1328,50 @@ tcl_DbPut(interp, objc, objv, dbp) recno, dtmp, (u_int32_t)dlen); DB_ASSERT(dbp->env, ptr != NULL); } + } else if (type == DB_HEAP) { + /* + * For heap we need to translate each record number in + * the passed in array into an RID. Bulk put can only + * be used to update existing heap records, so we don't + * need to worry about writing to the aux recno db. + */ + memset(&hkey, 0, sizeof(hkey)); + hkey.data = &rid; + hkey.ulen = hkey.size = sizeof(DB_HEAP_RID); + hkey.flags = DB_DBT_USERMEM; + rid.pgno = 0; + rid.indx = 0; + + /* set up key for recno auxiliary db */ + memset(&rkey, 0, sizeof(rkey)); + rkey.data = &recno; + rkey.ulen = rkey.size = sizeof(db_recno_t); + rkey.flags = DB_DBT_USERMEM; + + /* Set up the DB ptr for the recno db */ + recdbp = ((DBTCL_INFO *)dbp->api_internal)->hrdbp; + + /* The records must exist, don't need the recno put. */ + skiprecno = 1; + + DB_MULTIPLE_WRITE_INIT(ptr, &key); + for (i = 0; i + 1 < elemc; i += 2) { + result = _GetUInt32(interp, elemv[i], &recno); + dtmp = Tcl_GetByteArrayFromObj(elemv[i + 1], + &dlen); + ret = recdbp->get(recdbp, txn, &rkey, &hkey, 0); + if (ret == 0) { + DB_MULTIPLE_KEY_WRITE_NEXT(ptr, + &key, hkey.data, hkey.size, + dtmp, (u_int32_t)dlen); + DB_ASSERT(dbp->env, ptr != NULL); + } else { + result = _ReturnSetup(interp, ret, + DB_RETOK_DBPUT(ret), + "db put heap bulk"); + goto out; + } + } } else { DB_MULTIPLE_WRITE_INIT(ptr, &key); for (i = 0; i + 1 < elemc; i += 2) { @@ -1222,6 +1384,13 @@ tcl_DbPut(interp, objc, objv, dbp) DB_ASSERT(dbp->env, ptr != NULL); } } + if (sort_multiple != 0) { + ret = dbp->sort_multiple(dbp, &key, NULL, multiflag); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "sort_multiple"); + if (ret != 0) + goto out; + } } else if (type == DB_QUEUE || type == DB_RECNO) { /* * If we are a recno db and we are NOT using append, then the @@ -1315,11 +1484,12 @@ tcl_DbPut(interp, objc, objv, dbp) result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put"); } else { - /* Do put into heap db first, then recno db. Varieties of - * -multiple are not supported in heap (checked above), so - * multiflag has been removed from the code. - */ - ret = dbp->put(dbp, txn, &hkey, &data, hflag); + /* Do put into heap db first, then recno db. */ + if (multiflag == 0) { + ret = dbp->put(dbp, txn, &hkey, &data, hflag); + } else { + ret = dbp->put(dbp, txn, &key, &data, hflag | multiflag); + } result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put heap"); if (ret) @@ -1334,6 +1504,7 @@ tcl_DbPut(interp, objc, objv, dbp) result = _ReturnSetup(interp, ret, DB_RETOK_DBPUT(ret), "db put"); } + /* * If for some reason the recno put does not work and the * heap one does, lets try and delete the heap record if @@ -1490,13 +1661,6 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) if (result != TCL_OK) goto out; i++; - /* heap doesnt support multi yet, just catch here */ - if (type == DB_HEAP) { - Tcl_SetResult(interp, - "Heap doesnt support -multi", TCL_STATIC); - result = TCL_ERROR; - goto out; - } break; case DBGET_NOLEASE: rmw |= DB_IGNORE_LEASE; @@ -1893,7 +2057,7 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) recdbp = ((DBTCL_INFO *)dbp->api_internal)->hrdbp; FLD_CLR(hflag, DB_GET_BOTH); ret = recdbp->get(recdbp, - txn, &key, &rdata, hflag | rmw | mflag); + txn, &key, &rdata, hflag | rmw); if (ret == 0) { /* The rdata will be the key for the heap get. */ rid.pgno = ((DB_HEAP_RID *)rdata.data)->pgno; @@ -1915,7 +2079,7 @@ tcl_DbGet(interp, objc, objv, dbp, ispget) */ if (mflag & DB_MULTIPLE) result = _SetMultiList(interp, - retlist, &key, &data, type, flag); + retlist, &key, &data, type, flag, NULL); else if (type == DB_RECNO || type == DB_QUEUE) if (ispget) result = _Set3DBTList(interp, @@ -2138,6 +2302,7 @@ tcl_DbDelete(interp, objc, objv, dbp) "-glob", "-multiple", "-multiple_key", + "-sort_multiple", "-txn", NULL }; @@ -2146,26 +2311,29 @@ tcl_DbDelete(interp, objc, objv, dbp) DBDEL_GLOB, DBDEL_MULTIPLE, DBDEL_MULTIPLE_KEY, + DBDEL_SORT_MULTIPLE, DBDEL_TXN }; DB *recdbp; DBC *dbc; - DBT key, data, hkey, rdata; + DBT key, data, hkey, rdata, rkey; DBTYPE type; DB_HEAP_RID rid; DB_TXN *txn; Tcl_Obj **elemv; - void *dtmp, *ktmp, *ptr; + void *dtmp, *ktmp, *ptr, *rptr; db_recno_t recno; - int dlen, elemc, freekey, i, j, klen, optindex, result, ret; + int dlen, elemc, freekey, freerkey, i, j, klen, optindex, result, ret; + int sort_multiple; u_int32_t dflag, flag, multiflag; char *arg, *pattern, *prefix, msg[MSG_SIZE]; COMPQUIET(recdbp, NULL); result = TCL_OK; - freekey = 0; + freekey = freerkey = 0; dflag = 0; multiflag = 0; + sort_multiple = 0; pattern = prefix = NULL; txn = NULL; if (objc < 3) { @@ -2175,7 +2343,9 @@ tcl_DbDelete(interp, objc, objv, dbp) dtmp = ktmp = NULL; memset(&key, 0, sizeof(key)); + memset(&rkey, 0, sizeof(rkey)); memset(&hkey, 0, sizeof(hkey)); + memset(&rkey, 0, sizeof(rkey)); memset(&rdata, 0, sizeof(rdata)); /* @@ -2243,11 +2413,28 @@ tcl_DbDelete(interp, objc, objv, dbp) FLAG_CHECK(multiflag); multiflag |= DB_MULTIPLE_KEY; break; + case DBDEL_SORT_MULTIPLE: + sort_multiple = 1; + break; } if (result != TCL_OK) break; } + (void)dbp->get_type(dbp, &type); + + if (sort_multiple != 0 && multiflag == 0) { + Tcl_SetResult(interp, + "-sort_multiple must be used with -multiple and -multiple_key", + TCL_STATIC); + result = TCL_ERROR; + } else if (sort_multiple != 0 && type != DB_BTREE) { + Tcl_SetResult(interp, + "-sort_multiple must be used on btree database", + TCL_STATIC); + result = TCL_ERROR; + } + if (result != TCL_OK) goto out; /* @@ -2286,22 +2473,10 @@ tcl_DbDelete(interp, objc, objv, dbp) * If it is a RECNO database, the key is a record number and must be * setup up to contain a db_recno_t. Otherwise the key is a "string". */ - (void)dbp->get_type(dbp, &type); ret = 0; while (i < objc && ret == 0) { memset(&key, 0, sizeof(key)); if (multiflag == DB_MULTIPLE) { - /* - * Heap is not supporting bulk on initially, so - * check if type is heap and if so throw an error. - */ - if (type == DB_HEAP) { - Tcl_SetResult(interp, - "Heap doesnt support -multiple", TCL_STATIC); - result = TCL_ERROR; - goto out; - } - /* * To work out how big a buffer is needed, we first * need to find out the total length of the data and @@ -2314,8 +2489,24 @@ tcl_DbDelete(interp, objc, objv, dbp) return (result); memset(&key, 0, sizeof(key)); - key.ulen = DB_ALIGN((u_int32_t)klen + (u_int32_t)elemc - * sizeof(u_int32_t) * 2, 1024UL); + memset(&rkey, 0, sizeof(rkey)); + if (type == DB_HEAP) { + key.ulen = DB_ALIGN((u_int32_t)elemc * + (sizeof(DB_HEAP_RID) + + sizeof(u_int32_t) * 2), + 1024UL); + rkey.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, + 1024UL); + rkey.flags = DB_DBT_USERMEM | DB_DBT_BULK; + if ((ret = __os_malloc( + dbp->env, rkey.ulen, &rkey.data)) != 0) + return (ret); + freerkey = 1; + } else + key.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, + 1024UL); key.flags = DB_DBT_USERMEM | DB_DBT_BULK; if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0) @@ -2334,6 +2525,54 @@ tcl_DbDelete(interp, objc, objv, dbp) &key, recno, dtmp, 0); DB_ASSERT(dbp->env, ptr != NULL); } + } else if (type == DB_HEAP) { + /* + * For heap we need to translate each record + * number in the passed in array into an RID. + * Bulk put can only be used to update existing + * heap records, so we don't need to worry about + * writing to the aux recno db. + */ + memset(&hkey, 0, sizeof(hkey)); + hkey.data = &rid; + hkey.ulen = hkey.size = sizeof(DB_HEAP_RID); + hkey.flags = DB_DBT_USERMEM; + rid.pgno = 0; + rid.indx = 0; + + /* set up key for recno auxiliary db */ + memset(&data, 0, sizeof(rdata)); + data.data = &recno; + data.ulen = data.size = sizeof(db_recno_t); + data.flags = DB_DBT_USERMEM; + + /* Set up the DB ptr for the recno db */ + recdbp = + ((DBTCL_INFO *)dbp->api_internal)->hrdbp; + + DB_MULTIPLE_WRITE_INIT(ptr, &key); + DB_MULTIPLE_RECNO_WRITE_INIT(rptr, &rkey); + for (j = 0; j < elemc; j++) { + result = + _GetUInt32(interp, + elemv[j], &recno); + if (result != TCL_OK) + return (result); + ret = recdbp->get( + recdbp, txn, &data, &hkey, 0); + if (ret != 0) { + result = _ReturnSetup(interp, + ret, DB_RETOK_DBPUT(ret), + "db del heap bulk"); + goto out; + } + DB_MULTIPLE_WRITE_NEXT(ptr, + &key, hkey.data, hkey.size); + DB_ASSERT(dbp->env, ptr != NULL); + DB_MULTIPLE_RECNO_WRITE_NEXT(rptr, + &rkey, recno, dtmp, 0); + DB_ASSERT(dbp->env, rptr != NULL); + } } else { DB_MULTIPLE_WRITE_INIT(ptr, &key); for (j = 0; j < elemc; j++) { @@ -2344,18 +2583,14 @@ tcl_DbDelete(interp, objc, objv, dbp) DB_ASSERT(dbp->env, ptr != NULL); } } + if (sort_multiple != 0) { + ret = dbp->sort_multiple(dbp, &key, NULL, multiflag); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "sort_multiple"); + if (ret != 0) + goto loopend; + } } else if (multiflag == DB_MULTIPLE_KEY) { - /* - * Heap is not supporting bulk on initially, so - * check if type is heap and if so throw an error. - */ - if (type == DB_HEAP) { - Tcl_SetResult(interp, - "Heap doesnt support -multiple_key", TCL_STATIC); - result = TCL_ERROR; - goto out; - } - /* * To work out how big a buffer is needed, we first * need to find out the total length of the data (len) @@ -2368,8 +2603,24 @@ tcl_DbDelete(interp, objc, objv, dbp) return (result); memset(&key, 0, sizeof(key)); - key.ulen = DB_ALIGN((u_int32_t)klen + - (u_int32_t)elemc * sizeof(u_int32_t) * 2, 1024UL); + memset(&rkey, 0, sizeof(rkey)); + if (type == DB_HEAP) { + key.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(DB_HEAP_RID) + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, + 1024UL); + rkey.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, + 1024UL); + rkey.flags = DB_DBT_USERMEM | DB_DBT_BULK; + if ((ret = __os_malloc( + dbp->env, rkey.ulen, &rkey.data)) != 0) + return (ret); + freerkey = 1; + } else + key.ulen = DB_ALIGN((u_int32_t)klen + + (u_int32_t)elemc * sizeof(u_int32_t) * 2, + 1024UL); key.flags = DB_DBT_USERMEM | DB_DBT_BULK; if ((ret = __os_malloc(dbp->env, key.ulen, &key.data)) != 0) @@ -2390,6 +2641,57 @@ tcl_DbDelete(interp, objc, objv, dbp) &key, recno, dtmp, (u_int32_t)dlen); DB_ASSERT(dbp->env, ptr != NULL); } + } else if (type == DB_HEAP) { + /* + * For heap we need to translate each record + * number in the passed in array into an RID. + * Bulk put can only be used to update existing + * heap records, so we don't need to worry about + * writing to the aux recno db. + */ + memset(&hkey, 0, sizeof(hkey)); + hkey.data = &rid; + hkey.ulen = hkey.size = sizeof(DB_HEAP_RID); + hkey.flags = DB_DBT_USERMEM; + rid.pgno = 0; + rid.indx = 0; + + /* set up key for recno auxiliary db */ + memset(&data, 0, sizeof(rdata)); + data.data = &recno; + data.ulen = data.size = sizeof(db_recno_t); + data.flags = DB_DBT_USERMEM; + + /* Set up the DB ptr for the recno db */ + recdbp = + ((DBTCL_INFO *)dbp->api_internal)->hrdbp; + + DB_MULTIPLE_WRITE_INIT(ptr, &key); + DB_MULTIPLE_RECNO_WRITE_INIT(rptr, &rkey); + for (j = 0; j + 1 < elemc; j += 2) { + result = + _GetUInt32(interp, + elemv[j], &recno); + if (result != TCL_OK) + return (result); + dtmp = Tcl_GetByteArrayFromObj( + elemv[j + 1], &dlen); + ret = recdbp->get( + recdbp, txn, &data, &hkey, 0); + if (ret != 0) { + result = _ReturnSetup(interp, + ret, DB_RETOK_DBPUT(ret), + "db del heap bulk"); + goto out; + } + DB_MULTIPLE_KEY_WRITE_NEXT(ptr, + &key, hkey.data, hkey.size, + dtmp, (u_int32_t)dlen); + DB_ASSERT(dbp->env, ptr != NULL); + DB_MULTIPLE_RECNO_WRITE_NEXT(rptr, + &rkey, recno, dtmp, 0); + DB_ASSERT(dbp->env, rptr != NULL); + } } else { DB_MULTIPLE_WRITE_INIT(ptr, &key); for (j = 0; j + 1 < elemc; j += 2) { @@ -2403,6 +2705,13 @@ tcl_DbDelete(interp, objc, objv, dbp) DB_ASSERT(dbp->env, ptr != NULL); } } + if (sort_multiple != 0) { + ret = dbp->sort_multiple(dbp, &key, NULL, multiflag); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "sort_multiple"); + if (ret != 0) + goto loopend; + } } else if (type == DB_RECNO || type == DB_QUEUE) { result = _GetUInt32(interp, objv[i++], &recno); if (result == TCL_OK) { @@ -2431,7 +2740,12 @@ tcl_DbDelete(interp, objc, objv, dbp) _debug_check(); if (type != DB_HEAP) ret = dbp->del(dbp, txn, &key, dflag | multiflag); - else { + else if (multiflag == DB_MULTIPLE || + multiflag == DB_MULTIPLE_KEY) { + ret = recdbp->del( + recdbp, txn, &rkey, dflag | DB_MULTIPLE); + ret = dbp->del(dbp, txn, &key, dflag | multiflag); + } else { /* set up the recno data, which will be heap key */ rdata.ulen = sizeof(DB_HEAP_RID); rdata.flags = DB_DBT_USERMEM; @@ -2485,12 +2799,18 @@ tcl_DbDelete(interp, objc, objv, dbp) * If we have any error, set up return result and stop * processing keys. */ +loopend: if (freekey && key.data != NULL) __os_free(dbp->env, key.data); + if (freerkey && rkey.data != NULL) + __os_free(dbp->env, rkey.data); if (ret != 0) break; } - result = _ReturnSetup(interp, ret, DB_RETOK_DBDEL(ret), "db del"); + + if (result == TCL_OK) + result = _ReturnSetup(interp, + ret, DB_RETOK_DBDEL(ret), "db del"); /* * At this point we've either finished or, if we have a pattern, diff --git a/lang/tcl/tcl_db_pkg.c b/lang/tcl/tcl_db_pkg.c index 0dbe9ef1..a190f9de 100644 --- a/lang/tcl/tcl_db_pkg.c +++ b/lang/tcl/tcl_db_pkg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -541,6 +541,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp) "-errpfx", "-home", "-log_dir", + "-metadata_dir", "-mode", "-msgfile", "-private", @@ -638,6 +639,7 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp) TCL_ENV_ERRPFX, TCL_ENV_HOME, TCL_ENV_LOG_DIR, + TCL_ENV_METADATA_DIR, TCL_ENV_MODE, TCL_ENV_MSGFILE, TCL_ENV_PRIVATE, @@ -1631,6 +1633,19 @@ bdb_EnvOpen(interp, objc, objv, ip, dbenvp) result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "set_lg_dir"); break; + case TCL_ENV_METADATA_DIR: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "-metadata_dir dir"); + result = TCL_ERROR; + break; + } + arg = Tcl_GetStringFromObj(objv[i++], NULL); + _debug_check(); + ret = dbenv->set_metadata_dir(dbenv, arg); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "set_metadata_dir"); + break; case TCL_ENV_TMP_DIR: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -1790,8 +1805,10 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) "-ffactor", "-hash", "-heap", + "-heap_regionsize", "-inorder", "-len", + "-lk_exclusive", "-maxsize", "-mode", "-msgfile", @@ -1851,8 +1868,10 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) TCL_DB_FFACTOR, TCL_DB_HASH, TCL_DB_HEAP, + TCL_DB_HEAP_REGIONSIZE, TCL_DB_INORDER, TCL_DB_LEN, + TCL_DB_LK_EXCLUSIVE, TCL_DB_MAXSIZE, TCL_DB_MODE, TCL_DB_MSGFILE, @@ -1882,7 +1901,7 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) Tcl_Obj **myobjv; u_int32_t gbytes, bytes, open_flags, set_flags, uintarg; - int endarg, encenble, i, intarg, mode, myobjc, ncaches; + int endarg, encenble, i, intarg, mode, myobjc, ncaches, excl, nowait; int optindex, result, ret, set_err, set_msg, set_pfx, subdblen; u_char *subdbtmp; char *arg, *db, *dbr, *passwd, *subdb, *subdbr, msg[MSG_SIZE]; @@ -2088,6 +2107,21 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "set_h_hash"); break; + case TCL_DB_HEAP_REGIONSIZE: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "-heap_regionsize npages"); + result = TCL_ERROR; + break; + } + result = _GetUInt32(interp, objv[i++], &uintarg); + if (result == TCL_OK) { + _debug_check(); + ret = (*dbp)->set_heap_regionsize(*dbp, uintarg); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "set_heap_regionsize"); + } + break; case TCL_DB_LORDER: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -2426,6 +2460,20 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) DB_RETOK_STD(ret), "set_re_len"); } break; + case TCL_DB_LK_EXCLUSIVE: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "-lk_exclusive nowait"); + break; + } + result = Tcl_GetIntFromObj(interp, objv[i++], &intarg); + if (result == TCL_OK) { + _debug_check(); + ret = (*dbp)->set_lk_exclusive(*dbp, intarg); + result = _ReturnSetup(interp, ret, + DB_RETOK_STD(ret), "set_lk_exclusive"); + } + break; case TCL_DB_MAXSIZE: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -2744,6 +2792,9 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) else ret = hrdbp->set_encrypt(hrdbp, passwd, 0); } + (void)(*dbp)->get_lk_exclusive((*dbp), &excl, &nowait); + if (excl) + (void)hrdbp->set_lk_exclusive(hrdbp, nowait); ret = hrdbp->open(hrdbp, txn, dbr, subdbr, DB_RECNO, open_flags, mode); if (ret) { @@ -2795,6 +2846,8 @@ bdb_DbOpen(interp, objc, objv, ip, dbp) else ret = hsdbp->set_encrypt(hsdbp, passwd, 0); } + if (excl) + (void)hsdbp->set_lk_exclusive(hsdbp, nowait); ret = hsdbp->open(hsdbp, txn, dbr, subdbr, DB_BTREE, open_flags, mode); if (ret) { diff --git a/lang/tcl/tcl_dbcursor.c b/lang/tcl/tcl_dbcursor.c index 6ecc34d4..a6df38dc 100644 --- a/lang/tcl/tcl_dbcursor.c +++ b/lang/tcl/tcl_dbcursor.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -545,7 +545,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) DBCGET_SETRANGE, DBCGET_SETRECNO }; - DB *hrdbp, *hsdbp, *thisdbp; + DB *hrdbp, *hsdbp, *pdbp, *phrdbp, *phsdbp, *thisdbp; DB_HEAP_RID rid; DBT hkey, key, data, pdata, rkey, rdata, tmpdata; DBTCL_INFO *dbcip, *dbip; @@ -565,7 +565,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) result = TCL_OK; flag = heapflag = 0; freekey = freedata = 0; - hrdbp = hsdbp = NULL; + hrdbp = hsdbp = pdbp = phrdbp = phsdbp = NULL; type = ptype = DB_UNKNOWN; memset(&hkey, 0, sizeof(hkey)); memset(&key, 0, sizeof(key)); @@ -755,6 +755,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) goto out; heapflag = flag & ~DB_OPFLAGS_MASK; heapflag &= ~DB_MULTIPLE_KEY; + heapflag &= ~DB_MULTIPLE; if (F_ISSET(dbc, DBC_READ_COMMITTED)) heapflag |= DB_READ_COMMITTED; if (F_ISSET(dbc, DBC_READ_UNCOMMITTED)) @@ -776,15 +777,21 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) } thisdbp = dbip->i_dbp; (void)thisdbp->get_type(thisdbp, &type); - if (ispget && thisdbp->s_primary != NULL) - (void)thisdbp-> - s_primary->get_type(thisdbp->s_primary, &ptype); - else + if (ispget && thisdbp->s_primary != NULL) { + pdbp = thisdbp->s_primary; + (void)pdbp->get_type(pdbp, &ptype); + } else ptype = DB_UNKNOWN; if (type == DB_HEAP) { hrdbp = dbip->hrdbp; hsdbp = dbip->hsdbp; } + if (pdbp != NULL && ptype == DB_HEAP) { + phrdbp = ((DBTCL_INFO *) + pdbp->api_internal)->hrdbp; + phsdbp = ((DBTCL_INFO *) + pdbp->api_internal)->hsdbp; + } } /* * When we get here, we better have: @@ -965,7 +972,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) data.data = &rid; data.size = data.ulen = sizeof(DB_HEAP_RID); data.flags = DB_DBT_USERMEM; - ret = hrdbp->get(hrdbp, dbc->txn, &rkey, &data, heapflag); + ret = phrdbp->get(phrdbp, dbc->txn, &rkey, &data, heapflag); if (ret != 0) { result = _ReturnSetup( interp, ret, DB_RETOK_DBGET(ret), "db get"); @@ -983,9 +990,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) hkey.data = &rid; hkey.ulen = hkey.size = data.size; hkey.flags = DB_DBT_USERMEM; - hsdbp = ((DBTCL_INFO *) - dbc->dbp->s_primary->api_internal)->hsdbp; - ret = hsdbp->pget(hsdbp, + ret = phsdbp->pget(phsdbp, dbc->txn, &hkey, &data, &tmpdata, 0); } @@ -1005,7 +1010,7 @@ tcl_DbcGet(interp, objc, objv, dbc, ispget) } else { if (flag & (DB_MULTIPLE|DB_MULTIPLE_KEY)) result = _SetMultiList(interp, - retlist, &key, &data, type, flag); + retlist, &key, &data, type, flag, dbc); else if ((type == DB_RECNO || type == DB_QUEUE) && key.data != NULL) { if (ispget) @@ -1067,12 +1072,13 @@ out1: out: if (key.data != NULL && F_ISSET(&key, DB_DBT_MALLOC)) __os_ufree(dbc->env, key.data); - if (type != DB_HEAP && - key.data != NULL && F_ISSET(&key, DB_DBT_USERMEM)) + if (key.data != NULL && F_ISSET(&key, DB_DBT_USERMEM) && + key.data != &rid) __os_free(dbc->env, key.data); if (data.data != NULL && F_ISSET(&data, DB_DBT_MALLOC)) __os_ufree(dbc->env, data.data); - if (data.data != NULL && F_ISSET(&data, DB_DBT_USERMEM)) + if (data.data != NULL && F_ISSET(&data, DB_DBT_USERMEM) && + data.data != &rid) __os_free(dbc->env, data.data); if (pdata.data != NULL && F_ISSET(&pdata, DB_DBT_MALLOC)) __os_ufree(dbc->env, pdata.data); diff --git a/lang/tcl/tcl_env.c b/lang/tcl/tcl_env.c index 40b0767a..e79ac2cf 100644 --- a/lang/tcl/tcl_env.c +++ b/lang/tcl/tcl_env.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -154,6 +154,7 @@ env_Cmd(clientData, interp, objc, objv) "get_lk_max_locks", "get_lk_max_objects", "get_lk_partitions", + "get_metadata_dir", "get_mp_max_openfd", "get_mp_max_write", "get_mp_mmapsize", @@ -284,6 +285,7 @@ env_Cmd(clientData, interp, objc, objv) ENVGETLKMAXLOCKS, ENVGETLKMAXOBJECTS, ENVGETLKPARTITIONS, + ENVGETMETADATADIR, ENVGETMPMAXOPENFD, ENVGETMPMAXWRITE, ENVGETMPMMAPSIZE, @@ -312,7 +314,7 @@ env_Cmd(clientData, interp, objc, objv) time_t timeval; u_int32_t bytes, gbytes, value; long shm_key; - int cmdindex, i, intvalue, listobjc, ncache, result, ret, t_ret; + int cmdindex, i, intvalue, listobjc, ncache, result, ret; const char *strval, **dirs; char *strarg, newname[MSG_SIZE]; #ifdef CONFIG_TEST @@ -808,29 +810,7 @@ env_Cmd(clientData, interp, objc, objv) result = tcl_CDSGroup(interp, objc, objv, dbenv, envip); break; case ENVCLOSE: - /* - * No args for this. Error if there are some. - */ - if (objc > 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - return (TCL_ERROR); - } - /* - * Any transactions will be aborted, and an mpools - * closed automatically. We must delete any txn - * and mp widgets we have here too for this env. - * NOTE: envip is freed when we come back from - * this function. Set it to NULL to make sure no - * one tries to use it later. - */ - ret = __mutex_free(dbenv->env, &envip->i_mutex); - _debug_check(); - if ((t_ret = dbenv->close(dbenv, 0)) != 0 && ret == 0) - ret = t_ret; - result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), - "env close"); - _EnvInfoDelete(interp, envip); - envip = NULL; + result = tcl_EnvClose(interp, objc, objv, dbenv, envip); break; case ENVDBREMOVE: result = env_DbRemove(interp, objc, objv, dbenv); @@ -1036,6 +1016,16 @@ env_Cmd(clientData, interp, objc, objv) "env get_lk_partitions")) == TCL_OK) res = Tcl_NewLongObj((long)value); break; + case ENVGETMETADATADIR: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, NULL); + return (TCL_ERROR); + } + ret = dbenv->get_metadata_dir(dbenv, &strval); + if ((result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "env get_metadata_dir")) == TCL_OK) + res = NewStringObj(strval, strlen(strval)); + break; case ENVGETMPMAXOPENFD: if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, NULL); @@ -1259,6 +1249,7 @@ tcl_EnvRemove(interp, objc, objv) "-force", "-home", "-log_dir", + "-metadata_dir", "-tmp_dir", "-use_environ", "-use_environ_root", @@ -1274,6 +1265,7 @@ tcl_EnvRemove(interp, objc, objv) ENVREM_FORCE, ENVREM_HOME, ENVREM_LOGDIR, + ENVREM_METADATADIR, ENVREM_TMPDIR, ENVREM_USE_ENVIRON, ENVREM_USE_ENVIRON_ROOT @@ -1281,13 +1273,13 @@ tcl_EnvRemove(interp, objc, objv) DB_ENV *dbenv; u_int32_t cflag, enc_flag, flag, forceflag, sflag; int i, optindex, result, ret; - char *datadir, *home, *logdir, *passwd, *tmpdir; + char *datadir, *home, *logdir, *mddir, *passwd, *tmpdir; result = TCL_OK; cflag = flag = forceflag = sflag = 0; home = NULL; passwd = NULL; - datadir = logdir = tmpdir = NULL; + datadir = logdir = mddir = tmpdir = NULL; enc_flag = 0; if (objc < 2) { @@ -1368,6 +1360,15 @@ tcl_EnvRemove(interp, objc, objv) } logdir = Tcl_GetStringFromObj(objv[i++], NULL); break; + case ENVREM_METADATADIR: + if (i >= objc) { + Tcl_WrongNumArgs(interp, 2, objv, + "-metadata_dir dir"); + result = TCL_ERROR; + break; + } + mddir = Tcl_GetStringFromObj(objv[i++], NULL); + break; case ENVREM_TMPDIR: if (i >= objc) { Tcl_WrongNumArgs(interp, 2, objv, @@ -1407,6 +1408,14 @@ tcl_EnvRemove(interp, objc, objv) if (result != TCL_OK) goto error; } + if (mddir != NULL) { + _debug_check(); + ret = dbenv->set_metadata_dir(dbenv, mddir); + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), + "set_metadata_dir"); + if (result != TCL_OK) + goto error; + } if (tmpdir != NULL) { _debug_check(); ret = dbenv->set_tmp_dir(dbenv, tmpdir); @@ -1502,6 +1511,70 @@ _EnvInfoDelete(interp, envip) _DeleteInfo(envip); } +/* + * PUBLIC: int tcl_EnvClose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, + * PUBLIC: DB_ENV *, DBTCL_INFO *)); + * + * tcl_EnvClose -- + * Implements the DB_ENV->close command. + */ +int +tcl_EnvClose(interp, objc, objv, dbenv, envip) + Tcl_Interp *interp; /* Interpreter */ + int objc; /* arg count */ + Tcl_Obj * CONST* objv; /* args */ + DB_ENV *dbenv; /* Database pointer */ + DBTCL_INFO *envip; /* Info pointer */ +{ + static const char *closeoptions[] = { + "-forcesync", + NULL + }; + enum closeoptions { + FORCESYNC + }; + int i, result, ret, t_ret; + u_int32_t flags; + + result = TCL_OK; + flags = 0; + Tcl_SetResult(interp, "0", TCL_STATIC); + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?-forcesync?"); + return (TCL_ERROR); + } else if (objc == 3) { + /* + * If there is an arg, make sure it is the right one. + */ + if (Tcl_GetIndexFromObj(interp, objv[2], closeoptions, "option", + TCL_EXACT, &i) != TCL_OK) + return (IS_HELP(objv[2])); + + switch ((enum closeoptions)i) { + case FORCESYNC: + flags |= DB_FORCESYNC; + break; + } + } + + /* + * Any transactions will be aborted, and an mpools + * closed automatically. We must delete any txn + * and mp widgets we have here too for this env. + * NOTE: envip is freed when we come back from + * this function. Set it to NULL to make sure no + * one tries to use it later. + */ + ret = __mutex_free(dbenv->env, &envip->i_mutex); + _debug_check(); + if ((t_ret = dbenv->close(dbenv, flags)) != 0 && ret == 0) + ret = t_ret; + result = _ReturnSetup(interp, ret, DB_RETOK_STD(ret), "env close"); + _EnvInfoDelete(interp, envip); + envip = NULL; + return (result); +} + #ifdef CONFIG_TEST /* * PUBLIC: int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, @@ -1622,6 +1695,7 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) Tcl_Obj *onoff; /* On or off */ { static const char *verbwhich[] = { + "backup", "deadlock", "fileops", "fileops_all", @@ -1641,6 +1715,7 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) NULL }; enum verbwhich { + ENVVERB_BACKUP, ENVVERB_DEADLOCK, ENVVERB_FILEOPS, ENVVERB_FILEOPS_ALL, @@ -1675,6 +1750,9 @@ tcl_EnvVerbose(interp, dbenv, which, onoff) return (IS_HELP(which)); switch ((enum verbwhich)optindex) { + case ENVVERB_BACKUP: + wh = DB_VERB_BACKUP; + break; case ENVVERB_DEADLOCK: wh = DB_VERB_DEADLOCK; break; @@ -3034,6 +3112,7 @@ env_GetVerbose(interp, objc, objv, dbenv) u_int32_t flag; char *arg; } verbose_flags[] = { + { DB_VERB_BACKUP, "backup" }, { DB_VERB_DEADLOCK, "deadlock" }, { DB_VERB_FILEOPS, "fileops" }, { DB_VERB_FILEOPS_ALL, "fileops_all" }, diff --git a/lang/tcl/tcl_internal.c b/lang/tcl/tcl_internal.c index cea70f35..a358ae99 100644 --- a/lang/tcl/tcl_internal.c +++ b/lang/tcl/tcl_internal.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -112,6 +112,8 @@ _NameToInfo(name) { DBTCL_INFO *p; + if (name == NULL) + return (NULL); LIST_FOREACH(p, &__db_infohead, entries) if (strcmp(name, p->i_name) == 0) return (p); @@ -372,25 +374,46 @@ _Set3DBTList(interp, list, elem1, is1recno, elem2, is2recno, elem3) * _SetMultiList -- build a list for return from multiple get. * * PUBLIC: int _SetMultiList __P((Tcl_Interp *, - * PUBLIC: Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t)); + * PUBLIC: Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t, DBC*)); */ int -_SetMultiList(interp, list, key, data, type, flag) +_SetMultiList(interp, list, key, data, type, flag, dbc) Tcl_Interp *interp; Tcl_Obj *list; DBT *key, *data; DBTYPE type; u_int32_t flag; + DBC *dbc; { + DB *hsdbp; + DB_TXN *txn; + DBT hkey, rkey, rdata; + DBTCL_INFO *dbcip; db_recno_t recno; u_int32_t dlen, klen; - int result; + int result, ret; void *pointer, *dp, *kp; recno = 0; dlen = 0; kp = NULL; + hsdbp = NULL; + txn = NULL; + if (type == DB_HEAP) { + memset(&hkey, 0, sizeof(DBT)); + memset(&rkey, 0, sizeof(DBT)); + rkey.data = &recno; + rkey.size = rkey.ulen = sizeof(recno); + rkey.flags = DB_DBT_USERMEM; + memset(&rdata, 0, sizeof(DBT)); + rdata.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL; + + dbcip = _PtrToInfo(dbc); + hsdbp = (dbcip != NULL) ? dbcip->i_parent->hsdbp : NULL; + txn = (dbc != NULL) ? dbc->txn : NULL; + } + DB_MULTIPLE_INIT(pointer, data); result = TCL_OK; @@ -413,7 +436,20 @@ _SetMultiList(interp, list, key, data, type, flag) if (pointer == NULL) break; - if (type == DB_RECNO || type == DB_QUEUE) { + if (type == DB_HEAP || type == DB_RECNO || type == DB_QUEUE) { + if (type == DB_HEAP) { + if (flag & DB_MULTIPLE_KEY) { + hkey.data = kp; + hkey.size = klen; + ret = hsdbp->pget(hsdbp, txn, + &hkey, &rkey, &rdata, 0); + result = _ReturnSetup(interp, + ret, DB_RETOK_DBGET(ret), "db get"); + if (result == TCL_ERROR) + return (result); + } else + recno = 0; + } result = _SetListRecnoElem(interp, list, recno, dp, dlen); recno++; diff --git a/lang/tcl/tcl_lock.c b/lang/tcl/tcl_lock.c index 9a0dd5cf..5a06b1a0 100644 --- a/lang/tcl/tcl_lock.c +++ b/lang/tcl/tcl_lock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_log.c b/lang/tcl/tcl_log.c index 3a876e95..3024f7b1 100644 --- a/lang/tcl/tcl_log.c +++ b/lang/tcl/tcl_log.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_mp.c b/lang/tcl/tcl_mp.c index e7a46b71..ba4318da 100644 --- a/lang/tcl/tcl_mp.c +++ b/lang/tcl/tcl_mp.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -426,6 +426,7 @@ tcl_MpStat(interp, objc, objv, dbenv) MAKE_WSTAT_LIST("Pages created", (*fsp)->st_page_create); MAKE_WSTAT_LIST("Pages read in", (*fsp)->st_page_in); MAKE_WSTAT_LIST("Pages written", (*fsp)->st_page_out); + MAKE_WSTAT_LIST("Backup spins", (*fsp)->st_backup_spins); /* * Now that we have a complete "per-file" stat list, append * that to the other list. diff --git a/lang/tcl/tcl_mutex.c b/lang/tcl/tcl_mutex.c index 30570ec0..384f91ad 100644 --- a/lang/tcl/tcl_mutex.c +++ b/lang/tcl/tcl_mutex.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_rep.c b/lang/tcl/tcl_rep.c index bc372d14..a616cc7c 100644 --- a/lang/tcl/tcl_rep.c +++ b/lang/tcl/tcl_rep.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1030,7 +1030,8 @@ tcl_RepStat(interp, objc, objv, dbenv) MAKE_WSTAT_LIST("Elections won", sp->st_elections_won); MAKE_STAT_LIST("Election phase", sp->st_election_status); MAKE_STAT_LIST("Election winner", sp->st_election_cur_winner); - MAKE_STAT_LIST("Election generation number", sp->st_election_gen); + MAKE_STAT_LIST("Election winner generation number", + sp->st_election_gen); MAKE_STAT_LIST("Election data generation number", sp->st_election_datagen); MAKE_STAT_LSN("Election max LSN", &sp->st_election_lsn); diff --git a/lang/tcl/tcl_seq.c b/lang/tcl/tcl_seq.c index faea8d9e..75f59fee 100644 --- a/lang/tcl/tcl_seq.c +++ b/lang/tcl/tcl_seq.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_txn.c b/lang/tcl/tcl_txn.c index fe842253..e8c69c08 100644 --- a/lang/tcl/tcl_txn.c +++ b/lang/tcl/tcl_txn.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/lang/tcl/tcl_util.c b/lang/tcl/tcl_util.c index 9560f596..0e83826f 100644 --- a/lang/tcl/tcl_util.c +++ b/lang/tcl/tcl_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_compact.c b/src/btree/bt_compact.c index 4a2843cb..b455ff23 100644 --- a/src/btree/bt_compact.c +++ b/src/btree/bt_compact.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -465,7 +465,7 @@ retry: pg = NULL; * The stack will be rooted at the page that spans * the current and next pages. The two subtrees * are returned below that. For BTREE the current - * page subtreee will be first while for RECNO the + * page subtree will be first while for RECNO the * next page subtree will be first */ if (ndbc == NULL && (ret = __dbc_dup(dbc, &ndbc, 0)) != 0) @@ -773,7 +773,7 @@ retry: pg = NULL; P_FREESPACE(dbp, pg) > factor && c_data->compact_pages != 0) { /* * merging may have to free the parent page, if it does, - * refetch it but do it decending the tree. + * refetch it but do it descending the tree. */ epg = &cp->csp[-1]; if ((ppg = epg->page) == NULL) { @@ -1735,7 +1735,7 @@ fits: memset(&bi, 0, sizeof(bi)); * If we merged any records then we will revisit this * node when we merge its leaves. If not we will return * NOTGRANTED and our caller will do a retry. We only - * need to do this if we are in a transation. If not then + * need to do this if we are in a transaction. If not then * we cannot abort and things will be hosed up on error * anyway. */ @@ -1798,7 +1798,7 @@ fits: memset(&bi, 0, sizeof(bi)); /* * __bam_dpages may decide to collapse the tree * so we need to free our other stack. The tree - * will change in hight and our stack will nolonger + * will change in height and our stack will nolonger * be valid. */ cp->csp = save_csp; @@ -2051,6 +2051,7 @@ __bam_truncate_root_page(dbc, pg, indx, c_data) BOVERFLOW *bo; DB *dbp; db_pgno_t *pgnop; + u_int32_t tlen; COMPQUIET(c_data, NULL); COMPQUIET(bo, NULL); @@ -2060,16 +2061,21 @@ __bam_truncate_root_page(dbc, pg, indx, c_data) if (B_TYPE(bi->type) == B_OVERFLOW) { bo = (BOVERFLOW *)(bi->data); pgnop = &bo->pgno; - } else + tlen = bo->tlen; + } else { + /* Tlen is not used if this is not an overflow. */ + tlen = 0; pgnop = &bi->pgno; + } } else { bo = GET_BOVERFLOW(dbp, pg, indx); pgnop = &bo->pgno; + tlen = bo->tlen; } DB_ASSERT(dbp->env, IS_DIRTY(pg)); - return (__db_truncate_root(dbc, pg, indx, pgnop, bo->tlen)); + return (__db_truncate_root(dbc, pg, indx, pgnop, tlen)); } /* @@ -2618,9 +2624,11 @@ err: if (txn != NULL && ret != 0) else sflag = 0; if (txn == NULL) { - if ((t_ret = __LPUT(dbc, meta_lock)) != 0 && ret == 0) + if (dbc != NULL && + (t_ret = __LPUT(dbc, meta_lock)) != 0 && ret == 0) ret = t_ret; - if ((t_ret = __LPUT(dbc, root_lock)) != 0 && ret == 0) + if (dbc != NULL && + (t_ret = __LPUT(dbc, root_lock)) != 0 && ret == 0) ret = t_ret; } if (meta != NULL && (t_ret = __memp_fput(dbp->mpf, diff --git a/src/btree/bt_compare.c b/src/btree/bt_compare.c index 74be5110..5c009071 100644 --- a/src/btree/bt_compare.c +++ b/src/btree/bt_compare.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/btree/bt_compress.c b/src/btree/bt_compress.c index c768172b..3f293461 100644 --- a/src/btree/bt_compress.c +++ b/src/btree/bt_compress.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" @@ -14,6 +14,9 @@ static int __bam_compress_marshal_data __P((DB *, const DBT *, DBT *)); static int __bam_compress_set_dbt __P((DB *, DBT *, const void *, u_int32_t)); +static int __bam_compress_check_sort_multiple_key __P((DB *, DBT *)); +static int __bam_compress_check_sort_multiple __P((DB *, DBT *, DBT *)); +static int __bam_compress_check_sort_multiple_keyonly __P((DB *, DBT *)); static int __bamc_compress_del_and_get_next __P((DBC *, DBT *, DBT *)); static int __bamc_compress_get_bothc __P((DBC *, DBT *, u_int32_t)); static int __bamc_compress_get_multiple_key __P((DBC *, DBT *, u_int32_t)); @@ -1574,7 +1577,7 @@ __bamc_compress_get_prev(dbc, flags) tofind = (u_int32_t)-1; } else if (cp->prevcursor == 0) { /* - * The current key is at the begining of the + * The current key is at the beginning of the * compressed block, so get the last key from the * previous block */ @@ -1674,7 +1677,7 @@ __bamc_compress_get_prev_nodup(dbc, flags) /* * Linear search for the next non-duplicate key - this is * especially inefficient for DB_PREV_NODUP, since we have to - * decompress from the begining of the chunk to find previous + * decompress from the beginning of the chunk to find previous * key/data pairs. Instead we could check for key equality as we * decompress. */ @@ -1744,9 +1747,6 @@ __bamc_compress_get_next_dup(dbc, key, flags) dbp = dbc->dbp; t = (BTREE *)dbp->bt_internal; - if (cp->currentKey == 0) - return (EINVAL); - if (F_ISSET(cp, C_COMPRESS_DELETED)) { /* * Check that the next entry has the same key as the @@ -1757,7 +1757,8 @@ __bamc_compress_get_next_dup(dbc, key, flags) F_CLR(cp, C_COMPRESS_DELETED); return (t->bt_compare(dbp, cp->currentKey, &cp->del_key) == 0 ? 0 : DB_NOTFOUND); - } + } else if (cp->currentKey == 0) + return (EINVAL); /* Check that the next entry has the same key as the previous entry */ ret = __bamc_next_decompress(dbc); @@ -2270,6 +2271,8 @@ __bamc_compress_iput(dbc, key, data, flags) multi = LF_ISSET(DB_MULTIPLE|DB_MULTIPLE_KEY); LF_CLR(DB_MULTIPLE|DB_MULTIPLE_KEY); + if (flags == 0) + flags = DB_KEYLAST; switch (flags) { case DB_CURRENT: @@ -2336,11 +2339,17 @@ __bamc_compress_iput(dbc, key, data, flags) dbc, key, data, DB_GET_BOTH_RANGE, 0); break; case DB_MULTIPLE: + if ((ret = __bam_compress_check_sort_multiple(dbp, + key, data)) != 0) + goto end; __bam_cs_create_multiple(&stream, key, data); ret = __bamc_compress_merge_insert( dbc, &stream, &key->doff, flags); break; case DB_MULTIPLE_KEY: + if ((ret = __bam_compress_check_sort_multiple_key(dbp, + key)) != 0) + goto end; __bam_cs_create_multiple_key(&stream, key); ret = __bamc_compress_merge_insert( dbc, &stream, &key->doff, flags); @@ -2537,6 +2546,7 @@ __bamc_compress_ibulk_del(dbc, key, flags) DBT *key; u_int32_t flags; { + int ret; BTREE_COMPRESS_STREAM stream; switch (flags) { @@ -2544,10 +2554,16 @@ __bamc_compress_ibulk_del(dbc, key, flags) __bam_cs_create_single_keyonly(&stream, key); return (__bamc_compress_merge_delete_dups(dbc, &stream, NULL)); case DB_MULTIPLE: + if ((ret = __bam_compress_check_sort_multiple_keyonly( + dbc->dbp, key)) != 0) + return (ret); __bam_cs_create_multiple_keyonly(&stream, key); return (__bamc_compress_merge_delete_dups( dbc, &stream, &key->doff)); case DB_MULTIPLE_KEY: + if ((ret = __bam_compress_check_sort_multiple_key( + dbc->dbp, key)) != 0) + return (ret); __bam_cs_create_multiple_key(&stream, key); return (__bamc_compress_merge_delete(dbc, &stream, &key->doff)); default: @@ -3020,4 +3036,138 @@ err: return (ret); } +/* + * Check if the key/data pairs in the bulk buffer are sorted. + */ +static int +__bam_compress_check_sort_multiple_key(dbp, key) + DB *dbp; + DBT *key; +{ +#ifdef DIAGNOSTIC + void *kptr; + DBT key1, data1, key2, data2; + + memset(&key1, 0, sizeof(DBT)); + memset(&data1, 0, sizeof(DBT)); + memset(&key2, 0, sizeof(DBT)); + memset(&data2, 0, sizeof(DBT)); + + DB_MULTIPLE_INIT(kptr, key); + DB_MULTIPLE_KEY_NEXT(kptr, key, + key2.data, key2.size, data2.data, data2.size); + /* No key/data pair in the bulk buffer */ + if (kptr == NULL) + return (0); + + for (;;) { + DB_MULTIPLE_KEY_NEXT(kptr, key, + key1.data, key1.size, data1.data, data1.size); + if (kptr == NULL) + break; + if (__db_compare_both(dbp, &key1, &data1, &key2, &data2) < 0) { + __db_errx(dbp->env, DB_STR("1170", + "The key/data pairs in the buffer are not sorted.")); + return (EINVAL); + } + key2.data = key1.data; + key2.size = key1.size; + data2.data = data1.data; + data2.size = data1.size; + } +#else + COMPQUIET(dbp, NULL); + COMPQUIET(key, NULL); +#endif + return (0); +} + +/* + * Check if the key/data pairs in the bulk buffer are sorted. + */ +static int +__bam_compress_check_sort_multiple(dbp, key, data) + DB *dbp; + DBT *key, *data; +{ +#ifdef DIAGNOSTIC + void *kptr, *dptr; + DBT key1, data1, key2, data2; + + memset(&key1, 0, sizeof(DBT)); + memset(&data1, 0, sizeof(DBT)); + memset(&key2, 0, sizeof(DBT)); + memset(&data2, 0, sizeof(DBT)); + + DB_MULTIPLE_INIT(kptr, key); + DB_MULTIPLE_INIT(dptr, data); + DB_MULTIPLE_NEXT(kptr, key, key2.data, key2.size); + DB_MULTIPLE_NEXT(dptr, data, data2.data, data2.size); + /* No key/data pair in the bulk buffer */ + if (kptr == NULL || dptr == NULL) + return (0); + + for (;;) { + DB_MULTIPLE_NEXT(kptr, key, key1.data, key1.size); + DB_MULTIPLE_NEXT(dptr, data, data1.data, data1.size); + if (kptr == NULL || dptr == NULL) + break; + if (__db_compare_both(dbp, &key1, &data1, &key2, &data2) < 0) { + __db_errx(dbp->env, DB_STR("1171", + "The key/data pairs in the buffer are not sorted.")); + return (EINVAL); + } + key2.data = key1.data; + key2.size = key1.size; + data2.data = data1.data; + data2.size = data1.size; + } +#else + COMPQUIET(dbp, NULL); + COMPQUIET(key, NULL); + COMPQUIET(data, NULL); +#endif + return (0); +} + +/* + * Check if the keys in the bulk buffer are sorted. + */ +static int +__bam_compress_check_sort_multiple_keyonly(dbp, key) + DB *dbp; + DBT *key; +{ +#ifdef DIAGNOSTIC + void *kptr; + DBT key1, key2; + + memset(&key1, 0, sizeof(DBT)); + memset(&key2, 0, sizeof(DBT)); + + DB_MULTIPLE_INIT(kptr, key); + DB_MULTIPLE_NEXT(kptr, key, key2.data, key2.size); + /* No DBT item in the bulk buffer */ + if (kptr == NULL) + return (0); + + for (;;) { + DB_MULTIPLE_NEXT(kptr, key, key1.data, key1.size); + if (kptr == NULL) + break; + if (__db_compare_both(dbp, &key1, NULL, &key2, NULL) < 0) { + __db_errx(dbp->env, DB_STR("1172", + "The DBT items in the buffer are not sorted")); + return (EINVAL); + } + key2.data = key1.data; + key2.size = key1.size; + } +#else + COMPQUIET(dbp, NULL); + COMPQUIET(key, NULL); +#endif + return (0); +} + #endif diff --git a/src/btree/bt_conv.c b/src/btree/bt_conv.c index 03a3867a..348ce5c2 100644 --- a/src/btree/bt_conv.c +++ b/src/btree/bt_conv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_curadj.c b/src/btree/bt_curadj.c index 1caab975..78606009 100644 --- a/src/btree/bt_curadj.c +++ b/src/btree/bt_curadj.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_cursor.c b/src/btree/bt_cursor.c index be1c9287..860c31ce 100644 --- a/src/btree/bt_cursor.c +++ b/src/btree/bt_cursor.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_delete.c b/src/btree/bt_delete.c index 6e1baa66..37496b3f 100644 --- a/src/btree/bt_delete.c +++ b/src/btree/bt_delete.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/btree/bt_method.c b/src/btree/bt_method.c index 68bb3a9b..5cf93d2e 100644 --- a/src/btree/bt_method.c +++ b/src/btree/bt_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_open.c b/src/btree/bt_open.c index 64618412..7be141c1 100644 --- a/src/btree/bt_open.c +++ b/src/btree/bt_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/btree/bt_put.c b/src/btree/bt_put.c index 8265b571..13316181 100644 --- a/src/btree/bt_put.c +++ b/src/btree/bt_put.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/btree/bt_rec.c b/src/btree/bt_rec.c index 511f44bf..026564b6 100644 --- a/src/btree/bt_rec.c +++ b/src/btree/bt_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -256,7 +256,7 @@ check_next: /* /* * Check the state of the split page. If its a rootsplit - * then thats the rootpage otherwise its the left page. + * then that's the rootpage otherwise its the left page. */ if (rootsplit) { DB_ASSERT(env, pgno == argp->ppgno); @@ -587,7 +587,7 @@ check_next: /* /* * Check the state of the split page. If its a rootsplit - * then thats the rootpage otherwise its the left page. + * then that's the rootpage otherwise its the left page. */ if (rootsplit) { DB_ASSERT(env, pgno == argp->ppgno); diff --git a/src/btree/bt_reclaim.c b/src/btree/bt_reclaim.c index c17a0d16..f465cc5a 100644 --- a/src/btree/bt_reclaim.c +++ b/src/btree/bt_reclaim.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -44,7 +44,7 @@ __bam_reclaim(dbp, ip, txn, flags) /* Walk the tree, freeing pages. */ ret = __bam_traverse(dbc, DB_LOCK_WRITE, - PGNO_INVALID, __db_reclaim_callback, (void*)(uintptr_t)flags); + PGNO_INVALID, __db_reclaim_callback, &flags); if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0) ret = t_ret; diff --git a/src/btree/bt_recno.c b/src/btree/bt_recno.c index d9162ab1..9356a742 100644 --- a/src/btree/bt_recno.c +++ b/src/btree/bt_recno.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_rsearch.c b/src/btree/bt_rsearch.c index af6f2b2a..36d1c667 100644 --- a/src/btree/bt_rsearch.c +++ b/src/btree/bt_rsearch.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/btree/bt_search.c b/src/btree/bt_search.c index e1054698..e809a852 100644 --- a/src/btree/bt_search.c +++ b/src/btree/bt_search.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -315,7 +315,7 @@ retry: if ((ret = __bam_get_root(dbc, start_pgno, slevel, flags, &stack)) != 0) lock = cp->csp->lock; set_stack = stack; /* - * Determine if we need to lock interiror nodes. + * Determine if we need to lock interior nodes. * If we have record numbers we always lock. Otherwise we only * need to do this if we are write locking and we are returning * a stack of nodes. SR_NEXT will eventually get a stack and @@ -710,7 +710,7 @@ lock_next: h = NULL; ret != DB_LOCK_DEADLOCK)) goto err; - /* Relase the parent if we are holding it. */ + /* Release the parent if we are holding it. */ if (parent_h != NULL && (ret = __memp_fput(mpf, dbc->thread_info, parent_h, dbc->priority)) != 0) @@ -734,7 +734,7 @@ lock_next: h = NULL; * free. If we are at the LEAF level we can * hold on to the lock if the page is still * of the right type. Otherwise we need to - * besure this page cannot move to an off page + * be sure this page cannot move to an off page * duplicate tree (which are not locked) and * masquerade as the page we want. */ diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c index fe27b947..8299c69a 100644 --- a/src/btree/bt_split.c +++ b/src/btree/bt_split.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -77,7 +77,7 @@ __bam_split(dbc, arg, root_pgnop) /* * First get a lock on the metadata page, we will have to allocate - * pages and cannot get a lock while we have the search tree pinnned. + * pages and cannot get a lock while we have the search tree pinned. */ pgno = PGNO_BASE_MD; diff --git a/src/btree/bt_stat.c b/src/btree/bt_stat.c index 9f1a65ee..668c4fdb 100644 --- a/src/btree/bt_stat.c +++ b/src/btree/bt_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -99,6 +99,14 @@ __bam_stat(dbc, spp, flags) if (ret != 0) goto err; + /* Discard the metadata page. */ + ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority); + meta = NULL; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + /* Walk the tree. */ if ((ret = __bam_traverse(dbc, DB_LOCK_READ, PGNO_INVALID, __bam_stat_callback, sp)) != 0) @@ -117,13 +125,16 @@ __bam_stat(dbc, spp, flags) write_meta = !F_ISSET(dbp, DB_AM_RDONLY) && (!MULTIVERSION(dbp) || dbc->txn != NULL); meta_only: - if (t->bt_meta != PGNO_BASE_MD || write_meta) { - ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority); - meta = NULL; - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; + if (meta == NULL || t->bt_meta != PGNO_BASE_MD || write_meta) { + if (meta != NULL) { + ret = __memp_fput(mpf, + dbc->thread_info, meta, dbc->priority); + meta = NULL; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + goto err; + } if ((ret = __db_lget(dbc, 0, t->bt_meta, write_meta ? DB_LOCK_WRITE : DB_LOCK_READ, @@ -176,18 +187,18 @@ meta_only: *(DB_BTREE_STAT **)spp = sp; err: /* Discard the second page. */ - if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) - ret = t_ret; if (h != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, h, dbc->priority)) != 0 && ret == 0) ret = t_ret; + if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) + ret = t_ret; /* Discard the metadata page. */ - if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) - ret = t_ret; if (meta != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, meta, dbc->priority)) != 0 && ret == 0) ret = t_ret; + if ((t_ret = __LPUT(dbc, metalock)) != 0 && ret == 0) + ret = t_ret; if (ret != 0 && sp != NULL) { __os_ufree(env, sp); diff --git a/src/btree/bt_upgrade.c b/src/btree/bt_upgrade.c index e0c5a407..c9123351 100644 --- a/src/btree/bt_upgrade.c +++ b/src/btree/bt_upgrade.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/btree/bt_verify.c b/src/btree/bt_verify.c index b1cc9a36..99354a58 100644 --- a/src/btree/bt_verify.c +++ b/src/btree/bt_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -52,16 +52,11 @@ __bam_vrfy_meta(dbp, vdp, meta, pgno, flags) return (ret); /* - * If VRFY_INCOMPLETE is not set, then we didn't come through - * __db_vrfy_pagezero and didn't incompletely - * check this page--we haven't checked it at all. - * Thus we need to call __db_vrfy_meta and check the common fields. - * - * If VRFY_INCOMPLETE is set, we've already done all the same work - * in __db_vrfy_pagezero, so skip the check. + * If we came through __db_vrfy_pagezero, we have already checked the + * common fields. However, we used the on-disk metadata page, it may + * have been stale. We now have the page from mpool, so check that. */ - if (!F_ISSET(pip, VRFY_INCOMPLETE) && - (ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { + if ((ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { if (ret == DB_VERIFY_BAD) isbad = 1; else @@ -914,9 +909,12 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pgno, nentries, ovflok, hasdups, flags) BKEYDATA *bk; BOVERFLOW *bo; BTREE *bt; + DB_MPOOLFILE *mpf; DBC *dbc; DBT dbta, dbtb, dup_1, dup_2, *p1, *p2, *tmp; ENV *env; + PAGE *child; + db_pgno_t cpgno; VRFY_PAGEINFO *pip; db_indx_t i, *inp; int adj, cmp, freedup_1, freedup_2, isbad, ret, t_ret; @@ -957,7 +955,38 @@ __bam_vrfy_itemorder(dbp, vdp, ip, h, pgno, nentries, ovflok, hasdups, flags) func = __bam_defcmp; if (dbp->bt_internal != NULL) { bt = (BTREE *)dbp->bt_internal; - if (bt->bt_compare != NULL) + if (TYPE(h) == P_IBTREE && (bt->bt_compare != NULL || + dupfunc != __bam_defcmp)) { + /* + * The problem here is that we cannot + * tell the difference between an off + * page duplicate internal page and + * a main database internal page. + * Walk down the tree to figure it out. + */ + mpf = dbp->mpf; + child = h; + while (TYPE(child) == P_IBTREE) { + bi = GET_BINTERNAL(dbp, child, 0); + cpgno = bi->pgno; + if (child != h && + (ret = __memp_fput(mpf, + vdp->thread_info, child, + DB_PRIORITY_UNCHANGED)) != 0) + goto err; + if ((ret = __memp_fget(mpf, + &cpgno, vdp->thread_info, + NULL, 0, &child)) != 0) + goto err; + } + if (TYPE(child) == P_LDUP) + func = dupfunc; + else if (bt->bt_compare != NULL) + func = bt->bt_compare; + if ((ret = __memp_fput(mpf, vdp->thread_info, + child, DB_PRIORITY_UNCHANGED)) != 0) + goto err; + } else if (bt->bt_compare != NULL) func = bt->bt_compare; } } @@ -1063,7 +1092,8 @@ retry: p1 = &dbta; * if overflow items are unsafe. */ overflow: if (!ovflok) { - F_SET(pip, VRFY_INCOMPLETE); + if (pip != NULL) + F_SET(pip, VRFY_INCOMPLETE); goto err; } @@ -1194,7 +1224,9 @@ overflow: if (!ovflok) { if (dup_1.data == NULL || dup_2.data == NULL) { DB_ASSERT(env, !ovflok); - F_SET(pip, VRFY_INCOMPLETE); + if (pip != NULL) + F_SET(pip, + VRFY_INCOMPLETE); goto err; } @@ -1204,7 +1236,8 @@ overflow: if (!ovflok) { * until we do the structure check * and see whether DUPSORT is set. */ - if (dupfunc(dbp, &dup_1, &dup_2) > 0) + if (dupfunc(dbp, &dup_1, &dup_2) > 0 && + pip != NULL) F_SET(pip, VRFY_DUPS_UNSORTED); if (freedup_1) diff --git a/src/btree/btree.src b/src/btree/btree.src index 6155d902..08e5a206 100644 --- a/src/btree/btree.src +++ b/src/btree/btree.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/bsearch.c b/src/clib/bsearch.c index b59ce5fd..3e55009a 100644 --- a/src/clib/bsearch.c +++ b/src/clib/bsearch.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -30,8 +30,8 @@ void *bsearch(key, base, nmemb, size, cmp) /* not doing a binary search, but searching linearly */ for (i=0; i < nmemb; i++) { - if (*(pid_t*)key - *((pid_t*)base + i) == 0) - return ((pid_t*)base + i); + if ((*cmp)(key, (const void *)((char *)base + i * size)) == 0) + return ((void *)((char *)base + i * size)); } return (NULL); diff --git a/src/clib/getcwd.c b/src/clib/getcwd.c index 5490f587..83e8b62d 100644 --- a/src/clib/getcwd.c +++ b/src/clib/getcwd.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1989, 1991, 1993 diff --git a/src/clib/getopt.c b/src/clib/getopt.c index 1ee2321e..ca98e7f1 100644 --- a/src/clib/getopt.c +++ b/src/clib/getopt.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1987, 1993, 1994 diff --git a/src/clib/isalpha.c b/src/clib/isalpha.c index 352dcf6c..6bf1ffb7 100644 --- a/src/clib/isalpha.c +++ b/src/clib/isalpha.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/isdigit.c b/src/clib/isdigit.c new file mode 100644 index 00000000..d1b2a65e --- /dev/null +++ b/src/clib/isdigit.c @@ -0,0 +1,28 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +/* + * isdigit -- + * + * PUBLIC: #ifndef HAVE_ISDIGIT + * PUBLIC: int isdigit __P((int)); + * PUBLIC: #endif + */ +int +isdigit(c) + int c; +{ + /* + * Depends on ASCII-like character ordering. + */ + return (c >= '0' && c <= '9' ? 1 : 0); +} diff --git a/src/clib/isprint.c b/src/clib/isprint.c index 64d79369..685e20ea 100644 --- a/src/clib/isprint.c +++ b/src/clib/isprint.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/isspace.c b/src/clib/isspace.c index 55a17f30..df450d3b 100644 --- a/src/clib/isspace.c +++ b/src/clib/isspace.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/memcmp.c b/src/clib/memcmp.c index d402996c..7fec827c 100644 --- a/src/clib/memcmp.c +++ b/src/clib/memcmp.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993 diff --git a/src/clib/memmove.c b/src/clib/memmove.c index a4bd7d97..34a181cc 100644 --- a/src/clib/memmove.c +++ b/src/clib/memmove.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993 diff --git a/src/clib/printf.c b/src/clib/printf.c index be8c4818..a2c01296 100644 --- a/src/clib/printf.c +++ b/src/clib/printf.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/raise.c b/src/clib/raise.c index 253444c0..ad0e567f 100644 --- a/src/clib/raise.c +++ b/src/clib/raise.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/snprintf.c b/src/clib/snprintf.c index ded44e22..6b31d850 100644 --- a/src/clib/snprintf.c +++ b/src/clib/snprintf.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/clib/strerror.c b/src/clib/strerror.c index 6637791c..62bd7dd5 100644 --- a/src/clib/strerror.c +++ b/src/clib/strerror.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1988, 1993 diff --git a/src/clib/time.c b/src/clib/time.c index debb661b..abc2ab2d 100644 --- a/src/clib/time.c +++ b/src/clib/time.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/clock.c b/src/common/clock.c index 720fcbf5..e1f917af 100644 --- a/src/common/clock.c +++ b/src/common/clock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/crypto_stub.c b/src/common/crypto_stub.c index 33b6ae62..95faebdb 100644 --- a/src/common/crypto_stub.c +++ b/src/common/crypto_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/db_byteorder.c b/src/common/db_byteorder.c index 24a5acfa..71428f0a 100644 --- a/src/common/db_byteorder.c +++ b/src/common/db_byteorder.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/db_compint.c b/src/common/db_compint.c index 180055a4..9f5ccf9a 100644 --- a/src/common/db_compint.c +++ b/src/common/db_compint.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" diff --git a/src/common/db_err.c b/src/common/db_err.c index 9d62559d..6edc37b6 100644 --- a/src/common/db_err.c +++ b/src/common/db_err.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -888,8 +888,12 @@ __db_check_txn(dbp, txn, assoc_locker, read_op) return (0); open_err: - __db_errx(env, DB_STR("0101", - "Transaction that opened the DB handle is still active")); + if (F2_ISSET(dbp, DB2_AM_EXCL)) + __db_errx(env, DB_STR("0209", +"Exclusive database handles can only have one active transaction at a time.")); + else + __db_errx(env, DB_STR("0101", + "Transaction that opened the DB handle is still active")); return (EINVAL); } diff --git a/src/common/db_getlong.c b/src/common/db_getlong.c index e1ae09e6..cac55a0e 100644 --- a/src/common/db_getlong.c +++ b/src/common/db_getlong.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/db_idspace.c b/src/common/db_idspace.c index a04deeb7..a9cbb1bf 100644 --- a/src/common/db_idspace.c +++ b/src/common/db_idspace.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/db_log2.c b/src/common/db_log2.c index 1edd8af6..9c929f84 100644 --- a/src/common/db_log2.c +++ b/src/common/db_log2.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 diff --git a/src/common/db_shash.c b/src/common/db_shash.c index f79e7023..a056e4b1 100644 --- a/src/common/db_shash.c +++ b/src/common/db_shash.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/dbt.c b/src/common/dbt.c index 4ae1c5a9..90409f2c 100644 --- a/src/common/dbt.c +++ b/src/common/dbt.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/mkpath.c b/src/common/mkpath.c index 575a584d..c684692c 100644 --- a/src/common/mkpath.c +++ b/src/common/mkpath.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/openflags.c b/src/common/openflags.c index 2c4d00e6..cec1f081 100644 --- a/src/common/openflags.c +++ b/src/common/openflags.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/os_method.c b/src/common/os_method.c index f0cfb4ff..1ee06d7a 100644 --- a/src/common/os_method.c +++ b/src/common/os_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/util_arg.c b/src/common/util_arg.c index 92824b33..73416cb7 100644 --- a/src/common/util_arg.c +++ b/src/common/util_arg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/util_cache.c b/src/common/util_cache.c index 5489e9cd..1206940b 100644 --- a/src/common/util_cache.c +++ b/src/common/util_cache.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/util_log.c b/src/common/util_log.c index ed50c5f1..d158d3f0 100644 --- a/src/common/util_log.c +++ b/src/common/util_log.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/util_sig.c b/src/common/util_sig.c index 6a71f4c1..02a0fcb2 100644 --- a/src/common/util_sig.c +++ b/src/common/util_sig.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/common/zerofill.c b/src/common/zerofill.c index 11bb018f..37662ddc 100644 --- a/src/common/zerofill.c +++ b/src/common/zerofill.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/crypto/aes_method.c b/src/crypto/aes_method.c index 22dfa823..47193539 100644 --- a/src/crypto/aes_method.c +++ b/src/crypto/aes_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * Some parts of this code originally written by Adam Stubblefield, * -- astubble@rice.edu. diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index d4b771c0..b731496f 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * Some parts of this code originally written by Adam Stubblefield * -- astubble@rice.edu diff --git a/src/db/crdel.src b/src/db/crdel.src index 02d80c8f..70473899 100644 --- a/src/db/crdel.src +++ b/src/db/crdel.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/crdel_rec.c b/src/db/crdel_rec.c index d63074364..08e7bae8 100644 --- a/src/db/crdel_rec.c +++ b/src/db/crdel_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -53,11 +53,11 @@ __crdel_metasub_recover(env, dbtp, lsnp, op, info) goto done; if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, 0, &pagep)) != 0) { - /* + /* * If this is an in-memory file, this might be OK. Also, heap * can get there through a truncate and we have to redo page 1 */ - if ((file_dbp->type == DB_HEAP || + if ((file_dbp->type == DB_HEAP || F_ISSET(file_dbp, DB_AM_INMEM)) && (ret = __memp_fget(mpf, &argp->pgno, ip, NULL, DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &pagep)) == 0) { diff --git a/src/db/db.c b/src/db/db.c index f8b7bacb..0d9d1e6e 100644 --- a/src/db/db.c +++ b/src/db/db.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -459,6 +459,13 @@ __env_setup(dbp, txn, fname, dname, id, flags) env = dbp->env; dbenv = env->dbenv; + /* + * When verifying an in-memory db, we need to pass dname to + * __env_mpool. That is the only time fname will be used. + */ + if (F_ISSET(dbp, DB_AM_INMEM) && F_ISSET(dbp, DB_AM_VERIFYING)) + fname = dname; + /* If we don't yet have an environment, it's time to create it. */ if (!F_ISSET(env, ENV_OPEN_CALLED)) { #if defined(HAVE_MIXED_SIZE_ADDRESSING) && (SIZEOF_CHAR_P == 8) @@ -479,8 +486,8 @@ __env_setup(dbp, txn, fname, dname, id, flags) } /* Join the underlying cache. */ - if ((!F_ISSET(dbp, DB_AM_INMEM) || dname == NULL) && - (ret = __env_mpool(dbp, fname, flags)) != 0) + if ((!F_ISSET(dbp, DB_AM_INMEM) || F_ISSET(dbp, DB_AM_VERIFYING) || + dname == NULL) && (ret = __env_mpool(dbp, fname, flags)) != 0) return (ret); /* We may need a per-thread mutex. */ @@ -1119,6 +1126,8 @@ never_opened: return (ret); if ((ret = __ham_db_create(dbp)) != 0) return (ret); + if ((ret = __heap_db_create(dbp)) != 0) + return (ret); if ((ret = __qam_db_create(dbp)) != 0) return (ret); diff --git a/src/db/db.src b/src/db/db.src index 2e8a08e2..879c7856 100644 --- a/src/db/db.src +++ b/src/db/db.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_am.c b/src/db/db_am.c index da2251cc..1cf3a505 100644 --- a/src/db/db_am.c +++ b/src/db/db_am.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -43,6 +43,7 @@ __db_cursor_int(dbp, ip, txn, dbtype, root, flags, locker, dbcp) { DBC *dbc; DBC_INTERNAL *cp; + DB_LOCKREQ req; ENV *env; db_threadid_t tid; int allocated, envlid, ret; @@ -306,6 +307,42 @@ __db_cursor_int(dbp, ip, txn, dbtype, root, flags, locker, dbcp) F_SET(dbc, DBC_RECOVER); if (F_ISSET(dbp, DB_AM_COMPENSATE)) F_SET(dbc, DBC_DONTLOCK); + /* + * If this database is exclusive then the cursor + * does not need to get locks. + */ + if (F2_ISSET(dbp, DB2_AM_EXCL)) { + F_SET(dbc, DBC_DONTLOCK); + if (IS_REAL_TXN(txn)&& !LF_ISSET(DBC_OPD | DBC_DUPLICATE)) { + /* + * Exclusive databases can only have one active + * transaction at a time since there are no internal + * locks to prevent one transaction from reading and + * writing another's uncommitted changes. + */ + if (dbp->cur_txn != NULL && dbp->cur_txn != txn) { + __db_errx(env, DB_STR("0749", +"Exclusive database handles can only have one active transaction at a time.")); + ret = EINVAL; + goto err; + } + /* Do not trade a second time. */ + if (dbp->cur_txn != txn) { + /* Trade the handle lock to the txn locker. */ + memset(&req, 0, sizeof(req)); + req.lock = dbp->handle_lock; + req.op = DB_LOCK_TRADE; + if ((ret = __lock_vec(env, txn->locker, 0, + &req, 1, 0)) != 0) + goto err; + dbp->cur_txn = txn; + dbp->cur_locker = txn->locker; + if ((ret = __txn_lockevent(env, txn, dbp, + &dbp->handle_lock, dbp->locker)) != 0) + goto err; + } + } + } #ifdef HAVE_REPLICATION /* * If we are replicating from a down rev version then we must @@ -361,7 +398,7 @@ __db_cursor_int(dbp, ip, txn, dbtype, root, flags, locker, dbcp) dbc->thread_info = ip; #ifdef DIAGNOSTIC if (dbc->locker != NULL) - ip->dbth_locker = + ip->dbth_locker = R_OFFSET(&(env->lk_handle->reginfo), dbc->locker); else ip->dbth_locker = INVALID_ROFF; @@ -399,6 +436,7 @@ __db_put(dbp, ip, txn, key, data, flags) DBT *key, *data; u_int32_t flags; { + DB_HEAP_RID rid; DBC *dbc; DBT tdata, tkey; ENV *env; @@ -505,6 +543,10 @@ __db_put(dbp, ip, txn, key, data, flags) tdata.data, tdata.size); if (bulk_kptr == NULL || bulk_ptr == NULL) break; + if (dbp->type == DB_HEAP) { + memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID)); + tkey.data = &rid; + } ret = __dbc_put(dbc, &tkey, &tdata, LF_ISSET(DB_OPFLAGS_MASK)); if (ret == 0) @@ -528,6 +570,10 @@ __db_put(dbp, ip, txn, key, data, flags) tkey.size, tdata.data, tdata.size); if (bulk_ptr == NULL) break; + if (dbp->type == DB_HEAP) { + memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID)); + tkey.data = &rid; + } ret = __dbc_put(dbc, &tkey, &tdata, LF_ISSET(DB_OPFLAGS_MASK)); if (ret == 0) @@ -560,6 +606,7 @@ __db_del(dbp, ip, txn, key, flags) DBT *key; u_int32_t flags; { + DB_HEAP_RID rid; DBC *dbc; DBT data, tkey; void *bulk_ptr; @@ -630,6 +677,11 @@ bulk_next: if (dbp->type == DB_QUEUE || dbp->type == DB_RECNO) tkey.data, tkey.size, data.data, data.size); if (bulk_ptr == NULL) goto err; + if (dbp->type == DB_HEAP) { + memcpy(&rid, tkey.data, sizeof(DB_HEAP_RID)); + tkey.data = &rid; + } + } /* We're not interested in the data -- do not return it. */ @@ -979,7 +1031,7 @@ __db_secondary_close(sdbp, flags) int doclose; /* - * If the opening trasaction is rolled back then the db handle + * If the opening transaction is rolled back then the db handle * will have already been refreshed, we just need to call * __db_close to free the data. */ diff --git a/src/db/db_backup.c b/src/db/db_backup.c new file mode 100644 index 00000000..66d7382a --- /dev/null +++ b/src/db/db_backup.c @@ -0,0 +1,775 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/db_am.h" +#include "dbinc/heap.h" +#include "dbinc/mp.h" +#include "dbinc/partition.h" + +#ifdef HAVE_QUEUE +#include "dbinc/qam.h" +#endif + +static void save_error __P((const DB_ENV *, const char *, const char *)); +static int backup_read_log_dir __P((DB_ENV *, const char *, int *, u_int32_t)); +static int backup_read_data_dir + __P((DB_ENV *, DB_THREAD_INFO *, const char *, const char *, u_int32_t)); +static int backup_dir_clean + __P((DB_ENV *, const char *, const char *, int *, u_int32_t)); +static int backup_data_copy + __P((DB_ENV *, const char *, const char *, const char *, int)); + +/* + * __db_dbbackup_pp -- + * Copy a database file coordinated with mpool. + * + * PUBLIC: int __db_dbbackup_pp __P((DB_ENV *, + * PUBLIC: const char *, const char *, u_int32_t)); + */ +int +__db_dbbackup_pp(dbenv, dbfile, target, flags) + DB_ENV *dbenv; + const char *dbfile, *target; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + int ret; + + if ((ret = __db_fchk(dbenv->env, + "DB_ENV->dbbackup", flags, DB_EXCL)) != 0) + return (ret); + ENV_ENTER(dbenv->env, ip); + + ret = __db_dbbackup(dbenv, ip, dbfile, target, flags); + + ENV_LEAVE(dbenv->env, ip); + return (ret); +} + +/* + * __db_dbbackup -- + * Copy a database file coordinated with mpool. + * + * PUBLIC: int __db_dbbackup __P((DB_ENV *, DB_THREAD_INFO *, + * PUBLIC: const char *, const char *, u_int32_t)); + */ +int +__db_dbbackup(dbenv, ip, dbfile, target, flags) + DB_ENV *dbenv; + DB_THREAD_INFO *ip; + const char *dbfile, *target; + u_int32_t flags; +{ + DB *dbp; + DB_FH *fp; + void *handle; + int ret, retry_count, t_ret; + + dbp = NULL; + retry_count = 0; + +retry: if ((ret = __db_create_internal(&dbp, dbenv->env, 0)) == 0 && + (ret = __db_open(dbp, ip, NULL, dbfile, NULL, + DB_UNKNOWN, DB_AUTO_COMMIT | DB_RDONLY, 0, PGNO_BASE_MD)) != 0) { + if (ret == DB_LOCK_DEADLOCK || ret == DB_LOCK_NOTGRANTED) { + (void)__db_close(dbp, NULL, DB_NOSYNC); + dbp = NULL; + if (++retry_count > 100) + return (ret); + __db_errx(dbenv->env, DB_STR_A("0702", + "Deadlock while opening %s, retrying", "%s"), dbfile); + __os_yield(dbenv->env, 1, 0); + goto retry; + } + } + + if (ret == 0) { + if ((ret = __memp_backup_open(dbenv->env, + dbp->mpf, dbfile, target, flags, &fp, &handle)) == 0) { + if (dbp->type == DB_HEAP) + ret = __heap_backup( + dbenv, dbp, ip, fp, handle, flags); + else + ret = __memp_backup_mpf( + dbenv->env, dbp->mpf, + ip, 0, dbp->mpf->mfp->last_pgno, + fp, handle, flags); + } + if ((t_ret = __memp_backup_close(dbenv->env, + dbp->mpf, dbfile, fp, handle)) != 0 && ret == 0) + ret = t_ret; + } + +#ifdef HAVE_QUEUE + /* + * For compatibility with the 5.2 and patch versions of db_copy + * dump the queue extents here. + */ + if (ret == 0 && dbp->type == DB_QUEUE) + ret = __qam_backup_extents(dbp, ip, target, flags); +#endif + + if (dbp != NULL && + (t_ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0 && ret == 0) + ret = t_ret; + + if (ret != 0) + __db_err(dbenv->env, ret, "Backup Failed"); + return (ret); +} + +/* + * backup_dir_clean -- + * Clean out the backup directory. + */ +static int +backup_dir_clean(dbenv, backup_dir, log_dir, remove_maxp, flags) + DB_ENV *dbenv; + const char *backup_dir, *log_dir; + int *remove_maxp; + u_int32_t flags; +{ + ENV *env; + int cnt, fcnt, ret, v; + const char *dir; + char **names, buf[DB_MAXPATHLEN], path[DB_MAXPATHLEN]; + + env = dbenv->env; + + /* We may be cleaning a log directory separate from the target. */ + if (log_dir != NULL) { + if ((ret = __os_concat_path(buf, + sizeof(buf), backup_dir, log_dir)) != 0) { + buf[sizeof(buf) - 1] = '\0'; + __db_errx(env, DB_STR_A("0717", + "%s: path too long", "%s"), buf); + return (EINVAL); + } + dir = buf; + } else + dir = backup_dir; + + /* Get a list of file names. */ + if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) { + if (log_dir != NULL && !LF_ISSET(DB_BACKUP_UPDATE)) + return (0); + __db_err(env, + ret, DB_STR_A("0718", "%s: directory read", "%s"), dir); + return (ret); + } + for (cnt = fcnt; --cnt >= 0;) { + /* + * Skip non-log files (if update was specified). + */ + if (!IS_LOG_FILE(names[cnt])) { + if (LF_ISSET(DB_BACKUP_UPDATE)) + continue; + } else { + /* Track the highest-numbered log file removed. */ + v = atoi(names[cnt] + sizeof(LFPREFIX) - 1); + if (*remove_maxp < v) + *remove_maxp = v; + } + if ((ret = __os_concat_path(path, + sizeof(path), dir, names[cnt])) != 0) { + path[sizeof(path) - 1] = '\0'; + __db_errx(env, DB_STR_A("0714", + "%s: path too long", "%s"), path); + return (EINVAL); + } + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msg(env, DB_STR_A("0715", "removing %s", + "%s"), path); + if ((ret = __os_unlink(env, path, 0)) != 0) + return (ret); + } + + __os_dirfree(env, names, fcnt); + + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP) && *remove_maxp != 0) + __db_msg(env, DB_STR_A("0719", + "highest numbered log file removed: %d", "%d"), + *remove_maxp); + + return (0); +} + +/* + * backup_data_copy -- + * Copy a non-database file into the backup directory. + */ +static int +backup_data_copy(dbenv, file, from_dir, to_dir, log) + DB_ENV *dbenv; + const char *file, *from_dir, *to_dir; + int log; +{ + DB_BACKUP *backup; + DB_FH *rfhp, *wfhp; + ENV *env; + u_int32_t gigs, off; + size_t nr, nw; + int ret, t_ret; + char *buf; + void *handle; + char from[DB_MAXPATHLEN], to[DB_MAXPATHLEN]; + + rfhp = wfhp = NULL; + handle = NULL; + buf = NULL; + env = dbenv->env; + backup = env->backup_handle; + + if ((ret = __os_concat_path(from, + sizeof(from), from_dir, file)) != 0) { + from[sizeof(from) - 1] = '\0'; + __db_errx(env, DB_STR_A("0728", + "%s: path too long", "%s"), from); + goto err; + } + if ((ret = __os_concat_path(to, + sizeof(to), to_dir, file)) != 0) { + to[sizeof(to) - 1] = '\0'; + __db_errx(env, DB_STR_A("0729", + "%s: path too long", "%s"), to); + goto err; + } + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msg(env, DB_STR_A("0726", + "copying %s to %s", "%s %s"), from, to); + + if ((ret = __os_malloc(env, MEGABYTE, &buf)) != 0) { + __db_err(env, ret, DB_STR_A("0727", + "%lu buffer allocation", "%lu"), (u_long)MEGABYTE); + return (ret); + } + + /* Open the input file. */ + if ((ret = __os_open(env, from, 0, DB_OSO_RDONLY, 0, &rfhp)) != 0) { + if (ret == ENOENT && !log) { + ret = 0; + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msg(env, DB_STR_A("0730", + "%s%c%s not present", "%s %c %s"), + from_dir, PATH_SEPARATOR[0], file); + goto done; + } + __db_err(env, ret, "%s", buf); + goto err; + } + + /* Open the output file. */ + if (backup != NULL && backup->open != NULL) + ret = backup->open(env->dbenv, file, to_dir, &handle); + else { + if ((ret = __os_open(env, to, 0, + DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &wfhp)) != 0) { + __db_err(env, ret, "%s", to); + goto err; + } + } + + off = 0; + gigs = 0; + /* Copy the data. */ + while ((ret = __os_read(env, rfhp, buf, MEGABYTE, &nr)) == 0 && + nr > 0) { + if (backup != NULL && backup->write != NULL) { + if ((ret = backup->write(env->dbenv, gigs, + off, (u_int32_t)nr, (u_int8_t *)buf, handle)) != 0) + break; + } else { + if ((ret = __os_write(env, wfhp, buf, nr, &nw)) != 0) + break; + if (nr != nw) { + ret = EIO; + break; + } + } + off += (u_int32_t)nr; + if (off >= GIGABYTE) { + gigs++; + off -= GIGABYTE; + } + } + if (ret != 0) + __db_err(env, ret, DB_STR("0748", "Write failed.")); + +err: +done: if (buf != NULL) + __os_free(env, buf); + + if (backup != NULL && backup->close != NULL && + (t_ret = backup->close(env->dbenv, file, handle)) != 0 && ret != 0) + ret = t_ret; + if (rfhp != NULL && + (t_ret = __os_closehandle(env, rfhp)) != 0 && ret == 0) + ret = t_ret; + + /* We may be running on a remote filesystem; force the flush. */ + if (ret == 0 && wfhp != NULL) { + ret = __os_fsync(env, wfhp); + if (ret != 0) + __db_err(env, ret, DB_STR("0731", "Sync failed")); + } + if (wfhp != NULL && + (t_ret = __os_closehandle(env, wfhp)) != 0 && ret == 0) + ret = t_ret; + return (ret); +} + +static void save_error(dbenv, prefix, errstr) + const DB_ENV *dbenv; + const char *prefix; + const char *errstr; +{ + COMPQUIET(prefix, NULL); + if (DB_GLOBAL(saved_errstr) != NULL) + __os_free(dbenv->env, DB_GLOBAL(saved_errstr)); + (void)__os_strdup(dbenv->env, errstr, &DB_GLOBAL(saved_errstr)); +} + +/* + * backup_read_data_dir -- + * Read a directory looking for databases to copy. + */ +static int +backup_read_data_dir(dbenv, ip, dir, backup_dir, flags) + DB_ENV *dbenv; + DB_THREAD_INFO *ip; + const char *dir, *backup_dir; + u_int32_t flags; +{ + DB_MSGBUF mb; + ENV *env; + FILE *savefile; + int fcnt, ret; + size_t cnt; + const char *bd; + char **names, buf[DB_MAXPATHLEN], bbuf[DB_MAXPATHLEN]; + void (*savecall) (const DB_ENV *, const char *, const char *); + + env = dbenv->env; + memset(bbuf, 0, sizeof(bbuf)); + + bd = backup_dir; + if (!LF_ISSET(DB_BACKUP_SINGLE_DIR) && dir != env->db_home) { + cnt = sizeof(bbuf); + /* Build a path name to the destination. */ + if ((ret = __os_concat_path(bbuf, sizeof(bbuf), + backup_dir, dir)) != 0 || + (((cnt = strlen(bbuf)) == sizeof(bbuf) || + (cnt == sizeof(bbuf) - 1 && + strchr(PATH_SEPARATOR, bbuf[cnt - 1]) == NULL)) && + LF_ISSET(DB_CREATE))) { + bbuf[sizeof(bbuf) - 1] = '\0'; + __db_errx(env, DB_STR_A("0720", + "%s: path too long", "%s"), bbuf); + return (1); + } + + /* Create the path. */ + if (LF_ISSET(DB_CREATE)) { + if (strchr(PATH_SEPARATOR, bbuf[cnt - 1]) == NULL) + bbuf[cnt] = PATH_SEPARATOR[0]; + + if ((ret = __db_mkpath(env, bbuf)) != 0) { + __db_err(env, ret, DB_STR_A("0721", + "%s: cannot create", "%s"), bbuf); + return (ret); + } + /* step on the trailing '/' */ + bbuf[cnt] = '\0'; + } + bd = bbuf; + + } + if (!__os_abspath(dir) && dir != env->db_home) { + /* Build a path name to the source. */ + if ((ret = __os_concat_path(buf, + sizeof(buf), env->db_home, dir)) != 0) { + buf[sizeof(buf) - 1] = '\0'; + __db_errx(env, DB_STR_A("0722", + "%s: path too long", "%s"), buf); + return (EINVAL); + } + dir = buf; + } + /* Get a list of file names. */ + if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) { + __db_err(env, ret, DB_STR_A("0723", "%s: directory read", + "%s"), dir); + return (ret); + } + for (cnt = (size_t)fcnt; cnt-- > 0;) { + /* + * Skip files in DB's name space, except replication dbs. + */ + if (IS_LOG_FILE(names[cnt])) + continue; + if (IS_DB_FILE(names[cnt]) && !IS_REP_FILE(names[cnt]) +#ifdef HAVE_PARTITION + && !IS_PARTITION_DB_FILE(names[cnt]) +#endif + ) + continue; + + /* + * Skip DB_CONFIG. + */ + if (LF_ISSET(DB_BACKUP_SINGLE_DIR) && + !strncmp(names[cnt], "DB_CONFIG", sizeof("DB_CONFIG"))) + continue; + + /* + * Copy the database. + */ + + DB_MSGBUF_INIT(&mb); + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msgadd(env, &mb, DB_STR_A("0724", + "copying database %s%c%s to %s%c%s", + "%s%c%s %s%c%s"), + dir, PATH_SEPARATOR[0], names[cnt], + bd, PATH_SEPARATOR[0], names[cnt]); + + /* + * Suppress errors on non-db files. + */ + savecall = dbenv->db_errcall; + dbenv->db_errcall = save_error; + savefile = dbenv->db_errfile; + dbenv->db_errfile = NULL; + + ret = __db_dbbackup(dbenv, ip, names[cnt], bd, flags); + + dbenv->db_errcall = savecall; + dbenv->db_errfile = savefile; + + /* The file might not be a database. */ + if (ret == ENOENT || ret == EINVAL) { + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) { + __db_msgadd(env, &mb, " -- Not a database"); + DB_MSGBUF_FLUSH(env, &mb); + } + if (LF_ISSET(DB_BACKUP_FILES)) + ret = backup_data_copy( + dbenv, names[cnt], dir, bd, 0); + else + ret = 0; + } else if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + DB_MSGBUF_FLUSH(env, &mb); + + if (ret != 0) { + if (DB_GLOBAL(saved_errstr) != NULL) { + __db_errx(env, "%s", DB_GLOBAL(saved_errstr)); + __os_free(env, DB_GLOBAL(saved_errstr)); + DB_GLOBAL(saved_errstr) = NULL; + } + break; + } + } + + __os_dirfree(env, names, fcnt); + + return (ret); +} + +/* + * backup_read_log_dir -- + * Read a directory looking for log files to copy. + */ +static int +backup_read_log_dir(dbenv, backup_dir, copy_minp, flags) + DB_ENV *dbenv; + const char *backup_dir; + int *copy_minp; + u_int32_t flags; +{ + ENV *env; + u_int32_t aflag; + size_t cnt; + int ret, update, v; + const char *backupd; + char **begin, **names, *logd; + char from[DB_MAXPATHLEN], to[DB_MAXPATHLEN]; + + env = dbenv->env; + ret = 0; + begin = NULL; + memset(to, 0, sizeof(to)); + + /* + * Figure out where the log files are and create the log + * destination directory if necessary. + */ + backupd = backup_dir; + if ((logd = dbenv->db_log_dir) == NULL) + logd = env->db_home; + else { + if (!LF_ISSET(DB_BACKUP_SINGLE_DIR)) { + cnt = sizeof(to); + if ((ret = __os_concat_path(to, + sizeof(to), backup_dir, logd)) != 0 || + (((cnt = strlen(to)) == sizeof(to) || + (cnt == sizeof(to) - 1 && + strchr(PATH_SEPARATOR, to[cnt - 1]) == NULL)) && + LF_ISSET(DB_CREATE))) { + to[sizeof(to) - 1] = '\0'; + __db_errx(env, DB_STR_A("0733", + "%s: path too long", "%s"), to); + goto err; + } + if (LF_ISSET(DB_CREATE)) { + if (strchr(PATH_SEPARATOR, to[cnt - 1]) == NULL) + to[cnt] = PATH_SEPARATOR[0]; + + if ((ret = __db_mkpath(env, to)) != 0) { + __db_err(env, ret, DB_STR_A("0734", + "%s: cannot create", "%s"), to); + goto err; + } + to[cnt] = '\0'; + } + if ((ret = __os_strdup(env, to, (void*) &backupd)) != 0) + goto err; + } + if (!__os_abspath(logd)) { + if ((ret = __os_concat_path(from, + sizeof(from), env->db_home, logd)) != 0) { + from[sizeof(from) - 1] = '\0'; + __db_errx(env, DB_STR_A("0732", + "%s: path too long", "%s"), from); + goto err; + } + if ((ret = __os_strdup(env, from, &logd)) != 0) + goto err; + } + } + + update = LF_ISSET(DB_BACKUP_UPDATE); +again: aflag = DB_ARCH_LOG; + + /* + * If this is an update and we are deleting files, first process + * those files that can be removed, then repeat with the rest. + */ + if (update) + aflag = 0; + + /* Flush the log to get latest info. */ + if ((ret = __log_flush(env, NULL)) != 0) { + __db_err(env, ret, DB_STR("0735", "Can't flush log")); + goto err; + } + + /* Get a list of file names to be copied. */ + if ((ret = __log_archive(env, &names, aflag)) != 0) { + __db_err(env, ret, DB_STR("0736", "Can't get log file names")); + goto err; + } + if (names == NULL) + goto done; + begin = names; + for (; *names != NULL; names++) { + /* Track the lowest-numbered log file copied. */ + v = atoi(*names + sizeof(LFPREFIX) - 1); + if (*copy_minp == 0 || *copy_minp > v) + *copy_minp = v; + + if ((ret = __os_concat_path(from, + sizeof(from), logd, *names)) != 0) { + from[sizeof(from) - 1] = '\0'; + __db_errx(env, DB_STR_A("0737", + "%s: path too long", "%s"), from); + goto err; + } + + /* + * If we're going to remove the file, attempt to rename it + * instead of copying and then removing. The likely failure + * is EXDEV (source and destination are on different volumes). + * Fall back to a copy, regardless of the error. We don't + * worry about partial contents, the copy truncates the file + * on open. + */ + if (update) { + if ((ret = __os_concat_path(to, + sizeof(to), backupd, *names)) != 0) { + to[sizeof(to) - 1] = '\0'; + __db_errx(env, DB_STR_A("0738", + "%s: path too long", "%s"), to); + goto err; + } + if (__os_rename(env, from, to, 1) == 0) { + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msg(env, DB_STR_A("0739", + "moving %s to %s", + "%s %s"), from, to); + continue; + } + } + + /* Copy the file. */ + if (backup_data_copy(dbenv, *names, logd, backupd, 1) != 0) { + ret = 1; + goto err; + } + + if (update) { + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP)) + __db_msg(env, DB_STR_A("0740", + "removing %s", "%s"), from); + if ((ret = __os_unlink(env, from, 0)) != 0) { + __db_err(env, ret, DB_STR_A("0741", + "unlink of %s failed", "%s"), from); + goto err; + } + } + + } + + __os_ufree(env, begin); + begin = NULL; +done: if (update) { + update = 0; + goto again; + } + + if (FLD_ISSET(dbenv->verbose, DB_VERB_BACKUP) && *copy_minp != 0) + __db_msg(env, DB_STR_A("0742", + "lowest numbered log file copied: %d", "%d"), + *copy_minp); +err: if (logd != dbenv->db_log_dir && logd != env->db_home) + __os_free(env, logd); + if (backupd != NULL && backupd != backup_dir) + __os_free(env, (void *)backupd); + if (begin != NULL) + __os_ufree(env, begin); + + return (ret); +} + +/* + * __db_backup -- + * Backup databases in the enviornment. + * + * PUBLIC: int __db_backup __P((DB_ENV *, const char *, u_int32_t)); + */ +int +__db_backup(dbenv, target, flags) + DB_ENV *dbenv; + const char *target; + u_int32_t flags; +{ + DB_THREAD_INFO *ip; + ENV *env; + int copy_min, remove_max, ret; + char **dir; + + env = dbenv->env; + remove_max = copy_min = 0; + +#undef OKFLAGS +#define OKFLAGS \ + (DB_CREATE | DB_EXCL | DB_BACKUP_FILES | DB_BACKUP_SINGLE_DIR | \ + DB_BACKUP_UPDATE | DB_BACKUP_NO_LOGS | DB_BACKUP_CLEAN) + + if ((ret = __db_fchk(env, "DB_ENV->backup", flags, OKFLAGS)) != 0) + return (ret); + + if (target == NULL) { + __db_errx(env, + DB_STR("0716", "Target directory may not be null.")); + return (EINVAL); + } + + /* + * If the target directory for the backup does not exist, create it + * with mode read-write-execute for the owner. Ignore errors here, + * it's simpler and more portable to just always try the create. If + * there's a problem, we'll fail with reasonable errors later. + */ + if (LF_ISSET(DB_CREATE)) + (void)__os_mkdir(NULL, target, DB_MODE_700); + + if (LF_ISSET(DB_BACKUP_CLEAN)) { + if (!LF_ISSET(DB_BACKUP_SINGLE_DIR) && + dbenv->db_log_dir != NULL && + (ret = backup_dir_clean(dbenv, target, + dbenv->db_log_dir, &remove_max, flags)) != 0) + return (ret); + if ((ret = backup_dir_clean(dbenv, + target, NULL, &remove_max, flags)) != 0) + return (ret); + + } + + ENV_ENTER(env, ip); + + /* + * If the UPDATE option was not specified, copy all database + * files found in the database environment home directory and + * data directories.. + */ + if ((ret = __env_set_backup(env, 1)) != 0) + goto end; + F_SET(dbenv, DB_ENV_HOTBACKUP); + if (!LF_ISSET(DB_BACKUP_UPDATE)) { + if ((ret = backup_read_data_dir(dbenv, + ip, env->db_home, target, flags)) != 0) + goto err; + for (dir = dbenv->db_data_dir; + dir != NULL && *dir != NULL; ++dir) { + /* + * Don't allow absolute path names taken from the + * enviroment -- running recovery with them would + * corrupt the source files. + */ + if (!LF_ISSET(DB_BACKUP_SINGLE_DIR) + && __os_abspath(*dir)) { + __db_errx(env, DB_STR_A("0725", +"data directory '%s' is absolute path, not permitted unless backup is to a single directory", + "%s"), *dir); + ret = EINVAL; + goto err; + } + if ((ret = backup_read_data_dir( + dbenv, ip, *dir, target, flags)) != 0) + goto err; + } + } + + /* + * Copy all log files found in the log directory. + * The log directory defaults to the home directory. + */ + if ((ret = backup_read_log_dir(dbenv, target, ©_min, flags)) != 0) + goto err; + /* + * If we're updating a snapshot, the lowest-numbered log file copied + * into the backup directory should be less than, or equal to, the + * highest-numbered log file removed from the backup directory during + * cleanup. + */ + if (LF_ISSET(DB_BACKUP_UPDATE) && remove_max < copy_min && + !(remove_max == 0 && copy_min == 1)) { + __db_errx(env, DB_STR_A("0743", +"the largest log file removed (%d) must be greater than or equal the smallest log file copied (%d)", + "%d %d"), remove_max, copy_min); + ret = EINVAL; + } + +err: F_CLR(dbenv, DB_ENV_HOTBACKUP); + (void)__env_set_backup(env, 0); +end: ENV_LEAVE(env, ip); + return (ret); +} diff --git a/src/db/db_cam.c b/src/db/db_cam.c index 76b0c6ee..6ee8b579 100644 --- a/src/db/db_cam.c +++ b/src/db/db_cam.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1849,7 +1849,7 @@ __dbc_put_primary(dbc, key, data, flags) if ((ret = __dbc_put_append(dbc, key, data, &put_state, flags)) != 0) goto err; - } + } /* * PUT_NOOVERWRITE with secondaries is a troublesome case. We need @@ -1968,17 +1968,19 @@ err: (t_ret = __db_s_done(sdbp, dbc->txn)) != 0 && ret == 0) ret = t_ret; - for (skeyp = all_skeys; skeyp - all_skeys < s_count; skeyp++) { - if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) { - for (nskey = skeyp->size, tskeyp = (DBT *)skeyp->data; - nskey > 0; - nskey--, tskeyp++) - FREE_IF_NEEDED(env, tskeyp); + if (all_skeys != NULL) { + for (skeyp = all_skeys; skeyp - all_skeys < s_count; skeyp++) { + if (F_ISSET(skeyp, DB_DBT_MULTIPLE)) { + for (nskey = skeyp->size, + tskeyp = (DBT *)skeyp->data; + nskey > 0; + nskey--, tskeyp++) + FREE_IF_NEEDED(env, tskeyp); + } + FREE_IF_NEEDED(env, skeyp); } - FREE_IF_NEEDED(env, skeyp); - } - if (all_skeys != NULL) __os_free(env, all_skeys); + } return (ret); } @@ -2456,13 +2458,14 @@ __dbc_pget(dbc, skey, pkey, data, flags) { DB *pdbp, *sdbp; DBC *dbc_n, *pdbc; - DBT nullpkey; + DBT nullpkey, *save_data; u_int32_t save_pkey_flags, tmp_flags, tmp_read_locking, tmp_rmw; int pkeymalloc, ret, t_ret; sdbp = dbc->dbp; pdbp = sdbp->s_primary; dbc_n = NULL; + save_data = NULL; pkeymalloc = t_ret = 0; /* @@ -2564,13 +2567,17 @@ __dbc_pget(dbc, skey, pkey, data, flags) break; } - if (F_ISSET(dbc, DBC_PARTITIONED | DBC_TRANSIENT)) + if (dbc->internal->opd != NULL || + F_ISSET(dbc, DBC_PARTITIONED | DBC_TRANSIENT)) { dbc_n = dbc; - else { + save_data = dbc_n->rdata; + } else { if ((ret = __dbc_dup(dbc, &dbc_n, tmp_flags)) != 0) return (ret); F_SET(dbc_n, DBC_TRANSIENT); } + dbc_n->rdata = dbc->rkey; + dbc_n->rkey = dbc->rskey; if (tmp_rmw) F_SET(dbc_n, DBC_RMW); @@ -2585,8 +2592,6 @@ __dbc_pget(dbc, skey, pkey, data, flags) SWAP_IF_NEEDED(sdbp, pkey); retry: /* Step 1. */ - dbc_n->rdata = dbc->rkey; - dbc_n->rkey = dbc->rskey; ret = __dbc_get(dbc_n, skey, pkey, flags); /* Restore pkey's flags in case we stomped the PARTIAL flag. */ pkey->flags = save_pkey_flags; @@ -2670,6 +2675,7 @@ retry: /* Step 1. */ F_SET(pdbc, DBC_TRANSIENT); SET_RET_MEM(pdbc, dbc); ret = __dbc_get(pdbc, pkey, data, DB_SET); + DB_ASSERT(pdbp->env, ret != DB_PAGE_NOTFOUND); /* * If the item wasn't found in the primary, this is a bug; our @@ -2682,7 +2688,7 @@ retry: /* Step 1. */ ret = t_ret; else if (ret == DB_NOTFOUND) { - if (!F_ISSET(pdbc, DBC_READ_UNCOMMITTED)) + if (!F_ISSET(dbc, DBC_READ_UNCOMMITTED)) ret = __db_secondary_corrupt(pdbp); else switch (flags) { case DB_GET_BOTHC: @@ -2692,7 +2698,7 @@ retry: /* Step 1. */ case DB_PREV: case DB_PREV_DUP: case DB_PREV_NODUP: - PERFMON5(env, race, dbc_get, + PERFMON5(pdbp->env, race, dbc_get, sdbp->fname, sdbp->dname, ret, flags, pkey); goto retry; default: @@ -2701,6 +2707,10 @@ retry: /* Step 1. */ } err: /* Cleanup and cursor resolution. */ + if (dbc_n == dbc) { + dbc_n->rkey = dbc_n->rdata; + dbc_n->rdata = save_data; + } if ((t_ret = __dbc_cleanup(dbc, dbc_n, ret)) != 0 && ret == 0) ret = t_ret; if (pkeymalloc) { diff --git a/src/db/db_cds.c b/src/db/db_cds.c index 2e157624..185d5487 100644 --- a/src/db/db_cds.c +++ b/src/db/db_cds.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_compact.c b/src/db/db_compact.c index f4975d61..d0f4801e 100644 --- a/src/db/db_compact.c +++ b/src/db/db_compact.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -373,13 +373,13 @@ __db_free_freelist(dbp, ip, txn) ret = __memp_free_freelist(dbp->mpf); -err: if ((t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) +err: if (dbc != NULL && (t_ret = __LPUT(dbc, lock)) != 0 && ret == 0) ret = t_ret; if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) ret = t_ret; - if (auto_commit && __txn_abort(txn) != 0 && ret == 0) + if (auto_commit && (t_ret = __txn_abort(txn)) != 0 && ret == 0) ret = t_ret; return (ret); @@ -668,6 +668,7 @@ __db_truncate_root(dbc, ppg, indx, pgnop, tlen) dbp = dbc->dbp; + DB_ASSERT(dbc->dbp->env, IS_DIRTY(ppg)); if ((ret = __memp_fget(dbp->mpf, pgnop, dbc->thread_info, dbc->txn, 0, &page)) != 0) goto err; @@ -789,6 +790,8 @@ __db_find_free(dbc, type, size, bstart, freep) goto err; } start = i; + if (size == 1) + goto found; while (i < nelems - 1 && list[i] + 1 == list[i + 1]) { i++; if (i - start == size - 1) @@ -1066,6 +1069,8 @@ __db_move_metadata(dbc, metap, c_data) ret = __txn_lockevent(dbp->env, dbp->cur_txn, dbp, &dbp->handle_lock, dbp->locker); } + if (dbp->log_filename != NULL) + dbp->log_filename->meta_pgno = dbp->meta_pgno; if (dbp->type == DB_HASH) { ht = dbp->h_internal; ht->meta_pgno = dbp->meta_pgno; @@ -1076,7 +1081,6 @@ __db_move_metadata(dbc, metap, c_data) bt->revision = ++dbp->mpf->mfp->revision; } - err: if ((t_ret = __db_close(mdbp, dbc->txn, DB_NOSYNC)) != 0 && ret == 0) ret = t_ret; return (ret); diff --git a/src/db/db_conv.c b/src/db/db_conv.c index 4c3e7f89..210b4d6e 100644 --- a/src/db/db_conv.c +++ b/src/db/db_conv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -847,7 +847,7 @@ __db_recordswap(op, size, hdr, data, pgin) case P_HASH: case P_HASH_UNSORTED: switch (OP_MODE_GET(op)) { - /* KEYDATA and DUPLICATE records do not inclued the header. */ + /* KEYDATA and DUPLICATE records do not include the header. */ case H_KEYDATA: break; case H_DUPLICATE: diff --git a/src/db/db_copy.c b/src/db/db_copy.c index 2722c9d3..359c74be 100644 --- a/src/db/db_copy.c +++ b/src/db/db_copy.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -11,15 +11,11 @@ #include "dbinc/db_page.h" #include "dbinc/db_am.h" -#ifdef HAVE_QUEUE -#include "dbinc/qam.h" -static int copy_queue_extents __P((DB *, const char *, const char *)); -#endif - - /* * db_copy -- - * Copy a database file using mpool. + * Copy a database file coordinated with mpool. + * This is for backward compatibility to the quick fix in 5.2. + * * EXTERN: int db_copy __P((DB_ENV *, * EXTERN: const char *, const char *, const char *)); */ @@ -30,227 +26,6 @@ db_copy(dbenv, dbfile, target, passwd) const char *target; const char *passwd; { - DB *dbp; - DB_FH *fp; - DB_MPOOLFILE *mpf; - ENV *env; - void *pagep; - db_pgno_t pgno; - int ret, t_ret; - char *path; - size_t nw; - -#ifdef HAVE_QUEUE - DBTYPE type; - u_int32_t extentsize; -#endif - - path = NULL; - dbp = NULL; - fp = NULL; - env = dbenv->env; -retry: if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - /* - * If the database is encrypted we need to encript the pages - * before outputting them since we will read decrypted pages. - */ - if (passwd != NULL && - (ret = dbp->set_encrypt(dbp, passwd, DB_ENCRYPT_AES)) != 0) - goto err; - - if ((ret = dbp->open(dbp, NULL, - dbfile, NULL, DB_UNKNOWN, DB_AUTO_COMMIT | DB_RDONLY, 0)) != 0) { - if (ret == DB_LOCK_DEADLOCK || ret == DB_LOCK_NOTGRANTED) { - dbenv->errx(dbenv, DB_STR_A("0702", - "Deadlock while opening %s, retrying", "%s"), dbfile); - (void)dbp->close(dbp, DB_NOSYNC); - goto retry; - } - goto err; - } - if ((ret = __os_malloc(env, - strlen(target) + strlen(dbfile) + 2, &path)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("0703", - "Cannot allocate space for path: %s", "%s"), target); - goto err; - } - - (void)strcpy(path, target); - (void)strncat(path, &PATH_SEPARATOR[0], 1); - (void)strcat(path, dbfile); - - if ((ret = __os_open(env, - path, 0, DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &fp)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("0704", - "Cannot open traget file: %s", "%s"), path); - goto err; - } - - mpf = dbp->get_mpf(dbp); - for (pgno = 0; ret == 0 ; pgno++) { - if ((ret = mpf->get(mpf, &pgno, NULL, 0, &pagep)) != 0) - break; - if (F_ISSET(dbp, DB_AM_CHKSUM) || passwd != NULL) - ret = __db_encrypt_and_checksum_pg(env, dbp, pagep); - if (ret == 0 && ((ret = __os_write(env, - fp, pagep, dbp->pgsize, &nw)) != 0 || nw != dbp->pgsize)) { - if (ret == 0) - ret = EIO; - } - if ((t_ret = mpf->put(mpf, - pagep, DB_PRIORITY_VERY_LOW, 0)) != 0 && ret == 0) - ret = t_ret; - } - - if (ret == DB_PAGE_NOTFOUND) - ret = 0; - -#ifdef HAVE_QUEUE - /* Queue exents cannot be read directly, use the internal interface. */ - if (ret == 0) { - if ((ret = dbp->get_type(dbp, &type) != 0)) - goto err; - if (type == DB_QUEUE && - (ret = dbp->get_q_extentsize(dbp, &extentsize)) == 0 && - extentsize != 0) - ret = copy_queue_extents(dbp, target, passwd); - } -#endif - /* We have read pages for which log records may still be in cache. */ - if (ret == 0) - ret = dbenv->log_flush(dbenv, NULL); - -err: if (path != NULL) - __os_free(env, path); - if (fp != NULL && (t_ret = __os_closehandle(env, fp)) != 0 && ret == 0) - ret = t_ret; - if (dbp != NULL && - (t_ret = dbp->close(dbp, DB_NOSYNC)) != 0 && ret == 0) - ret = t_ret; - return (ret); + COMPQUIET(passwd, NULL); + return (__db_dbbackup_pp(dbenv, dbfile, target, 0)); } - -#ifdef HAVE_QUEUE -/* - * copy_queue_extents -- - * Routine to safely copy the active queue extents of a database. - * This routine must use internal BDB interfaces. - */ -static int -copy_queue_extents(dbp, target, passwd) - DB *dbp; - const char *target; - const char *passwd; -{ - DBC *dbc; - DB_ENV *dbenv; - DB_FH *fp; - DB_QUEUE_STAT *sp; - ENV *env; - void *pagep; - db_recno_t current, first; - db_pgno_t pgno, stop; - u_int32_t extid, page_ext; - char *path; - size_t nw; - int ret, t_ret; - - /* Find out the first and last record numbers in the database. */ - if ((ret = dbp->stat(dbp, NULL, &sp, DB_FAST_STAT)) != 0) - return (ret); - - current = sp->qs_cur_recno; - first = sp->qs_first_recno; - page_ext = sp->qs_extentsize; - - dbenv = dbp->dbenv; - env = dbp->env; - fp = NULL; - if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) - return (ret); - if ((ret = __os_malloc(env, - strlen(target) + strlen(dbp->fname) + strlen(QUEUE_EXTENT), - &path)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("0705", - "Cannot allocate space for path: %s", "%s"), target); - goto err; - } - - extid = UINT32_MAX; -again: - if (current >= first) - stop = QAM_RECNO_PAGE(dbp, current); - else - stop = QAM_RECNO_PAGE(dbp, UINT32_MAX); - - for (pgno = QAM_RECNO_PAGE(dbp, first); pgno <= stop; pgno++) { - if (extid != QAM_PAGE_EXTENT(dbp, pgno)) { - if (fp != NULL && - (ret = __os_closehandle(env, fp)) != 0) - goto err; - fp = NULL; - extid = QAM_PAGE_EXTENT(dbp, pgno); - (void)sprintf(path, QUEUE_EXTENT, - target, PATH_SEPARATOR[0], dbp->fname, extid); - if ((ret = __os_open(env, path, 0, - DB_OSO_CREATE | DB_OSO_TRUNC, - DB_MODE_600, &fp)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("0706", - "Cannot open traget file: %s", "%s"), path); - goto err; - } - } - ret = __qam_fget(dbc, &pgno, 0, &pagep); - - /* - * Skip to the next extent if this extent has not - * been created yet or if it is not completly populated. - */ - if (ret == DB_PAGE_NOTFOUND || ret == ENOENT) { - /* - * Compute the page number of the first page in - * the next extent. - */ - pgno = QAM_PAGE_EXTENT( - dbp, pgno + page_ext) * page_ext; - /* Decrement, the loop will increment. */ - pgno--; - ret = 0; - continue; - } - if (ret != 0) - goto err; - - if (F_ISSET(dbp, DB_AM_CHKSUM) || passwd != NULL) - ret = __db_encrypt_and_checksum_pg(env, dbp, pagep); - if (ret == 0 && ((ret = __os_write(env, - fp, pagep, dbp->pgsize, &nw)) != 0 || nw != dbp->pgsize)) { - if (ret == 0) - ret = EIO; - dbenv->err(dbenv, ret, DB_STR_A("0707", - "Failed to write page %lu output to %s", "%s"), - (u_long)pgno, path); - } - if ((t_ret = __qam_fput(dbc, - pgno, pagep, DB_PRIORITY_VERY_LOW)) != 0 && ret == 0) - ret = t_ret; - if (ret != 0) - goto err; - } - - if (current < first) { - first = 1; - goto again; - } - -err: if (fp != NULL && (t_ret = __os_closehandle(env, fp)) != 0 && ret == 0) - ret = t_ret; - - if (dbc != NULL && (t_ret = dbc->close(dbc)) != 0 && ret == 0) - ret = t_ret; - - __os_free(env, path); - return (ret); -} -#endif diff --git a/src/db/db_dispatch.c b/src/db/db_dispatch.c index 9d12b947..06de4ef7 100644 --- a/src/db/db_dispatch.c +++ b/src/db/db_dispatch.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 diff --git a/src/db/db_dup.c b/src/db/db_dup.c index ff00da87..9fd04791 100644 --- a/src/db/db_dup.c +++ b/src/db/db_dup.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_iface.c b/src/db/db_iface.c index 6e9949b9..59e0ba53 100644 --- a/src/db/db_iface.c +++ b/src/db/db_iface.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1355,6 +1355,27 @@ __db_open_arg(dbp, txn, fname, dname, type, flags) return (EINVAL); } + /* Exclusive database handles cannot be threaded.*/ + if (LF_ISSET(DB_THREAD) && F2_ISSET(dbp, DB2_AM_EXCL)) { + __db_errx(env, DB_STR("0744", + "Exclusive database handles cannot be threaded.")); + return (EINVAL); + } + + /* Exclusive database handles require transactional environments. */ + if (F2_ISSET(dbp, DB2_AM_EXCL) && !TXN_ON(env)) { + __db_errx(env, DB_STR("0745", + "Exclusive database handles require transactional environments.")); + return (EINVAL); + } + + /* Replication clients cannot open exclusive database handles. */ + if (F2_ISSET(dbp, DB2_AM_EXCL) && IS_REP_CLIENT(env)) { + __db_errx(env, DB_STR("0746", +"Exclusive database handles cannot be opened on replication clients.")); + return (EINVAL); + } + /* DB_MULTIVERSION requires a database configured for transactions. */ if (LF_ISSET(DB_MULTIVERSION) && !IS_REAL_TXN(txn)) { __db_errx(env, DB_STR("0597", diff --git a/src/db/db_join.c b/src/db/db_join.c index 9e03776d..751cf9e2 100644 --- a/src/db/db_join.c +++ b/src/db/db_join.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_meta.c b/src/db/db_meta.c index 914a66d0..8f97ebd8 100644 --- a/src/db/db_meta.c +++ b/src/db/db_meta.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -445,21 +445,17 @@ no_sort: ldbt.data = h; ldbt.size = P_OVERHEAD(dbp); /* - * If we are truncating the file, we need to make sure - * the logging happens before the truncation. If we + * If we are removing pages from the file, we need to make + * sure the logging happens before the truncation. If we * are truncating multiple pages we don't need to flush the * log here as it will be flushed by __db_truncate_freelist. - * If we are zeroing pages rather than truncating we still - * need to flush since they will not have valid LSNs. */ lflag = 0; - if (h->pgno == last_pgno #ifdef HAVE_FTRUNCATE - && do_truncate == 0 -#endif - ) + if (h->pgno == last_pgno && do_truncate == 0) lflag = DB_FLUSH; +#endif switch (h->type) { case P_HASH: case P_IBTREE: @@ -508,9 +504,7 @@ logged: ret = __db_truncate_freelist( dbc, meta, h, list, start, nelem); h = NULL; - } else -#endif - if (h->pgno == last_pgno) { + } else if (h->pgno == last_pgno) { /* * We are going to throw this page away, but if we are * using MVCC then this version may stick around and we @@ -534,7 +528,6 @@ logged: DB_ASSERT(dbp->env, meta->pgno == PGNO_BASE_MD); meta->last_pgno--; } else { -#ifdef HAVE_FTRUNCATE if (list != NULL) { /* Put the page number into the list. */ if ((ret = @@ -549,6 +542,8 @@ logged: ((u_int8_t*)&list[nelem] - (u_int8_t*)lp)); *lp = h->pgno; } +#else + { #endif /* * If we are not truncating the page then we @@ -735,7 +730,7 @@ again: if (DBC_LOGGING(dbc)) { lpgno = lp[elems - 1].pgno; } /* - * If this is not the begining of the list fetch the end + * If this is not the beginning of the list fetch the end * of the previous segment. This page becomes the last_free * page and will link to this segment if it is not truncated. */ diff --git a/src/db/db_method.c b/src/db/db_method.c index 63ad63d9..82d03e5f 100644 --- a/src/db/db_method.c +++ b/src/db/db_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -48,6 +48,8 @@ static int __db_get_encrypt_flags __P((DB *, u_int32_t *)); static int __db_set_encrypt __P((DB *, const char *, u_int32_t)); static int __db_get_feedback __P((DB *, void (**)(DB *, int, int))); static int __db_set_feedback __P((DB *, void (*)(DB *, int, int))); +static int __db_get_lk_exclusive __P((DB *, int *, int *)); +static int __db_set_lk_exclusive __P((DB *, int)); static void __db_map_flags __P((DB *, u_int32_t *, u_int32_t *)); static int __db_get_pagesize __P((DB *, u_int32_t *)); static int __db_set_paniccall __P((DB *, void (*)(DB_ENV *, int))); @@ -207,7 +209,7 @@ err: if (dbp != NULL) { __os_free(env, dbp); } - if (F_ISSET(env, ENV_DBLOCAL)) + if (dbp != NULL && F_ISSET(env, ENV_DBLOCAL)) (void)__env_close(dbp->dbenv, 0); return (ret); @@ -279,6 +281,8 @@ __db_init(dbp, flags) dbp->get_type = __db_get_type; dbp->join = __db_join_pp; dbp->key_range = __db_key_range_pp; + dbp->get_lk_exclusive = __db_get_lk_exclusive; + dbp->set_lk_exclusive = __db_set_lk_exclusive; dbp->open = __db_open_pp; dbp->pget = __db_pget_pp; dbp->put = __db_put_pp; @@ -760,6 +764,30 @@ __db_set_feedback(dbp, feedback) return (0); } +static int +__db_get_lk_exclusive(dbp, onoff, nowait) + DB *dbp; + int *onoff; + int *nowait; +{ + *onoff = (F2_ISSET(dbp, DB2_AM_EXCL) ? 1 : 0); + *nowait = (F2_ISSET(dbp, DB2_AM_NOWAIT) ? 1 : 0); + return (0); +} + +static int +__db_set_lk_exclusive(dbp, nowait) + DB *dbp; + int nowait; +{ + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_lk_exclusive"); + + F2_CLR(dbp, DB2_AM_NOWAIT); + F2_SET(dbp, (nowait ? DB2_AM_NOWAIT|DB2_AM_EXCL : + DB2_AM_EXCL)); + return (0); +} + /* * __db_map_flags -- * Maps between public and internal flag values. diff --git a/src/db/db_open.c b/src/db/db_open.c index 5d2f6434..fefda48f 100644 --- a/src/db/db_open.c +++ b/src/db/db_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -22,6 +22,8 @@ #include "dbinc/qam.h" #include "dbinc/txn.h" +static int __db_handle_lock __P((DB *)); + /* * __db_open -- * DB->open method. @@ -222,6 +224,16 @@ __db_open(dbp, ip, txn, fname, dname, type, flags, mode, meta_pgno) goto err; } + /* + * Internal exclusive databases need to use the shared + * memory pool to lock out existing database handles before + * it gets its handle lock. So getting the lock is delayed + * until after the memory pool is allocated. + */ + if (F2_ISSET(dbp, DB2_AM_INTEXCL) && + (ret = __db_handle_lock(dbp)) != 0) + goto err; + switch (dbp->type) { case DB_BTREE: ret = __bam_open(dbp, ip, txn, fname, meta_pgno, flags); @@ -264,8 +276,11 @@ __db_open(dbp, ip, txn, fname, dname, type, flags, mode, meta_pgno) if (IS_REAL_TXN(txn)) ret = __txn_lockevent(env, txn, dbp, &dbp->handle_lock, dbp->locker); - else if (LOCKING_ON(env)) - /* Trade write handle lock for read handle lock. */ + else if (LOCKING_ON(env) && !F2_ISSET(dbp, DB2_AM_EXCL)) + /* + * Trade write handle lock for read handle lock, + * unless this is an exclusive database handle. + */ ret = __lock_downgrade(env, &dbp->handle_lock, DB_LOCK_READ, 0); } @@ -420,7 +435,7 @@ err: return (ret); * Take a buffer containing a meta-data page and check it for a valid LSN, * checksum (and verify the checksum if necessary) and possibly decrypt it. * - * Return 0 on success, >0 (errno) on error, -1 on checksum mismatch. + * Return 0 on success, >0 (errno). * * PUBLIC: int __db_chk_meta __P((ENV *, DB *, DBMETA *, u_int32_t)); */ @@ -463,7 +478,7 @@ chk_retry: if ((ret = __db_check_chksum(env, NULL, env->crypto_handle, chksum, meta, DBMETASIZE, is_hmac)) != 0) { if (is_hmac || swapped) - return (ret); + return (DB_CHKSUM_FAIL); M_32_SWAP(orig_chk); swapped = 1; @@ -475,8 +490,10 @@ chk_retry: if ((ret = F_CLR(dbp, DB_AM_CHKSUM); #ifdef HAVE_CRYPTO - ret = __crypto_decrypt_meta(env, - dbp, (u_int8_t *)meta, LF_ISSET(DB_CHK_META)); + if (__crypto_decrypt_meta(env, + dbp, (u_int8_t *)meta, LF_ISSET(DB_CHK_META)) != 0) + ret = DB_CHKSUM_FAIL; + else #endif /* Now that we're decrypted, we can check LSN. */ @@ -586,9 +603,12 @@ swap_retry: * checksum and decrypt. Don't distinguish between configuration and * checksum match errors here, because we haven't opened the database * and even a checksum error isn't a reason to panic the environment. + * If DB_SKIP_CHK is set, it means the checksum was already checked + * and the page was already decrypted. */ - if ((ret = __db_chk_meta(env, dbp, meta, flags)) != 0) { - if (ret == -1) + if (!LF_ISSET(DB_SKIP_CHK) && + (ret = __db_chk_meta(env, dbp, meta, flags)) != 0) { + if (ret == DB_CHKSUM_FAIL) __db_errx(env, DB_STR_A("0640", "%s: metadata page checksum error", "%s"), name); goto bad_format; @@ -798,3 +818,40 @@ err: if (old_page != NULL && (t_ret = __memp_fput(dbp->mpf, } return (ret); } + +static int +__db_handle_lock(dbp) + DB *dbp; +{ + ENV *env; + int ret; + u_int32_t old_flags; + + env = dbp->env; + ret = 0; + old_flags = dbp->flags; + + /* + * Internal exclusive database handles need to get and hold + * their own handle locks so that the client cannot open any + * external handles on that database. + */ + F_CLR(dbp, DB_AM_RECOVER); + F_SET(dbp, DB_AM_NOT_DURABLE); + + /* Begin exclusive handle lockout. */ + dbp->mpf->mfp->excl_lockout = 1; + + if ((ret = __lock_id(env, NULL, &dbp->locker)) != 0) + goto err; + LOCK_INIT(dbp->handle_lock); + if ((ret = __fop_lock_handle(env, dbp, dbp->locker, DB_LOCK_WRITE, + NULL, 0))!= 0) + goto err; + +err: /* End exclusive handle lockout. */ + dbp->mpf->mfp->excl_lockout = 0; + dbp->flags = old_flags; + + return (ret); +} diff --git a/src/db/db_overflow.c b/src/db/db_overflow.c index fb83c938..d992ec0d 100644 --- a/src/db/db_overflow.c +++ b/src/db/db_overflow.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -603,7 +603,7 @@ __db_coff(dbc, dbt, match, cmpfunc, cmpp) PAGE *dbt_pagep, *match_pagep; db_pgno_t dbt_pgno, match_pgno; u_int32_t cmp_bytes, dbt_bufsz, dbt_len, match_bufsz; - u_int32_t match_len, max_data, page_sz; + u_int32_t match_len, max_data, page_space; u_int8_t *p1, *p2; int ret; void *dbt_buf, *match_buf; @@ -612,7 +612,7 @@ __db_coff(dbc, dbt, match, cmpfunc, cmpp) ip = dbc->thread_info; txn = dbc->txn; mpf = dbp->mpf; - page_sz = dbp->pgsize; + page_space = P_MAXSPACE(dbp, dbp->pgsize); *cmpp = 0; dbt_buf = match_buf = NULL; @@ -664,7 +664,7 @@ err1: if (dbt_buf != NULL) mpf, ip, dbt_pagep, DB_PRIORITY_UNCHANGED); return (ret); } - cmp_bytes = page_sz < max_data ? page_sz : max_data; + cmp_bytes = page_space < max_data ? page_space : max_data; for (p1 = (u_int8_t *)dbt_pagep + P_OVERHEAD(dbp), p2 = (u_int8_t *)match_pagep + P_OVERHEAD(dbp); cmp_bytes-- > 0; ++p1, ++p2) @@ -675,7 +675,7 @@ err1: if (dbt_buf != NULL) dbt_pgno = NEXT_PGNO(dbt_pagep); match_pgno = NEXT_PGNO(match_pagep); - max_data -= page_sz; + max_data -= page_space; if ((ret = __memp_fput(mpf, ip, dbt_pagep, DB_PRIORITY_UNCHANGED)) != 0) { (void)__memp_fput(mpf, diff --git a/src/db/db_ovfl_vrfy.c b/src/db/db_ovfl_vrfy.c index 2956b137..fa630f7b 100644 --- a/src/db/db_ovfl_vrfy.c +++ b/src/db/db_ovfl_vrfy.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 diff --git a/src/db/db_pr.c b/src/db/db_pr.c index 3add6a92..d95440f9 100644 --- a/src/db/db_pr.c +++ b/src/db/db_pr.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -225,6 +225,7 @@ __db_prdb(dbp, flags) __db_msg(env, "gbytes: %lu", (u_long)hp->gbytes); __db_msg(env, "bytes: %lu", (u_long)hp->bytes); __db_msg(env, "curregion: %lu", (u_long)hp->curregion); + __db_msg(env, "region_size: %lu", (u_long)hp->region_size); __db_msg(env, "maxpgno: %lu", (u_long)hp->maxpgno); break; case DB_UNKNOWN: @@ -599,6 +600,7 @@ __db_heapmeta(env, dbp, h, flags) __db_meta(env, dbp, (DBMETA *)h, NULL, flags); __db_msg(env, "\tcurregion: %lu", (u_long)h->curregion); + __db_msg(env, "\tregion_size: %lu", (u_long)h->region_size); __db_msg(env, "\tnregions: %lu", (u_long)h->nregions); __db_msg(env, "\tgbytes: %lu", (u_long)h->gbytes); __db_msg(env, "\tbytes: %lu", (u_long)h->bytes); @@ -765,7 +767,7 @@ __db_prpage_int(env, mbp, dbp, lead, h, pagesize, data, flags) case P_HEAPMETA: return (__db_heapmeta(env, dbp, (HEAPMETA *)h, flags)); case P_IHEAP: - if (!LF_ISSET(DB_PR_PAGE)) + if (!LF_ISSET(DB_PR_PAGE) || dbp == NULL) return (0); return (__db_heapint(dbp, (HEAPPG *)h, flags)); default: @@ -967,7 +969,7 @@ __db_prpage_int(env, mbp, dbp, lead, h, pagesize, data, flags) "split: 0x%02x tsize: %lu next: %lu.%lu ", hh->flags, (u_long)hs->tsize, (u_long)hs->nextpg, (u_long)hs->nextindx); - + hdata = (u_int8_t *)hh + sizeof(HEAPSPLITHDR); } __db_prbytes(env, mbp, hdata, hh->size); @@ -1120,6 +1122,28 @@ __db_prflags(env, mbp, flags, fn, prefix, suffix) DB_MSGBUF_FLUSH(env, mbp); } +/* + * __db_name_to_val -- + * Return the integral value associated with the string, or -1 if missing. + * It is intended for looking up string names of enums and single bit + * in order to get a numeric value. + * + * PUBLIC: int __db_name_to_val __P((FN const *, char *)); + */ +int +__db_name_to_val(strtable, s) + FN const *strtable; + char *s; +{ + if (s != NULL) { + do { + if (strcasecmp(strtable->name, s) == 0) + return ((int)strtable->mask); + } while ((++strtable)->name != NULL); + } + return (-1); +} + /* * __db_pagetype_to_string -- * Return the name of the specified page type. @@ -1287,7 +1311,7 @@ __db_dump(dbp, subname, callback, handle, pflag, keyflag) key.size = key.ulen = sizeof(DB_HEAP_RID); key.flags = DB_DBT_USERMEM; } - + retry: while ((ret = __dbc_get(dbcp, &key, &data, !is_heap ? DB_NEXT | DB_MULTIPLE_KEY : DB_NEXT )) == 0) { @@ -1665,13 +1689,24 @@ __db_prheader(dbp, subname, pflag, keyflag, handle, callback, vdp, meta_pgno) if ((ret = callback(handle, buf)) != 0) goto err; } - if (tmp2_u_int32 != 0) { snprintf(buf, buflen, "heap_bytes=%lu\n", (u_long)tmp2_u_int32); if ((ret = callback(handle, buf)) != 0) goto err; } + + if ((ret = + __heap_get_heap_regionsize(dbp, &tmp_u_int32)) != 0) { + __db_err(env, ret, "DB->get_heap_regionsize"); + goto err; + } + if (tmp_u_int32 != 0) { + snprintf(buf, buflen, + "heap_regionsize=%lu\n", (u_long)tmp_u_int32); + if ((ret = callback(handle, buf)) != 0) + goto err; + } break; #else ret = __db_no_heap_am(env); diff --git a/src/db/db_rec.c b/src/db/db_rec.c index 329cce47..8ba1124e 100644 --- a/src/db/db_rec.c +++ b/src/db/db_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -886,10 +886,13 @@ __db_pg_free_recover_int(env, ip, argp, file_dbp, lsnp, mpf, op, data) /* * If we are at the end of the file truncate, otherwise * put on the free list. - */ + */ +#ifdef HAVE_FTRUNCATE if (argp->pgno == argp->last_pgno) meta->last_pgno = argp->pgno - 1; - else if (is_meta) + else +#endif + if (is_meta) meta->free = argp->pgno; else NEXT_PGNO(prevp) = argp->pgno; @@ -924,9 +927,11 @@ check_meta: ip, NULL, 0, &pagep)) != 0) { if (ret != DB_PAGE_NOTFOUND) goto out; +#ifdef HAVE_FTRUNCATE if (is_meta && DB_REDO(op) && meta->last_pgno <= argp->pgno) goto trunc; +#endif goto done; } } else if ((ret = __memp_fget(mpf, &argp->pgno, @@ -960,6 +965,7 @@ check_meta: * The page can be truncated if it was truncated at runtime * and the current metapage reflects the truncation. */ +#ifdef HAVE_FTRUNCATE if (is_meta && meta->last_pgno <= argp->pgno && argp->last_pgno <= argp->pgno) { if ((ret = __memp_fput(mpf, ip, @@ -975,7 +981,9 @@ trunc: if ((ret = __memp_ftruncate(mpf, NULL, ip, P_INIT(pagep, 0, PGNO_INVALID, PGNO_INVALID, PGNO_INVALID, 0, P_INVALID); ZERO_LSN(pagep->lsn); - } else if (cmp_p == 0 || IS_ZERO_LSN(LSN(pagep))) { + } else +#endif + if (cmp_p == 0 || IS_ZERO_LSN(LSN(pagep))) { REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); P_INIT(pagep, file_dbp->pgsize, argp->pgno, PGNO_INVALID, argp->next, 0, P_INVALID); @@ -1328,7 +1336,13 @@ __db_pg_trunc_recover(env, dbtp, lsnp, op, info) else meta->free = pglist->pgno; } - meta->last_pgno = last_pgno; + /* + * If this is part of a multi record truncate + * this could be just the last page of this record + * don't move the meta->last_pgno forward. + */ + if (meta->last_pgno > last_pgno) + meta->last_pgno = last_pgno; LSN(meta) = *lsnp; } } else { @@ -1350,7 +1364,7 @@ __db_pg_trunc_recover(env, dbtp, lsnp, op, info) } /* * Link the truncated part back into the free list. - * Its either after the last_free page or direclty + * Its either after the last_free page or directly * linked to the metadata page. */ if (argp->last_free != PGNO_INVALID) { @@ -1460,8 +1474,11 @@ __db_realloc_recover(env, dbtp, lsnp, op, info) DB_THREAD_INFO *ip; PAGE *pagep; db_pglist_t *pglist, *lp; +#ifdef HAVE_FTRUNCATE db_pgno_t *list; - u_int32_t felem, nelem, pos; + u_int32_t felem, pos; +#endif + u_int32_t nelem; int cmp_n, cmp_p, ret; ip = ((DB_TXNHEAD *)info)->thread_info; @@ -2598,7 +2615,7 @@ next: if ((ret = __memp_fget(mpf, &argp->npgno, ip, NULL, 0, &pagep)) != 0) { bt->bt_root = argp->npgno; } } - if (argp->pgno == file_dbp->meta_pgno) + if (argp->pgno == file_dbp->meta_pgno) file_dbp->meta_pgno = argp->npgno; /* diff --git a/src/db/db_reclaim.c b/src/db/db_reclaim.c index ea298d77..b902769a 100644 --- a/src/db/db_reclaim.c +++ b/src/db/db_reclaim.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -89,7 +89,7 @@ __db_reclaim_callback(dbc, p, cookie, putp) if ((dbp->type == DB_BTREE || dbp->type == DB_RECNO) && PGNO(p) == ((BTREE *)dbp->bt_internal)->bt_root) return (0); - if ((ret = __db_free(dbc, p, P_TO_UINT32(cookie))) != 0) + if ((ret = __db_free(dbc, p, *(u_int32_t *)cookie)) != 0) return (ret); *putp = 1; diff --git a/src/db/db_remove.c b/src/db/db_remove.c index 897e1899..591a29b2 100644 --- a/src/db/db_remove.c +++ b/src/db/db_remove.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_rename.c b/src/db/db_rename.c index 744b8aca..2812b948 100644 --- a/src/db/db_rename.c +++ b/src/db/db_rename.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_ret.c b/src/db/db_ret.c index 02fec8bc..709605f6 100644 --- a/src/db/db_ret.c +++ b/src/db/db_ret.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_setid.c b/src/db/db_setid.c index e4a274d2..697c3ff7 100644 --- a/src/db/db_setid.c +++ b/src/db/db_setid.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_setlsn.c b/src/db/db_setlsn.c index 824fab85..1a3280ed 100644 --- a/src/db/db_setlsn.c +++ b/src/db/db_setlsn.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_sort_multiple.c b/src/db/db_sort_multiple.c index 8ed61e58..c5e2e941 100644 --- a/src/db/db_sort_multiple.c +++ b/src/db/db_sort_multiple.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" diff --git a/src/db/db_stati.c b/src/db/db_stati.c index 418b470b..61744e81 100644 --- a/src/db/db_stati.c +++ b/src/db/db_stati.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_truncate.c b/src/db/db_truncate.c index e990152f..0eeb0c64 100644 --- a/src/db/db_truncate.c +++ b/src/db/db_truncate.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_upg.c b/src/db/db_upg.c index 3693f71d..de5d0dc7 100644 --- a/src/db/db_upg.c +++ b/src/db/db_upg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -316,6 +316,11 @@ __db_upgrade(dbp, fname, flags) goto err; } break; + case DB_HEAPMAGIC: + /* + * There's no upgrade needed for Heap yet. + */ + break; case DB_QAMMAGIC: switch (((DBMETA *)mbuf)->version) { case 1: @@ -352,6 +357,7 @@ __db_upgrade(dbp, fname, flags) switch (((DBMETA *)mbuf)->magic) { case DB_BTREEMAGIC: case DB_HASHMAGIC: + case DB_HEAPMAGIC: case DB_QAMMAGIC: __db_errx(env, DB_STR_A("0670", "%s: DB->upgrade only supported on native byte-order systems", diff --git a/src/db/db_upg_opd.c b/src/db/db_upg_opd.c index 7e1130b9..992115ad 100644 --- a/src/db/db_upg_opd.c +++ b/src/db/db_upg_opd.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_vrfy.c b/src/db/db_vrfy.c index e3e0c6a7..9cb94ad2 100644 --- a/src/db/db_vrfy.c +++ b/src/db/db_vrfy.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -13,6 +13,7 @@ #include "dbinc/db_swap.h" #include "dbinc/db_verify.h" #include "dbinc/btree.h" +#include "dbinc/fop.h" #include "dbinc/hash.h" #include "dbinc/heap.h" #include "dbinc/lock.h" @@ -42,11 +43,14 @@ static int __db_salvage_unknowns __P((DB *, VRFY_DBINFO *, void *, static int __db_verify_arg __P((DB *, const char *, void *, u_int32_t)); static int __db_vrfy_freelist __P((DB *, VRFY_DBINFO *, db_pgno_t, u_int32_t)); +static int __db_vrfy_getpagezero + __P((DB *, DB_FH *, const char *, u_int8_t *, u_int32_t)); static int __db_vrfy_invalid __P((DB *, VRFY_DBINFO *, PAGE *, db_pgno_t, u_int32_t)); static int __db_vrfy_orderchkonly __P((DB *, VRFY_DBINFO *, const char *, const char *, u_int32_t)); -static int __db_vrfy_pagezero __P((DB *, VRFY_DBINFO *, DB_FH *, u_int32_t)); +static int __db_vrfy_pagezero __P((DB *, + VRFY_DBINFO *, DB_FH *, const char *, u_int32_t)); static int __db_vrfy_subdbs __P((DB *, VRFY_DBINFO *, const char *, u_int32_t)); static int __db_vrfy_structure __P((DB *, VRFY_DBINFO *, @@ -241,27 +245,32 @@ __db_verify(dbp, ip, name, subdb, handle, callback, lp, rp, flags) if (LF_ISSET(DB_PRINTABLE)) F_SET(vdp, SALVAGE_PRINTABLE); - /* Find the real name of the file. */ - if ((ret = __db_appname(env, - DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0) - goto err; + if (name != NULL) { + /* Find the real name of the file. */ + if ((ret = __db_appname(env, + DB_APP_DATA, name, &dbp->dirname, &real_name)) != 0) + goto err; - /* - * Our first order of business is to verify page 0, which is - * the metadata page for the master database of subdatabases - * or of the only database in the file. We want to do this by hand - * rather than just calling __db_open in case it's corrupt--various - * things in __db_open might act funny. - * - * Once we know the metadata page is healthy, I believe that it's - * safe to open the database normally and then use the page swapping - * code, which makes life easier. - */ - if ((ret = __os_open(env, real_name, 0, DB_OSO_RDONLY, 0, &fhp)) != 0) - goto err; + /* + * Our first order of business is to verify page 0, which is the + * metadata page for the master database of subdatabases or of + * the only database in the file. We want to do this by hand + * rather than just calling __db_open in case it's + * corrupt--various things in __db_open might act funny. + * + * Once we know the metadata page is healthy, I believe that + * it's safe to open the database normally and then use the page + * swapping code, which makes life easier. + */ + if ((ret = __os_open(env, + real_name, 0, DB_OSO_RDONLY, 0, &fhp)) != 0) + goto err; + } else { + MAKE_INMEM(dbp); + } /* Verify the metadata page 0; set pagesize and type. */ - if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, flags)) != 0) { + if ((ret = __db_vrfy_pagezero(dbp, vdp, fhp, subdb, flags)) != 0) { if (ret == DB_VERIFY_BAD) isbad = 1; else @@ -286,19 +295,23 @@ __db_verify(dbp, ip, name, subdb, handle, callback, lp, rp, flags) /* * Set our name in the Queue subsystem; we may need it later - * to deal with extents. + * to deal with extents. In-memory databases are not allowed to have + * extents. */ - if (dbp->type == DB_QUEUE && + if (dbp->type == DB_QUEUE && name != NULL && (ret = __qam_set_ext_data(dbp, name)) != 0) goto err; /* Mark the dbp as opened, so that we correctly handle its close. */ F_SET(dbp, DB_AM_OPEN_CALLED); - /* Find out the page number of the last page in the database. */ + /* + * Find out the page number of the last page in the database. We'll + * use this later to verify the metadata page. We don't verify now + * because the data from __db_vrfy_pagezero could be stale. + */ if ((ret = __memp_get_last_pgno(dbp->mpf, &vdp->last_pgno)) != 0) goto err; - /* * DB_ORDERCHKONLY is a special case; our file consists of * several subdatabases, which use different hash, bt_compare, @@ -428,6 +441,84 @@ done: err: return (ret); } +/* + * __db_vrfy_getpagezero -- + * Store the master metadata page into a local buffer. For safety, skip + * the DB paging code and read the page directly from disk (via seek and + * read) or the mpool. + */ +static int +__db_vrfy_getpagezero(dbp, fhp, name, mbuf, flags) + DB *dbp; + DB_FH *fhp; + const char *name; + u_int8_t *mbuf; + u_int32_t flags; +{ + DB_MPOOLFILE *mpf; + ENV *env; + PAGE *h; + db_pgno_t pgno; + int ret, t_ret; + size_t nr; + + env = dbp->env; + + if (F_ISSET(dbp, DB_AM_INMEM)) { + /* + * Now get the metadata page from the cache, if possible. If + * we're verifying an in-memory db, this is the only metadata + * page we have. + * + * + * Open the in-memory db file and get the metadata page. + */ + if ((ret = __memp_fcreate_pp(env->dbenv, &mpf, DB_VERIFY)) != 0) + return (ret); + if ((ret = __memp_set_flags(mpf, DB_MPOOL_NOFILE, 1)) != 0) + goto mpf_err; + if ((ret = __memp_fopen_pp(mpf, + name, DB_ODDFILESIZE | DB_RDONLY, 0, 0)) != 0) + goto mpf_err; + pgno = PGNO_BASE_MD; + if ((ret = __memp_fget_pp(mpf, &pgno, NULL, 0, &h)) != 0) { + __db_err(env, ret, DB_STR_A("0747", + "Metadata page %lu cannot be read from mpool", + "%lu"), (u_long)pgno); + goto mpf_err; + } + memcpy(mbuf, (u_int8_t *)h, DBMETASIZE); + ret = __memp_fput_pp(mpf, h, DB_PRIORITY_UNCHANGED, 0); +mpf_err: if ((t_ret = __memp_fclose_pp(mpf, 0)) != 0 || ret != 0) { + return (ret == 0 ? t_ret : ret); + } + } else { + /* + * Seek to the metadata page. + * + * Note that if we're just starting a verification, dbp->pgsize + * may be zero; this is okay, as we want page zero anyway and + * 0*0 == 0. + */ + if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0 || + (ret = __os_read(env, fhp, mbuf, DBMETASIZE, &nr)) != 0) { + __db_err(env, ret, DB_STR_A("0520", + "Metadata page %lu cannot be read", "%lu"), + (u_long)PGNO_BASE_MD); + return (ret); + } + + if (nr != DBMETASIZE) { + EPRINT((env, DB_STR_A("0521", + "Page %lu: Incomplete metadata page", "%lu"), + (u_long)PGNO_BASE_MD)); + return (DB_VERIFY_FATAL); + } + } + + return (ret); +} + /* * __db_vrfy_pagezero -- * Verify the master metadata page. Use seek, read, and a local buffer @@ -436,17 +527,17 @@ done: err: * Must correctly (or best-guess) set dbp->type and dbp->pagesize. */ static int -__db_vrfy_pagezero(dbp, vdp, fhp, flags) +__db_vrfy_pagezero(dbp, vdp, fhp, name, flags) DB *dbp; VRFY_DBINFO *vdp; DB_FH *fhp; + const char *name; u_int32_t flags; { DBMETA *meta; ENV *env; VRFY_PAGEINFO *pip; db_pgno_t freelist; - size_t nr; int isbad, ret, swapped; u_int8_t mbuf[DBMETASIZE]; @@ -456,36 +547,18 @@ __db_vrfy_pagezero(dbp, vdp, fhp, flags) meta = (DBMETA *)mbuf; dbp->type = DB_UNKNOWN; + if ((ret = __db_vrfy_getpagezero(dbp, fhp, name, mbuf, flags)) != 0) + return (ret); + if ((ret = __db_vrfy_getpageinfo(vdp, PGNO_BASE_MD, &pip)) != 0) return (ret); - /* - * Seek to the metadata page. - * Note that if we're just starting a verification, dbp->pgsize - * may be zero; this is okay, as we want page zero anyway and - * 0*0 == 0. - */ - if ((ret = __os_seek(env, fhp, 0, 0, 0)) != 0 || - (ret = __os_read(env, fhp, mbuf, DBMETASIZE, &nr)) != 0) { - __db_err(env, ret, DB_STR_A("0520", - "Metadata page %lu cannot be read", "%lu"), - (u_long)PGNO_BASE_MD); - return (ret); - } - - if (nr != DBMETASIZE) { - EPRINT((env, DB_STR_A("0521", - "Page %lu: Incomplete metadata page", "%lu"), - (u_long)PGNO_BASE_MD)); - return (DB_VERIFY_FATAL); - } - if ((ret = __db_chk_meta(env, dbp, meta, 1)) != 0) { EPRINT((env, DB_STR_A("0522", "Page %lu: metadata page corrupted", "%lu"), (u_long)PGNO_BASE_MD)); isbad = 1; - if (ret != -1) { + if (ret != DB_CHKSUM_FAIL) { EPRINT((env, DB_STR_A("0523", "Page %lu: could not check metadata page", "%lu"), (u_long)PGNO_BASE_MD)); @@ -641,6 +714,7 @@ __db_vrfy_pagezero(dbp, vdp, fhp, flags) /* Set up the dbp's fileid. We don't use the regular open path. */ memcpy(dbp->fileid, meta->uid, DB_FILE_ID_LEN); + dbp->preserve_fid = 1; if (swapped == 1) F_SET(dbp, DB_AM_SWAP); @@ -690,13 +764,16 @@ __db_vrfy_walkpages(dbp, vdp, handle, callback, flags) */ if ((t_ret = __memp_fget(mpf, &i, vdp->thread_info, NULL, 0, &h)) != 0) { - if (dbp->type == DB_HASH) { + if (dbp->type == DB_HASH || + (dbp->type == DB_QUEUE && + F_ISSET(dbp, DB_AM_INMEM))) { if ((t_ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) goto err1; pip->type = P_INVALID; pip->pgno = i; F_CLR(pip, VRFY_IS_ALLZEROES); + F_SET(pip, VRFY_NONEXISTENT); if ((t_ret = __db_vrfy_putpageinfo( env, vdp, pip)) != 0) goto err1; @@ -1356,7 +1433,7 @@ __db_vrfy_datapage(dbp, vdp, h, pgno, flags) } /* - * __db_vrfy_meta-- + * __db_vrfy_meta -- * Verify the access-method common parts of a meta page, using * normal mpool routines. * @@ -1472,9 +1549,9 @@ __db_vrfy_meta(dbp, vdp, meta, pgno, flags) } /* Can correctly be PGNO_INVALID--that's just the end of the list. */ - if (meta->free != PGNO_INVALID && IS_VALID_PGNO(meta->free)) + if (IS_VALID_PGNO(meta->free)) pip->free = meta->free; - else if (!IS_VALID_PGNO(meta->free)) { + else { isbad = 1; EPRINT((env, DB_STR_A("0551", "Page %lu: nonsensical free list pgno %lu", "%lu %lu"), @@ -1485,9 +1562,10 @@ __db_vrfy_meta(dbp, vdp, meta, pgno, flags) * Check that the meta page agrees with what we got from mpool. * If we don't have FTRUNCATE then mpool could include some * zeroed pages at the end of the file, we assume the meta page - * is correct. + * is correct. Queue does not update the meta page's last_pgno. */ - if (pgno == PGNO_BASE_MD && meta->last_pgno != vdp->last_pgno) { + if (pgno == PGNO_BASE_MD && + dbtype != DB_QUEUE && meta->last_pgno != vdp->last_pgno) { #ifdef HAVE_FTRUNCATE isbad = 1; EPRINT((env, DB_STR_A("0552", @@ -1537,8 +1615,8 @@ __db_vrfy_freelist(dbp, vdp, meta, flags) for (next_pgno = pip->free; next_pgno != PGNO_INVALID; next_pgno = pip->next_pgno) { cur_pgno = pip->pgno; - if ((ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) - return (ret); + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + return (t_ret); /* This shouldn't happen, but just in case. */ if (!IS_VALID_PGNO(next_pgno)) { @@ -1548,22 +1626,29 @@ __db_vrfy_freelist(dbp, vdp, meta, flags) return (DB_VERIFY_BAD); } + if (next_pgno > vdp->last_pgno) { + EPRINT((env, DB_STR_A("0713", + "Page %lu: page %lu on free list beyond last_pgno %lu", + "%lu %lu %lu"), (u_long)cur_pgno, + (u_long)next_pgno, (u_long)vdp->last_pgno)); + ret = DB_VERIFY_BAD; + } /* Detect cycles. */ - if ((ret = __db_vrfy_pgset_get(pgset, + if ((t_ret = __db_vrfy_pgset_get(pgset, vdp->thread_info, vdp->txn, next_pgno, &p)) != 0) - return (ret); + return (t_ret); if (p != 0) { EPRINT((env, DB_STR_A("0554", "Page %lu: page %lu encountered a second time on free list", "%lu %lu"), (u_long)cur_pgno, (u_long)next_pgno)); return (DB_VERIFY_BAD); } - if ((ret = __db_vrfy_pgset_inc(pgset, + if ((t_ret = __db_vrfy_pgset_inc(pgset, vdp->thread_info, vdp->txn, next_pgno)) != 0) - return (ret); + return (t_ret); - if ((ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0) - return (ret); + if ((t_ret = __db_vrfy_getpageinfo(vdp, next_pgno, &pip)) != 0) + return (t_ret); if (pip->type != P_INVALID) { EPRINT((env, DB_STR_A("0555", @@ -1574,7 +1659,7 @@ __db_vrfy_freelist(dbp, vdp, meta, flags) } } - if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0) + if ((t_ret = __db_vrfy_putpageinfo(env, vdp, pip)) != 0 && ret == 0) ret = t_ret; return (ret); } diff --git a/src/db/db_vrfy_stub.c b/src/db/db_vrfy_stub.c index b3acda2d..5037f33e 100644 --- a/src/db/db_vrfy_stub.c +++ b/src/db/db_vrfy_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/db_vrfyutil.c b/src/db/db_vrfyutil.c index 863f0624..d72e1188 100644 --- a/src/db/db_vrfyutil.c +++ b/src/db/db_vrfyutil.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/db/partition.c b/src/db/partition.c index c18bbaa4..f8beaf16 100644 --- a/src/db/partition.c +++ b/src/db/partition.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -321,6 +321,7 @@ __partition_open(dbp, ip, txn, fname, type, flags, mode, do_open) part_db = part->handles[part_id]; part_db->flags = F_ISSET(dbp, ~(DB_AM_CREATED | DB_AM_CREATED_MSTR | DB_AM_OPEN_CALLED)); + F_SET(part_db, DB_AM_PARTDB); part_db->adj_fileid = dbp->adj_fileid; part_db->pgsize = dbp->pgsize; part_db->priority = dbp->priority; @@ -495,7 +496,7 @@ err: /* Put the metadata page back. */ /* * Support for sorting keys. Keys must be sorted using the btree - * compare function so if we call qsort in __partiton_setup_keys + * compare function so if we call qsort in __partition_setup_keys * we use this structure to pass the DBP and compare function. */ struct key_sort { @@ -769,7 +770,7 @@ __partition_get_dirs(dbp, dirpp) return (0); if ((ret = __os_calloc(env, - sizeof(char *), part->nparts + 1, (char **)&part->dirs)) != 0) + sizeof(char *), part->nparts + 1, (void *) &part->dirs)) != 0) return (ret); for (i = 0; i < part->nparts; i++) @@ -862,7 +863,7 @@ __partc_get_pp(dbc, key, data, flags) return (ret); } /* - * __partiton_get -- + * __partition_get -- * cursor get opeartion on a partitioned database. * * PUBLIC: int __partc_get __P((DBC*, DBT *, DBT *, u_int32_t)); @@ -1152,7 +1153,7 @@ __partc_destroy(dbc) } /* - * __partiton_close + * __partition_close * Close a partitioned database. * * PUBLIC: int __partition_close __P((DB *, DB_TXN *, u_int32_t)); @@ -1193,7 +1194,7 @@ __partition_close(dbp, txn, flags) } /* - * __partiton_sync + * __partition_sync * Sync a partitioned database. * * PUBLIC: int __partition_sync __P((DB *)); @@ -1224,7 +1225,7 @@ __partition_sync(dbp) } /* - * __partiton_stat + * __partition_stat * Stat a partitioned database. * * PUBLIC: int __partition_stat __P((DBC *, void *, u_int32_t)); @@ -1646,7 +1647,7 @@ __part_key_range(dbc, dbt, kp, flags) kp->greater *= my_elems; kp->greater /= total_elems; /* - * Proportially add weight from the subtrees to the + * Proportionally add weight from the subtrees to the * left and right of this one. */ kp->less += less_elems / total_elems; diff --git a/src/dbinc/atomic.h b/src/dbinc/atomic.h index 1a96e2af..096176a5 100644 --- a/src/dbinc/atomic.h +++ b/src/dbinc/atomic.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -29,7 +29,7 @@ extern "C" { * If the db_atomic_t's value is still oldval, set it to newval. * It returns 1 for success or 0 for failure. * - * The ENV * paramter is used only when HAVE_ATOMIC_SUPPORT is undefined. + * The ENV * parameter is used only when HAVE_ATOMIC_SUPPORT is undefined. * * If the platform does not natively support any one of these operations, * then atomic operations will be emulated with this sequence: diff --git a/src/dbinc/btree.h b/src/dbinc/btree.h index 6dde03d9..86bbec14 100644 --- a/src/dbinc/btree.h +++ b/src/dbinc/btree.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994, 1995, 1996 @@ -301,7 +301,7 @@ struct __cursor { * We store prevcursor in order to be able to perform one level of * DB_PREV by returning prevKey/prevData. We need prev2cursor to more * efficiently do a subsequent DB_PREV with a linear search from the - * begining of the compressed chunk. + * beginning of the compressed chunk. * * When we delete entries, we set the cursor to point to the next entry * after the last deleted key, and set C_COMPRESS_DELETED. The del_key @@ -394,13 +394,13 @@ struct __cursor { * We leave the loop only by breaking out if we do not have a subdb * or we are sure the have the right revision. * - * It must be guranteed that we cannot read an old root pgno and a + * It must be guaranteed that we cannot read an old root pgno and a * current revision number. We note that the global revision number * and DB handle information are only updated while holding the latches * and locks of the master database pages. - * If another thread is sychronizing the DB handle with the master + * If another thread is synchronizing the DB handle with the master * database it will exclusively latch both the old and new pages so we will - * sychronize on that. + * synchronize on that. */ #define BAM_GET_ROOT(dbc, root_pgno, \ page, get_mode, lock_mode, lock, ret) do { \ @@ -541,7 +541,7 @@ typedef enum { #define BPI_SPACEONLY 0x01 /* Only check for space to update. */ #define BPI_NORECNUM 0x02 /* Not update the recnum on the left. */ #define BPI_NOLOGGING 0x04 /* Don't log the update. */ -#define BPI_REPLACE 0x08 /* Repleace the record. */ +#define BPI_REPLACE 0x08 /* Replace the record. */ #if defined(__cplusplus) } diff --git a/src/dbinc/clock.h b/src/dbinc/clock.h index 8a3bfd5e..caeaee70 100644 --- a/src/dbinc/clock.h +++ b/src/dbinc/clock.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/crypto.h b/src/dbinc/crypto.h index bd53c704..ea7a9cf0 100644 --- a/src/dbinc/crypto.h +++ b/src/dbinc/crypto.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/cxx_int.h b/src/dbinc/cxx_int.h index 626937b8..5492ead7 100644 --- a/src/dbinc/cxx_int.h +++ b/src/dbinc/cxx_int.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/db.in b/src/dbinc/db.in index f4d3f6ba..a948910e 100644 --- a/src/dbinc/db.in +++ b/src/dbinc/db.in @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ * @@ -469,10 +469,10 @@ struct __db_lockreq { /******************************************************* * Logging. *******************************************************/ -#define DB_LOGVERSION 18 /* Current log version. */ -#define DB_LOGVERSION_LATCHING 15 /* Log version using latching. */ -#define DB_LOGCHKSUM 12 /* Check sum headers. */ -#define DB_LOGOLDVER 8 /* Oldest log version supported. */ +#define DB_LOGVERSION 19 /* Current log version. */ +#define DB_LOGVERSION_LATCHING 15 /* Log version using latching: db-4.8 */ +#define DB_LOGCHKSUM 12 /* Check sum headers: db-4.5 */ +#define DB_LOGOLDVER 8 /* Oldest version supported: db-4.2 */ #define DB_LOGMAGIC 0x040988 /* @@ -545,7 +545,7 @@ struct __db_log_stat { /* SHARED */ u_int32_t st_lg_size; /* Log file size. */ u_int32_t st_wc_bytes; /* Bytes to log since checkpoint. */ u_int32_t st_wc_mbytes; /* Megabytes to log since checkpoint. */ - u_int32_t st_fileid_init; /* Inital allocation for fileids. */ + u_int32_t st_fileid_init; /* Initial allocation for fileids. */ #ifndef __TEST_DB_NO_STATISTICS u_int32_t st_nfileid; /* Current number of fileids. */ u_int32_t st_maxnfileid; /* Maximum number of fileids used. */ @@ -708,11 +708,12 @@ struct __db_mpoolfile { * multiple threads of control. */ #define MP_FILEID_SET 0x001 /* Application supplied a file ID. */ -#define MP_FLUSH 0x002 /* Was opened to flush a buffer. */ -#define MP_MULTIVERSION 0x004 /* Opened for multiversion access. */ -#define MP_OPEN_CALLED 0x008 /* File opened. */ -#define MP_READONLY 0x010 /* File is readonly. */ -#define MP_DUMMY 0x020 /* File is dummy for __memp_fput. */ +#define MP_FLUSH 0x002 /* Was used to flush a buffer. */ +#define MP_FOR_FLUSH 0x004 /* Was opened to flush a buffer. */ +#define MP_MULTIVERSION 0x008 /* Opened for multiversion access. */ +#define MP_OPEN_CALLED 0x010 /* File opened. */ +#define MP_READONLY 0x020 /* File is readonly. */ +#define MP_DUMMY 0x040 /* File is dummy for __memp_fput. */ u_int32_t flags; }; @@ -780,6 +781,7 @@ struct __db_mpool_fstat { uintmax_t st_page_create; /* Pages created in the cache. */ uintmax_t st_page_in; /* Pages read in. */ uintmax_t st_page_out; /* Pages written out. */ + uintmax_t st_backup_spins; /* Number of spins during a copy. */ #endif char *file_name; /* File name. */ }; @@ -1399,18 +1401,19 @@ typedef enum { /* DB (private) error return codes. */ #define DB_ALREADY_ABORTED (-30899) -#define DB_DELETED (-30898)/* Recovery file marked deleted. */ -#define DB_EVENT_NOT_HANDLED (-30897)/* Forward event to application. */ -#define DB_NEEDSPLIT (-30896)/* Page needs to be split. */ -#define DB_REP_BULKOVF (-30895)/* Rep bulk buffer overflow. */ -#define DB_REP_LOGREADY (-30894)/* Rep log ready for recovery. */ -#define DB_REP_NEWMASTER (-30893)/* We have learned of a new master. */ -#define DB_REP_PAGEDONE (-30892)/* This page was already done. */ -#define DB_SURPRISE_KID (-30891)/* Child commit where parent +#define DB_CHKSUM_FAIL (-30898)/* Checksum failed. */ +#define DB_DELETED (-30897)/* Recovery file marked deleted. */ +#define DB_EVENT_NOT_HANDLED (-30896)/* Forward event to application. */ +#define DB_NEEDSPLIT (-30895)/* Page needs to be split. */ +#define DB_REP_BULKOVF (-30894)/* Rep bulk buffer overflow. */ +#define DB_REP_LOGREADY (-30893)/* Rep log ready for recovery. */ +#define DB_REP_NEWMASTER (-30892)/* We have learned of a new master. */ +#define DB_REP_PAGEDONE (-30891)/* This page was already done. */ +#define DB_SURPRISE_KID (-30890)/* Child commit where parent didn't know it was a parent. */ -#define DB_SWAPBYTES (-30890)/* Database needs byte swapping. */ -#define DB_TXN_CKP (-30889)/* Encountered ckp record in log. */ -#define DB_VERIFY_FATAL (-30888)/* DB->verify cannot proceed. */ +#define DB_SWAPBYTES (-30889)/* Database needs byte swapping. */ +#define DB_TXN_CKP (-30888)/* Encountered ckp record in log. */ +#define DB_VERIFY_FATAL (-30887)/* DB->verify cannot proceed. */ /* Database handle. */ struct __db { @@ -1650,6 +1653,8 @@ struct __db { __P((DB *, u_int32_t (**)(DB *, const void *, u_int32_t))); int (*get_h_nelem) __P((DB *, u_int32_t *)); int (*get_heapsize) __P((DB *, u_int32_t *, u_int32_t *)); + int (*get_heap_regionsize) __P((DB *, u_int32_t *)); + int (*get_lk_exclusive) __P((DB *, int *, int *)); int (*get_lorder) __P((DB *, int *)); DB_MPOOLFILE *(*get_mpf) __P((DB *)); void (*get_msgcall) __P((DB *, @@ -1709,6 +1714,8 @@ struct __db { __P((DB *, u_int32_t (*)(DB *, const void *, u_int32_t))); int (*set_h_nelem) __P((DB *, u_int32_t)); int (*set_heapsize) __P((DB *, u_int32_t, u_int32_t, u_int32_t)); + int (*set_heap_regionsize) __P((DB *, u_int32_t)); + int (*set_lk_exclusive) __P((DB *, int)); int (*set_lorder) __P((DB *, int)); void (*set_msgcall) __P((DB *, void (*)(const DB_ENV *, const char *))); void (*set_msgfile) __P((DB *, FILE *)); @@ -1784,21 +1791,28 @@ struct __db { #define DB_AM_NOT_DURABLE 0x00008000 /* Do not log changes */ #define DB_AM_OPEN_CALLED 0x00010000 /* DB->open called */ #define DB_AM_PAD 0x00020000 /* Fixed-length record pad */ -#define DB_AM_PGDEF 0x00040000 /* Page size was defaulted */ -#define DB_AM_RDONLY 0x00080000 /* Database is readonly */ -#define DB_AM_READ_UNCOMMITTED 0x00100000 /* Support degree 1 isolation */ -#define DB_AM_RECNUM 0x00200000 /* DB_RECNUM */ -#define DB_AM_RECOVER 0x00400000 /* DB opened by recovery routine */ -#define DB_AM_RENUMBER 0x00800000 /* DB_RENUMBER */ -#define DB_AM_REVSPLITOFF 0x01000000 /* DB_REVSPLITOFF */ -#define DB_AM_SECONDARY 0x02000000 /* Database is a secondary index */ -#define DB_AM_SNAPSHOT 0x04000000 /* DB_SNAPSHOT */ -#define DB_AM_SUBDB 0x08000000 /* Subdatabases supported */ -#define DB_AM_SWAP 0x10000000 /* Pages need to be byte-swapped */ -#define DB_AM_TXN 0x20000000 /* Opened in a transaction */ -#define DB_AM_VERIFYING 0x40000000 /* DB handle is in the verifier */ +#define DB_AM_PARTDB 0x00040000 /* Handle for a database partition */ +#define DB_AM_PGDEF 0x00080000 /* Page size was defaulted */ +#define DB_AM_RDONLY 0x00100000 /* Database is readonly */ +#define DB_AM_READ_UNCOMMITTED 0x00200000 /* Support degree 1 isolation */ +#define DB_AM_RECNUM 0x00400000 /* DB_RECNUM */ +#define DB_AM_RECOVER 0x00800000 /* DB opened by recovery routine */ +#define DB_AM_RENUMBER 0x01000000 /* DB_RENUMBER */ +#define DB_AM_REVSPLITOFF 0x02000000 /* DB_REVSPLITOFF */ +#define DB_AM_SECONDARY 0x04000000 /* Database is a secondary index */ +#define DB_AM_SNAPSHOT 0x08000000 /* DB_SNAPSHOT */ +#define DB_AM_SUBDB 0x10000000 /* Subdatabases supported */ +#define DB_AM_SWAP 0x20000000 /* Pages need to be byte-swapped */ +#define DB_AM_TXN 0x40000000 /* Opened in a transaction */ +#define DB_AM_VERIFYING 0x80000000 /* DB handle is in the verifier */ u_int32_t orig_flags; /* Flags at open, for refresh */ u_int32_t flags; + +#define DB2_AM_EXCL 0x00000001 /* Exclusively lock the handle */ +#define DB2_AM_INTEXCL 0x00000002 /* Internal exclusive lock. */ +#define DB2_AM_NOWAIT 0x00000004 /* Do not wait for handle lock */ + u_int32_t orig_flags2; /* Second flags word; for refresh */ + u_int32_t flags2; /* Second flags word */ }; /* @@ -2198,6 +2212,7 @@ struct __db_heap_stat { /* SHARED */ u_int32_t heap_pagecnt; /* Page count. */ u_int32_t heap_pagesize; /* Page size. */ u_int32_t heap_nregions; /* Number of regions. */ + u_int32_t heap_regionsize; /* Number of pages in a region. */ }; /* Queue statistics structure. */ @@ -2248,6 +2263,16 @@ typedef enum { DB_MEM_THREAD=6 } DB_MEM_CONFIG; +/* + * Backup configuration types. + */ +typedef enum { + DB_BACKUP_READ_COUNT = 1, + DB_BACKUP_READ_SLEEP = 2, + DB_BACKUP_SIZE = 3, + DB_BACKUP_WRITE_DIRECT = 4 +} DB_BACKUP_CONFIG; + struct __db_env { ENV *env; /* Linked ENV structure */ @@ -2280,6 +2305,7 @@ struct __db_env { /* Application specified paths */ char *db_log_dir; /* Database log file directory */ + char *db_md_dir; /* Persistent metadata directory */ char *db_tmp_dir; /* Database tmp file directory */ char *db_create_dir; /* Create directory for data files */ @@ -2394,8 +2420,10 @@ struct __db_env { /* DB_ENV PUBLIC HANDLE LIST BEGIN */ int (*add_data_dir) __P((DB_ENV *, const char *)); + int (*backup) __P((DB_ENV *, const char *, u_int32_t)); int (*cdsgroup_begin) __P((DB_ENV *, DB_TXN **)); int (*close) __P((DB_ENV *, u_int32_t)); + int (*dbbackup) __P((DB_ENV *, const char *, const char *, u_int32_t)); int (*dbremove) __P((DB_ENV *, DB_TXN *, const char *, const char *, u_int32_t)); int (*dbrename) __P((DB_ENV *, @@ -2413,6 +2441,11 @@ struct __db_env { int (*get_create_dir) __P((DB_ENV *, const char **)); int (*get_data_dirs) __P((DB_ENV *, const char ***)); int (*get_data_len) __P((DB_ENV *, u_int32_t *)); + int (*get_backup_callbacks) __P((DB_ENV *, + int (**)(DB_ENV *, const char *, const char *, void **), + int (**)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + int (**)(DB_ENV *, const char *, void *))); + int (*get_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t *)); int (*get_encrypt_flags) __P((DB_ENV *, u_int32_t *)); void (*get_errcall) __P((DB_ENV *, void (**)(const DB_ENV *, const char *, const char *))); @@ -2439,6 +2472,7 @@ struct __db_env { int (*get_lk_tablesize) __P((DB_ENV *, u_int32_t *)); int (*get_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t *)); int (*get_memory_max) __P((DB_ENV *, u_int32_t *, u_int32_t *)); + int (*get_metadata_dir) __P((DB_ENV *, const char **)); int (*get_mp_max_openfd) __P((DB_ENV *, int *)); int (*get_mp_max_write) __P((DB_ENV *, int *, db_timeout_t *)); int (*get_mp_mmapsize) __P((DB_ENV *, size_t *)); @@ -2561,6 +2595,12 @@ struct __db_env { int (*set_create_dir) __P((DB_ENV *, const char *)); int (*set_data_dir) __P((DB_ENV *, const char *)); int (*set_data_len) __P((DB_ENV *, u_int32_t)); + int (*set_backup_callbacks) __P((DB_ENV *, + int (*)(DB_ENV *, const char *, const char *, void **), + int (*)(DB_ENV *, u_int32_t, + u_int32_t, u_int32_t, u_int8_t *, void *), + int (*)(DB_ENV *, const char *, void *))); + int (*set_backup_config) __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t)); int (*set_encrypt) __P((DB_ENV *, const char *, u_int32_t)); void (*set_errcall) __P((DB_ENV *, void (*)(const DB_ENV *, const char *, const char *))); @@ -2588,6 +2628,7 @@ struct __db_env { int (*set_lk_tablesize) __P((DB_ENV *, u_int32_t)); int (*set_memory_init) __P((DB_ENV *, DB_MEM_CONFIG, u_int32_t)); int (*set_memory_max) __P((DB_ENV *, u_int32_t, u_int32_t)); + int (*set_metadata_dir) __P((DB_ENV *, const char *)); int (*set_mp_max_openfd) __P((DB_ENV *, int)); int (*set_mp_max_write) __P((DB_ENV *, int, db_timeout_t)); int (*set_mp_mmapsize) __P((DB_ENV *, size_t)); diff --git a/src/dbinc/db_185.in b/src/dbinc/db_185.in index 971d6b68..43735344 100644 --- a/src/dbinc/db_185.in +++ b/src/dbinc/db_185.in @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/dbinc/db_am.h b/src/dbinc/db_am.h index 6158abf8..f34578c4 100644 --- a/src/dbinc/db_am.h +++ b/src/dbinc/db_am.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -304,6 +304,8 @@ struct __db_foreign_info { */ #define DB_CHK_META 0x01 /* Checksum the meta page. */ #define DB_CHK_NOLSN 0x02 /* Don't check the LSN. */ +#define DB_CHK_ONLY 0x04 /* Only do the checksum. */ +#define DB_SKIP_CHK 0x08 /* Don't checksum or decrypt the meta page. */ /* * Flags to __db_truncate_page. diff --git a/src/dbinc/db_cxx.in b/src/dbinc/db_cxx.in index 55fc7ce6..84fc0f88 100644 --- a/src/dbinc/db_cxx.in +++ b/src/dbinc/db_cxx.in @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -224,10 +224,12 @@ public: virtual int get_feedback(void (**)(Db *, int, int)); virtual int get_flags(u_int32_t *); virtual int get_heapsize(u_int32_t *, u_int32_t *); + virtual int get_heap_regionsize(u_int32_t *); virtual int get_h_compare(int (**)(Db *, const Dbt *, const Dbt *)); virtual int get_h_ffactor(u_int32_t *); virtual int get_h_hash(u_int32_t (**)(Db *, const void *, u_int32_t)); virtual int get_h_nelem(u_int32_t *); + virtual int get_lk_exclusive(bool *, bool *); virtual int get_lorder(int *); virtual void get_msgcall(void (**)(const DbEnv *, const char *)); virtual void get_msgfile(FILE **); @@ -280,12 +282,14 @@ public: virtual int set_feedback(void (*)(Db *, int, int)); virtual int set_flags(u_int32_t); virtual int set_heapsize(u_int32_t, u_int32_t); + virtual int set_heap_regionsize(u_int32_t); virtual int set_h_compare(h_compare_fcn_type); /*deprecated*/ virtual int set_h_compare(int (*)(Db *, const Dbt *, const Dbt *)); virtual int set_h_ffactor(u_int32_t); virtual int set_h_hash(h_hash_fcn_type); /*deprecated*/ virtual int set_h_hash(u_int32_t (*)(Db *, const void *, u_int32_t)); virtual int set_h_nelem(u_int32_t); + virtual int set_lk_exclusive(bool); virtual int set_lorder(int); virtual void set_msgcall(void (*)(const DbEnv *, const char *)); virtual void set_msgfile(FILE *); @@ -488,8 +492,11 @@ public: // These methods match those in the C interface. // virtual int add_data_dir(const char *); + virtual int backup(const char *target, u_int32_t flags); virtual int cdsgroup_begin(DbTxn **tid); virtual int close(u_int32_t); + virtual int dbbackup( + const char *dbfile, const char *target, u_int32_t flags); virtual int dbremove(DbTxn *txn, const char *name, const char *subdb, u_int32_t flags); virtual int dbrename(DbTxn *txn, const char *name, const char *subdb, @@ -510,6 +517,16 @@ public: virtual int set_alloc(db_malloc_fcn_type, db_realloc_fcn_type, db_free_fcn_type); virtual void set_app_private(void *); + virtual int get_backup_callbacks( + int (**)(DbEnv *, const char *, const char *, void **), + int (**)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + int (**)(DbEnv *, const char *, void *)); + virtual int set_backup_callbacks( + int (*)(DbEnv *, const char *, const char *, void **), + int (*)(DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + int (*)(DbEnv *, const char *, void *)); + virtual int get_backup_config(DB_BACKUP_CONFIG, u_int32_t *); + virtual int set_backup_config(DB_BACKUP_CONFIG, u_int32_t); virtual int get_cachesize(u_int32_t *, u_int32_t *, int *); virtual int set_cachesize(u_int32_t, u_int32_t, int); virtual int get_cache_max(u_int32_t *, u_int32_t *); @@ -571,6 +588,8 @@ public: virtual int set_memory_init(DB_MEM_CONFIG, u_int32_t); virtual int get_memory_max(u_int32_t *, u_int32_t *); virtual int set_memory_max(u_int32_t, u_int32_t); + virtual int get_metadata_dir(const char **); + virtual int set_metadata_dir(const char *); virtual int get_mp_mmapsize(size_t *); virtual int set_mp_mmapsize(size_t); virtual int get_mp_max_openfd(int *); @@ -798,6 +817,12 @@ public: // static int _app_dispatch_intercept(DB_ENV *dbenv, DBT *dbt, DB_LSN *lsn, db_recops op); + static int _backup_close_intercept(DB_ENV *dbenv, + const char *dbname, void *handle); + static int _backup_open_intercept(DB_ENV *dbenv, + const char *dbname, const char *target, void **handle); + static int _backup_write_intercept(DB_ENV *dbenv, u_int32_t off_gbytes, + u_int32_t off_bytes, u_int32_t size, u_int8_t *buf, void *handle); static void _paniccall_intercept(DB_ENV *dbenv, int errval); static void _feedback_intercept(DB_ENV *dbenv, int opcode, int pct); static void _event_func_intercept(DB_ENV *dbenv, u_int32_t, void *); @@ -837,6 +862,11 @@ private: __DB_STD(ostream) *message_stream_; int (*app_dispatch_callback_)(DbEnv *, Dbt *, DbLsn *, db_recops); + int (*backup_close_callback_)(DbEnv *, const char *, void *); + int (*backup_open_callback_)( + DbEnv *, const char *, const char *, void **); + int (*backup_write_callback_)( + DbEnv *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *); int (*isalive_callback_)(DbEnv *, pid_t, db_threadid_t, u_int32_t); void (*error_callback_)(const DbEnv *, const char *, const char *); void (*feedback_callback_)(DbEnv *, int, int); diff --git a/src/dbinc/db_dispatch.h b/src/dbinc/db_dispatch.h index b0cc30e9..b6382871 100644 --- a/src/dbinc/db_dispatch.h +++ b/src/dbinc/db_dispatch.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 diff --git a/src/dbinc/db_int.in b/src/dbinc/db_int.in index 243be98e..42439107 100644 --- a/src/dbinc/db_int.in +++ b/src/dbinc/db_int.in @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -262,6 +262,9 @@ typedef struct __fn { #define F_CLR(p, f) (p)->flags &= ~(f) #define F_ISSET(p, f) ((p)->flags & (f)) #define F_SET(p, f) (p)->flags |= (f) +#define F2_CLR(p, f) ((p)->flags2 &= ~(f)) +#define F2_ISSET(p, f) ((p)->flags2 & (f)) +#define F2_SET(p, f) ((p)->flags2 |= (f)) #define LF_CLR(f) ((flags) &= ~(f)) #define LF_ISSET(f) ((flags) & (f)) #define LF_SET(f) ((flags) |= (f)) @@ -335,6 +338,12 @@ typedef struct __fn { #define STAT_SET_VERB(env, cat, subcat, val, newval, id1, id2) NOP_STATEMENT #endif +#if defined HAVE_SIMPLE_THREAD_TYPE +#define DB_THREADID_INIT(t) COMPQUIET((t), 0) +#else +#define DB_THREADID_INIT(t) memset(&(t), 0, sizeof(t)) +#endif + /* * These macros are used when an error condition is first noticed. They allow * one to be notified (via e.g. DTrace, SystemTap, ...) when an error occurs @@ -535,8 +544,9 @@ typedef enum { DB_APP_NONE=0, /* No type (region). */ DB_APP_DATA, /* Data file. */ DB_APP_LOG, /* Log file. */ - DB_APP_TMP, /* Temporary file. */ - DB_APP_RECOVER /* We are in recovery. */ + DB_APP_META, /* Persistent metadata file. */ + DB_APP_RECOVER, /* We are in recovery. */ + DB_APP_TMP /* Temporary file. */ } APPNAME; /* @@ -737,6 +747,18 @@ typedef struct __flag_map { u_int32_t inflag, outflag; } FLAG_MAP; +typedef struct __db_backup_handle { + int (*open) __P((DB_ENV *, const char *, const char *, void **)); + int (*write) __P((DB_ENV *, + u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *)); + int (*close) __P((DB_ENV *, const char *, void *)); + u_int32_t size; + u_int32_t read_count; + u_int32_t read_sleep; +#define BACKUP_WRITE_DIRECT 0x0001 + int flags; +} DB_BACKUP; + /* * Internal database environment structure. * @@ -811,6 +833,8 @@ struct __env { DB_REP *rep_handle; /* Replication handle */ DB_TXNMGR *tx_handle; /* Txn handle */ + DB_BACKUP *backup_handle; /* database copy configuration. */ + /* * XA support. */ diff --git a/src/dbinc/db_join.h b/src/dbinc/db_join.h index ffe70834..aecf059a 100644 --- a/src/dbinc/db_join.h +++ b/src/dbinc/db_join.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/db_page.h b/src/dbinc/db_page.h index 9e17d96f..2d4de2e5 100644 --- a/src/dbinc/db_page.h +++ b/src/dbinc/db_page.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -392,8 +392,9 @@ typedef struct __heaphdrsplt { F_ISSET((dbp), DB_AM_CHKSUM) ? HEAPPG_CHKSUM : HEAPPG_NORMAL) /* Each byte in the bitmap describes 4 pages (2 bits per page.) */ -#define HEAP_REGION_COUNT(size) ((size - HEAPPG_SZ(dbp)) * 4) -#define HEAP_DEFAULT_REGION_MAX HEAP_REGION_COUNT(8 * 1024) +#define HEAP_REGION_COUNT(dbp, size) (((size) - HEAPPG_SZ(dbp)) * 4) +#define HEAP_DEFAULT_REGION_MAX(dbp) \ + (HEAP_REGION_COUNT(dbp, (u_int32_t)8 * 1024)) #define HEAP_REGION_SIZE(dbp) (((HEAP*) (dbp)->heap_internal)->region_size) /* Figure out which region a given page belongs to. */ diff --git a/src/dbinc/db_swap.h b/src/dbinc/db_swap.h index 9eb3b284..352ae227 100644 --- a/src/dbinc/db_swap.h +++ b/src/dbinc/db_swap.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/dbinc/db_upgrade.h b/src/dbinc/db_upgrade.h index 67891561..45fb624d 100644 --- a/src/dbinc/db_upgrade.h +++ b/src/dbinc/db_upgrade.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/db_verify.h b/src/dbinc/db_verify.h index 99e6c866..68acbf6c 100644 --- a/src/dbinc/db_verify.h +++ b/src/dbinc/db_verify.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -180,6 +180,7 @@ struct __vrfy_pageinfo { #define VRFY_IS_RRECNO 0x1000 #define VRFY_OVFL_LEAFSEEN 0x2000 #define VRFY_HAS_COMPRESS 0x4000 +#define VRFY_NONEXISTENT 0x8000 u_int32_t flags; LIST_ENTRY(__vrfy_pageinfo) links; diff --git a/src/dbinc/debug.h b/src/dbinc/debug.h index 4950821c..a8da000d 100644 --- a/src/dbinc/debug.h +++ b/src/dbinc/debug.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/fop.h b/src/dbinc/fop.h index 34b4d45d..94f27f9f 100644 --- a/src/dbinc/fop.h +++ b/src/dbinc/fop.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/globals.h b/src/dbinc/globals.h index d798a7e9..95e5c118 100644 --- a/src/dbinc/globals.h +++ b/src/dbinc/globals.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -66,6 +66,8 @@ typedef struct __db_globals { pid_t *active_pids; /* array active pids */ + char *saved_errstr; /* saved error string from backup */ + /* Underlying OS interface jump table.*/ void (*j_assert) __P((const char *, const char *, int)); int (*j_close) __P((int)); diff --git a/src/dbinc/hash.h b/src/dbinc/hash.h index 72f1e644..f485128a 100644 --- a/src/dbinc/hash.h +++ b/src/dbinc/hash.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/dbinc/heap.h b/src/dbinc/heap.h index 0771921a..ca3407e0 100644 --- a/src/dbinc/heap.h +++ b/src/dbinc/heap.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. */ #ifndef _DB_HEAP_H_ diff --git a/src/dbinc/hmac.h b/src/dbinc/hmac.h index 2d6bb8fb..2a495b17 100644 --- a/src/dbinc/hmac.h +++ b/src/dbinc/hmac.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/lock.h b/src/dbinc/lock.h index c94590f7..eab51832 100644 --- a/src/dbinc/lock.h +++ b/src/dbinc/lock.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -26,7 +26,7 @@ extern "C" { /* * A locker's deadlock resolution priority is stored as a 32 bit unsigned * integer. The maximum priority is DB_LOCK_MAXPRIORITY and the default - * priorit is DB_LOCK_DEFPRIORITY. + * priority is DB_LOCK_DEFPRIORITY. */ #define DB_LOCK_DEFPRIORITY 100 #define DB_LOCK_MAXPRIORITY UINT32_MAX diff --git a/src/dbinc/log.h b/src/dbinc/log.h index 912f61b1..c4dea6fc 100644 --- a/src/dbinc/log.h +++ b/src/dbinc/log.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -72,12 +72,16 @@ struct __fname { #define DBREG_PREOPEN 4 /* Open in mpool only. */ #define DBREG_RCLOSE 5 /* File close after recovery. */ #define DBREG_REOPEN 6 /* Open for in-memory database. */ +#define DBREG_XCHKPNT 7 /* Checkpoint of exclusive file. */ +#define DBREG_XOPEN 8 /* File exclusive open. */ +#define DBREG_XREOPEN 9 /* File exclusive open in-memory. */ /* These bits are logged so db_printlog can handle page data. */ #define DBREG_OP_MASK 0xf /* Opcode mask */ #define DBREG_BIGEND 0x1000 /* Db Big endian. */ #define DBREG_CHKSUM 0x2000 /* Db is checksummed. */ #define DBREG_ENCRYPT 0x4000 /* Db is encrypted. */ +#define DBREG_EXCL 0x8000 /* Db is exclusive. */ /******************************************************* * LOG: @@ -90,6 +94,7 @@ struct __log_persist; typedef struct __log_persist LOGP; #define LFPREFIX "log." /* Log file name prefix. */ #define LFNAME "log.%010d" /* Log file name template. */ #define LFNAME_V1 "log.%05d" /* Log file name template, rev 1. */ +#define IS_LOG_FILE(name) (strncmp(name, LFPREFIX, sizeof(LFPREFIX) - 1) == 0) #define LG_MAX_DEFAULT (10 * MEGABYTE) /* 10 MB. */ #define LG_MAX_INMEM (256 * 1024) /* 256 KB. */ @@ -285,7 +290,7 @@ struct __log { /* SHARED */ /* BEGIN fields protected by rep->mtx_clientdb. */ DB_LSN waiting_lsn; /* First log record after a gap. */ DB_LSN verify_lsn; /* LSN we are waiting to verify. */ - DB_LSN prev_ckp; /* LSN of ckp preceeding verify_lsn. */ + DB_LSN prev_ckp; /* LSN of ckp preceding verify_lsn. */ DB_LSN max_wait_lsn; /* Maximum LSN requested. */ DB_LSN max_perm_lsn; /* Maximum PERMANENT LSN processed. */ db_timespec max_lease_ts; /* Maximum Lease timestamp seen. */ diff --git a/src/dbinc/log_verify.h b/src/dbinc/log_verify.h index 9fc7db7e..fa90ace4 100644 --- a/src/dbinc/log_verify.h +++ b/src/dbinc/log_verify.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -115,7 +115,7 @@ struct __lv_filereg_info { struct __lv_filelife { int32_t dbregid; /* The primary key. */ DBTYPE dbtype; /* The database type. */ - u_int32_t lifetime; /* DBREG_OPEN, DBREG_CHKPNT, DBREG_CLOSE */ + u_int32_t lifetime; /* DBREG_CHKPNT, DBREG_CLOSE, DBREG_OPEN, DBREG_XCHKPNT, DBREG_XOPEN */ db_pgno_t meta_pgno; /* The meta_pgno; */ u_int8_t fileid[DB_FILE_ID_LEN]; DB_LSN lsn; /* The lsn of log updating lifetime. */ @@ -193,11 +193,13 @@ struct __ckp_verify_params { #define INVAL_DBREGID -1 /* - * During recovery, DBREG_CHKPNT can be seen as open, and it's followed by - * a DBREG_RCLOSE or DBREG_CLOSE. + * During recovery, DBREG_CHKPNT and DBREG_XCHKPNT can be seen as open, + * and it's followed by a DBREG_RCLOSE or DBREG_CLOSE. */ #define IS_DBREG_OPEN(opcode) (opcode == DBREG_OPEN || opcode == \ - DBREG_PREOPEN || opcode == DBREG_REOPEN || opcode == DBREG_CHKPNT) + DBREG_PREOPEN || opcode == DBREG_REOPEN || opcode == DBREG_CHKPNT \ + || opcode == DBREG_XCHKPNT || opcode == DBREG_XOPEN || \ + opcode == DBREG_XREOPEN) #define IS_DBREG_CLOSE(opcode) (opcode == DBREG_CLOSE || opcode == DBREG_RCLOSE) #define IS_LOG_VRFY_SUPPORTED(version) ((version) == DB_LOGVERSION) diff --git a/src/dbinc/mp.h b/src/dbinc/mp.h index 2a6510f1..9a10c6d9 100644 --- a/src/dbinc/mp.h +++ b/src/dbinc/mp.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -362,6 +362,7 @@ struct __db_mpool_fstat_int { /* SHARED */ uintmax_t st_page_create; /* Pages created in the cache. */ uintmax_t st_page_in; /* Pages read in. */ uintmax_t st_page_out; /* Pages written out. */ + uintmax_t st_backup_spins; /* Number of spins by a backup. */ #endif }; @@ -394,14 +395,29 @@ struct __db_mpool_fstat_int { /* SHARED */ struct __mpoolfile { /* SHARED */ db_mutex_t mutex; /* MPOOLFILE mutex. */ +#ifndef HAVE_ATOMICFILEREAD + /* Information to synchronize backups. */ + u_int32_t backup_in_progress; /* Backup running. */ + pid_t pid; /* Process doing backup. */ + db_threadid_t tid; /* Thread doing backup. */ + db_atomic_t writers; /* Number of current writers. */ + db_mutex_t mtx_write; /* block writers while updating.*/ + db_pgno_t low_pgno, high_pgno;/* Low and high backup range.*/ +#endif + /* Protected by MPOOLFILE mutex. */ u_int32_t revision; /* Bumped on any movement subdbs. */ u_int32_t mpf_cnt; /* Ref count: DB_MPOOLFILEs. */ + u_int32_t neutral_cnt; /* Ref count: refs that don't care about + * MVCC or DURABLE. That is, read-only + * or write behind references. + */ u_int32_t block_cnt; /* Ref count: blocks in cache. */ db_pgno_t last_pgno; /* Last page in the file. */ db_pgno_t last_flushed_pgno; /* Last page flushed to disk. */ db_pgno_t orig_last_pgno; /* Original last page in the file. */ db_pgno_t maxpgno; /* Maximum page number. */ + u_int8_t excl_lockout; /* Internal exclusive db lockout. */ roff_t path_off; /* File name location. */ diff --git a/src/dbinc/mutex.h b/src/dbinc/mutex.h index d3f92967..b699142c 100644 --- a/src/dbinc/mutex.h +++ b/src/dbinc/mutex.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -43,41 +43,42 @@ extern "C" { #define MTX_ATOMIC_EMULATION 2 #define MTX_DB_HANDLE 3 #define MTX_ENV_DBLIST 4 -#define MTX_ENV_HANDLE 5 -#define MTX_ENV_REGION 6 -#define MTX_LOCK_REGION 7 -#define MTX_LOGICAL_LOCK 8 -#define MTX_LOG_FILENAME 9 -#define MTX_LOG_FLUSH 10 -#define MTX_LOG_HANDLE 11 -#define MTX_LOG_REGION 12 -#define MTX_MPOOLFILE_HANDLE 13 -#define MTX_MPOOL_BH 14 -#define MTX_MPOOL_FH 15 -#define MTX_MPOOL_FILE_BUCKET 16 -#define MTX_MPOOL_HANDLE 17 -#define MTX_MPOOL_HASH_BUCKET 18 -#define MTX_MPOOL_REGION 19 -#define MTX_MUTEX_REGION 20 -#define MTX_MUTEX_TEST 21 -#define MTX_REP_CHKPT 22 -#define MTX_REP_DATABASE 23 -#define MTX_REP_DIAG 24 -#define MTX_REP_EVENT 25 -#define MTX_REP_REGION 26 -#define MTX_REP_START 27 -#define MTX_REP_WAITER 28 -#define MTX_REPMGR 29 -#define MTX_SEQUENCE 30 -#define MTX_TWISTER 31 -#define MTX_TCL_EVENTS 32 -#define MTX_TXN_ACTIVE 33 -#define MTX_TXN_CHKPT 34 -#define MTX_TXN_COMMIT 35 -#define MTX_TXN_MVCC 36 -#define MTX_TXN_REGION 37 +#define MTX_ENV_EXCLDBLIST 5 +#define MTX_ENV_HANDLE 6 +#define MTX_ENV_REGION 7 +#define MTX_LOCK_REGION 8 +#define MTX_LOGICAL_LOCK 9 +#define MTX_LOG_FILENAME 10 +#define MTX_LOG_FLUSH 11 +#define MTX_LOG_HANDLE 12 +#define MTX_LOG_REGION 13 +#define MTX_MPOOLFILE_HANDLE 14 +#define MTX_MPOOL_BH 15 +#define MTX_MPOOL_FH 16 +#define MTX_MPOOL_FILE_BUCKET 17 +#define MTX_MPOOL_HANDLE 18 +#define MTX_MPOOL_HASH_BUCKET 19 +#define MTX_MPOOL_REGION 20 +#define MTX_MUTEX_REGION 21 +#define MTX_MUTEX_TEST 22 +#define MTX_REP_CHKPT 23 +#define MTX_REP_DATABASE 24 +#define MTX_REP_DIAG 25 +#define MTX_REP_EVENT 26 +#define MTX_REP_REGION 27 +#define MTX_REP_START 28 +#define MTX_REP_WAITER 29 +#define MTX_REPMGR 30 +#define MTX_SEQUENCE 31 +#define MTX_TWISTER 32 +#define MTX_TCL_EVENTS 33 +#define MTX_TXN_ACTIVE 34 +#define MTX_TXN_CHKPT 35 +#define MTX_TXN_COMMIT 36 +#define MTX_TXN_MVCC 37 +#define MTX_TXN_REGION 38 -#define MTX_MAX_ENTRY 37 +#define MTX_MAX_ENTRY 38 /* The following macros are defined on some platforms, e.g. QNX. */ #undef __mutex_init diff --git a/src/dbinc/mutex_int.h b/src/dbinc/mutex_int.h index 6d0aa0c2..b9bccdf7 100644 --- a/src/dbinc/mutex_int.h +++ b/src/dbinc/mutex_int.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/os.h b/src/dbinc/os.h index cc15fb69..2515e6ee 100644 --- a/src/dbinc/os.h +++ b/src/dbinc/os.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/partition.h b/src/dbinc/partition.h index 55336b35..09e42573 100644 --- a/src/dbinc/partition.h +++ b/src/dbinc/partition.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * $Id$ @@ -16,7 +16,7 @@ extern "C" { typedef struct __db_partition { u_int32_t nparts; /* number of partitions. */ DBT *keys; /* array of range keys. */ - void *data; /* the partion info. */ + void *data; /* the partition info. */ const char **dirs; /* locations for partitions. */ DB **handles; /* array of partition handles. */ u_int32_t (*callback) (DB *, DBT *); @@ -26,7 +26,7 @@ typedef struct __db_partition { } DB_PARTITION; /* - * Internal part of a partitoned cursor. + * Internal part of a partitioned cursor. */ typedef struct __part_internal { __DBC_INTERNAL @@ -38,6 +38,8 @@ typedef struct __part_internal { #define PART_NAME "__dbp.%s.%03d" #define PART_LEN (strlen("__dbp..")+3) #define PART_PREFIX "__dbp." +#define IS_PARTITION_DB_FILE(name) (strncmp(name, PART_PREFIX, \ + sizeof(PART_PREFIX) - 1) == 0) #define DB_IS_PARTITIONED(dbp) \ (dbp->p_internal != NULL && \ diff --git a/src/dbinc/perfmon.h b/src/dbinc/perfmon.h index 84017695..c3b9b9fa 100644 --- a/src/dbinc/perfmon.h +++ b/src/dbinc/perfmon.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/qam.h b/src/dbinc/qam.h index 91de4185..657c11e2 100644 --- a/src/dbinc/qam.h +++ b/src/dbinc/qam.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -122,17 +122,21 @@ typedef struct __qam_filelist { (DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) + \ ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)) * index)))) +#define QAM_OUTSIDE_QUEUE(meta, recno) \ + (((meta)->cur_recno >= (meta)->first_recno ? \ + ((recno) < (meta)->first_recno || \ + (recno) > (meta)->cur_recno) : \ + ((recno) > (meta)->cur_recno && \ + (recno) < (meta)->first_recno))) + #define QAM_AFTER_CURRENT(meta, recno) \ - ((recno) >= (meta)->cur_recno && \ - ((meta)->first_recno <= (meta)->cur_recno || \ - ((recno) < (meta)->first_recno && \ - (recno) - (meta)->cur_recno < (meta)->first_recno - (recno)))) + ((recno) == (meta)->cur_recno || \ + (QAM_OUTSIDE_QUEUE(meta, recno) && \ + ((recno) - (meta)->cur_recno) <= ((meta)->first_recno - (recno)))) #define QAM_BEFORE_FIRST(meta, recno) \ - ((recno) < (meta)->first_recno && \ - ((meta)->first_recno <= (meta)->cur_recno || \ - ((recno) > (meta)->cur_recno && \ - (recno) - (meta)->cur_recno > (meta)->first_recno - (recno)))) + (QAM_OUTSIDE_QUEUE(meta, recno) && \ + ((meta)->first_recno - (recno)) < ((recno) - (meta)->cur_recno)) #define QAM_NOT_VALID(meta, recno) \ (recno == RECNO_OOB || \ diff --git a/src/dbinc/queue.h b/src/dbinc/queue.h index 0198febd..5a62741a 100644 --- a/src/dbinc/queue.h +++ b/src/dbinc/queue.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1991, 1993 diff --git a/src/dbinc/region.h b/src/dbinc/region.h index 001be762..ac0ff16f 100644 --- a/src/dbinc/region.h +++ b/src/dbinc/region.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -121,6 +121,8 @@ extern "C" { #define DB_REGION_PREFIX "__db" /* DB file name prefix. */ #define DB_REGION_FMT "__db.%03d" /* Region file name format. */ #define DB_REGION_ENV "__db.001" /* Primary environment name. */ +#define IS_DB_FILE(name) (strncmp(name, DB_REGION_PREFIX, \ + sizeof(DB_REGION_PREFIX) - 1) == 0) #define INVALID_REGION_ID 0 /* Out-of-band region ID. */ #define REGION_ID_ENV 1 /* Primary environment ID. */ diff --git a/src/dbinc/rep.h b/src/dbinc/rep.h index d6750872..75004239 100644 --- a/src/dbinc/rep.h +++ b/src/dbinc/rep.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -32,6 +32,8 @@ extern "C" { #define REPLSNHIST "__db.lsn.history" #define REPMEMBERSHIP "__db.membership" #define REPSYSDBPGSZ 1024 +#define IS_REP_FILE(name) (strcmp(name, REPSYSDBNAME) == 0) + /* Current version of commit token format, and LSN history database format. */ #define REP_COMMIT_TOKEN_FMT_VERSION 1 @@ -122,6 +124,7 @@ extern "C" { #define DB_LOGVERSION_50 17 #define DB_LOGVERSION_51 17 #define DB_LOGVERSION_52 18 +#define DB_LOGVERSION_53 19 #define DB_LOGVERSION_MIN DB_LOGVERSION_44 #define DB_REPVERSION_INVALID 0 #define DB_REPVERSION_44 3 @@ -132,7 +135,8 @@ extern "C" { #define DB_REPVERSION_50 5 #define DB_REPVERSION_51 5 #define DB_REPVERSION_52 6 -#define DB_REPVERSION DB_REPVERSION_52 +#define DB_REPVERSION_53 7 +#define DB_REPVERSION DB_REPVERSION_53 #define DB_REPVERSION_MIN DB_REPVERSION_44 /* @@ -389,6 +393,7 @@ typedef struct __rep { /* SHARED */ u_int site_max; /* Total array slots allocated. */ int self_eid; /* Where to find the local site. */ u_int siteinfo_seq; /* Number of updates to this info. */ + u_int32_t min_log_file; /* Earliest log needed by repgroup. */ pid_t listener; @@ -626,7 +631,7 @@ do { \ * between the time of this call and the use of the pointers. * * The current file information (curinfo) is stored in shared region - * memory and accessed via an offset. It contains two DBTs that themselves + * memory and accessed via an offset. It contains DBTs that themselves * point to allocated data. __rep_nextfile() manages this information in a * single chunk of shared memory. * @@ -647,6 +652,12 @@ do { \ sizeof(__rep_fileinfo_args) + (curinfo)->uid.size); \ else \ (curinfo)->info.data = NULL; \ + if ((curinfo)->dir.size > 0) \ + (curinfo)->dir.data = R_ADDR(infop, rep->curinfo_off + \ + sizeof(__rep_fileinfo_args) + (curinfo)->uid.size + \ + (curinfo)->info.size); \ + else \ + (curinfo)->dir.data = NULL; \ } while (0) /* @@ -795,10 +806,14 @@ struct __db_rep { socket_t listen_fd; db_timespec last_bcast; /* Time of last broadcast msg. */ - int finished; /* Repmgr threads should shut down. */ + /* + * Status of repmgr. It is ready when repmgr is not yet started. It + * is running after repmgr is (re)started. It is stopped if the env + * of the running repmgr is closed, or the site is removed. + */ + enum { ready, running, stopped } repmgr_status; int new_connection; /* Since last master seek attempt. */ int takeover_pending; /* We've been elected master. */ - int mgr_started; int gmdb_busy; int client_intent; /* Will relinquish master role. */ int gmdb_dirty; diff --git a/src/dbinc/repmgr.h b/src/dbinc/repmgr.h index 78a7b9d6..d8fd199c 100644 --- a/src/dbinc/repmgr.h +++ b/src/dbinc/repmgr.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -55,6 +55,7 @@ extern "C" { #define REPMGR_MAX_V4_MSG_TYPE 8 #define HEARTBEAT_MIN_VERSION 2 #define CHANNEL_MIN_VERSION 4 +#define CONN_COLLISION_VERSION 4 #define GM_MIN_VERSION 4 #define OWN_MIN_VERSION 4 @@ -203,7 +204,7 @@ struct __repmgr_runnable { */ struct __repmgr_retry { TAILQ_ENTRY(__repmgr_retry) entries; - u_int eid; + int eid; db_timespec time; }; @@ -343,9 +344,6 @@ struct __repmgr_connection { #define CONN_READY 6 /* Everything's fine. */ int state; -#define CONN_INCOMING 0x01 - u_int32_t flags; - /* * Input: while we're reading a message, we keep track of what phase * we're in. In both phases, we use a REPMGR_IOVECS to keep track of @@ -488,8 +486,8 @@ typedef struct { (((u_int)(e)) < db_rep->site_cnt)) #define FOR_EACH_REMOTE_SITE_INDEX(i) \ for ((i) = (db_rep->self_eid == 0 ? 1 : 0); \ - (i) < db_rep->site_cnt; \ - ((int)++(i)) == db_rep->self_eid ? ++(i) : i) + ((u_int)i) < db_rep->site_cnt; \ + (int)(++(i)) == db_rep->self_eid ? ++(i) : i) struct __repmgr_site { repmgr_netaddr_t net_addr; @@ -513,8 +511,20 @@ struct __repmgr_site { db_timespec last_rcvd_timestamp; /* Contents depends on state. */ - union { - REPMGR_CONNECTION *conn; /* when CONNECTED */ + struct { + struct { /* when CONNECTED */ + /* + * The only time we ever have two connections is in case + * of a "collision" on the "server" side. In that case, + * the incoming connection either will be closed + * promptly by the remote "client", or it is a half-open + * connection due to the remote client system having + * crashed and rebooted, in which case KEEPALIVE will + * eventually clear it. + */ + REPMGR_CONNECTION *in; /* incoming connection */ + REPMGR_CONNECTION *out; /* outgoing connection */ + } conn; REPMGR_RETRY *retry; /* when PAUSING */ /* Unused when CONNECTING. */ } ref; @@ -736,12 +746,6 @@ typedef struct { (p) == DB_REPMGR_ACKS_QUORUM || \ (p) == DB_REPMGR_ACKS_ONE_PEER) -#define IS_SITE_AVAILABLE(s) ((s)->state == SITE_CONNECTED && \ - (s)->ref.conn->state == CONN_READY) - -#define IS_SITE_HANDSHAKEN(s) ((s)->state == SITE_CONNECTED && \ - IS_READY_STATE((s)->ref.conn->state)) - /* * Most of the code in repmgr runs while holding repmgr's main mutex, which * resides in db_rep->mutex. This mutex is owned by a single repmgr process, diff --git a/src/dbinc/shqueue.h b/src/dbinc/shqueue.h index 7c2a15da..22464462 100644 --- a/src/dbinc/shqueue.h +++ b/src/dbinc/shqueue.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/tcl_db.h b/src/dbinc/tcl_db.h index 754b31d5..4c56164f 100644 --- a/src/dbinc/tcl_db.h +++ b/src/dbinc/tcl_db.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc/txn.h b/src/dbinc/txn.h index 36546377..7cbae263 100644 --- a/src/dbinc/txn.h +++ b/src/dbinc/txn.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -20,7 +20,8 @@ typedef enum { TXN_CLOSE, /* Close a DB handle whose close had failed. */ TXN_REMOVE, /* Remove a file. */ TXN_TRADE, /* Trade lockers. */ - TXN_TRADED /* Already traded; downgrade lock. */ + TXN_TRADED, /* Already traded; downgrade lock. */ + TXN_XTRADE /* Trade lockers on exclusive db handle. */ } TXN_EVENT_T; struct __db_txnregion; typedef struct __db_txnregion DB_TXNREGION; @@ -53,7 +54,7 @@ DB_ALIGN8 struct __db_txn_stat_int { /* SHARED */ DB_LSN st_last_ckp; /* lsn of the last checkpoint */ time_t st_time_ckp; /* time of last checkpoint */ u_int32_t st_last_txnid; /* last transaction id given out */ - u_int32_t st_inittxns; /* inital txns allocated */ + u_int32_t st_inittxns; /* initial txns allocated */ u_int32_t st_maxtxns; /* maximum txns possible */ uintmax_t st_naborts; /* number of aborted transactions */ uintmax_t st_nbegins; /* number of begun transactions */ diff --git a/src/dbinc/win_db.h b/src/dbinc/win_db.h index 497aaa07..ba57cd1f 100644 --- a/src/dbinc/win_db.h +++ b/src/dbinc/win_db.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * The following provides the information necessary to build Berkeley * DB on native Windows, and other Windows environments such as MinGW. diff --git a/src/dbinc/xa.h b/src/dbinc/xa.h index 726104c3..7283c1ea 100644 --- a/src/dbinc/xa.h +++ b/src/dbinc/xa.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbinc_auto/api_flags.in b/src/dbinc_auto/api_flags.in index 3768c73f..9727ede2 100644 --- a/src/dbinc_auto/api_flags.in +++ b/src/dbinc_auto/api_flags.in @@ -5,30 +5,35 @@ #define DB_ARCH_LOG 0x00000004 #define DB_ARCH_REMOVE 0x00000008 #define DB_AUTO_COMMIT 0x00000100 +#define DB_BACKUP_CLEAN 0x00000002 +#define DB_BACKUP_FILES 0x00000008 +#define DB_BACKUP_NO_LOGS 0x00000010 +#define DB_BACKUP_SINGLE_DIR 0x00000020 +#define DB_BACKUP_UPDATE 0x00000040 #define DB_BOOTSTRAP_HELPER 0x00000001 #define DB_CDB_ALLDB 0x00000040 #define DB_CHKSUM 0x00000008 #define DB_CKP_INTERNAL 0x00000002 #define DB_CREATE 0x00000001 #define DB_CURSOR_BULK 0x00000001 -#define DB_CURSOR_TRANSIENT 0x00000004 +#define DB_CURSOR_TRANSIENT 0x00000008 #define DB_CXX_NO_EXCEPTIONS 0x00000002 #define DB_DATABASE_LOCKING 0x00000080 -#define DB_DIRECT 0x00000010 +#define DB_DIRECT 0x00000020 #define DB_DIRECT_DB 0x00000200 #define DB_DSYNC_DB 0x00000400 #define DB_DUP 0x00000010 -#define DB_DUPSORT 0x00000004 -#define DB_DURABLE_UNKNOWN 0x00000020 +#define DB_DUPSORT 0x00000002 +#define DB_DURABLE_UNKNOWN 0x00000040 #define DB_ENCRYPT 0x00000001 #define DB_ENCRYPT_AES 0x00000001 -#define DB_EXCL 0x00000040 -#define DB_EXTENT 0x00000040 -#define DB_FAILCHK 0x00000020 +#define DB_EXCL 0x00000004 +#define DB_EXTENT 0x00000100 +#define DB_FAILCHK 0x00000010 #define DB_FAILCHK_ISALIVE 0x00000040 #define DB_FAST_STAT 0x00000001 #define DB_FCNTL_LOCKING 0x00000800 -#define DB_FLUSH 0x00000001 +#define DB_FLUSH 0x00000002 #define DB_FORCE 0x00000001 #define DB_FORCESYNC 0x00000001 #define DB_FOREIGN_ABORT 0x00000001 @@ -48,26 +53,28 @@ #define DB_INIT_REP 0x00001000 #define DB_INIT_TXN 0x00002000 #define DB_INORDER 0x00000020 -#define DB_INTERNAL_DB 0x00001000 +#define DB_INTERNAL_PERSISTENT_DB 0x00001000 +#define DB_INTERNAL_TEMPORARY_DB 0x00002000 #define DB_JOIN_NOSORT 0x00000001 #define DB_LEGACY 0x00000004 #define DB_LOCAL_SITE 0x00000008 #define DB_LOCKDOWN 0x00004000 #define DB_LOCK_CHECK 0x00000001 -#define DB_LOCK_NOWAIT 0x00000002 -#define DB_LOCK_RECORD 0x00000004 -#define DB_LOCK_SET_TIMEOUT 0x00000008 -#define DB_LOCK_SWITCH 0x00000010 -#define DB_LOCK_UPGRADE 0x00000020 +#define DB_LOCK_IGNORE_REC 0x00000002 +#define DB_LOCK_NOWAIT 0x00000004 +#define DB_LOCK_RECORD 0x00000008 +#define DB_LOCK_SET_TIMEOUT 0x00000010 +#define DB_LOCK_SWITCH 0x00000020 +#define DB_LOCK_UPGRADE 0x00000040 #define DB_LOG_AUTO_REMOVE 0x00000001 -#define DB_LOG_CHKPNT 0x00000002 +#define DB_LOG_CHKPNT 0x00000001 #define DB_LOG_COMMIT 0x00000004 #define DB_LOG_DIRECT 0x00000002 #define DB_LOG_DSYNC 0x00000004 #define DB_LOG_IN_MEMORY 0x00000008 #define DB_LOG_NOCOPY 0x00000008 #define DB_LOG_NOT_DURABLE 0x00000010 -#define DB_LOG_NO_DATA 0x00000004 +#define DB_LOG_NO_DATA 0x00000002 #define DB_LOG_VERIFY_CAF 0x00000001 #define DB_LOG_VERIFY_DBFILE 0x00000002 #define DB_LOG_VERIFY_ERR 0x00000004 @@ -86,26 +93,26 @@ #define DB_MPOOL_LAST 0x00000010 #define DB_MPOOL_NEW 0x00000020 #define DB_MPOOL_NOFILE 0x00000001 -#define DB_MPOOL_NOLOCK 0x00000002 +#define DB_MPOOL_NOLOCK 0x00000004 #define DB_MPOOL_TRY 0x00000040 #define DB_MPOOL_UNLINK 0x00000002 #define DB_MULTIPLE 0x00000800 #define DB_MULTIPLE_KEY 0x00004000 -#define DB_MULTIVERSION 0x00000004 +#define DB_MULTIVERSION 0x00000008 #define DB_MUTEX_ALLOCATED 0x00000001 #define DB_MUTEX_LOCKED 0x00000002 #define DB_MUTEX_LOGICAL_LOCK 0x00000004 #define DB_MUTEX_PROCESS_ONLY 0x00000008 #define DB_MUTEX_SELF_BLOCK 0x00000010 #define DB_MUTEX_SHARED 0x00000020 -#define DB_NOERROR 0x00002000 +#define DB_NOERROR 0x00004000 #define DB_NOFLUSH 0x00001000 #define DB_NOLOCKING 0x00002000 -#define DB_NOMMAP 0x00000008 +#define DB_NOMMAP 0x00000010 #define DB_NOORDERCHK 0x00000002 #define DB_NOPANIC 0x00004000 #define DB_NOSYNC 0x00000001 -#define DB_NO_AUTO_COMMIT 0x00004000 +#define DB_NO_AUTO_COMMIT 0x00008000 #define DB_NO_CHECKPOINT 0x00008000 #define DB_ODDFILESIZE 0x00000080 #define DB_ORDERCHKONLY 0x00000004 @@ -116,7 +123,7 @@ #define DB_PR_PAGE 0x00000010 #define DB_PR_RECOVERYTEST 0x00000020 #define DB_RDONLY 0x00000400 -#define DB_RDWRMASTER 0x00008000 +#define DB_RDWRMASTER 0x00010000 #define DB_READ_COMMITTED 0x00000400 #define DB_READ_UNCOMMITTED 0x00000200 #define DB_RECNUM 0x00000040 @@ -179,42 +186,43 @@ #define DB_ST_RELEN 0x00008000 #define DB_ST_TOPLEVEL 0x00010000 #define DB_SYSTEM_MEM 0x00080000 -#define DB_THREAD 0x00000010 +#define DB_THREAD 0x00000020 #define DB_TIME_NOTGRANTED 0x00040000 -#define DB_TRUNCATE 0x00010000 -#define DB_TXN_BULK 0x00000008 +#define DB_TRUNCATE 0x00020000 +#define DB_TXN_BULK 0x00000010 #define DB_TXN_FAMILY 0x00000040 #define DB_TXN_NOSYNC 0x00000001 -#define DB_TXN_NOT_DURABLE 0x00000002 +#define DB_TXN_NOT_DURABLE 0x00000004 #define DB_TXN_NOWAIT 0x00000002 -#define DB_TXN_SNAPSHOT 0x00000010 -#define DB_TXN_SYNC 0x00000004 +#define DB_TXN_SNAPSHOT 0x00000004 +#define DB_TXN_SYNC 0x00000008 #define DB_TXN_WAIT 0x00000080 #define DB_TXN_WRITE_NOSYNC 0x00000020 #define DB_UNREF 0x00020000 #define DB_UPGRADE 0x00000001 #define DB_USE_ENVIRON 0x00000004 #define DB_USE_ENVIRON_ROOT 0x00000008 -#define DB_VERB_DEADLOCK 0x00000001 -#define DB_VERB_FILEOPS 0x00000002 -#define DB_VERB_FILEOPS_ALL 0x00000004 -#define DB_VERB_RECOVERY 0x00000008 -#define DB_VERB_REGISTER 0x00000010 -#define DB_VERB_REPLICATION 0x00000020 -#define DB_VERB_REPMGR_CONNFAIL 0x00000040 -#define DB_VERB_REPMGR_MISC 0x00000080 -#define DB_VERB_REP_ELECT 0x00000100 -#define DB_VERB_REP_LEASE 0x00000200 -#define DB_VERB_REP_MISC 0x00000400 -#define DB_VERB_REP_MSGS 0x00000800 -#define DB_VERB_REP_SYNC 0x00001000 -#define DB_VERB_REP_SYSTEM 0x00002000 -#define DB_VERB_REP_TEST 0x00004000 -#define DB_VERB_WAITSFOR 0x00008000 +#define DB_VERB_BACKUP 0x00000001 +#define DB_VERB_DEADLOCK 0x00000002 +#define DB_VERB_FILEOPS 0x00000004 +#define DB_VERB_FILEOPS_ALL 0x00000008 +#define DB_VERB_RECOVERY 0x00000010 +#define DB_VERB_REGISTER 0x00000020 +#define DB_VERB_REPLICATION 0x00000040 +#define DB_VERB_REPMGR_CONNFAIL 0x00000080 +#define DB_VERB_REPMGR_MISC 0x00000100 +#define DB_VERB_REP_ELECT 0x00000200 +#define DB_VERB_REP_LEASE 0x00000400 +#define DB_VERB_REP_MISC 0x00000800 +#define DB_VERB_REP_MSGS 0x00001000 +#define DB_VERB_REP_SYNC 0x00002000 +#define DB_VERB_REP_SYSTEM 0x00004000 +#define DB_VERB_REP_TEST 0x00008000 +#define DB_VERB_WAITSFOR 0x00010000 #define DB_VERIFY 0x00000002 #define DB_VERIFY_PARTITION 0x00040000 -#define DB_WRITECURSOR 0x00000008 +#define DB_WRITECURSOR 0x00000010 #define DB_WRITELOCK 0x00000020 -#define DB_WRITEOPEN 0x00020000 +#define DB_WRITEOPEN 0x00040000 #define DB_XA_CREATE 0x00000001 #define DB_YIELDCPU 0x00080000 diff --git a/src/dbinc_auto/db_ext.h b/src/dbinc_auto/db_ext.h index 0ffefe31..de2a6ce4 100644 --- a/src/dbinc_auto/db_ext.h +++ b/src/dbinc_auto/db_ext.h @@ -61,6 +61,9 @@ int __db_relink_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __db_merge_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __db_pgno_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __db_init_print __P((ENV *, DB_DISTAB *)); +int __db_dbbackup_pp __P((DB_ENV *, const char *, const char *, u_int32_t)); +int __db_dbbackup __P((DB_ENV *, DB_THREAD_INFO *, const char *, const char *, u_int32_t)); +int __db_backup __P((DB_ENV *, const char *, u_int32_t)); int __dbc_close __P((DBC *)); int __dbc_destroy __P((DBC *)); int __dbc_cmp __P((DBC *, DBC *, int *)); @@ -214,6 +217,7 @@ const FN * __db_get_flags_fn __P((void)); int __db_prpage_int __P((ENV *, DB_MSGBUF *, DB *, char *, PAGE *, u_int32_t, u_int8_t *, u_int32_t)); void __db_prbytes __P((ENV *, DB_MSGBUF *, u_int8_t *, u_int32_t)); void __db_prflags __P((ENV *, DB_MSGBUF *, u_int32_t, const FN *, const char *, const char *)); +int __db_name_to_val __P((FN const *, char *)); const char *__db_pagetype_to_string __P((u_int32_t)); int __db_dump_pp __P((DB *, const char *, int (*)(void *, const void *), void *, int, int)); int __db_dump __P((DB *, const char *, int (*)(void *, const void *), void *, int, int)); diff --git a/src/dbinc_auto/env_ext.h b/src/dbinc_auto/env_ext.h index d9b8d669..55dbcba4 100644 --- a/src/dbinc_auto/env_ext.h +++ b/src/dbinc_auto/env_ext.h @@ -16,8 +16,11 @@ int __env_region_extend __P((ENV *, REGINFO *)); uintmax_t __env_elem_size __P((ENV *, void *)); void * __env_get_chunk __P((REGINFO *, void **, uintmax_t *)); void __env_alloc_print __P((REGINFO *, u_int32_t)); +int __env_get_backup_config __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t*)); +int __env_set_backup_config __P((DB_ENV *, DB_BACKUP_CONFIG, u_int32_t)); +int __env_get_backup_callbacks __P((DB_ENV *, int (**)(DB_ENV *, const char *, const char *, void **), int (**)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (**)(DB_ENV *, const char *, void *))); +int __env_set_backup_callbacks __P((DB_ENV *, int (*)(DB_ENV *, const char *, const char *, void **), int (*)(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), int (*)(DB_ENV *, const char *, void *))); int __env_read_db_config __P((ENV *)); -int __config_split __P((char *, char *[])); int __env_failchk_pp __P((DB_ENV *, u_int32_t)); int __env_failchk_int __P((DB_ENV *)); size_t __env_thread_size __P((ENV *, size_t)); @@ -41,9 +44,11 @@ int __env_set_encrypt __P((DB_ENV *, const char *, u_int32_t)); void __env_map_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *)); void __env_fetch_flags __P((const FLAG_MAP *, u_int, u_int32_t *, u_int32_t *)); int __env_set_flags __P((DB_ENV *, u_int32_t, int)); +int __env_set_backup __P((ENV *, int)); int __env_set_data_dir __P((DB_ENV *, const char *)); int __env_add_data_dir __P((DB_ENV *, const char *)); int __env_set_create_dir __P((DB_ENV *, const char *)); +int __env_set_metadata_dir __P((DB_ENV *, const char *)); int __env_set_data_len __P((DB_ENV *, u_int32_t)); int __env_set_intermediate_dir_mode __P((DB_ENV *, const char *)); void __env_get_errcall __P((DB_ENV *, void (**)(const DB_ENV *, const char *, const char *))); @@ -85,6 +90,7 @@ int __env_turn_off __P((ENV *, u_int32_t)); void __env_panic_set __P((ENV *, int)); int __env_ref_increment __P((ENV *)); int __env_ref_decrement __P((ENV *)); +int __env_ref_get __P((DB_ENV *, u_int32_t *)); int __env_detach __P((ENV *, int)); int __env_remove_env __P((ENV *)); int __env_region_attach __P((ENV *, REGINFO *, size_t, size_t)); diff --git a/src/dbinc_auto/heap_ext.h b/src/dbinc_auto/heap_ext.h index 0fe8f21b..8bc24b61 100644 --- a/src/dbinc_auto/heap_ext.h +++ b/src/dbinc_auto/heap_ext.h @@ -19,13 +19,16 @@ int __heap_pg_alloc_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __heap_trunc_meta_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __heap_trunc_page_print __P((ENV *, DBT *, DB_LSN *, db_recops, void *)); int __heap_init_print __P((ENV *, DB_DISTAB *)); +int __heap_backup __P((DB_ENV *, DB *, DB_THREAD_INFO *, DB_FH *, void *, u_int32_t)); int __heap_pgin __P((DB *, db_pgno_t, void *, DBT *)); int __heap_pgout __P((DB *, db_pgno_t, void *, DBT *)); int __heap_mswap __P((ENV *, PAGE *)); int __heap_db_create __P((DB *)); int __heap_db_close __P((DB *)); int __heap_get_heapsize __P((DB *, u_int32_t *, u_int32_t *)); +int __heap_get_heap_regionsize __P((DB *, u_int32_t *)); int __heap_set_heapsize __P((DB *, u_int32_t, u_int32_t, u_int32_t)); +int __heap_set_heap_regionsize __P((DB *, u_int32_t)); int __heap_exist __P((void)); int __heap_open __P((DB *, DB_THREAD_INFO *, DB_TXN *, const char *, db_pgno_t, u_int32_t)); int __heap_metachk __P((DB *, const char *, HEAPMETA *)); diff --git a/src/dbinc_auto/int_def.in b/src/dbinc_auto/int_def.in index 98ab0008..dce2831c 100644 --- a/src/dbinc_auto/int_def.in +++ b/src/dbinc_auto/int_def.in @@ -83,6 +83,9 @@ #define __db_merge_print __db_merge_print@DB_VERSION_UNIQUE_NAME@ #define __db_pgno_print __db_pgno_print@DB_VERSION_UNIQUE_NAME@ #define __db_init_print __db_init_print@DB_VERSION_UNIQUE_NAME@ +#define __db_dbbackup_pp __db_dbbackup_pp@DB_VERSION_UNIQUE_NAME@ +#define __db_dbbackup __db_dbbackup@DB_VERSION_UNIQUE_NAME@ +#define __db_backup __db_backup@DB_VERSION_UNIQUE_NAME@ #define __dbc_close __dbc_close@DB_VERSION_UNIQUE_NAME@ #define __dbc_destroy __dbc_destroy@DB_VERSION_UNIQUE_NAME@ #define __dbc_cmp __dbc_cmp@DB_VERSION_UNIQUE_NAME@ @@ -236,6 +239,7 @@ #define __db_prpage_int __db_prpage_int@DB_VERSION_UNIQUE_NAME@ #define __db_prbytes __db_prbytes@DB_VERSION_UNIQUE_NAME@ #define __db_prflags __db_prflags@DB_VERSION_UNIQUE_NAME@ +#define __db_name_to_val __db_name_to_val@DB_VERSION_UNIQUE_NAME@ #define __db_pagetype_to_string __db_pagetype_to_string@DB_VERSION_UNIQUE_NAME@ #define __db_dump_pp __db_dump_pp@DB_VERSION_UNIQUE_NAME@ #define __db_dump __db_dump@DB_VERSION_UNIQUE_NAME@ @@ -736,8 +740,11 @@ #define __env_elem_size __env_elem_size@DB_VERSION_UNIQUE_NAME@ #define __env_get_chunk __env_get_chunk@DB_VERSION_UNIQUE_NAME@ #define __env_alloc_print __env_alloc_print@DB_VERSION_UNIQUE_NAME@ +#define __env_get_backup_config __env_get_backup_config@DB_VERSION_UNIQUE_NAME@ +#define __env_set_backup_config __env_set_backup_config@DB_VERSION_UNIQUE_NAME@ +#define __env_get_backup_callbacks __env_get_backup_callbacks@DB_VERSION_UNIQUE_NAME@ +#define __env_set_backup_callbacks __env_set_backup_callbacks@DB_VERSION_UNIQUE_NAME@ #define __env_read_db_config __env_read_db_config@DB_VERSION_UNIQUE_NAME@ -#define __config_split __config_split@DB_VERSION_UNIQUE_NAME@ #define __env_failchk_pp __env_failchk_pp@DB_VERSION_UNIQUE_NAME@ #define __env_failchk_int __env_failchk_int@DB_VERSION_UNIQUE_NAME@ #define __env_thread_size __env_thread_size@DB_VERSION_UNIQUE_NAME@ @@ -761,9 +768,11 @@ #define __env_map_flags __env_map_flags@DB_VERSION_UNIQUE_NAME@ #define __env_fetch_flags __env_fetch_flags@DB_VERSION_UNIQUE_NAME@ #define __env_set_flags __env_set_flags@DB_VERSION_UNIQUE_NAME@ +#define __env_set_backup __env_set_backup@DB_VERSION_UNIQUE_NAME@ #define __env_set_data_dir __env_set_data_dir@DB_VERSION_UNIQUE_NAME@ #define __env_add_data_dir __env_add_data_dir@DB_VERSION_UNIQUE_NAME@ #define __env_set_create_dir __env_set_create_dir@DB_VERSION_UNIQUE_NAME@ +#define __env_set_metadata_dir __env_set_metadata_dir@DB_VERSION_UNIQUE_NAME@ #define __env_set_data_len __env_set_data_len@DB_VERSION_UNIQUE_NAME@ #define __env_set_intermediate_dir_mode __env_set_intermediate_dir_mode@DB_VERSION_UNIQUE_NAME@ #define __env_get_errcall __env_get_errcall@DB_VERSION_UNIQUE_NAME@ @@ -805,6 +814,7 @@ #define __env_panic_set __env_panic_set@DB_VERSION_UNIQUE_NAME@ #define __env_ref_increment __env_ref_increment@DB_VERSION_UNIQUE_NAME@ #define __env_ref_decrement __env_ref_decrement@DB_VERSION_UNIQUE_NAME@ +#define __env_ref_get __env_ref_get@DB_VERSION_UNIQUE_NAME@ #define __env_detach __env_detach@DB_VERSION_UNIQUE_NAME@ #define __env_remove_env __env_remove_env@DB_VERSION_UNIQUE_NAME@ #define __env_region_attach __env_region_attach@DB_VERSION_UNIQUE_NAME@ @@ -1054,13 +1064,16 @@ #define __heap_trunc_meta_print __heap_trunc_meta_print@DB_VERSION_UNIQUE_NAME@ #define __heap_trunc_page_print __heap_trunc_page_print@DB_VERSION_UNIQUE_NAME@ #define __heap_init_print __heap_init_print@DB_VERSION_UNIQUE_NAME@ +#define __heap_backup __heap_backup@DB_VERSION_UNIQUE_NAME@ #define __heap_pgin __heap_pgin@DB_VERSION_UNIQUE_NAME@ #define __heap_pgout __heap_pgout@DB_VERSION_UNIQUE_NAME@ #define __heap_mswap __heap_mswap@DB_VERSION_UNIQUE_NAME@ #define __heap_db_create __heap_db_create@DB_VERSION_UNIQUE_NAME@ #define __heap_db_close __heap_db_close@DB_VERSION_UNIQUE_NAME@ #define __heap_get_heapsize __heap_get_heapsize@DB_VERSION_UNIQUE_NAME@ +#define __heap_get_heap_regionsize __heap_get_heap_regionsize@DB_VERSION_UNIQUE_NAME@ #define __heap_set_heapsize __heap_set_heapsize@DB_VERSION_UNIQUE_NAME@ +#define __heap_set_heap_regionsize __heap_set_heap_regionsize@DB_VERSION_UNIQUE_NAME@ #define __heap_exist __heap_exist@DB_VERSION_UNIQUE_NAME@ #define __heap_open __heap_open@DB_VERSION_UNIQUE_NAME@ #define __heap_metachk __heap_metachk@DB_VERSION_UNIQUE_NAME@ @@ -1175,6 +1188,7 @@ #define __log_set_version __log_set_version@DB_VERSION_UNIQUE_NAME@ #define __log_get_oldversion __log_get_oldversion@DB_VERSION_UNIQUE_NAME@ #define __log_archive_pp __log_archive_pp@DB_VERSION_UNIQUE_NAME@ +#define __log_archive __log_archive@DB_VERSION_UNIQUE_NAME@ #define __log_get_stable_lsn __log_get_stable_lsn@DB_VERSION_UNIQUE_NAME@ #define __log_autoremove __log_autoremove@DB_VERSION_UNIQUE_NAME@ #define __log_check_page_lsn __log_check_page_lsn@DB_VERSION_UNIQUE_NAME@ @@ -1351,6 +1365,10 @@ #define __return_txn_pages __return_txn_pages@DB_VERSION_UNIQUE_NAME@ #define __memp_alloc __memp_alloc@DB_VERSION_UNIQUE_NAME@ #define __memp_free __memp_free@DB_VERSION_UNIQUE_NAME@ +#define __memp_backup_open __memp_backup_open@DB_VERSION_UNIQUE_NAME@ +#define __memp_backup_mpf __memp_backup_mpf@DB_VERSION_UNIQUE_NAME@ +#define __memp_backup_close __memp_backup_close@DB_VERSION_UNIQUE_NAME@ +#define __memp_failchk __memp_failchk@DB_VERSION_UNIQUE_NAME@ #define __memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@ #define __memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@ #define __memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@ @@ -1561,6 +1579,7 @@ #define __os_unmapfile __os_unmapfile@DB_VERSION_UNIQUE_NAME@ #define __os_mkdir __os_mkdir@DB_VERSION_UNIQUE_NAME@ #define __os_open __os_open@DB_VERSION_UNIQUE_NAME@ +#define __os_concat_path __os_concat_path@DB_VERSION_UNIQUE_NAME@ #define __os_id __os_id@DB_VERSION_UNIQUE_NAME@ #define __os_rename __os_rename@DB_VERSION_UNIQUE_NAME@ #define __os_isroot __os_isroot@DB_VERSION_UNIQUE_NAME@ @@ -1616,6 +1635,7 @@ #define __qam_exid __qam_exid@DB_VERSION_UNIQUE_NAME@ #define __qam_nameop __qam_nameop@DB_VERSION_UNIQUE_NAME@ #define __qam_lsn_reset __qam_lsn_reset@DB_VERSION_UNIQUE_NAME@ +#define __qam_backup_extents __qam_backup_extents@DB_VERSION_UNIQUE_NAME@ #define __qam_db_create __qam_db_create@DB_VERSION_UNIQUE_NAME@ #define __qam_db_close __qam_db_close@DB_VERSION_UNIQUE_NAME@ #define __qam_get_extentsize __qam_get_extentsize@DB_VERSION_UNIQUE_NAME@ @@ -1653,6 +1673,8 @@ #define __rep_egen_unmarshal __rep_egen_unmarshal@DB_VERSION_UNIQUE_NAME@ #define __rep_fileinfo_marshal __rep_fileinfo_marshal@DB_VERSION_UNIQUE_NAME@ #define __rep_fileinfo_unmarshal __rep_fileinfo_unmarshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_fileinfo_v6_marshal __rep_fileinfo_v6_marshal@DB_VERSION_UNIQUE_NAME@ +#define __rep_fileinfo_v6_unmarshal __rep_fileinfo_v6_unmarshal@DB_VERSION_UNIQUE_NAME@ #define __rep_grant_info_marshal __rep_grant_info_marshal@DB_VERSION_UNIQUE_NAME@ #define __rep_grant_info_unmarshal __rep_grant_info_unmarshal@DB_VERSION_UNIQUE_NAME@ #define __rep_logreq_marshal __rep_logreq_marshal@DB_VERSION_UNIQUE_NAME@ @@ -1825,6 +1847,7 @@ #define __repmgr_autostart __repmgr_autostart@DB_VERSION_UNIQUE_NAME@ #define __repmgr_start_selector __repmgr_start_selector@DB_VERSION_UNIQUE_NAME@ #define __repmgr_close __repmgr_close@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_stop __repmgr_stop@DB_VERSION_UNIQUE_NAME@ #define __repmgr_set_ack_policy __repmgr_set_ack_policy@DB_VERSION_UNIQUE_NAME@ #define __repmgr_get_ack_policy __repmgr_get_ack_policy@DB_VERSION_UNIQUE_NAME@ #define __repmgr_env_create __repmgr_env_create@DB_VERSION_UNIQUE_NAME@ @@ -1913,7 +1936,7 @@ #define __repmgr_bow_out __repmgr_bow_out@DB_VERSION_UNIQUE_NAME@ #define __repmgr_accept __repmgr_accept@DB_VERSION_UNIQUE_NAME@ #define __repmgr_compute_timeout __repmgr_compute_timeout@DB_VERSION_UNIQUE_NAME@ -#define __repmgr_master_connection __repmgr_master_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_connected_master __repmgr_connected_master@DB_VERSION_UNIQUE_NAME@ #define __repmgr_check_timeouts __repmgr_check_timeouts@DB_VERSION_UNIQUE_NAME@ #define __repmgr_first_try_connections __repmgr_first_try_connections@DB_VERSION_UNIQUE_NAME@ #define __repmgr_send_v1_handshake __repmgr_send_v1_handshake@DB_VERSION_UNIQUE_NAME@ @@ -1970,8 +1993,10 @@ #define __repmgr_init_recover __repmgr_init_recover@DB_VERSION_UNIQUE_NAME@ #endif #define __repmgr_schedule_connection_attempt __repmgr_schedule_connection_attempt@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_is_server __repmgr_is_server@DB_VERSION_UNIQUE_NAME@ #define __repmgr_reset_for_reading __repmgr_reset_for_reading@DB_VERSION_UNIQUE_NAME@ #define __repmgr_new_connection __repmgr_new_connection@DB_VERSION_UNIQUE_NAME@ +#define __repmgr_set_keepalive __repmgr_set_keepalive@DB_VERSION_UNIQUE_NAME@ #define __repmgr_new_site __repmgr_new_site@DB_VERSION_UNIQUE_NAME@ #define __repmgr_create_mutex __repmgr_create_mutex@DB_VERSION_UNIQUE_NAME@ #define __repmgr_destroy_mutex __repmgr_destroy_mutex@DB_VERSION_UNIQUE_NAME@ @@ -2034,6 +2059,7 @@ #define dbc_Cmd dbc_Cmd@DB_VERSION_UNIQUE_NAME@ #define env_Cmd env_Cmd@DB_VERSION_UNIQUE_NAME@ #define tcl_EnvRemove tcl_EnvRemove@DB_VERSION_UNIQUE_NAME@ +#define tcl_EnvClose tcl_EnvClose@DB_VERSION_UNIQUE_NAME@ #define tcl_EnvIdReset tcl_EnvIdReset@DB_VERSION_UNIQUE_NAME@ #define tcl_EnvLsnReset tcl_EnvLsnReset@DB_VERSION_UNIQUE_NAME@ #define tcl_EnvVerbose tcl_EnvVerbose@DB_VERSION_UNIQUE_NAME@ diff --git a/src/dbinc_auto/log_ext.h b/src/dbinc_auto/log_ext.h index 9f6e09ab..dde6742d 100644 --- a/src/dbinc_auto/log_ext.h +++ b/src/dbinc_auto/log_ext.h @@ -26,6 +26,7 @@ void __log_inmem_copyin __P((DB_LOG *, size_t, void *, size_t)); void __log_set_version __P((ENV *, u_int32_t)); int __log_get_oldversion __P((ENV *, u_int32_t *)); int __log_archive_pp __P((DB_ENV *, char **[], u_int32_t)); +int __log_archive __P((ENV *, char **[], u_int32_t)); int __log_get_stable_lsn __P((ENV *, DB_LSN *, int)); void __log_autoremove __P((ENV *)); int __log_check_page_lsn __P((ENV *, DB *, DB_LSN *)); diff --git a/src/dbinc_auto/mp_ext.h b/src/dbinc_auto/mp_ext.h index ef2be17f..d142b584 100644 --- a/src/dbinc_auto/mp_ext.h +++ b/src/dbinc_auto/mp_ext.h @@ -8,6 +8,10 @@ extern "C" { int __memp_alloc __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, size_t, roff_t *, void *)); void __memp_free __P((REGINFO *, void *)); +int __memp_backup_open __P((ENV *, DB_MPOOLFILE *, const char *, const char *, u_int32_t, DB_FH **, void**)); +int __memp_backup_mpf __P((ENV *, DB_MPOOLFILE *, DB_THREAD_INFO *, db_pgno_t, db_pgno_t, DB_FH *, void *, u_int32_t)); +int __memp_backup_close __P((ENV *, DB_MPOOLFILE *, const char *, DB_FH *, void *HANDLE)); +int __memp_failchk __P((ENV *)); int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int)); int __memp_pgread __P((DB_MPOOLFILE *, BH *, int)); int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int)); diff --git a/src/dbinc_auto/os_ext.h b/src/dbinc_auto/os_ext.h index dd63bf9c..a0a7b791 100644 --- a/src/dbinc_auto/os_ext.h +++ b/src/dbinc_auto/os_ext.h @@ -51,6 +51,7 @@ int __os_mapfile __P((ENV *, char *, DB_FH *, size_t, int, void **)); int __os_unmapfile __P((ENV *, void *, size_t)); int __os_mkdir __P((ENV *, const char *, int)); int __os_open __P((ENV *, const char *, u_int32_t, u_int32_t, int, DB_FH **)); +int __os_concat_path __P((char *, size_t, const char *, const char *)); void __os_id __P((DB_ENV *, pid_t *, db_threadid_t*)); int __os_rename __P((ENV *, const char *, const char *, u_int32_t)); int __os_isroot __P((void)); diff --git a/src/dbinc_auto/qam_ext.h b/src/dbinc_auto/qam_ext.h index 384bc988..3f143664 100644 --- a/src/dbinc_auto/qam_ext.h +++ b/src/dbinc_auto/qam_ext.h @@ -31,6 +31,7 @@ int __qam_extent_names __P((ENV *, char *, char ***)); void __qam_exid __P((DB *, u_int8_t *, u_int32_t)); int __qam_nameop __P((DB *, DB_TXN *, const char *, qam_name_op)); int __qam_lsn_reset __P((DB *, DB_THREAD_INFO *)); +int __qam_backup_extents __P((DB *, DB_THREAD_INFO *, const char *, u_int32_t)); int __qam_db_create __P((DB *)); int __qam_db_close __P((DB *, u_int32_t)); int __qam_get_extentsize __P((DB *, u_int32_t *)); diff --git a/src/dbinc_auto/rep_automsg.h b/src/dbinc_auto/rep_automsg.h index bddf8158..584040cf 100644 --- a/src/dbinc_auto/rep_automsg.h +++ b/src/dbinc_auto/rep_automsg.h @@ -32,7 +32,7 @@ typedef struct ___rep_egen_args { u_int32_t egen; } __rep_egen_args; -#define __REP_FILEINFO_SIZE 36 +#define __REP_FILEINFO_SIZE 40 typedef struct ___rep_fileinfo_args { u_int32_t pgsize; db_pgno_t pgno; @@ -43,8 +43,22 @@ typedef struct ___rep_fileinfo_args { u_int32_t db_flags; DBT uid; DBT info; + DBT dir; } __rep_fileinfo_args; +#define __REP_FILEINFO_V6_SIZE 36 +typedef struct ___rep_fileinfo_v6_args { + u_int32_t pgsize; + db_pgno_t pgno; + db_pgno_t max_pgno; + u_int32_t filenum; + u_int32_t finfo_flags; + u_int32_t type; + u_int32_t db_flags; + DBT uid; + DBT info; +} __rep_fileinfo_v6_args; + #define __REP_GRANT_INFO_SIZE 8 typedef struct ___rep_grant_info_args { u_int32_t msg_sec; @@ -102,5 +116,5 @@ typedef struct ___rep_lsn_hist_data_args { u_int32_t hist_nsec; } __rep_lsn_hist_data_args; -#define __REP_MAXMSG_SIZE 36 +#define __REP_MAXMSG_SIZE 40 #endif diff --git a/src/dbinc_auto/rep_ext.h b/src/dbinc_auto/rep_ext.h index 4cb1612a..89bdc797 100644 --- a/src/dbinc_auto/rep_ext.h +++ b/src/dbinc_auto/rep_ext.h @@ -14,6 +14,8 @@ int __rep_egen_marshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, size_t int __rep_egen_unmarshal __P((ENV *, __rep_egen_args *, u_int8_t *, size_t, u_int8_t **)); int __rep_fileinfo_marshal __P((ENV *, u_int32_t, __rep_fileinfo_args *, u_int8_t *, size_t, size_t *)); int __rep_fileinfo_unmarshal __P((ENV *, u_int32_t, __rep_fileinfo_args **, u_int8_t *, size_t, u_int8_t **)); +int __rep_fileinfo_v6_marshal __P((ENV *, u_int32_t, __rep_fileinfo_v6_args *, u_int8_t *, size_t, size_t *)); +int __rep_fileinfo_v6_unmarshal __P((ENV *, u_int32_t, __rep_fileinfo_v6_args **, u_int8_t *, size_t, u_int8_t **)); int __rep_grant_info_marshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, size_t *)); int __rep_grant_info_unmarshal __P((ENV *, __rep_grant_info_args *, u_int8_t *, size_t, u_int8_t **)); int __rep_logreq_marshal __P((ENV *, __rep_logreq_args *, u_int8_t *, size_t, size_t *)); diff --git a/src/dbinc_auto/repmgr_ext.h b/src/dbinc_auto/repmgr_ext.h index 49163a8a..b1237950 100644 --- a/src/dbinc_auto/repmgr_ext.h +++ b/src/dbinc_auto/repmgr_ext.h @@ -49,6 +49,7 @@ int __repmgr_valid_config __P((ENV *, u_int32_t)); int __repmgr_autostart __P((ENV *)); int __repmgr_start_selector __P((ENV *)); int __repmgr_close __P((ENV *)); +int __repmgr_stop __P((ENV *)); int __repmgr_set_ack_policy __P((DB_ENV *, int)); int __repmgr_get_ack_policy __P((DB_ENV *, int *)); int __repmgr_env_create __P((ENV *, DB_REP *)); @@ -86,7 +87,7 @@ void __repmgr_set_sites __P((ENV *)); int __repmgr_connect __P((ENV *, repmgr_netaddr_t *, REPMGR_CONNECTION **, int *)); int __repmgr_send __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u_int32_t)); int __repmgr_sync_siteaddr __P((ENV *)); -int __repmgr_send_broadcast __P((ENV *, u_int, const DBT *, const DBT *, u_int *, u_int *)); +int __repmgr_send_broadcast __P((ENV *, u_int, const DBT *, const DBT *, u_int *, u_int *, int *)); int __repmgr_send_one __P((ENV *, REPMGR_CONNECTION *, u_int, const DBT *, const DBT *, db_timeout_t)); int __repmgr_send_many __P((ENV *, REPMGR_CONNECTION *, REPMGR_IOVECS *, db_timeout_t)); int __repmgr_send_own_msg __P((ENV *, REPMGR_CONNECTION *, u_int32_t, u_int8_t *, u_int32_t)); @@ -137,7 +138,7 @@ void *__repmgr_select_thread __P((void *)); int __repmgr_bow_out __P((ENV *)); int __repmgr_accept __P((ENV *)); int __repmgr_compute_timeout __P((ENV *, db_timespec *)); -REPMGR_CONNECTION *__repmgr_master_connection __P((ENV *)); +REPMGR_SITE *__repmgr_connected_master __P((ENV *)); int __repmgr_check_timeouts __P((ENV *)); int __repmgr_first_try_connections __P((ENV *)); int __repmgr_send_v1_handshake __P((ENV *, REPMGR_CONNECTION *, void *, size_t)); @@ -193,9 +194,11 @@ int __repmgr_set_msg_dispatch __P((DB_ENV *, void (*)(DB_ENV *, DB_CHANNEL *, DB #ifndef HAVE_REPLICATION_THREADS int __repmgr_init_recover __P((ENV *, DB_DISTAB *)); #endif -int __repmgr_schedule_connection_attempt __P((ENV *, u_int, int)); +int __repmgr_schedule_connection_attempt __P((ENV *, int, int)); +int __repmgr_is_server __P((ENV *, REPMGR_SITE *)); void __repmgr_reset_for_reading __P((REPMGR_CONNECTION *)); int __repmgr_new_connection __P((ENV *, REPMGR_CONNECTION **, socket_t, int)); +int __repmgr_set_keepalive __P((ENV *, REPMGR_CONNECTION *)); int __repmgr_new_site __P((ENV *, REPMGR_SITE**, const char *, u_int)); int __repmgr_create_mutex __P((ENV *, mgr_mutex_t **)); int __repmgr_destroy_mutex __P((ENV *, mgr_mutex_t *)); @@ -218,7 +221,7 @@ int __repmgr_join __P((ENV *, void *)); int __repmgr_env_refresh __P((ENV *env)); int __repmgr_share_netaddrs __P((ENV *, void *, u_int, u_int)); int __repmgr_copy_in_added_sites __P((ENV *)); -int __repmgr_init_new_sites __P((ENV *, u_int, u_int)); +int __repmgr_init_new_sites __P((ENV *, int, int)); int __repmgr_failchk __P((ENV *)); int __repmgr_master_is_known __P((ENV *)); int __repmgr_stable_lsn __P((ENV *, DB_LSN *)); diff --git a/src/dbinc_auto/tcl_ext.h b/src/dbinc_auto/tcl_ext.h index c532f770..8b076c8b 100644 --- a/src/dbinc_auto/tcl_ext.h +++ b/src/dbinc_auto/tcl_ext.h @@ -21,6 +21,7 @@ int tcl_rep_send __P((DB_ENV *, const DBT *, const DBT *, const DB_LSN *, int, u int dbc_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); int env_Cmd __P((ClientData, Tcl_Interp *, int, Tcl_Obj * CONST*)); int tcl_EnvRemove __P((Tcl_Interp *, int, Tcl_Obj * CONST*)); +int tcl_EnvClose __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *, DBTCL_INFO *)); int tcl_EnvIdReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); int tcl_EnvLsnReset __P((Tcl_Interp *, int, Tcl_Obj * CONST*, DB_ENV *)); int tcl_EnvVerbose __P((Tcl_Interp *, DB_ENV *, Tcl_Obj *, Tcl_Obj *)); @@ -44,7 +45,7 @@ int _SetListElemWideInt __P((Tcl_Interp *, Tcl_Obj *, void *, int64_t)); int _SetListRecnoElem __P((Tcl_Interp *, Tcl_Obj *, db_recno_t, u_char *, u_int32_t)); int _SetListHeapElem __P((Tcl_Interp *, Tcl_Obj *, DB_HEAP_RID, u_char *, u_int32_t)); int _Set3DBTList __P((Tcl_Interp *, Tcl_Obj *, DBT *, int, DBT *, int, DBT *)); -int _SetMultiList __P((Tcl_Interp *, Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t)); +int _SetMultiList __P((Tcl_Interp *, Tcl_Obj *, DBT *, DBT*, DBTYPE, u_int32_t, DBC*)); int _GetGlobPrefix __P((char *, char **)); int _ReturnSetup __P((Tcl_Interp *, int, int, char *)); int _ErrorSetup __P((Tcl_Interp *, int, char *)); diff --git a/src/dbreg/dbreg.c b/src/dbreg/dbreg.c index 0a8ed4fe..5067edac 100644 --- a/src/dbreg/dbreg.c +++ b/src/dbreg/dbreg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -167,6 +167,8 @@ __dbreg_setup(dbp, fname, dname, create_txnid) F_SET(fnp, DBREG_CHKSUM); if (F_ISSET(dbp, DB_AM_ENCRYPT)) F_SET(fnp, DBREG_ENCRYPT); + if (F2_ISSET(dbp, DB2_AM_EXCL)) + F_SET(fnp, DBREG_EXCL); fnp->txn_ref = 1; fnp->mutex = dbp->mutex; @@ -706,10 +708,13 @@ __dbreg_failchk(env) LOG *lp; int ret, t_ret; char buf[DB_THREADID_STRLEN]; + db_threadid_t unused; if ((dblp = env->lg_handle) == NULL) return (0); + DB_THREADID_INIT(unused); + lp = dblp->reginfo.primary; dbenv = env->dbenv; ret = 0; @@ -717,13 +722,14 @@ __dbreg_failchk(env) MUTEX_LOCK(env, lp->mtx_filelist); for (fnp = SH_TAILQ_FIRST(&lp->fq, __fname); fnp != NULL; fnp = nnp) { nnp = SH_TAILQ_NEXT(fnp, q, __fname); - if (dbenv->is_alive(dbenv, fnp->pid, 0, DB_MUTEX_PROCESS_ONLY)) + if (dbenv->is_alive(dbenv, + fnp->pid, unused, DB_MUTEX_PROCESS_ONLY)) continue; MUTEX_LOCK(env, fnp->mutex); __db_msg(env, DB_STR_A("1502", "Freeing log information for process: %s, (ref %lu)", "%s %lu"), - dbenv->thread_id_string(dbenv, fnp->pid, 0, buf), + dbenv->thread_id_string(dbenv, fnp->pid, unused, buf), (u_long)fnp->txn_ref); if (fnp->txn_ref > 1 || F_ISSET(fnp, DB_FNAME_CLOSED)) { if (!F_ISSET(fnp, DB_FNAME_CLOSED)) { @@ -990,7 +996,9 @@ __dbreg_log_id(dbp, txn, id, needlock) fid_dbt.size = DB_FILE_ID_LEN; op = !F_ISSET(dbp, DB_AM_OPEN_CALLED) ? DBREG_PREOPEN : - (F_ISSET(dbp, DB_AM_INMEM) ? DBREG_REOPEN : DBREG_OPEN); + (F_ISSET(dbp, DB_AM_INMEM) ? + (F2_ISSET(dbp, DB2_AM_EXCL) ? DBREG_XREOPEN : DBREG_REOPEN): + (F2_ISSET(dbp, DB2_AM_EXCL) ? DBREG_XOPEN : DBREG_OPEN)); ret = __dbreg_register_log(env, txn, &unused, F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0, op | F_ISSET(fnp, DB_FNAME_DBREG_MASK), diff --git a/src/dbreg/dbreg.src b/src/dbreg/dbreg.src index f51f1379..c7740d63 100644 --- a/src/dbreg/dbreg.src +++ b/src/dbreg/dbreg.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbreg/dbreg_rec.c b/src/dbreg/dbreg_rec.c index aae6851f..1b387bb7 100644 --- a/src/dbreg/dbreg_rec.c +++ b/src/dbreg/dbreg_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 @@ -74,9 +74,11 @@ __dbreg_register_recover(env, dbtp, lsnp, op, info) opcode = FLD_ISSET(argp->opcode, DBREG_OP_MASK); switch (opcode) { - case DBREG_REOPEN: - case DBREG_PREOPEN: case DBREG_OPEN: + case DBREG_PREOPEN: + case DBREG_REOPEN: + case DBREG_XOPEN: + case DBREG_XREOPEN: /* * In general, we redo the open on REDO and abort on UNDO. * However, a reopen is a second instance of an open of @@ -86,7 +88,7 @@ __dbreg_register_recover(env, dbtp, lsnp, op, info) if ((DB_REDO(op) || op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES)) do_open = 1; - else if (opcode != DBREG_REOPEN) + else if (opcode != DBREG_REOPEN && opcode != DBREG_XREOPEN) do_close = 1; break; case DBREG_CLOSE: @@ -110,6 +112,7 @@ __dbreg_register_recover(env, dbtp, lsnp, op, info) do_close = 1; break; case DBREG_CHKPNT: + case DBREG_XCHKPNT: if (DB_UNDO(op) || op == DB_TXN_OPENFILES || op == DB_TXN_POPENFILES) do_open = 1; @@ -124,7 +127,8 @@ __dbreg_register_recover(env, dbtp, lsnp, op, info) * We must open the db even if the meta page is not * yet written as we may be creating subdatabase. */ - if (op == DB_TXN_OPENFILES && opcode != DBREG_CHKPNT) + if (op == DB_TXN_OPENFILES && opcode != DBREG_CHKPNT + && opcode != DBREG_XCHKPNT) F_SET(dblp, DBLOG_FORCE_OPEN); /* @@ -216,8 +220,10 @@ __dbreg_register_recover(env, dbtp, lsnp, op, info) * inside a currently aborting transaction * but not by the recovery code. */ - do_rem = F_ISSET(dbp, DB_AM_RECOVER) ? - op != DB_TXN_ABORT : op == DB_TXN_ABORT; + do_rem = (F_ISSET(dbp, DB_AM_RECOVER) || + F2_ISSET(dbp, DB2_AM_EXCL)) ? + op != DB_TXN_ABORT : + op == DB_TXN_ABORT; MUTEX_UNLOCK(env, dblp->mtx_dbreg); } else if (dbe->deleted) { MUTEX_UNLOCK(env, dblp->mtx_dbreg); @@ -330,7 +336,8 @@ __dbreg_open_file(env, txn, argp, info) * bit and try to open it again. */ if ((dbp = dbe->dbp) != NULL) { - if (opcode == DBREG_REOPEN || + if (opcode == DBREG_REOPEN || + opcode == DBREG_XREOPEN || !F_ISSET(dbp, DB_AM_OPEN_CALLED) || dbp->meta_pgno != argp->meta_pgno || argp->name.size == 0 || diff --git a/src/dbreg/dbreg_stat.c b/src/dbreg/dbreg_stat.c index 4d2f28a4..6dfb3869 100644 --- a/src/dbreg/dbreg_stat.c +++ b/src/dbreg/dbreg_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/dbreg/dbreg_util.c b/src/dbreg/dbreg_util.c index 6bbfc3f8..80de4d91 100644 --- a/src/dbreg/dbreg_util.c +++ b/src/dbreg/dbreg_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -101,6 +101,7 @@ __dbreg_log_files(env, opcode) DB_LSN r_unused; FNAME *fnp; LOG *lp; + u_int32_t lopcode; int ret; dblp = env->lg_handle; @@ -133,9 +134,12 @@ __dbreg_log_files(env, opcode) * For this we output DBREG_RCLOSE records so the files will be * closed on the forward pass. */ + lopcode = opcode; + if ( opcode == DBREG_CHKPNT && F_ISSET(fnp, DBREG_EXCL)) + lopcode = DBREG_XCHKPNT; if ((ret = __dbreg_register_log(env, NULL, &r_unused, F_ISSET(fnp, DB_FNAME_DURABLE) ? 0 : DB_LOG_NOT_DURABLE, - opcode | F_ISSET(fnp, DB_FNAME_DBREG_MASK), + lopcode | F_ISSET(fnp, DB_FNAME_DBREG_MASK), dbtp, &fid_dbt, fnp->id, fnp->s_type, fnp->meta_pgno, TXN_INVALID)) != 0) break; @@ -631,12 +635,16 @@ retry_inmem: goto skip_open; } - if (opcode == DBREG_REOPEN || try_inmem) { + if (opcode == DBREG_REOPEN || opcode == DBREG_XREOPEN || try_inmem) { MAKE_INMEM(dbp); fname = NULL; dname = name; } + if (opcode == DBREG_XOPEN || opcode == DBREG_XCHKPNT || + opcode == DBREG_XREOPEN) + F2_SET(dbp, DB2_AM_EXCL|DB2_AM_INTEXCL); + if ((ret = __db_open(dbp, NULL, txn, fname, dname, ftype, DB_DURABLE_UNKNOWN | DB_ODDFILESIZE, DB_MODE_600, meta_pgno)) == 0) { @@ -692,7 +700,8 @@ err: if (cstat == TXN_UNEXPECTED) * handling those cases specially, above. */ if (try_inmem == 0 && - opcode != DBREG_PREOPEN && opcode != DBREG_REOPEN) { + opcode != DBREG_PREOPEN && opcode != DBREG_REOPEN && + opcode != DBREG_XREOPEN) { if ((ret = __db_close(dbp, NULL, DB_NOSYNC)) != 0) return (ret); try_inmem = 1; diff --git a/src/env/env_alloc.c b/src/env/env_alloc.c index 4749e844..700bfb27 100644 --- a/src/env/env_alloc.c +++ b/src/env/env_alloc.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -287,7 +287,7 @@ retry: #ifdef HAVE_STATISTICS if (i >= DB_SIZE_Q_COUNT) - i = DB_SIZE_Q_COUNT - 1; + i = DB_SIZE_Q_COUNT - 1; ++head->pow2_size[i]; /* Note the size of the request. */ #endif @@ -568,7 +568,7 @@ again: if ((elp_tmp = SH_TAILQ_NEXT(elp, addrq, __alloc_element)) != NULL && done: elp->ulen = elp->len - sizeof(ALLOC_ELEMENT); #ifdef DIAGNOSTIC elp->ulen -= sizeof(uintmax_t); - /* There was room for the guarrd byte in the chunk that came in. */ + /* There was room for the guard byte in the chunk that came in. */ p[elp->ulen] = GUARD_BYTE; #endif *lenp -= len; @@ -630,6 +630,8 @@ __env_region_extend(env, infop) rp->alloc = rp->max - rp->size; rp->size += rp->alloc; rp->size = (size_t)ALIGNP_INC(rp->size, sizeof(size_t)); + if (rp->max - rp->size <= SHALLOC_FRAGMENT) + rp->size = rp->max; if (infop->fhp && (ret = __db_file_extend(env, infop->fhp, rp->size)) != 0) return (ret); diff --git a/src/env/env_backup.c b/src/env/env_backup.c new file mode 100644 index 00000000..9c79dbb4 --- /dev/null +++ b/src/env/env_backup.c @@ -0,0 +1,166 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" + +static int __env_backup_alloc __P((DB_ENV *)); + +static int +__env_backup_alloc(dbenv) + DB_ENV *dbenv; +{ + ENV *env; + + env = dbenv->env; + if (env->backup_handle != NULL) + return (0); + return (__os_calloc(env, 1, + sizeof(*env->backup_handle), &env->backup_handle)); +} + +/* + * __env_get_backup_config -- + * + * PUBLIC: int __env_get_backup_config __P((DB_ENV *, + * PUBLIC: DB_BACKUP_CONFIG, u_int32_t*)); + */ +int +__env_get_backup_config(dbenv, config, valuep) + DB_ENV *dbenv; + DB_BACKUP_CONFIG config; + u_int32_t *valuep; +{ + DB_BACKUP *backup; + + backup = dbenv->env->backup_handle; + if (backup == NULL) + return (EINVAL); + + switch (config) { + case DB_BACKUP_WRITE_DIRECT: + *valuep = F_ISSET(backup, BACKUP_WRITE_DIRECT); + break; + + case DB_BACKUP_READ_COUNT: + *valuep = backup->read_count; + break; + + case DB_BACKUP_READ_SLEEP: + *valuep = backup->read_sleep; + break; + + case DB_BACKUP_SIZE: + *valuep = backup->size; + break; + } + return (0); +} + +/* + * __env_set_backup_config -- + * + * PUBLIC: int __env_set_backup_config __P((DB_ENV *, + * PUBLIC: DB_BACKUP_CONFIG, u_int32_t)); + */ +int +__env_set_backup_config(dbenv, config, value) + DB_ENV *dbenv; + DB_BACKUP_CONFIG config; + u_int32_t value; +{ + DB_BACKUP *backup; + int ret; + + if ((ret = __env_backup_alloc(dbenv)) != 0) + return (ret); + + backup = dbenv->env->backup_handle; + switch (config) { + case DB_BACKUP_WRITE_DIRECT: + if (value == 0) + F_CLR(backup, BACKUP_WRITE_DIRECT); + else + F_SET(backup, BACKUP_WRITE_DIRECT); + break; + + case DB_BACKUP_READ_COUNT: + backup->read_count = value; + break; + + case DB_BACKUP_READ_SLEEP: + backup->read_sleep = value; + break; + + case DB_BACKUP_SIZE: + backup->size = value; + break; + } + + return (0); +} + +/* + * __env_get_backup_callbacks -- + * + * PUBLIC: int __env_get_backup_callbacks __P((DB_ENV *, + * PUBLIC: int (**)(DB_ENV *, const char *, const char *, void **), + * PUBLIC: int (**)(DB_ENV *, + * PUBLIC: u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + * PUBLIC: int (**)(DB_ENV *, const char *, void *))); + */ +int +__env_get_backup_callbacks(dbenv, openp, writep, closep) + DB_ENV *dbenv; + int (**openp)(DB_ENV *, const char *, const char *, void **); + int (**writep)(DB_ENV *, + u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *); + int (**closep)(DB_ENV *, const char *, void *); +{ + DB_BACKUP *backup; + + backup = dbenv->env->backup_handle; + if (backup == NULL) + return (EINVAL); + + *openp = backup->open; + *writep = backup->write; + *closep = backup->close; + return (0); +} + +/* + * __env_set_backup_callbacks -- + * + * PUBLIC: int __env_set_backup_callbacks __P((DB_ENV *, + * PUBLIC: int (*)(DB_ENV *, const char *, const char *, void **), + * PUBLIC: int (*)(DB_ENV *, + * PUBLIC: u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *), + * PUBLIC: int (*)(DB_ENV *, const char *, void *))); + */ +int +__env_set_backup_callbacks(dbenv, open_func, write_func, close_func) + DB_ENV *dbenv; + int (*open_func)(DB_ENV *, const char *, const char *, void **); + int (*write_func)(DB_ENV *, + u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *); + int (*close_func)(DB_ENV *, const char *, void *); +{ + DB_BACKUP *backup; + int ret; + + if ((ret = __env_backup_alloc(dbenv)) != 0) + return (ret); + + backup = dbenv->env->backup_handle; + backup->open = open_func; + backup->write = write_func; + backup->close = close_func; + return (0); +} diff --git a/src/env/env_config.c b/src/env/env_config.c index f0f4f60b..57496909 100644 --- a/src/env/env_config.c +++ b/src/env/env_config.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -13,8 +13,249 @@ #include "dbinc/log.h" #include "dbinc/mp.h" #include "dbinc/txn.h" +#include "dbinc/db_page.h" +#include "dbinc_auto/db_ext.h" + +/* + * DB_CONFIG lines are processed primarily by interpreting the command + * description tables initialized below. + * + * Most DB_CONFIG commands consist of a single token name followed by one or two + * integer or string arguments. These commands are described by entries in the + * config_descs[] array. + * + * The remaining, usually more complex, DB_CONFIG commands are handled by small + * code blocks in __config_parse(). Many of those commands need to translate + * option names to the integer values needed by the API configuration functions. + * Below the __config_descs[] initialization there are many FN array + * initializations which provide the mapping between user-specifiable strings + * and internally-used integer values. Typically there is one of these mappings + * defined for each complex DB_CONFIG command. Use __db_name_to_val() + * to translate a string to its integer value. + */ +typedef enum { + CFG_INT, /* The argument is 1 signed integer. */ + CFG_LONG, /* The argument is 1 signed long int. */ + CFG_UINT, /* The argument is 1 unsigned integer. */ + CFG_2INT, /* The arguments are 2 signed integers. */ + CFG_2UINT, /* The arguments are 2 unsigned integers. */ + CFG_STRING /* The rest of the line is a string. */ +} __db_config_type; + +typedef struct __db_config_desc { + char *name; /* The name of a simple DB_CONFIG command. */ + __db_config_type type; /* The enum describing its argument type(s). */ + int (*func)(); /* The function to call with the argument(s). */ +} CFG_DESC; + +/* These typedefs help eliminate lint warnings where "func" above is used. */ +typedef int (*CFG_FUNC_STRING) __P((DB_ENV *, const char *)); +typedef int (*CFG_FUNC_INT) __P((DB_ENV *, int)); +typedef int (*CFG_FUNC_LONG) __P((DB_ENV *, long)); +typedef int (*CFG_FUNC_UINT) __P((DB_ENV *, u_int32_t)); +typedef int (*CFG_FUNC_2INT) __P((DB_ENV *, int, int)); +typedef int (*CFG_FUNC_2UINT) __P((DB_ENV *, u_int32_t, u_int32_t)); + +/* + * This table lists the simple DB_CONFIG configuration commands. It is sorted by + * the command name, so that __config_scan() can bsearch() it. After making an + * addition to this table, please be sure that it remains sorted. With vi or + * vim, the following command line will do it: + * :/^static const CFG_DESC config_descs/+1, /^}/-1 ! sort + * + * This table can contain aliases. Aliases have different names with identical + * types and functions. At this time there are four aliases: + * Outdated Name Current Name + * db_data_dir set_data_dir + * db_log_dir set_lg_dir + * db_tmp_dir set_tmp_dir + * set_tas_spins mutex_set_tas_spins + */ +static const CFG_DESC config_descs[] = { + { "add_data_dir", CFG_STRING, __env_add_data_dir }, + { "db_data_dir", CFG_STRING, __env_set_data_dir }, + { "db_log_dir", CFG_STRING, __log_set_lg_dir }, + { "db_tmp_dir", CFG_STRING, __env_set_tmp_dir }, + { "mutex_set_align", CFG_UINT, __mutex_set_align }, + { "mutex_set_increment", CFG_UINT, __mutex_set_increment }, + { "mutex_set_init", CFG_UINT, __mutex_set_init }, + { "mutex_set_max", CFG_UINT, __mutex_set_max }, + { "mutex_set_tas_spins", CFG_UINT, __mutex_set_tas_spins }, + { "rep_set_clockskew", CFG_2UINT, __rep_set_clockskew }, + { "rep_set_limit", CFG_2UINT, __rep_set_limit }, + { "rep_set_nsites", CFG_UINT, __rep_set_nsites_pp }, + { "rep_set_priority", CFG_UINT, __rep_set_priority }, + { "rep_set_request", CFG_2UINT, __rep_set_request }, + { "set_cache_max", CFG_2UINT, __memp_set_cache_max }, + { "set_create_dir", CFG_STRING, __env_set_create_dir }, + { "set_data_dir", CFG_STRING, __env_set_data_dir }, + { "set_data_len", CFG_UINT, __env_set_data_len }, + { "set_intermediate_dir_mode",CFG_STRING, __env_set_intermediate_dir_mode }, + { "set_lg_bsize", CFG_UINT, __log_set_lg_bsize }, + { "set_lg_dir", CFG_STRING, __log_set_lg_dir }, + { "set_lg_filemode", CFG_INT, __log_set_lg_filemode }, + { "set_lg_max", CFG_UINT, __log_set_lg_max }, + { "set_lg_regionmax", CFG_UINT, __log_set_lg_regionmax }, + { "set_lk_max_lockers", CFG_UINT, __lock_set_lk_max_lockers }, + { "set_lk_max_locks", CFG_UINT, __lock_set_lk_max_locks }, + { "set_lk_max_objects", CFG_UINT, __lock_set_lk_max_objects }, + { "set_lk_partitions", CFG_UINT, __lock_set_lk_partitions }, + { "set_lk_tablesize", CFG_UINT, __lock_set_lk_tablesize }, + { "set_memory_max", CFG_2UINT, __env_set_memory_max }, + { "set_metadata_dir", CFG_STRING, __env_set_metadata_dir }, + { "set_mp_max_openfd", CFG_INT, __memp_set_mp_max_openfd }, + { "set_mp_max_write", CFG_2INT, __memp_set_mp_max_write }, + { "set_mp_mmapsize", CFG_UINT, __memp_set_mp_mmapsize }, + { "set_mp_mtxcount", CFG_UINT, __memp_set_mp_mtxcount }, + { "set_mp_pagesize", CFG_UINT, __memp_set_mp_pagesize }, + { "set_shm_key", CFG_LONG, __env_set_shm_key }, + { "set_tas_spins", CFG_UINT, __mutex_set_tas_spins }, + { "set_thread_count", CFG_UINT, __env_set_thread_count }, + { "set_tmp_dir", CFG_STRING, __env_set_tmp_dir }, + { "set_tx_max", CFG_UINT, __txn_set_tx_max } +}; + +/* + * Here are the option-name to option-value mappings used by complex commands. + */ +static const FN config_mem_init[] = { + { (u_int32_t) DB_MEM_LOCK, "DB_MEM_LOCK" }, + { (u_int32_t) DB_MEM_LOCKER, "DB_MEM_LOCKER" }, + { (u_int32_t) DB_MEM_LOCKOBJECT, "DB_MEM_LOCKOBJECT" }, + { (u_int32_t) DB_MEM_TRANSACTION, "DB_MEM_TRANSACTION" }, + { (u_int32_t) DB_MEM_THREAD, "DB_MEM_THREAD" }, + { (u_int32_t) DB_MEM_LOGID, "DB_MEM_LOGID" }, + { 0, NULL } +}; + +static const FN config_rep_config[] = { + { DB_REP_CONF_AUTOINIT, "db_rep_conf_autoinit" }, + { DB_REP_CONF_AUTOROLLBACK, "db_rep_conf_autorollback" }, + { DB_REP_CONF_BULK, "db_rep_conf_bulk" }, + { DB_REP_CONF_DELAYCLIENT, "db_rep_conf_delayclient" }, + { DB_REP_CONF_INMEM, "db_rep_conf_inmem" }, + { DB_REP_CONF_LEASE, "db_rep_conf_lease" }, + { DB_REP_CONF_NOWAIT, "db_rep_conf_nowait" }, + { DB_REPMGR_CONF_2SITE_STRICT, "db_repmgr_conf_2site_strict" }, + { DB_REPMGR_CONF_ELECTIONS, "db_repmgr_conf_elections" }, + { 0, NULL } +}; + +static const FN config_rep_timeout[] = { + { DB_REP_ACK_TIMEOUT, "db_rep_ack_timeout" }, + { DB_REP_CHECKPOINT_DELAY, "db_rep_checkpoint_delay" }, + { DB_REP_CONNECTION_RETRY, "db_rep_connection_retry" }, + { DB_REP_ELECTION_TIMEOUT, "db_rep_election_timeout" }, + { DB_REP_ELECTION_RETRY, "db_rep_election_retry" }, + { DB_REP_FULL_ELECTION_TIMEOUT, "db_rep_full_election_timeout" }, + { DB_REP_HEARTBEAT_MONITOR, "db_rep_heartbeat_monitor" }, + { DB_REP_HEARTBEAT_SEND, "db_rep_heartbeat_send" }, + { DB_REP_LEASE_TIMEOUT, "db_rep_lease_timeout" }, + { 0, NULL } +}; + +static const FN config_repmgr_ack_policy[] = { + { DB_REPMGR_ACKS_ALL, "db_repmgr_acks_all" }, + { DB_REPMGR_ACKS_ALL_AVAILABLE, "db_repmgr_acks_all_available" }, + { DB_REPMGR_ACKS_ALL_PEERS, "db_repmgr_acks_all_peers" }, + { DB_REPMGR_ACKS_NONE, "db_repmgr_acks_none" }, + { DB_REPMGR_ACKS_ONE, "db_repmgr_acks_one" }, + { DB_REPMGR_ACKS_ONE_PEER, "db_repmgr_acks_one_peer" }, + { DB_REPMGR_ACKS_QUORUM, "db_repmgr_acks_quorum" }, + { 0, NULL } +}; + +static const FN config_repmgr_site[] = { + { DB_BOOTSTRAP_HELPER, "db_bootstrap_helper" }, + { DB_GROUP_CREATOR, "db_group_creator" }, + { DB_LEGACY, "db_legacy" }, + { DB_LOCAL_SITE, "db_local_site" }, + { DB_REPMGR_PEER, "db_repmgr_peer" }, + { 0, NULL } +}; + +static const FN config_set_flags[] = { + { DB_AUTO_COMMIT, "db_auto_commit" }, + { DB_CDB_ALLDB, "db_cdb_alldb" }, + { DB_DIRECT_DB, "db_direct_db" }, + { DB_DSYNC_DB, "db_dsync_db" }, + { DB_MULTIVERSION, "db_multiversion" }, + { DB_NOLOCKING, "db_nolocking" }, + { DB_NOMMAP, "db_nommap" }, + { DB_NOPANIC, "db_nopanic" }, + { DB_OVERWRITE, "db_overwrite" }, + { DB_REGION_INIT, "db_region_init" }, + { DB_TIME_NOTGRANTED, "db_time_notgranted" }, + { DB_TXN_NOSYNC, "db_txn_nosync" }, + { DB_TXN_NOWAIT, "db_txn_nowait" }, + { DB_TXN_SNAPSHOT, "db_txn_snapshot" }, + { DB_TXN_WRITE_NOSYNC, "db_txn_write_nosync" }, + { DB_YIELDCPU, "db_yieldcpu" }, + { 0, NULL } +}; + +static const FN config_set_flags_forlog[] = { + { DB_LOG_DIRECT, "db_direct_log" }, + { DB_LOG_DSYNC, "db_dsync_log" }, + { DB_LOG_AUTO_REMOVE, "db_log_autoremove" }, + { DB_LOG_IN_MEMORY, "db_log_inmemory" }, + { 0, NULL } +}; + +static const FN config_log_set_config[] = { + { DB_LOG_DIRECT, "db_log_direct" }, + { DB_LOG_DSYNC, "db_log_dsync" }, + { DB_LOG_AUTO_REMOVE, "db_log_auto_remove" }, + { DB_LOG_IN_MEMORY, "db_log_in_memory" }, + { DB_LOG_ZERO, "db_log_zero" }, + { 0, NULL } +}; + +static const FN config_set_lk_detect[] = { + { DB_LOCK_DEFAULT, "db_lock_default" }, + { DB_LOCK_EXPIRE, "db_lock_expire" }, + { DB_LOCK_MAXLOCKS, "db_lock_maxlocks" }, + { DB_LOCK_MAXWRITE, "db_lock_maxwrite" }, + { DB_LOCK_MINLOCKS, "db_lock_minlocks" }, + { DB_LOCK_MINWRITE, "db_lock_minwrite" }, + { DB_LOCK_OLDEST, "db_lock_oldest" }, + { DB_LOCK_RANDOM, "db_lock_random" }, + { DB_LOCK_YOUNGEST, "db_lock_youngest" }, + { 0, NULL } +}; + +static const FN config_set_open_flags[] = { + { DB_INIT_REP, "db_init_rep" }, + { DB_PRIVATE, "db_private" }, + { DB_REGISTER, "db_register" }, + { DB_THREAD, "db_thread" }, + { 0, NULL } +}; + +static const FN config_set_verbose[] = { + { DB_VERB_BACKUP, "db_verb_backup" }, + { DB_VERB_DEADLOCK, "db_verb_deadlock" }, + { DB_VERB_FILEOPS, "db_verb_fileops" }, + { DB_VERB_FILEOPS_ALL, "db_verb_fileops_all" }, + { DB_VERB_RECOVERY, "db_verb_recovery" }, + { DB_VERB_REGISTER, "db_verb_register" }, + { DB_VERB_REPLICATION, "db_verb_replication" }, + { DB_VERB_REP_ELECT, "db_verb_rep_elect" }, + { DB_VERB_REP_LEASE, "db_verb_rep_lease" }, + { DB_VERB_REP_MISC, "db_verb_rep_misc" }, + { DB_VERB_REP_MSGS, "db_verb_rep_msgs" }, + { DB_VERB_REP_SYNC, "db_verb_rep_sync" }, + { DB_VERB_REP_SYSTEM, "db_verb_rep_system" }, + { DB_VERB_REP_TEST, "db_verb_rep_test" }, + { DB_VERB_REPMGR_CONNFAIL, "db_verb_repmgr_connfail" }, + { DB_VERB_REPMGR_MISC, "db_verb_repmgr_misc" }, + { DB_VERB_WAITSFOR, "db_verb_waitsfor" }, + { 0, NULL} +}; static int __config_parse __P((ENV *, char *, int)); +static int __config_scan __P((char *, char **, const CFG_DESC **)); +static int cmp_cfg_name __P((const void *, const void *element)); /* * __env_read_db_config -- @@ -64,55 +305,36 @@ __env_read_db_config(env) return (ret); } -#undef CONFIG_GET_INT -#define CONFIG_GET_INT(s, vp) do { \ +#undef CFG_GET_INT +#define CFG_GET_INT(s, vp) do { \ int __ret; \ if ((__ret = \ __db_getlong(env->dbenv, NULL, s, 0, INT_MAX, vp)) != 0) \ return (__ret); \ } while (0) -#undef CONFIG_GET_LONG -#define CONFIG_GET_LONG(s, vp) do { \ +#undef CFG_GET_LONG +#define CFG_GET_LONG(s, vp) do { \ int __ret; \ if ((__ret = \ __db_getlong(env->dbenv, NULL, s, 0, LONG_MAX, vp)) != 0) \ return (__ret); \ } while (0) -#undef CONFIG_GET_UINT -#define CONFIG_GET_UINT(s, vp) do { \ +#undef CFG_GET_UINT +#define CFG_GET_UINT(s, vp) do { \ int __ret; \ if ((__ret = \ __db_getulong(env->dbenv, NULL, s, 0, UINT_MAX, vp)) != 0) \ return (__ret); \ } while (0) -#undef CONFIG_INT -#define CONFIG_INT(s, f) do { \ - if (strcasecmp(s, argv[0]) == 0) { \ - long __v; \ - if (nf != 2) \ - goto format; \ - CONFIG_GET_INT(argv[1], &__v); \ - return (f(env->dbenv, (int)__v)); \ - } \ -} while (0) -#undef CONFIG_GET_UINT32 -#define CONFIG_GET_UINT32(s, vp) do { \ +#undef CFG_GET_UINT32 +#define CFG_GET_UINT32(s, vp) do { \ if (__db_getulong(env->dbenv, NULL, s, 0, UINT32_MAX, vp) != 0) \ return (EINVAL); \ } while (0) -#undef CONFIG_UINT32 -#define CONFIG_UINT32(s, f) do { \ - if (strcasecmp(s, argv[0]) == 0) { \ - u_long __v; \ - if (nf != 2) \ - goto format; \ - CONFIG_GET_UINT32(argv[1], &__v); \ - return (f(env->dbenv, (u_int32_t)__v)); \ - } \ -} while (0) -#undef CONFIG_SLOTS -#define CONFIG_SLOTS 10 +/* This is the maximum number of tokens in a DB_CONFIG line. */ +#undef CFG_SLOTS +#define CFG_SLOTS 10 /* * __config_parse -- @@ -127,67 +349,97 @@ __config_parse(env, s, lc) DB_ENV *dbenv; DB_SITE *site; u_long uv1, uv2; - u_int32_t flags; long lv1, lv2; u_int port; int i, nf, onoff, bad, ret, t_ret; - char *argv[CONFIG_SLOTS]; - DB_MEM_CONFIG mem_conf; + char *argv[CFG_SLOTS]; + const CFG_DESC *desc; bad = 0; dbenv = env->dbenv; - /* Split the line by white-space. */ - if ((nf = __config_split(s, argv)) < 2) { + + /* + * Split the input line in 's' into its argv-like components, returning + * the number of fields. If the command is one of the "simple" ones in + * config_descs, also return its command descriptor. + */ + if ((nf = __config_scan(s, argv, &desc)) < 2) { format: __db_errx(env, DB_STR_A("1584", "line %d: %s: incorrect name-value pair", "%d %s"), lc, argv[0]); return (EINVAL); } - if (strcasecmp(argv[0], "set_memory_max") == 0) { - if (nf != 3) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - return (__env_set_memory_max( - dbenv, (u_int32_t)uv1, (u_int32_t)uv2)); + /* Handle simple configuration lines here. */ + if (desc != NULL) { + ret = 0; + switch (desc->type) { + case CFG_INT: /* */ + if (nf != 2) + goto format; + CFG_GET_INT(argv[1], &lv1); + ret = ((CFG_FUNC_INT)desc->func)(dbenv, (int) lv1); + break; + + case CFG_LONG: /* */ + if (nf != 2) + goto format; + CFG_GET_LONG(argv[1], &lv1); + ret = ((CFG_FUNC_LONG)desc->func)(dbenv, lv1); + break; + + case CFG_UINT: /* */ + if (nf != 2) + goto format; + CFG_GET_UINT(argv[1], &uv1); + ret = ((CFG_FUNC_UINT)desc->func) + (dbenv, (u_int32_t) uv1); + break; + + case CFG_2INT: /* */ + if (nf != 3) + goto format; + CFG_GET_INT(argv[1], &lv1); + CFG_GET_INT(argv[2], &lv2); + ret = ((CFG_FUNC_2INT)desc->func) + (dbenv, (int) lv1, (int) lv2); + break; + + case CFG_2UINT: /* */ + if (nf != 3) + goto format; + CFG_GET_UINT(argv[1], &uv1); + CFG_GET_UINT(argv[2], &uv2); + ret = ((CFG_FUNC_2UINT)desc->func) + (dbenv, (u_int32_t) uv1, (u_int32_t) uv2); + break; + + case CFG_STRING: /* */ + ret = ((CFG_FUNC_STRING) desc->func)(dbenv, argv[1]); + break; + } + return (ret); } + + /* + * The commands not covered in config_descs are handled below, each + * with their own command-specific block of code. Most of them are + * fairly similar to each other, but not quite enough to warrant + * that they all be table-driven too. + */ + + /* set_memory_init db_mem_XXX */ if (strcasecmp(argv[0], "set_memory_init") == 0) { if (nf != 3) goto format; - if (strcasecmp(argv[1], "DB_MEM_LOCK") == 0) - mem_conf = DB_MEM_LOCK; - else if (strcasecmp(argv[1], "DB_MEM_LOCKER") == 0) - mem_conf = DB_MEM_LOCKER; - else if (strcasecmp(argv[1], "DB_MEM_LOCKOBJECT") == 0) - mem_conf = DB_MEM_LOCKOBJECT; - else if (strcasecmp(argv[1], "DB_MEM_TRANSACTION") == 0) - mem_conf = DB_MEM_TRANSACTION; - else if (strcasecmp(argv[1], "DB_MEM_THREAD") == 0) - mem_conf = DB_MEM_THREAD; - else if (strcasecmp(argv[1], "DB_MEM_LOGID") == 0) - mem_conf = DB_MEM_LOGID; - else + if ((lv1 = __db_name_to_val(config_mem_init, argv[1])) == -1) goto format; - CONFIG_GET_UINT32(argv[2], &uv2); - return (__env_set_memory_init(dbenv, mem_conf, (u_int32_t)uv2)); - } - - CONFIG_UINT32("mutex_set_align", __mutex_set_align); - CONFIG_UINT32("mutex_set_increment", __mutex_set_increment); - CONFIG_UINT32("mutex_set_init", __mutex_set_init); - CONFIG_UINT32("mutex_set_max", __mutex_set_max); - CONFIG_UINT32("mutex_set_tas_spins", __mutex_set_tas_spins); - - if (strcasecmp(argv[0], "rep_set_clockskew") == 0) { - if (nf != 3) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - return (__rep_set_clockskew( - dbenv, (u_int32_t)uv1, (u_int32_t)uv2)); + CFG_GET_UINT32(argv[2], &uv2); + return (__env_set_memory_init(dbenv, + (DB_MEM_CONFIG) lv1, (u_int32_t)uv2)); } + /* rep_set_config { db_rep_conf_XXX | db_repmgr_conf_XXX } [on|off] */ if (strcasecmp(argv[0], "rep_set_config") == 0) { if (nf != 2 && nf != 3) goto format; @@ -198,158 +450,49 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[2], "on") != 0) goto format; } - if (strcasecmp(argv[1], "db_rep_conf_autoinit") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_AUTOINIT, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_autorollback") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_AUTOROLLBACK, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_bulk") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_BULK, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_delayclient") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_DELAYCLIENT, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_inmem") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_INMEM, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_lease") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_LEASE, onoff)); - if (strcasecmp(argv[1], "db_rep_conf_nowait") == 0) - return (__rep_set_config(dbenv, - DB_REP_CONF_NOWAIT, onoff)); - if (strcasecmp(argv[1], "db_repmgr_conf_2site_strict") == 0) - return (__rep_set_config(dbenv, - DB_REPMGR_CONF_2SITE_STRICT, onoff)); - if (strcasecmp(argv[1], "db_repmgr_conf_elections") == 0) - return (__rep_set_config(dbenv, - DB_REPMGR_CONF_ELECTIONS, onoff)); - goto format; - } - - if (strcasecmp(argv[0], "rep_set_limit") == 0) { - if (nf != 3) + if ((lv1 = __db_name_to_val(config_rep_config, argv[1])) == -1) goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - return (__rep_set_limit( - dbenv, (u_int32_t)uv1, (u_int32_t)uv2)); - } - - if (strcasecmp(argv[0], "rep_set_nsites") == 0) { - if (nf != 2) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - return (__rep_set_nsites_pp( - dbenv, (u_int32_t)uv1)); - } - - if (strcasecmp(argv[0], "rep_set_priority") == 0) { - if (nf != 2) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - return (__rep_set_priority( - dbenv, (u_int32_t)uv1)); - } - - if (strcasecmp(argv[0], "rep_set_request") == 0) { - if (nf != 3) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - return (__rep_set_request( - dbenv, (u_int32_t)uv1, (u_int32_t)uv2)); + return (__rep_set_config(dbenv, (u_int32_t)lv1, onoff)); } + /* rep_set_timeout db_rep_XXX */ if (strcasecmp(argv[0], "rep_set_timeout") == 0) { if (nf != 3) goto format; - CONFIG_GET_UINT32(argv[2], &uv2); - if (strcasecmp(argv[1], "db_rep_ack_timeout") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_ACK_TIMEOUT, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_checkpoint_delay") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_CHECKPOINT_DELAY, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_connection_retry") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_CONNECTION_RETRY, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_election_timeout") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_ELECTION_TIMEOUT, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_election_retry") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_ELECTION_RETRY, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_full_election_timeout") == 0) - return (__rep_set_timeout(dbenv, - DB_REP_FULL_ELECTION_TIMEOUT, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_heartbeat_monitor") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_HEARTBEAT_MONITOR, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_heartbeat_send") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_HEARTBEAT_SEND, (u_int32_t)uv2)); - if (strcasecmp(argv[1], "db_rep_lease_timeout") == 0) - return (__rep_set_timeout( - dbenv, DB_REP_LEASE_TIMEOUT, (u_int32_t)uv2)); - goto format; + if ((lv1 = __db_name_to_val(config_rep_timeout, argv[1])) == -1) + goto format; + CFG_GET_UINT32(argv[2], &uv2); + return (__rep_set_timeout(dbenv, lv1, (db_timeout_t)uv2)); } + /* repmgr_set_ack_policy db_repmgr_acks_XXX */ if (strcasecmp(argv[0], "repmgr_set_ack_policy") == 0) { if (nf != 2) goto format; - if (strcasecmp(argv[1], "db_repmgr_acks_all") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_ALL)); - if (strcasecmp(argv[1], "db_repmgr_acks_all_available") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_ALL_AVAILABLE)); - if (strcasecmp(argv[1], "db_repmgr_acks_all_peers") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_ALL_PEERS)); - if (strcasecmp(argv[1], "db_repmgr_acks_none") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_NONE)); - if (strcasecmp(argv[1], "db_repmgr_acks_one") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_ONE)); - if (strcasecmp(argv[1], "db_repmgr_acks_one_peer") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_ONE_PEER)); - if (strcasecmp(argv[1], "db_repmgr_acks_quorum") == 0) - return (__repmgr_set_ack_policy( - dbenv, DB_REPMGR_ACKS_QUORUM)); - goto format; + if ((lv1 = + __db_name_to_val(config_repmgr_ack_policy, argv[1])) == -1) + goto format; + return (__repmgr_set_ack_policy(dbenv, lv1)); } /* * Configure name/value pairs of config information for a site (local or * remote). * - * repmgr_site host port [which value] ... + * repmgr_site host port [which value(on | off | unsigned)}] ... */ if (strcasecmp(argv[0], "repmgr_site") == 0) { if (nf < 3 || (nf % 2) == 0) goto format; - CONFIG_GET_UINT(argv[2], &uv2); + CFG_GET_UINT(argv[2], &uv2); port = (u_int)uv2; if ((ret = __repmgr_site(dbenv, argv[1], port, &site, 0)) != 0) return (ret); #ifdef HAVE_REPLICATION_THREADS for (i = 3; i < nf; i += 2) { - if (strcasecmp(argv[i], "db_bootstrap_helper") == 0) - uv1 = DB_BOOTSTRAP_HELPER; - else if (strcasecmp(argv[i], "db_group_creator") == 0) - uv1 = DB_GROUP_CREATOR; - else if (strcasecmp(argv[i], "db_legacy") == 0) - uv1 = DB_LEGACY; - else if (strcasecmp(argv[i], "db_local_site") == 0) - uv1 = DB_LOCAL_SITE; - else if (strcasecmp(argv[i], "db_repmgr_peer") == 0) - uv1 = DB_REPMGR_PEER; - else { + if ((lv1 = __db_name_to_val( + config_repmgr_site, argv[i])) == -1) { bad = 1; break; } @@ -359,9 +502,9 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[i + 1], "off") == 0) uv2 = 0; else - CONFIG_GET_UINT32(argv[i + 1], &uv2); + CFG_GET_UINT32(argv[i + 1], &uv2); if ((ret = __repmgr_site_config(site, - (u_int32_t)uv1, (u_int32_t)uv2)) != 0) + (u_int32_t)lv1, (u_int32_t)uv2)) != 0) break; } if ((t_ret = __repmgr_site_close(site)) != 0 && ret == 0) @@ -377,59 +520,29 @@ format: __db_errx(env, DB_STR_A("1584", return (ret); } + /* set_cachesize */ if (strcasecmp(argv[0], "set_cachesize") == 0) { if (nf != 4) goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - CONFIG_GET_INT(argv[3], &lv1); + CFG_GET_UINT32(argv[1], &uv1); + CFG_GET_UINT32(argv[2], &uv2); + CFG_GET_INT(argv[3], &lv1); return (__memp_set_cachesize( dbenv, (u_int32_t)uv1, (u_int32_t)uv2, (int)lv1)); } - if (strcasecmp(argv[0], "set_cache_max") == 0) { - if (nf != 3) - goto format; - CONFIG_GET_UINT32(argv[1], &uv1); - CONFIG_GET_UINT32(argv[2], &uv2); - return (__memp_set_cache_max( - dbenv, (u_int32_t)uv1, (u_int32_t)uv2)); - } - - if (strcasecmp(argv[0], "set_data_dir") == 0 || - strcasecmp(argv[0], "db_data_dir") == 0) { /* Compatibility. */ - if (nf != 2) - goto format; - return (__env_set_data_dir(dbenv, argv[1])); - } - - if (strcasecmp(argv[0], "add_data_dir") == 0) { - if (nf != 2) - goto format; - return (__env_add_data_dir(dbenv, argv[1])); - } - if (strcasecmp(argv[0], "set_create_dir") == 0) { - if (nf != 2) - goto format; - return (__env_set_create_dir(dbenv, argv[1])); - } - - /* Compatibility */ + /* set_intermediate_dir */ if (strcasecmp(argv[0], "set_intermediate_dir") == 0) { if (nf != 2) goto format; - CONFIG_GET_INT(argv[1], &lv1); + CFG_GET_INT(argv[1], &lv1); if (lv1 <= 0) goto format; env->dir_mode = (int)lv1; return (0); } - if (strcasecmp(argv[0], "set_intermediate_dir_mode") == 0) { - if (nf != 2) - goto format; - return (__env_set_intermediate_dir_mode(dbenv, argv[1])); - } + /* set_flags [on | off] */ if (strcasecmp(argv[0], "set_flags") == 0) { if (nf != 2 && nf != 3) goto format; @@ -440,52 +553,16 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[2], "on") != 0) goto format; } - if (strcasecmp(argv[1], "db_auto_commit") == 0) - return (__env_set_flags(dbenv, DB_AUTO_COMMIT, onoff)); - if (strcasecmp(argv[1], "db_cdb_alldb") == 0) - return (__env_set_flags(dbenv, DB_CDB_ALLDB, onoff)); - if (strcasecmp(argv[1], "db_direct_db") == 0) - return (__env_set_flags(dbenv, DB_DIRECT_DB, onoff)); - if (strcasecmp(argv[1], "db_dsync_db") == 0) - return (__env_set_flags(dbenv, DB_DSYNC_DB, onoff)); - if (strcasecmp(argv[1], "db_multiversion") == 0) - return (__env_set_flags(dbenv, DB_MULTIVERSION, onoff)); - if (strcasecmp(argv[1], "db_nolocking") == 0) - return (__env_set_flags(dbenv, DB_NOLOCKING, onoff)); - if (strcasecmp(argv[1], "db_nommap") == 0) - return (__env_set_flags(dbenv, DB_NOMMAP, onoff)); - if (strcasecmp(argv[1], "db_nopanic") == 0) - return (__env_set_flags(dbenv, DB_NOPANIC, onoff)); - if (strcasecmp(argv[1], "db_overwrite") == 0) - return (__env_set_flags(dbenv, DB_OVERWRITE, onoff)); - if (strcasecmp(argv[1], "db_region_init") == 0) - return (__env_set_flags(dbenv, DB_REGION_INIT, onoff)); - if (strcasecmp(argv[1], "db_time_notgranted") == 0) - return ( - __env_set_flags(dbenv, DB_TIME_NOTGRANTED, onoff)); - if (strcasecmp(argv[1], "db_txn_nosync") == 0) - return (__env_set_flags(dbenv, DB_TXN_NOSYNC, onoff)); - if (strcasecmp(argv[1], "db_txn_nowait") == 0) - return (__env_set_flags(dbenv, DB_TXN_NOWAIT, onoff)); - if (strcasecmp(argv[1], "db_txn_snapshot") == 0) - return (__env_set_flags(dbenv, DB_TXN_SNAPSHOT, onoff)); - if (strcasecmp(argv[1], "db_txn_write_nosync") == 0) - return ( - __env_set_flags(dbenv, DB_TXN_WRITE_NOSYNC, onoff)); - if (strcasecmp(argv[1], "db_yieldcpu") == 0) - return (__env_set_flags(dbenv, DB_YIELDCPU, onoff)); - if (strcasecmp(argv[1], "db_log_inmemory") == 0) - return ( - __log_set_config(dbenv, DB_LOG_IN_MEMORY, onoff)); - if (strcasecmp(argv[1], "db_direct_log") == 0) - return (__log_set_config(dbenv, DB_LOG_DIRECT, onoff)); - if (strcasecmp(argv[1], "db_dsync_log") == 0) - return (__log_set_config(dbenv, DB_LOG_DSYNC, onoff)); - if (strcasecmp(argv[1], "db_log_autoremove") == 0) - return ( - __log_set_config(dbenv, DB_LOG_AUTO_REMOVE, onoff)); + /* First see whether it is an env flag, then a log flag. */ + if ((lv1 = __db_name_to_val(config_set_flags, argv[1])) != -1) + return (__env_set_flags(dbenv, (u_int32_t)lv1, onoff)); + else if ((lv1 = + __db_name_to_val(config_set_flags_forlog, argv[1])) != -1) + return (__log_set_config(dbenv, (u_int32_t)lv1, onoff)); goto format; } + + /* log_set_config [on | off] */ if (strcasecmp(argv[0], "log_set_config") == 0) { if (nf != 2 && nf != 3) goto format; @@ -496,89 +573,32 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[2], "on") != 0) goto format; } - if (strcasecmp(argv[1], "db_log_auto_remove") == 0) - return ( - __log_set_config(dbenv, DB_LOG_AUTO_REMOVE, onoff)); - if (strcasecmp(argv[1], "db_log_direct") == 0) - return (__log_set_config(dbenv, DB_LOG_DIRECT, onoff)); - if (strcasecmp(argv[1], "db_log_dsync") == 0) - return (__log_set_config(dbenv, DB_LOG_DSYNC, onoff)); - if (strcasecmp(argv[1], "db_log_in_memory") == 0) - return ( - __log_set_config(dbenv, DB_LOG_IN_MEMORY, onoff)); - if (strcasecmp(argv[1], "db_log_zero") == 0) - return (__log_set_config(dbenv, DB_LOG_ZERO, onoff)); - goto format; - } - - CONFIG_UINT32("set_data_len", __env_set_data_len); - CONFIG_UINT32("set_lg_bsize", __log_set_lg_bsize); - CONFIG_INT("set_lg_filemode", __log_set_lg_filemode); - CONFIG_UINT32("set_lg_max", __log_set_lg_max); - CONFIG_UINT32("set_lg_regionmax", __log_set_lg_regionmax); - - if (strcasecmp(argv[0], "set_lg_dir") == 0 || - strcasecmp(argv[0], "db_log_dir") == 0) { /* Compatibility. */ - if (nf != 2) + if ((lv1 = + __db_name_to_val(config_log_set_config, argv[1])) == -1) goto format; - return (__log_set_lg_dir(dbenv, argv[1])); + return (__log_set_config(dbenv, (u_int32_t)lv1, onoff)); } + /* set_lk_detect db_lock_xxx */ if (strcasecmp(argv[0], "set_lk_detect") == 0) { if (nf != 2) goto format; - if (strcasecmp(argv[1], "db_lock_default") == 0) - flags = DB_LOCK_DEFAULT; - else if (strcasecmp(argv[1], "db_lock_expire") == 0) - flags = DB_LOCK_EXPIRE; - else if (strcasecmp(argv[1], "db_lock_maxlocks") == 0) - flags = DB_LOCK_MAXLOCKS; - else if (strcasecmp(argv[1], "db_lock_maxwrite") == 0) - flags = DB_LOCK_MAXWRITE; - else if (strcasecmp(argv[1], "db_lock_minlocks") == 0) - flags = DB_LOCK_MINLOCKS; - else if (strcasecmp(argv[1], "db_lock_minwrite") == 0) - flags = DB_LOCK_MINWRITE; - else if (strcasecmp(argv[1], "db_lock_oldest") == 0) - flags = DB_LOCK_OLDEST; - else if (strcasecmp(argv[1], "db_lock_random") == 0) - flags = DB_LOCK_RANDOM; - else if (strcasecmp(argv[1], "db_lock_youngest") == 0) - flags = DB_LOCK_YOUNGEST; - else + if ((lv1 = + __db_name_to_val(config_set_lk_detect, argv[1])) == -1) goto format; - return (__lock_set_lk_detect(dbenv, flags)); + return (__lock_set_lk_detect(dbenv, (u_int32_t)lv1)); } - CONFIG_UINT32("set_lk_max_locks", __lock_set_lk_max_locks); - CONFIG_UINT32("set_lk_max_lockers", __lock_set_lk_max_lockers); - CONFIG_UINT32("set_lk_max_objects", __lock_set_lk_max_objects); - CONFIG_UINT32("set_lk_partitions", __lock_set_lk_partitions); - CONFIG_UINT32("set_lk_tablesize", __lock_set_lk_tablesize); - + /* set_lock_timeout */ if (strcasecmp(argv[0], "set_lock_timeout") == 0) { if (nf != 2) goto format; - CONFIG_GET_UINT32(argv[1], &uv1); + CFG_GET_UINT32(argv[1], &uv1); return (__lock_set_env_timeout( dbenv, (u_int32_t)uv1, DB_SET_LOCK_TIMEOUT)); } - CONFIG_INT("set_mp_max_openfd", __memp_set_mp_max_openfd); - CONFIG_UINT32("set_mp_mtxcount", __memp_set_mp_mtxcount); - CONFIG_UINT32("set_mp_pagesize", __memp_set_mp_pagesize); - - if (strcasecmp(argv[0], "set_mp_max_write") == 0) { - if (nf != 3) - goto format; - CONFIG_GET_INT(argv[1], &lv1); - CONFIG_GET_INT(argv[2], &lv2); - return (__memp_set_mp_max_write( - dbenv, (int)lv1, (db_timeout_t)lv2)); - } - - CONFIG_UINT32("set_mp_mmapsize", __memp_set_mp_mmapsize); - + /* set_open_flags [on | off] */ if (strcasecmp(argv[0], "set_open_flags") == 0) { if (nf != 2 && nf != 3) goto format; @@ -589,83 +609,46 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[2], "on") != 0) goto format; } - if (strcasecmp(argv[1], "db_init_rep") == 0) { - if (onoff == 1) - FLD_SET(env->open_flags, DB_INIT_REP); - else - FLD_CLR(env->open_flags, DB_INIT_REP); - return (0); - } else if (strcasecmp(argv[1], "db_private") == 0) { - if (onoff == 1) - FLD_SET(env->open_flags, DB_PRIVATE); - else - FLD_CLR(env->open_flags, DB_PRIVATE); - return (0); - } else if (strcasecmp(argv[1], "db_register") == 0) { - if (onoff == 1) - FLD_SET(env->open_flags, DB_REGISTER); - else - FLD_CLR(env->open_flags, DB_REGISTER); - return (0); - } else if (strcasecmp(argv[1], "db_thread") == 0) { - if (onoff == 1) - FLD_SET(env->open_flags, DB_THREAD); - else - FLD_CLR(env->open_flags, DB_THREAD); - return (0); - } else + if ((lv1 = + __db_name_to_val(config_set_open_flags, argv[1])) == -1) goto format; + if (onoff == 1) + FLD_SET(env->open_flags, (u_int32_t)lv1); + else + FLD_CLR(env->open_flags, (u_int32_t)lv1); + return (0); } + /* set_region_init <0 or 1> */ if (strcasecmp(argv[0], "set_region_init") == 0) { if (nf != 2) goto format; - CONFIG_GET_INT(argv[1], &lv1); + CFG_GET_INT(argv[1], &lv1); if (lv1 != 0 && lv1 != 1) goto format; return (__env_set_flags( dbenv, DB_REGION_INIT, lv1 == 0 ? 0 : 1)); } + /* set_reg_timeout */ if (strcasecmp(argv[0], "set_reg_timeout") == 0) { if (nf != 2) goto format; - CONFIG_GET_UINT32(argv[1], &uv1); + CFG_GET_UINT32(argv[1], &uv1); return (__env_set_timeout( dbenv, (u_int32_t)uv1, DB_SET_REG_TIMEOUT)); } - if (strcasecmp(argv[0], "set_shm_key") == 0) { - if (nf != 2) - goto format; - CONFIG_GET_LONG(argv[1], &lv1); - return (__env_set_shm_key(dbenv, lv1)); - } - - /* - * The set_tas_spins method has been replaced by mutex_set_tas_spins. - * The set_tas_spins argv[0] remains for DB_CONFIG compatibility. - */ - CONFIG_UINT32("set_tas_spins", __mutex_set_tas_spins); - - if (strcasecmp(argv[0], "set_tmp_dir") == 0 || - strcasecmp(argv[0], "db_tmp_dir") == 0) { /* Compatibility.*/ - if (nf != 2) - goto format; - return (__env_set_tmp_dir(dbenv, argv[1])); - } - - CONFIG_UINT32("set_thread_count", __env_set_thread_count); - CONFIG_UINT32("set_tx_max", __txn_set_tx_max); - + /* set_txn_timeout */ if (strcasecmp(argv[0], "set_txn_timeout") == 0) { if (nf != 2) goto format; - CONFIG_GET_UINT32(argv[1], &uv1); + CFG_GET_UINT32(argv[1], &uv1); return (__lock_set_env_timeout( dbenv, (u_int32_t)uv1, DB_SET_TXN_TIMEOUT)); } + /* set_verbose db_verb_XXX [on | off] */ if (strcasecmp(argv[0], "set_verbose") == 0) { if (nf != 2 && nf != 3) goto format; @@ -676,69 +659,79 @@ format: __db_errx(env, DB_STR_A("1584", else if (strcasecmp(argv[2], "on") != 0) goto format; } - if (strcasecmp(argv[1], "db_verb_deadlock") == 0) - flags = DB_VERB_DEADLOCK; - else if (strcasecmp(argv[1], "db_verb_fileops") == 0) - flags = DB_VERB_FILEOPS; - else if (strcasecmp(argv[1], "db_verb_fileops_all") == 0) - flags = DB_VERB_FILEOPS_ALL; - else if (strcasecmp(argv[1], "db_verb_recovery") == 0) - flags = DB_VERB_RECOVERY; - else if (strcasecmp(argv[1], "db_verb_register") == 0) - flags = DB_VERB_REGISTER; - else if (strcasecmp(argv[1], "db_verb_replication") == 0) - flags = DB_VERB_REPLICATION; - else if (strcasecmp(argv[1], "db_verb_rep_elect") == 0) - flags = DB_VERB_REP_ELECT; - else if (strcasecmp(argv[1], "db_verb_rep_lease") == 0) - flags = DB_VERB_REP_LEASE; - else if (strcasecmp(argv[1], "db_verb_rep_misc") == 0) - flags = DB_VERB_REP_MISC; - else if (strcasecmp(argv[1], "db_verb_rep_msgs") == 0) - flags = DB_VERB_REP_MSGS; - else if (strcasecmp(argv[1], "db_verb_rep_sync") == 0) - flags = DB_VERB_REP_SYNC; - else if (strcasecmp(argv[1], "db_verb_rep_system") == 0) - flags = DB_VERB_REP_SYSTEM; - else if (strcasecmp(argv[1], "db_verb_rep_test") == 0) - flags = DB_VERB_REP_TEST; - else if (strcasecmp(argv[1], "db_verb_repmgr_connfail") == 0) - flags = DB_VERB_REPMGR_CONNFAIL; - else if (strcasecmp(argv[1], "db_verb_repmgr_misc") == 0) - flags = DB_VERB_REPMGR_MISC; - else if (strcasecmp(argv[1], "db_verb_waitsfor") == 0) - flags = DB_VERB_WAITSFOR; - else + if ((lv1 = __db_name_to_val(config_set_verbose, argv[1])) == -1) goto format; - return (__env_set_verbose(dbenv, flags, onoff)); + return (__env_set_verbose(dbenv, (u_int32_t)lv1, onoff)); } - __db_errx(env, DB_STR_A("1585", - "unrecognized name-value pair: %s", "%s"), s); + __db_errx(env, + DB_STR_A("1585", "unrecognized name-value pair: %s", "%s"), s); return (EINVAL); } -/* - * __config_split -- - * Split lines into white-space separated fields, returning the count of - * fields. - * - * PUBLIC: int __config_split __P((char *, char *[])); +/* cmp_cfg_name -- + * Bsearch comparison function for CFG_DESC.name, for looking up + * the names of simple commmands. */ -int -__config_split(input, argv) - char *input, *argv[CONFIG_SLOTS]; +static int +cmp_cfg_name(sought, element) + const void *sought; + const void *element; { + return + (strcmp((const char *) sought, ((const CFG_DESC *) element)->name)); +} + +/* + * __config_scan -- + * Split DB_CONFIG lines into fields. Usually each whitespace separated + * field is scanned as a distinct argument. However, if the command is + * recognized as one needing a single string value, then the rest of the + * line is returned as the one argument. That supports strings which + * contain whitespaces, such as some directory paths. + * + * This returns the number of fields. It sets *descptr to the command + * descriptor (if it is recognized), or NULL. + */ +static int +__config_scan(input, argv, descptr) + char *input, *argv[CFG_SLOTS]; + const CFG_DESC **descptr; +{ + size_t tablecount; int count; char **ap; - for (count = 0, ap = argv; (*ap = strsep(&input, " \t\n")) != NULL;) - if (**ap != '\0') { - ++count; - if (++ap == &argv[CONFIG_SLOTS - 1]) { - *ap = NULL; + tablecount = sizeof(config_descs) / sizeof(config_descs[0]); + *descptr = NULL; + for (count = 0, ap = argv; (*ap = strsep(&input, " \t\n")) != NULL;) { + /* Empty tokens are adjacent whitespaces; skip them. */ + if (**ap == '\0') + continue; + /* Accept a non-empty token as the next field. */ + count++; + ap++; + /* + * If that was the first token, look it up in the simple command + * table. If it is there and takes a single string value, then + * return the remainder of the line (after skipping over any + * leading whitespaces) without splitting it further. + */ + if (count == 1) { + *descptr = bsearch(argv[0], config_descs, + tablecount, sizeof(config_descs[0]), cmp_cfg_name); + if (*descptr != NULL && + (*descptr)->type == CFG_STRING) { + count++; + while (isspace(*input)) + input++; + *ap++ = input; break; } } + /* Stop scanning if the line has too many tokens. */ + if (count >= CFG_SLOTS) + break; + } return (count); } diff --git a/src/env/env_failchk.c b/src/env/env_failchk.c index 7f965c1d..05752f07 100644 --- a/src/env/env_failchk.c +++ b/src/env/env_failchk.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -90,6 +90,9 @@ __env_failchk_int(dbenv) (ret = __dbreg_failchk(env)) != 0)) goto err; + if ((ret = __memp_failchk(env)) != 0) + goto err; + #ifdef HAVE_REPLICATION_THREADS if (REP_ON(env) && (ret = __repmgr_failchk(env)) != 0) goto err; @@ -428,7 +431,11 @@ __env_set_state(env, ipp, state) #else if (memcmp(&id.pid, &ip->dbth_pid, sizeof(id.pid)) != 0) continue; +#ifdef HAVE_MUTEX_PTHREADS + if (pthread_equal(id.tid, ip->dbth_tid) == 0) +#else if (memcmp(&id.tid, &ip->dbth_tid, sizeof(id.tid)) != 0) +#endif continue; break; #endif @@ -441,7 +448,7 @@ __env_set_state(env, ipp, state) if (state == THREAD_VERIFY) { DB_ASSERT(env, ip != NULL && ip->dbth_state != THREAD_OUT); if (ipp != NULL) { - if (ip == NULL) /* The control block wasnt found */ + if (ip == NULL) /* The control block wasn't found */ return (EINVAL); *ipp = ip; } diff --git a/src/env/env_file.c b/src/env/env_file.c index cda15cd0..b102404d 100644 --- a/src/env/env_file.c +++ b/src/env/env_file.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/env/env_globals.c b/src/env/env_globals.c index be83bbd3..955e6738 100644 --- a/src/env/env_globals.c +++ b/src/env/env_globals.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -38,6 +38,7 @@ DB_GLOBALS __db_global_values = { 0, /* num_active_pids */ 0, /* size_active_pids */ NULL, /* active_pids */ + NULL, /* saved_errstr */ NULL, /* j_assert */ NULL, /* j_close */ NULL, /* j_dirfree */ diff --git a/src/env/env_method.c b/src/env/env_method.c index 77e981ad..63deacea 100644 --- a/src/env/env_method.c +++ b/src/env/env_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id: env_method.c,v dabaaeb7d839 2010/08/03 17:28:53 mike $ */ @@ -26,6 +26,7 @@ static int __env_get_data_len __P((DB_ENV *, u_int32_t *)); static int __env_get_flags __P((DB_ENV *, u_int32_t *)); static int __env_get_home __P((DB_ENV *, const char **)); static int __env_get_intermediate_dir_mode __P((DB_ENV *, const char **)); +static int __env_get_metadata_dir __P((DB_ENV *, const char **)); static int __env_get_shm_key __P((DB_ENV *, long *)); static int __env_get_thread_count __P((DB_ENV *, u_int32_t *)); static int __env_get_thread_id_fn __P((DB_ENV *, @@ -158,6 +159,8 @@ __db_env_init(dbenv) */ /* DB_ENV PUBLIC HANDLE LIST BEGIN */ dbenv->add_data_dir = __env_add_data_dir; + dbenv->backup = __db_backup; + dbenv->dbbackup = __db_dbbackup_pp; dbenv->cdsgroup_begin = __cdsgroup_begin_pp; dbenv->close = __env_close_pp; dbenv->dbremove = __env_dbremove_pp; @@ -170,6 +173,8 @@ __db_env_init(dbenv) dbenv->get_app_dispatch = __env_get_app_dispatch; dbenv->get_cache_max = __memp_get_cache_max; dbenv->get_cachesize = __memp_get_cachesize; + dbenv->get_backup_callbacks = __env_get_backup_callbacks; + dbenv->get_backup_config = __env_get_backup_config; dbenv->get_create_dir = __env_get_create_dir; dbenv->get_data_dirs = __env_get_data_dirs; dbenv->get_data_len = __env_get_data_len; @@ -197,6 +202,7 @@ __db_env_init(dbenv) dbenv->get_lk_tablesize = __lock_get_lk_tablesize; dbenv->get_memory_init = __env_get_memory_init; dbenv->get_memory_max = __env_get_memory_max; + dbenv->get_metadata_dir = __env_get_metadata_dir; dbenv->get_mp_max_openfd = __memp_get_mp_max_openfd; dbenv->get_mp_max_write = __memp_get_mp_max_write; dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize; @@ -297,6 +303,8 @@ __db_env_init(dbenv) dbenv->repmgr_stat_print = __repmgr_stat_print_pp; dbenv->set_alloc = __env_set_alloc; dbenv->set_app_dispatch = __env_set_app_dispatch; + dbenv->set_backup_callbacks = __env_set_backup_callbacks; + dbenv->set_backup_config = __env_set_backup_config; dbenv->set_cache_max = __memp_set_cache_max; dbenv->set_cachesize = __memp_set_cachesize; dbenv->set_create_dir = __env_set_create_dir; @@ -326,6 +334,7 @@ __db_env_init(dbenv) dbenv->set_lk_tablesize = __lock_set_lk_tablesize; dbenv->set_memory_init = __env_set_memory_init; dbenv->set_memory_max = __env_set_memory_max; + dbenv->set_metadata_dir = __env_set_metadata_dir; dbenv->set_mp_max_openfd = __memp_set_mp_max_openfd; dbenv->set_mp_max_write = __memp_set_mp_max_write; dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize; @@ -649,7 +658,7 @@ __env_set_memory_max(dbenv, gbytes, bytes) "Maximum memory size too large: maximum is 4GB")); return (EINVAL); } - dbenv->memory_max = (roff_t)((gbytes * GIGABYTE) + bytes); + dbenv->memory_max = ((roff_t)gbytes * GIGABYTE) + bytes; return (0); } @@ -922,10 +931,9 @@ __env_set_flags(dbenv, flags, on) int on; { ENV *env; - DB_TXNREGION *tenv; DB_THREAD_INFO *ip; u_int32_t mapped_flags; - int mem_on, needs_checkpoint, ret; + int mem_on, ret; env = dbenv->env; @@ -1002,30 +1010,10 @@ __env_set_flags(dbenv, flags, on) ENV_REQUIRES_CONFIG(env, env->tx_handle, "DB_ENV->set_flags: DB_HOTBACKUP_IN_PROGRESS", DB_INIT_TXN); - tenv = (DB_TXNREGION *)env->tx_handle->reginfo.primary; - needs_checkpoint = 0; ENV_ENTER(env, ip); - TXN_SYSTEM_LOCK(env); - if (on) { - tenv->n_hotbackup++; - if (tenv->n_bulk_txn > 0) - needs_checkpoint = 1; - } else { - if (tenv->n_hotbackup == 0) - needs_checkpoint = -1; /* signal count error */ - else - tenv->n_hotbackup--; - } - TXN_SYSTEM_UNLOCK(env); + ret = __env_set_backup(env, on); ENV_LEAVE(env, ip); - - if (needs_checkpoint == -1) { - __db_errx(env, DB_STR("1560", - "Attempt to decrement hotbackup counter past zero")); - return (EINVAL); - } - - if (needs_checkpoint && (ret = __txn_checkpoint(env, 0, 0, 0))) + if (ret != 0) return (ret); } @@ -1039,6 +1027,45 @@ __env_set_flags(dbenv, flags, on) return (0); } +/* + * __env_set_backup -- + * PUBLIC: int __env_set_backup __P((ENV *, int)); + */ +int +__env_set_backup(env, on) + ENV *env; + int on; +{ + DB_TXNREGION *tenv; + int needs_checkpoint, ret; + + tenv = (DB_TXNREGION *)env->tx_handle->reginfo.primary; + needs_checkpoint = 0; + + TXN_SYSTEM_LOCK(env); + if (on) { + tenv->n_hotbackup++; + if (tenv->n_bulk_txn > 0) + needs_checkpoint = 1; + } else { + if (tenv->n_hotbackup == 0) + needs_checkpoint = -1; /* signal count error */ + else + tenv->n_hotbackup--; + } + TXN_SYSTEM_UNLOCK(env); + + if (needs_checkpoint == -1) { + __db_errx(env, DB_STR("1560", + "Attempt to decrement hotbackup counter past zero")); + return (EINVAL); + } + + if (needs_checkpoint && (ret = __txn_checkpoint(env, 0, 0, 0))) + return (ret); + return (0); +} + static int __env_get_data_dirs(dbenv, dirpp) DB_ENV *dbenv; @@ -1163,6 +1190,49 @@ __env_get_intermediate_dir_mode(dbenv, modep) return (0); } +/* + * __env_set_metadata_dir -- + * DB_ENV->set_metadata_dir. + * + * PUBLIC: int __env_set_metadata_dir __P((DB_ENV *, const char *)); + */ +int +__env_set_metadata_dir(dbenv, dir) + DB_ENV *dbenv; + const char *dir; +{ + ENV *env; + int i, ret; + + env = dbenv->env; + + ENV_ILLEGAL_AFTER_OPEN(env, "DB_ENV->set_metadata_dir"); + + /* If metadata_dir is not already on data_dir list, add it. */ + for (i = 0; i < dbenv->data_next; i++) + if (strcmp(dir, dbenv->db_data_dir[i]) == 0) + break; + if (i == dbenv->data_next && + (ret = __env_add_data_dir(dbenv, dir)) != 0) { + __db_errx(env, DB_STR_A("1590", + "Could not add %s to environment list.", "%s"), dir); + return (ret); + } + + if (dbenv->db_md_dir != NULL) + __os_free(env, dbenv->db_md_dir); + return (__os_strdup(env, dir, &dbenv->db_md_dir)); +} + +static int +__env_get_metadata_dir(dbenv, dirp) + DB_ENV *dbenv; + const char **dirp; +{ + *dirp = dbenv->db_md_dir; + return (0); +} + /* * __env_set_data_len -- * DB_ENV->set_data_len. @@ -1646,6 +1716,7 @@ __env_get_verbose(dbenv, which, onoffp) int *onoffp; { switch (which) { + case DB_VERB_BACKUP: case DB_VERB_DEADLOCK: case DB_VERB_FILEOPS: case DB_VERB_FILEOPS_ALL: @@ -1683,6 +1754,7 @@ __env_set_verbose(dbenv, which, on) int on; { switch (which) { + case DB_VERB_BACKUP: case DB_VERB_DEADLOCK: case DB_VERB_FILEOPS: case DB_VERB_FILEOPS_ALL: diff --git a/src/env/env_name.c b/src/env/env_name.c index a57dc275..a3a0b371 100644 --- a/src/env/env_name.c +++ b/src/env/env_name.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -184,6 +184,10 @@ __db_appname(env, appname, file, dirp, namep) if (dbenv != NULL) dir = dbenv->db_tmp_dir; break; + case DB_APP_META: + if (dbenv != NULL) + dir = dbenv->db_md_dir; + break; } /* diff --git a/src/env/env_open.c b/src/env/env_open.c index a9e4cdc5..7eddca3a 100644 --- a/src/env/env_open.c +++ b/src/env/env_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -196,7 +196,7 @@ __env_open(dbenv, db_home, flags, mode) * We don't care if the current environment was private or not, we * want to remove files left over for any reason, from any session. */ - if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) +retry: if (LF_ISSET(DB_RECOVER | DB_RECOVER_FATAL)) #ifdef HAVE_REPLICATION if ((ret = __rep_reset_init(env)) != 0 || (ret = __env_remove_env(env)) != 0 || @@ -238,6 +238,19 @@ err: if (ret != 0) (void)__envreg_unregister(env, 1); } + /* + * If the open is called with DB_REGISTER we can potentially skip + * running recovery on a panicked environment. We can't check the panic + * bit earlier since checking requires opening the environment. + * Only retry if DB_RECOVER was specified - the register_recovery flag + * indicates that. + */ + if (ret == DB_RUNRECOVERY && !register_recovery && + !LF_ISSET(DB_RECOVER) && LF_ISSET(DB_REGISTER)) { + LF_SET(DB_RECOVER); + goto retry; + } + return (ret); } @@ -609,6 +622,13 @@ __env_close(dbenv, flags) * is closed. Rep region's internal database is already closed now. */ while ((dbp = TAILQ_FIRST(&env->dblist)) != NULL) { + /* + * Do not close the handle on a database partition, since it + * will be closed when closing the handle on the main database. + */ + while (dbp != NULL && F_ISSET(dbp, DB_AM_PARTDB)) + dbp = TAILQ_NEXT(dbp, dblistlinks); + DB_ASSERT(env, dbp != NULL); /* * Note down and ignore the error code. Since we can't do * anything about the dbp handle anyway if the close @@ -657,6 +677,9 @@ __env_close(dbenv, flags) if (dbenv->db_tmp_dir != NULL) __os_free(env, dbenv->db_tmp_dir); dbenv->db_tmp_dir = NULL; + if (dbenv->db_md_dir != NULL) + __os_free(env, dbenv->db_md_dir); + dbenv->db_md_dir = NULL; if (dbenv->db_data_dir != NULL) { for (p = dbenv->db_data_dir; *p != NULL; ++p) __os_free(env, *p); @@ -671,6 +694,11 @@ __env_close(dbenv, flags) env->db_home = NULL; } + if (env->backup_handle != NULL) { + __os_free(env, env->backup_handle); + env->backup_handle = NULL; + } + /* Discard the structure. */ __db_env_destroy(dbenv); @@ -1058,7 +1086,7 @@ __env_attach_regions(dbenv, flags, orig_flags, retry_ok) */ if ((ret = __mutex_open(env, create_ok)) != 0) goto err; - /* The MUTEX_REQUIRED() in __env_alloc() expectes this to be set. */ + /* The MUTEX_REQUIRED() in __env_alloc() expects this to be set. */ infop->mtx_alloc = ((REGENV *)infop->primary)->mtx_regenv; #endif /* diff --git a/src/env/env_recover.c b/src/env/env_recover.c index a8df6464..9636554a 100644 --- a/src/env/env_recover.c +++ b/src/env/env_recover.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -20,7 +20,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif static int __db_log_corrupt __P((ENV *, DB_LSN *)); @@ -526,7 +526,7 @@ done: (ret = __txn_checkpoint(env, 0, 0, DB_CKP_INTERNAL | DB_FORCE)) != 0) { /* - * If there was no space for the checkpoint or flushng db + * If there was no space for the checkpoint or flushing db * pages we can still bring the environment up, if only for * read-only access. We must not close the open files because a * subsequent recovery might still need to redo this portion @@ -925,7 +925,7 @@ __env_init_rec(env, version) * the recovery functions in reverse log version order. */ /* - * DB_LOGVERSION_52 is a strict superset of DB_LOGVERSION_50. + * DB_LOGVERSION_53 is a strict superset of DB_LOGVERSION_50. * So, only check > DB_LOGVERSION_48p2. If/When log records are * altered, the condition below will need to change. */ diff --git a/src/env/env_region.c b/src/env/env_region.c index c0be73fe..113bea21 100644 --- a/src/env/env_region.c +++ b/src/env/env_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -52,6 +52,7 @@ __env_attach(env, init_flagsp, create_ok, retry_ok) /* Repeated initialization. */ loop: renv = NULL; + rp = NULL; /* Set up the ENV's REG_INFO structure. */ if ((ret = __os_calloc(env, 1, sizeof(REGINFO), &infop)) != 0) @@ -548,6 +549,9 @@ retry: /* Close any open file handle. */ (void)__env_sys_detach(env, infop, F_ISSET(infop, REGION_CREATE)); + + if (rp != NULL && F_ISSET(env, DB_PRIVATE)) + __env_alloc_free(infop, rp); } /* Free the allocated name and/or REGINFO structure. */ @@ -746,6 +750,30 @@ __env_ref_decrement(env) __mutex_free(env, &renv->mtx_regenv) : 0); } +/* + * __env_ref_get -- + * Get the number of environment references. This is an unprotected + * read of refcnt to simply provide a spot check of the value. It + * is only intended for use as an internal utility routine. + * + * PUBLIC: int __env_ref_get __P((DB_ENV *, u_int32_t *)); + */ +int +__env_ref_get(dbenv, countp) + DB_ENV *dbenv; + u_int32_t *countp; +{ + ENV *env; + REGENV *renv; + REGINFO *infop; + + env = dbenv->env; + infop = env->reginfo; + renv = infop->primary; + *countp = renv->refcnt; + return (0); +} + /* * __env_detach -- * Detach from the environment. @@ -965,8 +993,7 @@ __env_remove_file(env) */ for (lastrm = -1, cnt = fcnt; --cnt >= 0;) { /* Skip anything outside our name space. */ - if (strncmp(names[cnt], - DB_REGION_PREFIX, sizeof(DB_REGION_PREFIX) - 1)) + if (!IS_DB_FILE(names[cnt])) continue; /* Skip queue extent files. */ @@ -1088,6 +1115,10 @@ err: /* Discard the underlying region. */ if (infop->addr != NULL) (void)__env_sys_detach(env, infop, F_ISSET(infop, REGION_CREATE)); + else if (infop->name != NULL) { + __os_free(env, infop->name); + infop->name = NULL; + } infop->rp = NULL; infop->id = INVALID_REGION_ID; diff --git a/src/env/env_register.c b/src/env/env_register.c index b51884b5..7475444d 100644 --- a/src/env/env_register.c +++ b/src/env/env_register.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -611,7 +611,7 @@ __envreg_isalive(dbenv, pid, tid, flags ) u_int32_t flags; { /* in this case we really do not care about tid, simply for lint */ - COMPQUIET(tid, 0); + DB_THREADID_INIT(tid); /* if is not an expected value then return early */ if (!((flags == 0) || (flags == DB_MUTEX_PROCESS_ONLY))) diff --git a/src/env/env_sig.c b/src/env/env_sig.c index d8ab7f10..6d127f85 100644 --- a/src/env/env_sig.c +++ b/src/env/env_sig.c @@ -30,7 +30,7 @@ #ifdef HAVE_MIXED_SIZE_ADDRESSING #define __STRUCTURE_COUNT 41 #else -#define __STRUCTURE_COUNT (41 + 103) +#define __STRUCTURE_COUNT (41 + 104) #endif /* @@ -127,6 +127,7 @@ __env_struct_sig() __ADD(__pin_list); __ADD(__env_thread_info); __ADD(__flag_map); + __ADD(__db_backup_handle); __ADD(__env); __ADD(__dbc_internal); __ADD(__dbpginfo); diff --git a/src/env/env_stat.c b/src/env/env_stat.c index 31dbeda3..9bc3fe7e 100644 --- a/src/env/env_stat.c +++ b/src/env/env_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -287,6 +287,7 @@ __env_print_dbenv_all(env, flags) STAT_ISSET("ThreadIdString", dbenv->thread_id_string); STAT_STRING("Log dir", dbenv->db_log_dir); + STAT_STRING("Metadata dir", dbenv->db_md_dir); STAT_STRING("Tmp dir", dbenv->db_tmp_dir); if (dbenv->db_data_dir == NULL) STAT_ISSET("Data dir", dbenv->db_data_dir); diff --git a/src/fileops/fileops.src b/src/fileops/fileops.src index 843f6135..cdb6af27 100644 --- a/src/fileops/fileops.src +++ b/src/fileops/fileops.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/fileops/fop_basic.c b/src/fileops/fop_basic.c index 0de5b788..d6c707f2 100644 --- a/src/fileops/fop_basic.c +++ b/src/fileops/fop_basic.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/fileops/fop_rec.c b/src/fileops/fop_rec.c index dcbd022d..52d6175d 100644 --- a/src/fileops/fop_rec.c +++ b/src/fileops/fop_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/fileops/fop_util.c b/src/fileops/fop_util.c index aeb00249..1925ffd1 100644 --- a/src/fileops/fop_util.c +++ b/src/fileops/fop_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -20,7 +20,8 @@ static int __fop_set_pgsize __P((DB *, DB_FH *, const char *)); static int __fop_inmem_create __P((DB *, const char *, DB_TXN *, u_int32_t)); static int __fop_inmem_dummy __P((DB *, DB_TXN *, const char *, u_int8_t *)); -static int __fop_inmem_read_meta __P((DB *, DB_TXN *, const char *, u_int32_t)); +static int __fop_inmem_read_meta __P((DB *, DB_TXN *, const char *, u_int32_t, + u_int32_t)); static int __fop_inmem_swap __P((DB *, DB *, DB_TXN *, const char *, const char *, const char *, DB_LOCKER *)); static int __fop_ondisk_dummy __P((DB *, DB_TXN *, const char *, u_int8_t *)); @@ -113,9 +114,11 @@ __fop_lock_handle(env, dbp, locker, mode, elockp, flags) /* * If we are in recovery, the only locking we should be - * doing is on the global environment. + * doing is on the global environment. The one exception + * is if we are opening an exclusive database on a client + * syncing with the master. */ - if (IS_RECOVERING(env)) + if (IS_RECOVERING(env) && !F2_ISSET(dbp, DB2_AM_INTEXCL)) return (elockp == NULL ? 0 : __ENV_LPUT(env, *elockp)); memcpy(lock_desc.fileid, dbp->fileid, DB_FILE_ID_LEN); @@ -126,6 +129,8 @@ __fop_lock_handle(env, dbp, locker, mode, elockp, flags) fileobj.data = &lock_desc; fileobj.size = sizeof(lock_desc); DB_TEST_SUBLOCKS(env, flags); + if (F2_ISSET(dbp, DB2_AM_INTEXCL)) + flags |= DB_LOCK_IGNORE_REC; if (elockp == NULL) ret = __lock_get(env, locker, flags, &fileobj, mode, &dbp->handle_lock); @@ -217,6 +222,7 @@ __fop_file_setup(dbp, ip, txn, name, mode, flags, retidp) int created_locker, create_ok, ret, retries, t_ret, tmp_created; int truncating, was_inval; char *real_name, *real_tmpname, *tmpname; + db_lockmode_t lockmode; *retidp = TXN_INVALID; @@ -227,12 +233,17 @@ __fop_file_setup(dbp, ip, txn, name, mode, flags, retidp) created_locker = tmp_created = truncating = was_inval = 0; real_name = real_tmpname = tmpname = NULL; dflags = F_ISSET(dbp, DB_AM_NOT_DURABLE) ? DB_LOG_NOT_DURABLE : 0; - aflags = LF_ISSET(DB_INTERNAL_DB) ? DB_APP_NONE : DB_APP_DATA; - LF_CLR(DB_INTERNAL_DB); + aflags = LF_ISSET(DB_INTERNAL_PERSISTENT_DB) ? DB_APP_META : + (LF_ISSET(DB_INTERNAL_TEMPORARY_DB) ? DB_APP_NONE : DB_APP_DATA); + LF_CLR(DB_INTERNAL_PERSISTENT_DB | DB_INTERNAL_TEMPORARY_DB); ret = 0; retries = 0; save_type = dbp->type; + if (F2_ISSET(dbp, DB2_AM_EXCL)) + lockmode = DB_LOCK_WRITE; + else + lockmode = DB_LOCK_READ; /* * Get a lockerid for this handle. There are paths through queue @@ -286,7 +297,8 @@ retry: * If we cannot create the file, only retry a few times. We * think we might be in a race with another create, but it could * be that the backup filename exists (that is, is left over from - * a previous crash). + * a previous crash). It is also possible to read the metadata + * page while it is being written and fail the checksum. */ if (++retries > DB_RETRY) { __db_errx(env, DB_STR_A("0002", @@ -357,7 +369,8 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = if (LOGGING_ON(env) && (ret = __env_dbreg_setup(dbp, txn, NULL, name, TXN_INVALID)) != 0) return (ret); - ret = __fop_inmem_read_meta(dbp, txn, name, flags); + ret = __fop_inmem_read_meta( + dbp, txn, name, flags, DB_CHK_META|DB_CHK_ONLY); } else { ret = __fop_read_meta(env, real_name, mbuf, sizeof(mbuf), fhp, @@ -381,11 +394,43 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = goto done; } - /* Case 4: This is a valid file. */ + /* + * Case 4: This is a valid file. Now check the + * checksum and decrypt the file so the file + * id can be obtained for the handle lock. Note that + * the checksum can fail if the database is being + * written (possible because the handle lock has + * not been obtained yet). So on checksum fail retry + * until the checksum succeeds or the number of + * retries is exhausted, then throw an error. + */ + if (ret == 0 && (ret = __db_chk_meta(env, dbp, + (DBMETA *)mbuf, DB_CHK_META)) == DB_CHKSUM_FAIL) { + if ((t_ret = __ENV_LPUT(env, elock)) != 0) { + ret = t_ret; + goto err; + } + /* + * Retry unless the number of retries is + * exhausted. + */ + if (!(retries < DB_RETRY)) { + __db_errx(env, DB_STR_A("0210", + "%s: metadata page checksum error", "%s"), real_name); + if (F_ISSET(dbp, DB_AM_RECOVER)) + ret = ENOENT; + else + ret = EINVAL; + goto err; + } + if ((ret = __os_closehandle(env, fhp)) != 0) + goto err; + goto retry; + } + /* Get the file id for the handle lock. */ if (ret == 0) - ret = __db_meta_setup(env, dbp, real_name, - (DBMETA *)mbuf, flags, DB_CHK_META); - + memcpy(dbp->fileid, + ((DBMETA *)mbuf)->uid, DB_FILE_ID_LEN); } /* Case 5: Invalid file. */ @@ -394,11 +439,12 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = /* Now, get our handle lock. */ if ((ret = __fop_lock_handle(env, - dbp, locker, DB_LOCK_READ, NULL, DB_LOCK_NOWAIT)) == 0) { + dbp, locker, lockmode, NULL, DB_LOCK_NOWAIT)) == 0) { if ((ret = __ENV_LPUT(env, elock)) != 0) goto err; } else if (ret != DB_LOCK_NOTGRANTED || - (txn != NULL && F_ISSET(txn, TXN_NOWAIT))) + ((txn != NULL && (F_ISSET(txn, TXN_NOWAIT))) || + F2_ISSET(dbp, DB2_AM_NOWAIT))) goto err; else { PERFMON3(env, @@ -424,7 +470,7 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = fhp = NULL; } if ((ret = __fop_lock_handle(env, - dbp, locker, DB_LOCK_READ, &elock, 0)) != 0) { + dbp, locker, lockmode, &elock, 0)) != 0) { if (F_ISSET(dbp, DB_AM_INMEM)) RESET_MPF(dbp, 0); goto err; @@ -436,9 +482,10 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = * To be sure we have the correct information we * try again. */ - if ((ret = __db_refresh(dbp, - txn, DB_NOSYNC, NULL, 1)) != 0) - goto err; + if (F_ISSET(dbp, DB_AM_INMEM)) { + RESET_MPF(dbp, 0); + MAKE_INMEM(dbp); + } if ((ret = __ENV_LPUT(env, dbp->handle_lock)) != 0) { LOCK_INIT(dbp->handle_lock); @@ -448,7 +495,20 @@ reopen: if (!F_ISSET(dbp, DB_AM_INMEM) && (ret = } - /* If we got here, then we have the handle lock. */ + /* + * If we got here, then we have the handle lock, it is now + * safe to check the rest of the meta data, since the file + * will not be deleted out from under the handle. + */ + if (F_ISSET(dbp, DB_AM_INMEM)) { + if ((ret = __fop_inmem_read_meta( + dbp, txn, name, flags, DB_SKIP_CHK)) != 0) + goto err; + } else { + if ((ret = __db_meta_setup(env, dbp, real_name, + (DBMETA *)mbuf, flags, DB_SKIP_CHK)) != 0) + goto err; + } /* * Check for a file in the midst of a rename. If we find that @@ -637,7 +697,8 @@ creat2: if (!F_ISSET(dbp, DB_AM_INMEM)) { } if (name != NULL && (ret = __fop_lock_handle(env, - dbp, locker, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn))) != 0) + dbp, locker, DB_LOCK_WRITE, NULL, NOWAIT_FLAG(txn)| + (F2_ISSET(dbp,DB2_AM_NOWAIT) ? DB_LOCK_NOWAIT : 0))) != 0) goto err; if (tmpname != NULL && tmpname != name && (ret = __fop_rename(env, stxn, tmpname, @@ -827,11 +888,12 @@ retry: if ((ret = __db_master_open(dbp, */ memcpy(dbp->fileid, mdbp->fileid, DB_FILE_ID_LEN); - lkmode = F_ISSET(dbp, DB_AM_CREATED) || LF_ISSET(DB_WRITEOPEN) ? - DB_LOCK_WRITE : DB_LOCK_READ; + lkmode = F_ISSET(dbp, DB_AM_CREATED) || LF_ISSET(DB_WRITEOPEN) || + F2_ISSET(dbp, DB2_AM_EXCL) ? DB_LOCK_WRITE : DB_LOCK_READ; if ((ret = __fop_lock_handle(env, dbp, txn == NULL ? dbp->locker : txn->locker, lkmode, NULL, - NOWAIT_FLAG(txn))) != 0) + NOWAIT_FLAG(txn) | + (F2_ISSET(dbp, DB2_AM_NOWAIT) ? DB_LOCK_NOWAIT : 0))) != 0) goto err; if ((ret = __db_init_subdb(mdbp, dbp, name, ip, txn)) != 0) { @@ -991,7 +1053,8 @@ retry: if (LOCKING_ON(env)) { /* Get meta-data */ if (F_ISSET(dbp, DB_AM_INMEM)) - ret = __fop_inmem_read_meta(dbp, txn, name, flags); + ret = __fop_inmem_read_meta( + dbp, txn, name, flags, DB_CHK_META); else if ((ret = __fop_read_meta(env, name, mbuf, sizeof(mbuf), fhp, 0, NULL)) == 0) ret = __db_meta_setup(env, dbp, @@ -1327,11 +1390,12 @@ err: } static int -__fop_inmem_read_meta(dbp, txn, name, flags) +__fop_inmem_read_meta(dbp, txn, name, flags, chkflags) DB *dbp; DB_TXN *txn; const char *name; u_int32_t flags; + u_int32_t chkflags; { DBMETA *metap; DB_THREAD_INFO *ip; @@ -1346,7 +1410,13 @@ __fop_inmem_read_meta(dbp, txn, name, flags) pgno = PGNO_BASE_MD; if ((ret = __memp_fget(dbp->mpf, &pgno, ip, txn, 0, &metap)) != 0) return (ret); - ret = __db_meta_setup(dbp->env, dbp, name, metap, flags, DB_CHK_META); + if (FLD_ISSET(chkflags, DB_CHK_ONLY)) { + if ((ret = __db_chk_meta(dbp->env, dbp, metap, chkflags)) == 0) + memcpy(dbp->fileid, + ((DBMETA *)metap)->uid, DB_FILE_ID_LEN); + } else + ret = __db_meta_setup( + dbp->env, dbp, name, metap, flags, chkflags); if ((t_ret = __memp_fput(dbp->mpf, ip, metap, dbp->priority)) && ret == 0) @@ -1661,7 +1731,8 @@ retry: LOCK_INIT(elock); * and allow this rename to succeed if that's the case. */ - if ((ret = __fop_inmem_read_meta(tmpdbp, txn, new, 0)) != 0) { + if ((ret = __fop_inmem_read_meta( + tmpdbp, txn, new, 0, DB_CHK_META)) != 0) { ret = EEXIST; goto err; } diff --git a/src/hash/hash.c b/src/hash/hash.c index fd0a9964..ae5736e7 100644 --- a/src/hash/hash.c +++ b/src/hash/hash.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 @@ -114,7 +114,7 @@ __ham_quick_delete(dbc) if ((ret = __hamc_writelock(dbc)) == 0) { ret = __ham_del_pair(dbc, 0, NULL); /* - * If a page was retreived during the delete, put it now. We + * If a page was retrieved during the delete, put it now. We * can't rely on the callers cursor close to do that, since bulk * delete operations keep the cursor open across deletes. */ diff --git a/src/hash/hash.src b/src/hash/hash.src index 7888532a..e544c6f3 100644 --- a/src/hash/hash.src +++ b/src/hash/hash.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_compact.c b/src/hash/hash_compact.c index f7f33e9b..83b5ffb1 100644 --- a/src/hash/hash_compact.c +++ b/src/hash/hash_compact.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * $Id$ */ @@ -16,8 +16,7 @@ #include "dbinc/mp.h" static int __ham_copy_data __P((DBC *, PAGE *, DB_COMPACT *, int *)); -static int __ham_truncate_overflow __P((DBC *, - PAGE *, u_int32_t, DB_COMPACT *, int *)); +static int __ham_truncate_overflow __P((DBC *, u_int32_t, DB_COMPACT *, int *)); /* * __ham_compact_int -- internal HASH compaction routine. @@ -113,6 +112,10 @@ __ham_compact_int(dbc, start, stop, factor, c_data, donep, flags) * because the page number is * not aligned. */ + if ((ret = __memp_dirty(mpf, &hcp->page, + dbc->thread_info, + dbc->txn, dbc->priority, 0)) != 0) + break; origpgno = pgno; if ((ret = __db_truncate_root(dbc, hcp->page, H_DATAINDEX(hcp->indx), &pgno, 0)) != 0) @@ -136,7 +139,7 @@ no_opd: if (check_trunc && HPAGE_PTYPE(H_PAIRDATA( dbp, hcp->page, hcp->indx)) == H_OFFPAGE) { /* This is an overflow chain. */ if ((ret = __ham_truncate_overflow(dbc, - hcp->page, H_DATAINDEX(hcp->indx), + H_DATAINDEX(hcp->indx), c_data, &pgs_done)) != 0) break; } @@ -146,7 +149,7 @@ no_opd: if (check_trunc && HPAGE_PTYPE(H_PAIRDATA( dbp, hcp->page, hcp->indx)) == H_OFFPAGE) { /* This is an overflow chain. */ if ((ret = __ham_truncate_overflow(dbc, - hcp->page, H_KEYINDEX(hcp->indx), + H_KEYINDEX(hcp->indx), c_data, &pgs_done)) != 0) break; } @@ -233,8 +236,6 @@ __ham_compact_bucket(dbc, c_data, pgs_donep) if (pg == NULL && (ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &pg)) != 0) break; - if (NEXT_PGNO(pg) == PGNO_INVALID) - break; /* Sort any unsorted pages before adding to the page. */ if (TYPE(pg) == P_HASH_UNSORTED) { if ((ret = __ham_sort_page_cursor(dbc, pg)) != 0) @@ -251,6 +252,8 @@ __ham_compact_bucket(dbc, c_data, pgs_donep) if (pgno != PGNO(pg)) (*pgs_donep)++; + if (NEXT_PGNO(pg) == PGNO_INVALID) + break; if ((ret = __ham_copy_data(dbc, pg, c_data, pgs_donep)) != 0) break; pgno = NEXT_PGNO(pg); @@ -376,27 +379,32 @@ __ham_copy_data(dbc, pg, c_data, pgs_donep) * __ham_truncate_overflow -- try to truncate pages from an overflow chain. */ static int -__ham_truncate_overflow(dbc, page, indx, c_data, pgs_done) +__ham_truncate_overflow(dbc, indx, c_data, pgs_done) DBC *dbc; - PAGE *page; u_int32_t indx; DB_COMPACT *c_data; int *pgs_done; { DB *dbp; + HASH_CURSOR *hcp; db_pgno_t origpgno, pgno; int ret; + hcp = (HASH_CURSOR *)dbc->internal; dbp = dbc->dbp; memcpy(&pgno, - HOFFPAGE_PGNO(P_ENTRY(dbp, page, indx)), sizeof(db_pgno_t)); + HOFFPAGE_PGNO(P_ENTRY(dbp, hcp->page, indx)), sizeof(db_pgno_t)); if (pgno > c_data->compact_truncate) { c_data->compact_pages_examine++; origpgno = pgno; - if ((ret = __db_truncate_root(dbc, page, indx, &pgno, 0)) != 0) + if ((ret = __memp_dirty(dbp->mpf, &hcp->page, + dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) + return (ret); + if ((ret = + __db_truncate_root(dbc, hcp->page, indx, &pgno, 0)) != 0) return (ret); if (pgno != origpgno) { - memcpy(HOFFPAGE_PGNO(P_ENTRY(dbp, page, indx)), + memcpy(HOFFPAGE_PGNO(P_ENTRY(dbp, hcp->page, indx)), &pgno, sizeof(db_pgno_t)); (*pgs_done)++; c_data->compact_pages--; @@ -427,7 +435,7 @@ __ham_compact_hash(dbp, ip, txn, c_data) PAGE *oldpage; db_pgno_t free_pgno, last_pgno, pgno, start_pgno; int flags, local_txn, ret, t_ret; - u_int32_t bucket, i; + u_int32_t bucket, i, size; local_txn = IS_DB_AUTO_COMMIT(dbp, txn); oldpage = NULL; @@ -453,11 +461,17 @@ __ham_compact_hash(dbp, ip, txn, c_data) /* * Find contiguous lower numbered pages for each hash table segment. */ - for (i = 1; i <= __db_log2(meta->max_bucket); i++) { - bucket = i == 0 ? 0 : 1 << (i - 1); + for (i = 0; i < NCACHED && meta->spares[i] != PGNO_INVALID; i++) { + if (i == 0) { + bucket = 0; + size = 1; + } else { + bucket = 1 << (i - 1); + size = bucket; + } start_pgno = meta->spares[i] + bucket; if ((ret = __db_find_free(dbc, P_HASH, - bucket, start_pgno, &free_pgno)) != 0) { + size, start_pgno, &free_pgno)) != 0) { if (ret != DB_NOTFOUND) break; ret = 0; @@ -479,7 +493,7 @@ __ham_compact_hash(dbp, ip, txn, c_data) * we must put it. */ for (pgno = start_pgno; - pgno < start_pgno + bucket; pgno++, free_pgno++) { + pgno < start_pgno + size; pgno++, free_pgno++) { if ((ret = __db_lget(dbc, LCK_COUPLE, pgno, DB_LOCK_WRITE, 0, &lock)) != 0) goto err; @@ -508,7 +522,7 @@ __ham_compact_hash(dbp, ip, txn, c_data) oldpage = NULL; c_data->compact_pages_examine++; } - meta->spares[i] = free_pgno - (2 * bucket); + meta->spares[i] = free_pgno - (size + bucket); } if (ret == 0 && F_ISSET(dbp, DB_AM_SUBDB) && PGNO(hcp->hdr) > c_data->compact_truncate) diff --git a/src/hash/hash_conv.c b/src/hash/hash_conv.c index 2c75538c..fa084f2a 100644 --- a/src/hash/hash_conv.c +++ b/src/hash/hash_conv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_dup.c b/src/hash/hash_dup.c index bdf3fd0b..879c33d7 100644 --- a/src/hash/hash_dup.c +++ b/src/hash/hash_dup.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/hash/hash_func.c b/src/hash/hash_func.c index 3988e129..baf6061c 100644 --- a/src/hash/hash_func.c +++ b/src/hash/hash_func.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993 diff --git a/src/hash/hash_meta.c b/src/hash/hash_meta.c index 0996dddf..d9a35cb4 100644 --- a/src/hash/hash_meta.c +++ b/src/hash/hash_meta.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -90,7 +90,9 @@ __ham_release_meta(dbc) hcp->hdr = NULL; } - return (__TLPUT(dbc, hcp->hlock)); + ret = __TLPUT(dbc, hcp->hlock); + hcp->hlock.mode = DB_LOCK_NG; + return (ret); } /* diff --git a/src/hash/hash_method.c b/src/hash/hash_method.c index 39c25f55..1da81e70 100644 --- a/src/hash/hash_method.c +++ b/src/hash/hash_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_open.c b/src/hash/hash_open.c index 0789b28e..3d0bb220 100644 --- a/src/hash/hash_open.c +++ b/src/hash/hash_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/hash/hash_page.c b/src/hash/hash_page.c index 22590327..7576fe61 100644 --- a/src/hash/hash_page.c +++ b/src/hash/hash_page.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1990, 1993, 1994 diff --git a/src/hash/hash_rec.c b/src/hash/hash_rec.c index b434c8e1..58965569 100644 --- a/src/hash/hash_rec.c +++ b/src/hash/hash_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 @@ -462,7 +462,7 @@ __ham_replace_recover(env, dbtp, lsnp, op, info) is_plus = 0; } /* - * When chaning from a "regular" record to an off page record + * When chaining from a "regular" record to an off page record * the old record does not contain a header while the new record * does and is at an offset of -1 relative to the data part of * the record. We add this to the amount of the change (which is @@ -1082,7 +1082,7 @@ __ham_contract_recover(env, dbtp, lsnp, op, info) DBC *dbc; HASH_CURSOR *hcp; HMETA *meta; - int cmp_n, cmp_p, ret; + int cmp_n, cmp_p, ret, t_ret; ip = ((DB_TXNHEAD *)info)->thread_info; REC_PRINT(__ham_contract_print); @@ -1120,7 +1120,8 @@ __ham_contract_recover(env, dbtp, lsnp, op, info) } *lsnp = argp->prev_lsn; -out: ret = __ham_release_meta(dbc); +out: if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0) + ret = t_ret; done: REC_CLOSE; } diff --git a/src/hash/hash_reclaim.c b/src/hash/hash_reclaim.c index c88a3695..ce3f6d9e 100644 --- a/src/hash/hash_reclaim.c +++ b/src/hash/hash_reclaim.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -52,7 +52,7 @@ __ham_reclaim(dbp, ip, txn, flags) F_SET(dbc, DBC_DONTLOCK); if ((ret = __ham_traverse(dbc, DB_LOCK_WRITE, - __db_reclaim_callback, (void *)(uintptr_t)flags, 1)) != 0) + __db_reclaim_callback, &flags, 1)) != 0) goto err; if ((ret = __dbc_close(dbc)) != 0) goto err; diff --git a/src/hash/hash_stat.c b/src/hash/hash_stat.c index afcaae14..683ce5a6 100644 --- a/src/hash/hash_stat.c +++ b/src/hash/hash_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_stub.c b/src/hash/hash_stub.c index 414634cc..57337ea9 100644 --- a/src/hash/hash_stub.c +++ b/src/hash/hash_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_upgrade.c b/src/hash/hash_upgrade.c index 2856c3a7..f66a7a58 100644 --- a/src/hash/hash_upgrade.c +++ b/src/hash/hash_upgrade.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/hash/hash_verify.c b/src/hash/hash_verify.c index dde4e676..662e7ac8 100644 --- a/src/hash/hash_verify.c +++ b/src/hash/hash_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -62,11 +62,11 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags) hfunc = __ham_func5; /* - * If we haven't already checked the common fields in pagezero, - * check them. + * If we came through __db_vrfy_pagezero, we have already checked the + * common fields. However, we used the on-disk metadata page, it may + * have been stale. We now have the page from mpool, so check that. */ - if (!F_ISSET(pip, VRFY_INCOMPLETE) && - (ret = __db_vrfy_meta(dbp, vdp, &m->dbmeta, pgno, flags)) != 0) { + if ((ret = __db_vrfy_meta(dbp, vdp, &m->dbmeta, pgno, flags)) != 0) { if (ret == DB_VERIFY_BAD) isbad = 1; else @@ -558,6 +558,15 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) goto err; + /* + * Hash pages that nothing has ever hashed to may never have actually + * come into existence, it is possible, and legal, for the first page in + * a bucket to not exist. This flag would have been set in + * __db_vrfy_walkpages. + */ + if (F_ISSET(pip, VRFY_NONEXISTENT)) + goto err; + /* Make sure we got a plausible page number. */ if (pgno > vdp->last_pgno || (pip->type != P_HASH && pip->type != P_HASH_UNSORTED)) { diff --git a/src/heap/heap.c b/src/heap/heap.c index 3d70bf40..ab404658 100644 --- a/src/heap/heap.c +++ b/src/heap/heap.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -130,11 +130,164 @@ __heap_bulk(dbc, data, flags) DBT *data; u_int32_t flags; { - COMPQUIET(dbc, NULL); - COMPQUIET(data, NULL); - COMPQUIET(flags, 0); + DB *dbp; + DB_HEAP_RID prev_rid, rid; + DBT sdata; + HEAP_CURSOR *cp; + HEAPHDR *hdr; + HEAPSPLITHDR *shdr; + PAGE *pg; + db_lockmode_t lock_type; + int is_key, ret; + int32_t *offp; + u_int32_t data_size, key_size, needed, space; + u_int8_t *dbuf, *np; - return (EINVAL); + ret = 0; + dbp = dbc->dbp; + cp = (HEAP_CURSOR *)dbc->internal; + hdr = NULL; + shdr = NULL; + + /* Check for additional bits for locking */ + if (F_ISSET(dbc, DBC_RMW)) + lock_type = DB_LOCK_WRITE; + else + lock_type = DB_LOCK_READ; + + /* + * np is the next place to copy things into the buffer. + * dbuf always stays at the beginning of the buffer. + */ + dbuf = data->data; + np = dbuf; + + /* Keep track of space that is left. There is a termination entry */ + space = data->ulen; + space -= sizeof(*offp); + + /* Build the offset/size table from the end up. */ + offp = (int32_t *)((u_int8_t *)dbuf + data->ulen); + offp--; + + /* + * key_size and data_size hold the 32-bit aligned size of the key and + * data values written to the buffer. + */ + key_size = DB_ALIGN(DB_HEAP_RID_SZ, sizeof(u_int32_t)); + data_size = 0; + + /* is_key indicates whether keys are returned. */ + is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0; + +next_pg: + rid.indx = cp->indx; + rid.pgno = cp->pgno; + pg = cp->page; + + /* + * Write records to the buffer, in the format needed by the DB_MULTIPLE + * macros. For a description of the data layout, see db.h. + */ + do { + if (HEAP_OFFSETTBL(dbp, pg)[rid.indx] == 0) + continue; + hdr = (HEAPHDR *)P_ENTRY(dbp, pg, rid.indx); + /* + * If this is a split record and not the first piece of the + * record, skip it. + */ + if (F_ISSET(hdr, HEAP_RECSPLIT) && + !F_ISSET(hdr, HEAP_RECFIRST)) + continue; + + /* + * Calculate how much space is needed to add this record. If + * there's not enough, we're done. If we haven't written any + * data to the buffer, or if we are doing a DBP->get, return + * DB_BUFFER_SMALL. + */ + needed = 0; + if (is_key) + needed = 2 * sizeof(*offp) + key_size; + if (F_ISSET(hdr, HEAP_RECSPLIT)) { + shdr = (HEAPSPLITHDR *)hdr; + data_size = DB_ALIGN(shdr->tsize, sizeof(u_int32_t)); + } else + data_size = DB_ALIGN(hdr->size, sizeof(u_int32_t)); + needed += 2 * sizeof(*offp) + data_size; + + if (needed > space) { + if (np == dbuf || F_ISSET(dbc, DBC_FROM_DB_GET)) { + data->size = (u_int32_t)DB_ALIGN( + needed + data->ulen - space, 1024); + return (DB_BUFFER_SMALL); + } + break; + } + + if (is_key) { + memcpy(np, &rid, key_size); + *offp-- = (int32_t)(np - dbuf); + *offp-- = (int32_t)DB_HEAP_RID_SZ; + np += key_size; + } + + if (F_ISSET(hdr, HEAP_RECSPLIT)) { + /* + * Use __heapc_gsplit to write a split record to the + * return buffer. gsplit will return any fetched pages + * to the cache, but will leave the cursor's current + * page alone. + */ + memset(&sdata, 0, sizeof(DBT)); + sdata.data = np; + sdata.size = sdata.ulen = shdr->tsize; + sdata.flags = DB_DBT_USERMEM; + /* gsplit expects the cursor to be positioned. */ + cp->pgno = rid.pgno; + cp->indx = rid.indx; + if ((ret = __heapc_gsplit( + dbc, &sdata, NULL, NULL)) != 0) + return (ret); + } else { + memcpy(np, + (u_int8_t *)hdr + sizeof(HEAPHDR), hdr->size); + } + *offp-- = (int32_t)(np - dbuf); + if (F_ISSET(hdr, HEAP_RECSPLIT)) + *offp-- = (int32_t)shdr->tsize; + else + *offp-- = (int32_t)hdr->size; + np += data_size; + space -= needed; + prev_rid = rid; + + /* + * The data and "metadata" ends of the buffer should never + * overlap. + */ + DB_ASSERT(dbp->env, (void *)np <= (void *)offp); + } while (++rid.indx < NUM_ENT(pg)); + + /* If we are off the page then try the next page. */ + if (rid.indx >= NUM_ENT(pg)) { + rid.pgno++; + ACQUIRE_CUR(dbc, lock_type, rid.pgno, 0, 0, ret); + if (ret == 0) { + cp->indx = 0; + goto next_pg; + } else if (ret != DB_PAGE_NOTFOUND) + return (ret); + } + + DB_ASSERT(dbp->env, (ret == 0 || ret == DB_PAGE_NOTFOUND)); + cp->indx = prev_rid.indx; + cp->pgno = prev_rid.pgno; + + *offp = -1; + + return (0); } static int @@ -264,7 +417,8 @@ start: if (STD_LOCKING(dbc) && (ret = __db_lget(dbc, cp->pgno - region_pgno - 1, spacebits); } -err: if (rpage != NULL && (t_ret = __memp_fput(mpf, +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (rpage != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, rpage, dbc->priority)) != 0 && ret == 0) ret = t_ret; rpage = NULL; @@ -490,7 +644,7 @@ first: pgno = FIRST_HEAP_DPAGE; break; case DB_LAST: /* - * Grab the metedata page to find the last page, and start + * Grab the metadata page to find the last page, and start * there looking backwards for the record with the highest * index and return that one. */ @@ -723,7 +877,7 @@ last: pgno = PGNO_BASE_MD; /* Lock the data page and get it. */ ACQUIRE_CUR(dbc, lock_type, pgno, 0, 0, ret); - + if (ret != 0) { if (ret == DB_PAGE_NOTFOUND) ret = DB_NOTFOUND; @@ -801,9 +955,12 @@ err: if (ret == 0 ) { if (LOCK_ISSET(cp->lock)) (void)__LPUT(dbc, cp->lock); } + DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); return (ret); } +#undef IS_FIRST +#define IS_FIRST (last_rid.pgno == PGNO_INVALID) /* * __heapc_reloc_partial -- * Move data from a too-full page to a new page. The old data page must @@ -821,7 +978,7 @@ __heapc_reloc_partial(dbc, key, data) HEAPHDR *old_hdr; HEAPSPLITHDR new_hdr; HEAP_CURSOR *cp; - int add_bytes, is_first, ret; + int add_bytes, ret; u_int32_t buflen, data_size, dlen, doff, left, old_size; u_int32_t remaining, size; u_int8_t *buf, *olddata; @@ -859,8 +1016,8 @@ __heapc_reloc_partial(dbc, key, data) dlen = data->dlen; data_size = old_size - dlen + data->size; } - - /* + + /* * We don't need a buffer large enough to hold the data_size * bytes, just one large enough to hold the bytes that will be * written to an individual page. We'll realloc to the necessary size @@ -869,7 +1026,7 @@ __heapc_reloc_partial(dbc, key, data) buflen = 0; buf = NULL; - /* + /* * We are updating an existing record, which will grow into a split * record. The strategy is to overwrite the existing record (or each * piece of the record if the record is already split.) If the new @@ -878,9 +1035,11 @@ __heapc_reloc_partial(dbc, key, data) * data. * * We start each loop with old_hdr pointed at the header for the old - * record and the necessary page write locked in cp->page. + * record and the necessary page write locked in cp->page. */ - add_bytes = is_first = 1; + last_rid.pgno = PGNO_INVALID; + last_rid.indx = 0; + add_bytes = 1; left = data_size; memset(&t_data, 0, sizeof(DBT)); remaining = 0; @@ -893,15 +1052,15 @@ __heapc_reloc_partial(dbc, key, data) next_rid.pgno = PGNO_INVALID; next_rid.indx = 0; } - - /* + + /* * Before we delete the old data, use it to construct the new * data. First figure out the size of the new piece, including * any remaining data from the last piece. */ if (doff >= old_hdr->size) if (F_ISSET(old_hdr, HEAP_RECLAST) || - !F_ISSET(old_hdr, HEAP_RECSPLIT)) { + !F_ISSET(old_hdr, HEAP_RECSPLIT)) { /* Post-pending. */ data_size = doff + data->size; } else { @@ -909,10 +1068,10 @@ __heapc_reloc_partial(dbc, key, data) data_size = old_hdr->size; } else if (doff + dlen > old_hdr->size) - /* + /* * Some of the to-be-overwritten bytes are on the next * piece, but we'll append all the new bytes to this - * piece if we haven't already written them. + * piece if we haven't already written them. */ data_size = doff + (add_bytes ? data->size : 0); else @@ -927,9 +1086,9 @@ __heapc_reloc_partial(dbc, key, data) } t_data.data = buf; - /* + /* * Adjust past any remaining bytes, they've already been moved - * to the beginning of the buffer. + * to the beginning of the buffer. */ buf += remaining; remaining = 0; @@ -967,7 +1126,7 @@ __heapc_reloc_partial(dbc, key, data) /* * The data to be removed spills over onto the * following page(s). Adjust dlen to account - * for the bytes removed from this page. + * for the bytes removed from this page. */ dlen = doff + dlen - old_hdr->size; doff = 0; @@ -997,12 +1156,59 @@ __heapc_reloc_partial(dbc, key, data) goto err; if (left == 0) - /* + /* * We've finished writing the new record, we're just * cleaning up the old record now. */ goto next_pg; + if (data_size == 0 && !IS_FIRST) { + /* + * This piece is being completely removed. We need to + * adjust the header of the previous piece now. + */ + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, + last_rid.pgno, 0, DB_MPOOL_DIRTY, ret); + if (ret != 0) + goto err; + + cp->indx = last_rid.indx; + old_hdr = (HEAPHDR *)(P_ENTRY(dbp, cp->page, cp->indx)); + + if (DBC_LOGGING(dbc)) { + old_size = DB_ALIGN(old_hdr->size + + HEAP_HDRSIZE(old_hdr), sizeof(u_int32_t)); + hdr_dbt.data = old_hdr; + hdr_dbt.size = HEAP_HDRSIZE(old_hdr); + log_dbt.data = + (u_int8_t *)old_hdr + hdr_dbt.size; + log_dbt.size = DB_ALIGN( + old_hdr->size, sizeof(u_int32_t)); + if ((ret = __heap_addrem_log(dbp, dbc->txn, + &LSN(cp->page), 0, DB_REM_HEAP, cp->pgno, + (u_int32_t)cp->indx, old_size, + &hdr_dbt, &log_dbt, &LSN(cp->page))) != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(cp->page)); + + ((HEAPSPLITHDR *)old_hdr)->nextpg = next_rid.pgno; + ((HEAPSPLITHDR *)old_hdr)->nextindx = next_rid.indx; + + if (DBC_LOGGING(dbc)) { + if ((ret = __heap_addrem_log(dbp, dbc->txn, + &LSN(cp->page), 0, DB_ADD_HEAP, cp->pgno, + (u_int32_t)cp->indx, old_size, + &hdr_dbt, &log_dbt, &LSN(cp->page))) != 0) + goto err; + } else + LSN_NOT_LOGGED(LSN(cp->page)); + + DISCARD(dbc, cp->page, cp->lock, 1, ret); + + goto next_pg; + } + /* Set up the header for the new record. */ memset(&new_hdr, 0, sizeof(HEAPSPLITHDR)); new_hdr.std_hdr.flags = HEAP_RECSPLIT; @@ -1013,15 +1219,15 @@ __heapc_reloc_partial(dbc, key, data) */ new_hdr.nextpg = next_rid.pgno; new_hdr.nextindx = next_rid.indx; - /* + /* * Figure out how much we can fit on the page, rounding down to * a multiple of 4. If we will have to expand the offset table, * account for that. It needs to be enough to at least fit the - * split header. + * split header. */ size = HEAP_FREESPACE(dbp, cp->page); if (NUM_ENT(cp->page) == 0 || - HEAP_FREEINDX(cp->page) > HEAP_HIGHINDX(cp->page)) + cp->indx > HEAP_HIGHINDX(cp->page)) size -= sizeof(db_indx_t); /* Round down to a multiple of 4. */ size = DB_ALIGN( @@ -1042,12 +1248,11 @@ __heapc_reloc_partial(dbc, key, data) new_hdr.nextpg = PGNO_INVALID; new_hdr.nextindx = 0; } - if (is_first) { + if (IS_FIRST) { new_hdr.std_hdr.flags |= HEAP_RECFIRST; new_hdr.tsize = left; - is_first = 0; } - + /* Now write the new data to the page. */ t_data.size = new_hdr.std_hdr.size; hdr_dbt.data = &new_hdr; @@ -1069,30 +1274,32 @@ __heapc_reloc_partial(dbc, key, data) /* * If any data couldn't fit on this page, it has to go onto the * next. Copy it to the front of the buffer and it will be - * preserved in the next loop. + * preserved in the next loop. */ if (new_hdr.std_hdr.size < data_size) { remaining = data_size - new_hdr.std_hdr.size; memmove(buf, buf + new_hdr.std_hdr.size, remaining); } + /* + * Remember this piece's RID, we may need to update the header + * if the next data piece is removed, or if this is the final + * piece and we add data to the end of the record. + */ +next_pg: last_rid.pgno = cp->pgno; + last_rid.indx = cp->indx; /* Get the next page, if any. */ -next_pg: if (next_rid.pgno != PGNO_INVALID) { + if (next_rid.pgno != PGNO_INVALID) { ACQUIRE_CUR(dbc, DB_LOCK_WRITE, next_rid.pgno, 0, DB_MPOOL_DIRTY, ret); if (ret != 0) goto err; cp->indx = next_rid.indx; old_hdr = (HEAPHDR *)(P_ENTRY(dbp, cp->page, cp->indx)); - DB_ASSERT(dbp->env, HEAP_HIGHINDX(cp->page) <= cp->indx); + DB_ASSERT(dbp->env, + HEAP_HIGHINDX(cp->page) <= cp->indx); DB_ASSERT(dbp->env, F_ISSET(old_hdr, HEAP_RECSPLIT)); } else { - /* - * Remember the final piece's RID, we may need to update - * the header after writing the rest of the record. - */ - last_rid.pgno = cp->pgno; - last_rid.indx = cp->indx; /* Discard the page and drop the lock, txn-ally. */ DISCARD(dbc, cp->page, cp->lock, 1, ret); if (ret != 0) @@ -1101,10 +1308,10 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { } } - /* + /* * If there is more work to do, let heapc_split do it. After * heapc_split returns we need to update nextpg and nextindx in the - * header of the last piece we wrote above. + * header of the last piece we wrote above. * * For logging purposes, we "delete" the old record and then "add" the * record. This makes redo/undo work as-is, but we won't actually @@ -1119,7 +1326,7 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { if ((ret = __heapc_split(dbc, &t_key, &t_data, 0)) != 0) goto err; - ACQUIRE_CUR(dbc, + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, last_rid.pgno, 0, DB_MPOOL_DIRTY, ret); if (ret != 0) goto err; @@ -1149,7 +1356,7 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { if (DBC_LOGGING(dbc)) { if ((ret = __heap_addrem_log(dbp, dbc->txn, &LSN(cp->page), 0, DB_ADD_HEAP, cp->pgno, - (u_int32_t)cp->indx,old_size, + (u_int32_t)cp->indx, old_size, &hdr_dbt, &log_dbt, &LSN(cp->page))) != 0) goto err; } else @@ -1158,7 +1365,8 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { DISCARD(dbc, cp->page, cp->lock, 1, ret); } -err: if (buf != NULL) +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (buf != NULL) __os_free(dbp->env, buf); return (ret); } @@ -1190,7 +1398,7 @@ __heapc_reloc(dbc, key, data) memset(&log_dbt, 0, sizeof(DBT)); COMPQUIET(key, NULL); - /* + /* * We are updating an existing record, which will grow into a split * record. The strategy is to overwrite the existing record (or each * piece of the record if the record is already split.) If the new @@ -1200,7 +1408,7 @@ __heapc_reloc(dbc, key, data) * * We start each loop with t_data.data positioned to the next byte to be * written, old_hdr pointed at the header for the old record and the - * necessary page write locked in cp->page. + * necessary page write locked in cp->page. */ is_first = 1; left = data->size; @@ -1239,7 +1447,7 @@ __heapc_reloc(dbc, key, data) goto err; if (left == 0) - /* + /* * We've finished writing the new record, we're just * cleaning up the old record now. */ @@ -1251,15 +1459,15 @@ __heapc_reloc(dbc, key, data) /* We'll set this later if next_rid.pgno == PGNO_INVALID. */ new_hdr.nextpg = next_rid.pgno; new_hdr.nextindx = next_rid.indx; - /* + /* * Figure out how much we can fit on the page, rounding down to * a multiple of 4. If we will have to expand the offset table, * account for that.It needs to be enough to at least fit the - * split header. + * split header. */ size = HEAP_FREESPACE(dbp, cp->page); if (NUM_ENT(cp->page) == 0 || - HEAP_FREEINDX(cp->page) > HEAP_HIGHINDX(cp->page)) + cp->indx > HEAP_HIGHINDX(cp->page)) size -= sizeof(db_indx_t); /* Round down to a multiple of 4. */ size = DB_ALIGN( @@ -1278,7 +1486,7 @@ __heapc_reloc(dbc, key, data) new_hdr.tsize = left; is_first = 0; } - + /* Now write the new data to the page. */ t_data.size = new_hdr.std_hdr.size; hdr_dbt.data = &new_hdr; @@ -1322,10 +1530,10 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { } } - /* + /* * If there is more work to do, let heapc_split do it. After * heapc_split returns we need to update nextpg and nextindx in the - * header of the last piece we wrote above. + * header of the last piece we wrote above. * * For logging purposes, we "delete" the old record and then "add" the * record. This makes redo/undo work as-is, but we won't actually @@ -1340,7 +1548,7 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { if ((ret = __heapc_split(dbc, &t_key, &t_data, 0)) != 0) goto err; - ACQUIRE_CUR(dbc, + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, last_rid.pgno, 0, DB_MPOOL_DIRTY, ret); if (ret != 0) goto err; @@ -1379,14 +1587,15 @@ next_pg: if (next_rid.pgno != PGNO_INVALID) { DISCARD(dbc, cp->page, cp->lock, 1, ret); } -err: return (ret); +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + return (ret); } /* * __heapc_put -- * * Put using a cursor. If the given key exists, update the associated data. If - * the given key does not exsit, return an error. + * the given key does not exsist, return an error. */ static int __heapc_put(dbc, key, data, flags, pgnop) @@ -1421,6 +1630,7 @@ __heapc_put(dbc, key, data, flags, pgnop) ret = __heapc_get(dbc, key, data, DB_SET, pgnop); F_CLR(key, DB_DBT_ISSET); dbc->flags = old_flags; + DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); if (ret != 0) return (ret); else if (flags == DB_NOOVERWRITE) @@ -1481,8 +1691,9 @@ __heapc_put(dbc, key, data, flags, pgnop) new_size = sizeof(HEAPSPLITHDR); /* Check whether we actually have enough space on this page. */ - if (new_size > old_size && - new_size - old_size > HEAP_FREESPACE(dbp, cp->page)) { + if (F_ISSET(old_hdr, HEAP_RECSPLIT) || + (new_size > old_size && + new_size - old_size > HEAP_FREESPACE(dbp, cp->page))) { /* * We've got to split the record, not enough room on the * page. Splitting the record will remove old_size bytes and @@ -1505,9 +1716,9 @@ __heapc_put(dbc, key, data, flags, pgnop) goto err; new_data.data = buf; - /* + /* * Preserve data->doff bytes at the start, or all of the old - * record plus padding, if post-pending. + * record plus padding, if post-pending. */ olddata = (u_int8_t *)old_hdr + sizeof(HEAPHDR); if (data->doff > old_hdr->size) { @@ -1527,7 +1738,7 @@ __heapc_put(dbc, key, data, flags, pgnop) /* Fill in remaining data from the old record, skipping dlen. */ if (data->doff < old_hdr->size) { olddata += data->doff + data->dlen; - memcpy(buf, + memcpy(buf, olddata, old_hdr->size - data->doff - data->dlen); } } else { @@ -1565,7 +1776,7 @@ __heapc_put(dbc, key, data, flags, pgnop) if ((ret = __heap_pitem(dbc, (PAGE *)cp->page, cp->indx, new_size, &hdr_dbt, &new_data)) != 0) goto err; - + /* Check whether we need to update the space bitmap. */ HEAP_CALCSPACEBITS(dbp, HEAP_FREESPACE(dbp, cp->page), space); @@ -1580,7 +1791,8 @@ __heapc_put(dbc, key, data, flags, pgnop) HEAP_SETSPACE(dbp, rpage, cp->pgno - region_pgno - 1, space); } -err: if (rpage != NULL && (t_ret = __memp_fput(mpf, +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (rpage != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, rpage, dbc->priority)) != 0 && ret == 0) ret = t_ret; if (F_ISSET(data, DB_DBT_PARTIAL)) @@ -1660,13 +1872,13 @@ find: while ((ret = __memp_fget(mpf, ®ion_pgno, dbc->thread_info, NULL, lk_mode, &rpage)) != 0 || TYPE(rpage) != P_IHEAP) { if (ret == DB_LOCK_NOTGRANTED) - goto next; + goto next_region; if (ret != 0 && ret != DB_PAGE_NOTFOUND) return (ret); /* * The region page doesn't exist, or hasn't been initialized, * create it, then try again. If the page exists, we have to - * drop it before initializing the region. + * drop it before initializing the region. */ if (ret == 0 && (ret = __memp_fput( mpf, dbc->thread_info, rpage, dbc->priority)) != 0) @@ -1741,7 +1953,7 @@ find: while ((ret = __memp_fget(mpf, ®ion_pgno, * around to the first region page. There is not currently a * data page locked. */ -next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; +next_region: region_pgno += HEAP_REGION_SIZE(dbp) + 1; if (region_pgno > h->maxpgno) region_pgno = FIRST_HEAP_RPAGE; @@ -1795,23 +2007,50 @@ next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; meta_pgno = PGNO_BASE_MD; if ((ret = __db_lget(dbc, LCK_ALWAYS, meta_pgno, DB_LOCK_WRITE, DB_LOCK_NOWAIT, &meta_lock)) != 0) { - if (ret != DB_LOCK_NOTGRANTED) - goto err; /* * We don't want to block while having latched * a page off the end of file. This could * get truncated by another thread and we * will deadlock. */ - DISCARD(dbc, cp->page, cp->lock, 0, ret); - if (ret != 0) - goto err; + p = cp->page != NULL; + DISCARD(dbc, cp->page, cp->lock, 0, t_ret); + if (t_ret != 0 || + (ret != DB_LOCK_NOTGRANTED && + ret != DB_LOCK_DEADLOCK)) + goto pg_err; if ((ret = __db_lget(dbc, LCK_ALWAYS, meta_pgno, DB_LOCK_WRITE, 0, &meta_lock)) != 0) - goto err; - ACQUIRE_CUR(dbc, DB_LOCK_WRITE, data_pgno, 0, 0, ret); - if (ret != 0) + goto pg_err; + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, + data_pgno, 0, DB_MPOOL_CREATE, ret); + /* + * We can race, having read this page when it was + * less than last_pgno but now an aborted + * allocation can make this page beyond last_pgno + * so we must free it. If we can't get the + * lock on the page again, then some other + * thread will handle the issue. + */ + if (ret != 0) { +pg_err: if (p != 0) { + ACQUIRE_CUR(dbc, DB_LOCK_WRITE, + data_pgno, 0, 0, t_ret); + if (t_ret == 0 && + PGNO(cp->page) == PGNO_INVALID) { + (void)__memp_fput(mpf, + dbc->thread_info, + cp->page, dbc->priority); + (void)__memp_fget(mpf, + &data_pgno, + dbc->thread_info, dbc->txn, + DB_MPOOL_FREE, &cp->page); + } + (void)__LPUT(dbc, cp->lock); + } + (void)__LPUT(dbc, meta_lock); goto err; + } /* Check if we lost a race. */ if (PGNO(cp->page) != PGNO_INVALID) { if ((ret = __LPUT(dbc, meta_lock)) != 0) @@ -1820,6 +2059,40 @@ next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; } } + /* + * Before creating a new page in this region, check that the + * region page still exists. By this point, the transaction + * that created the region must have aborted or committed, + * because we now hold the metadata lock. If we can't get the + * latch, the page must exist. + */ + ret = __memp_fget(mpf, ®ion_pgno, + dbc->thread_info, NULL, DB_MPOOL_TRY, &rpage); + if (ret == DB_LOCK_NOTGRANTED) + ret = 0; + else if (ret != 0) { + /* + * Free up the metadata lock. If this was an error + * other than a missing region page, bail. + */ + if ((t_ret = __LPUT(dbc, meta_lock)) != 0) + ret = t_ret; + if (ret != DB_PAGE_NOTFOUND) + goto err; + /* + * The region no longer exists. Release the page's lock + * (we haven't created the page yet) and find a new page + * on a different region. + */ + DISCARD(dbc, cp->page, cp->lock, 0, t_ret); + goto find; + } else + ret = __memp_fput(mpf, + dbc->thread_info, rpage, dbc->priority); + rpage = NULL; + if (ret != 0) + goto meta_unlock; + if ((ret = __memp_fget(mpf, &meta_pgno, dbc->thread_info, dbc->txn, DB_MPOOL_DIRTY, &meta)) != 0) goto err; @@ -1845,7 +2118,7 @@ next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; ret = t_ret; meta = NULL; if (ret != 0) - goto err; + goto meta_unlock; /* If the page doesn't actually exist we need to create it. */ if (cp->pgno == PGNO_INVALID) { @@ -1853,13 +2126,13 @@ next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; if ((ret = __memp_fget(mpf, &cp->pgno, dbc->thread_info, dbc->txn, DB_MPOOL_CREATE | DB_MPOOL_DIRTY, &cp->page)) != 0) - goto err; + goto meta_unlock; DB_ASSERT(dbp->env, cp->pgno == data_pgno); } else if ((ret = __memp_dirty(mpf, &cp->page, dbc->thread_info, dbc->txn, dbc->priority, 0)) != 0) { /* Did not read the page, so we can release the lock. */ DISCARD(dbc, cp->page, cp->lock, 0, t_ret); - goto err; + goto meta_unlock; } /* Now that we have the page we initialize it and we're done. */ @@ -1867,7 +2140,7 @@ next: region_pgno += HEAP_REGION_SIZE(dbp) + 1; dbp->pgsize, cp->pgno, P_INVALID, P_INVALID, 0, P_HEAP); LSN(cp->page) = meta_lsn; - if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0) +meta_unlock: if ((t_ret = __TLPUT(dbc, meta_lock)) != 0 && ret == 0) ret = t_ret; if (ret != 0) goto err; @@ -1893,7 +2166,8 @@ check: if (size + sizeof(db_indx_t) > HEAP_FREESPACE(dbp, cp->page)) { } h->curpgindx = data_pgno - region_pgno - 1; -err: if (rpage != NULL && (t_ret = __memp_fput(mpf, +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (rpage != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, rpage, dbc->priority)) != 0 && ret == 0) ret = t_ret; @@ -1985,7 +2259,8 @@ __heap_append(dbc, key, data) HEAP_SETSPACE(dbp, rpage, cp->pgno - region_pgno - 1, space); } -err: if (rpage != NULL && (t_ret = __memp_fput(mpf, +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (rpage != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, rpage, dbc->priority)) != 0 && ret == 0) ret = t_ret; @@ -2058,7 +2333,7 @@ __heapc_split(dbc, key, data, is_first) * 33% free. */ size = DB_ALIGN(dbp->pgsize / 3, sizeof(u_int32_t)); - else + else hdrs.std_hdr.flags |= HEAP_RECFIRST; if ((ret = __heap_getpage(dbc, size, &availbits)) != 0) @@ -2073,12 +2348,12 @@ __heapc_split(dbc, key, data, is_first) /* * If we're called from heapc_reloc, we are only writing * a piece of the full record and shouldn't set - * HEAP_RECFIRST. + * HEAP_RECFIRST. */ if (!is_first) F_CLR(&(hdrs.std_hdr), HEAP_RECFIRST); } else { - /* + /* * Figure out how much room is on the page. If we will * have to expand the offset table, account for that. */ @@ -2110,7 +2385,8 @@ __heapc_split(dbc, key, data, is_first) DB_ASSERT(dbp->env, (F_ISSET(data, DB_DBT_PARTIAL) || t_data.data >= data->data)); t_data.size = hdrs.std_hdr.size; - if (F_ISSET(data, DB_DBT_PARTIAL) && t_data.size > left - doff) { + if (F_ISSET(data, DB_DBT_PARTIAL) && + t_data.size > left - doff) { if (buflen < t_data.size) { if (__os_realloc( dbp->env, t_data.size, &buf) != 0) @@ -2130,7 +2406,7 @@ __heapc_split(dbc, key, data, is_first) memcpy(buf, data->data, left - doff); doff -= t_data.size - left + doff; buf = t_data.data; - } + } hdr_dbt.data = &hdrs; hdr_dbt.size = sizeof(HEAPSPLITHDR); indx = HEAP_FREEINDX(cp->page); @@ -2199,6 +2475,7 @@ err: if (rpage != NULL && (t_ret = __memp_fput(mpf, if (ret == 0 && key != NULL) ret = __db_retcopy(dbp->env, key, &rid, DB_HEAP_RID_SZ, &dbc->rkey->data, &dbc->rkey->ulen); + DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); return (ret); } @@ -2227,7 +2504,7 @@ __heap_pitem(dbc, pagep, indx, nbytes, hdr, data) DB_ASSERT(dbp->env, IS_DIRTY(pagep)); DB_ASSERT(dbp->env, nbytes == DB_ALIGN(nbytes, sizeof(u_int32_t))); DB_ASSERT(dbp->env, DB_ALIGN(((HEAPHDR *)hdr->data)->size, - sizeof (u_int32_t)) >= data->size); + sizeof(u_int32_t)) >= data->size); DB_ASSERT(dbp->env, nbytes >= hdr->size + data->size); /* @@ -2263,7 +2540,7 @@ __heap_pitem(dbc, pagep, indx, nbytes, hdr, data) else if (HEAP_FREEINDX(pagep) >= indx) { if (indx > (u_int32_t)HEAP_HIGHINDX(pagep) + 1) HEAP_FREEINDX(pagep) = HEAP_HIGHINDX(pagep) + 1; - else + else HEAP_FREEINDX(pagep) = indx + 1; } while (++HEAP_HIGHINDX(pagep) < indx) @@ -2489,20 +2766,25 @@ skip_alloc: /* * If we have the last piece of this record and we're * reading the entire record, then what we need should - * equal what is remaining. + * equal what is remaining. */ if (F_ISSET((HEAPHDR *)hdr, HEAP_RECLAST) && !F_ISSET(dbt, DB_DBT_PARTIAL) && (hdr->std_hdr.size != needed)) { + __db_errx(env, DB_STR_A("1167", + "Incorrect record size in header: %s: rid %lu.%lu", + "%s %lu %lu"), dbc->dbp->fname, + (u_long)(cp->pgno), (u_long)(cp->indx)); ret = __env_panic(env, DB_RUNRECOVERY); goto err; } } } -err: if (putpage && dpage != NULL && (t_ret = __memp_fput(mpf, +err: DB_ASSERT(dbp->env, ret != DB_PAGE_NOTFOUND); + if (putpage && dpage != NULL && (t_ret = __memp_fput(mpf, dbc->thread_info, dpage, dbp->priority)) != 0 && ret == 0) - ret = t_ret; + ret = t_ret; if ((t_ret = __TLPUT(dbc, data_lock)) != 0 && ret == 0) ret = t_ret; diff --git a/src/heap/heap.src b/src/heap/heap.src index e0b072a7..47bd4bb0 100644 --- a/src/heap/heap.src +++ b/src/heap/heap.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/heap/heap_backup.c b/src/heap/heap_backup.c new file mode 100644 index 00000000..4588b0ba --- /dev/null +++ b/src/heap/heap_backup.c @@ -0,0 +1,66 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" +#include "db_int.h" +#include "dbinc/db_page.h" +#include "dbinc/heap.h" +#include "dbinc/mp.h" + +/* + * __heap_backup -- + * Copy a heap database file coordinated with mpool. + * + * PUBLIC: int __heap_backup __P((DB_ENV *, DB *, + * PUBLIC: DB_THREAD_INFO *, DB_FH *, void *, u_int32_t)); + */ +int +__heap_backup(dbenv, dbp, ip, fp, handle, flags) + DB_ENV *dbenv; + DB *dbp; + DB_THREAD_INFO *ip; + DB_FH *fp; + void *handle; + u_int32_t flags; +{ + HEAPPG *p; + db_pgno_t chunk_pgno, high_pgno, max_pgno; + int ret; + + max_pgno = dbp->mpf->mfp->last_pgno; + chunk_pgno = FIRST_HEAP_RPAGE; + + for (;;) { + /* + * Get the chunk page and the chunk's highest used page. + * Immediately return the page, it makes error handling easier. + */ + if ((ret = __memp_fget(dbp->mpf, + &chunk_pgno, ip, NULL, 0, &p)) != 0) + break; + high_pgno = p->high_pgno; + if ((ret = __memp_fput(dbp->mpf, + ip, p, DB_PRIORITY_UNCHANGED)) != 0) + break; + + /* + * Backup all the used pages in this chunk, starting at the + * chunk page. If this is the very first chunk, be sure to + * backup the db meta page, too. + */ + if ((ret = __memp_backup_mpf(dbenv->env, dbp->mpf, ip, + chunk_pgno == FIRST_HEAP_RPAGE ? 0 : chunk_pgno, + high_pgno, fp, handle, flags)) != 0) + break; + chunk_pgno += HEAP_REGION_SIZE(dbp) + 1; + if (chunk_pgno > max_pgno) + break; + } + + return (ret); +} diff --git a/src/heap/heap_conv.c b/src/heap/heap_conv.c index 0fb8844e..9f432d13 100644 --- a/src/heap/heap_conv.c +++ b/src/heap/heap_conv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" @@ -85,7 +85,8 @@ __heap_mswap(env, pg) SWAP32(p); /* nregions */ SWAP32(p); /* gbytes */ SWAP32(p); /* bytes */ - p += 93 * sizeof(u_int32_t); /* unused */ + SWAP32(p); /* region_size */ + p += 92 * sizeof(u_int32_t); /* unused */ SWAP32(p); /* crypto_magic */ return (0); diff --git a/src/heap/heap_method.c b/src/heap/heap_method.c index 39e70298..f938b5e7 100644 --- a/src/heap/heap_method.c +++ b/src/heap/heap_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -28,10 +28,12 @@ __heap_db_create(dbp) if ((ret = __os_calloc(dbp->env, 1, sizeof(HEAP), &h)) != 0) return (ret); dbp->heap_internal = h; - h->region_size = HEAP_DEFAULT_REGION_MAX; + h->region_size = 0; dbp->get_heapsize = __heap_get_heapsize; + dbp->get_heap_regionsize = __heap_get_heap_regionsize; dbp->set_heapsize = __heap_set_heapsize; + dbp->set_heap_regionsize = __heap_set_heap_regionsize; return (0); } @@ -48,7 +50,7 @@ __heap_db_close(dbp) { HEAP *h; int ret; - + ret = 0; if ((h = dbp->heap_internal) == NULL) return (0); @@ -81,6 +83,27 @@ __heap_get_heapsize(dbp, gbytes, bytes) return (0); } +/* + * __heap_get_heap_regionsize -- + * Get the region size of the heap. + * + * PUBLIC: int __heap_get_heap_regionsize __P((DB *, u_int32_t *)); + */ +int +__heap_get_heap_regionsize(dbp, npages) + DB *dbp; + u_int32_t *npages; +{ + HEAP *h; + + DB_ILLEGAL_METHOD(dbp, DB_OK_HEAP); + + h = dbp->heap_internal; + *npages = h->region_size; + + return (0); +} + /* * __heap_set_heapsize -- * Set the initial size of the heap. @@ -105,9 +128,36 @@ __heap_set_heapsize(dbp, gbytes, bytes, flags) return (0); } +/* + * __heap_set_heap_regionsize -- + * Set the region size of the heap. + * + * PUBLIC: int __heap_set_heap_regionsize __P((DB *, u_int32_t)); + */ +int +__heap_set_heap_regionsize(dbp, npages) + DB *dbp; + u_int32_t npages; +{ + HEAP *h; + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_heap_regionsize"); + DB_ILLEGAL_METHOD(dbp, DB_OK_HEAP); + + if (npages == 0) { + __db_errx(dbp->env, DB_STR("1168", "region size may not be 0")); + return (EINVAL); + } + + h = dbp->heap_internal; + h->region_size = npages; + + return (0); +} + /* * __heap_exist -- - * Test to see if heap exists or not, used in Perl interface + * Test to see if heap exists or not, used in Perl interface * * PUBLIC: int __heap_exist __P((void)); */ diff --git a/src/heap/heap_open.c b/src/heap/heap_open.c index f8fb2921..6827450d 100644 --- a/src/heap/heap_open.c +++ b/src/heap/heap_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" @@ -217,15 +217,29 @@ __heap_new_file(dbp, ip, txn, fhp, name) DB_MPOOLFILE *mpf; DB_PGINFO pginfo; ENV *env; + HEAP *h; HEAPMETA *meta; HEAPPG *region; db_pgno_t pgno; int ret, t_ret; + u_int32_t max_size; void *buf; env = dbp->env; mpf = dbp->mpf; buf = NULL; + h = (HEAP *)dbp->heap_internal; + max_size = HEAP_REGION_COUNT(dbp, dbp->pgsize); + + if (h->region_size == 0) + h->region_size = HEAP_DEFAULT_REGION_MAX(dbp) > max_size ? + max_size : HEAP_DEFAULT_REGION_MAX(dbp); + else if (h->region_size > max_size) { + __db_errx(dbp->env, DB_STR_A("1169", + "region size may not be larger than %lu", + "%lu"), (u_long)max_size); + return (EINVAL); + } if (F_ISSET(dbp, DB_AM_INMEM)) { /* Build the meta-data page. */ @@ -419,8 +433,6 @@ __heap_init_meta(dbp, meta, pgno, lsnp) memcpy(meta->dbmeta.uid, dbp->fileid, DB_FILE_ID_LEN); meta->gbytes = h->gbytes; meta->bytes = h->bytes; - if (h->region_size > HEAP_REGION_COUNT(dbp->pgsize)) - h->region_size = HEAP_REGION_COUNT(dbp->pgsize); meta->region_size = h->region_size; meta->nregions = 1; meta->curregion = 1; diff --git a/src/heap/heap_rec.c b/src/heap/heap_rec.c index 012a834c..578a61c4 100644 --- a/src/heap/heap_rec.c +++ b/src/heap/heap_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_config.h" @@ -156,14 +156,14 @@ __heap_pg_alloc_recover(env, dbtp, lsnp, op, info) REC_DIRTY(mpf, ip, file_dbp->priority, &meta); LSN(meta) = argp->meta_lsn; if (meta->dbmeta.last_pgno != argp->last_pgno) { - if (file_dbp->mpf->mfp->last_pgno == + if (file_dbp->mpf->mfp->last_pgno == meta->dbmeta.last_pgno) trunc = 1; meta->dbmeta.last_pgno = argp->last_pgno; } if (argp->ptype == P_IHEAP && HEAP_REGION_NUM(file_dbp, argp->pgno) == meta->nregions) { - do + do meta->nregions--; while (argp->last_pgno < (meta->nregions - 1) * HEAP_REGION_SIZE(file_dbp)); @@ -196,16 +196,16 @@ __heap_pg_alloc_recover(env, dbtp, lsnp, op, info) argp->pgno, PGNO_INVALID, PGNO_INVALID, 0, argp->ptype); LSN(pagep) = *lsnp; } else if ((cmp_n == 0 || IS_ZERO_LSN(LSN(pagep))) && DB_UNDO(op)) { - if (argp->pgno > meta->dbmeta.last_pgno) { - if (argp->pgno == file_dbp->mpf->mfp->last_pgno) - trunc = 1; - } else if (!IS_ZERO_LSN(LSN(pagep))){ + if (argp->pgno == file_dbp->mpf->mfp->last_pgno) + trunc = 1; + else if (!IS_ZERO_LSN(LSN(pagep))) { REC_DIRTY(mpf, ip, file_dbp->priority, &pagep); memset(pagep, 0, file_dbp->pgsize); } } /* If the page is newly allocated and aborted, give it back. */ - if (pagep != NULL && trunc == 1) { + if (pagep != NULL && (trunc == 1 || + (IS_ZERO_LSN(LSN(pagep)) && TYPE(pagep) != P_IHEAP))) { if ((ret = __memp_fput(mpf, ip, pagep, file_dbp->priority)) != 0) goto out; @@ -213,6 +213,18 @@ __heap_pg_alloc_recover(env, dbtp, lsnp, op, info) if ((ret = __memp_fget(mpf, &argp->pgno, ip, NULL, DB_MPOOL_FREE, &pagep)) != 0) goto out; + if (trunc == 0 && argp->pgno <= mpf->mfp->last_flushed_pgno) { + /* + * If this page is on disk we need to zero it. + * This is safe since we never free pages other + * than backing out an allocation, so there can + * not be a previous allocate and free of this + * page that is reflected on disk. + */ + if ((ret = __db_zero_extend(env, mpf->fhp, + argp->pgno, argp->pgno, file_dbp->pgsize)) != 0) + goto out; + } } /* * Keep the region high_pgno up to date This not logged so we @@ -228,12 +240,12 @@ __heap_pg_alloc_recover(env, dbtp, lsnp, op, info) goto out; if (pagep->high_pgno >= argp->pgno) goto done; - if ((ret = __memp_dirty(mpf, &pagep, ip, NULL, + if ((ret = __memp_dirty(mpf, &pagep, ip, NULL, DB_PRIORITY_UNCHANGED, 0)) != 0) goto done; pagep->high_pgno = argp->pgno; } - + do_meta: if (trunc == 1 && (ret = __memp_ftruncate(mpf, NULL, ip, meta->dbmeta.last_pgno + 1, @@ -302,7 +314,7 @@ __heap_trunc_meta_recover(env, dbtp, lsnp, op, info) LSN(meta) = *lsnp; if ((ret = __memp_ftruncate(mpf, dbc->txn, ip, PGNO_BASE_MD + 1, MP_TRUNC_NOCACHE)) != 0) - goto out; + goto out; } done: *lsnp = argp->prev_lsn; @@ -362,7 +374,7 @@ __heap_trunc_page_recover(env, dbtp, lsnp, op, info) pagep = NULL; if ((ret = __memp_fget(mpf, &argp->pgno, dbc->thread_info, dbc->txn, DB_MPOOL_FREE, &pagep)) != 0) - goto out; + goto out; } done: *lsnp = argp->prev_lsn; diff --git a/src/heap/heap_reclaim.c b/src/heap/heap_reclaim.c index 9623974a..8cedb223 100644 --- a/src/heap/heap_reclaim.c +++ b/src/heap/heap_reclaim.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -77,7 +77,8 @@ __heap_truncate(dbc, countp) LSN_NOT_LOGGED(LSN(pg)); if (pgno == next_region) { - next_region += region_size; + DB_ASSERT(dbp->env, TYPE(pg) == P_IHEAP); + next_region += region_size + 1; } else { /* * We can't use pg->entries to calculate the record @@ -102,7 +103,7 @@ __heap_truncate(dbc, countp) break; if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, dbc->txn, DB_MPOOL_FREE, &pg)) != 0) - break; + break; } if ((t_ret = __TLPUT(dbc, lock)) != 0 && ret == 0) ret = t_ret; @@ -126,8 +127,8 @@ __heap_truncate(dbc, countp) if ((ret = __memp_ftruncate(mpf, dbc->txn, dbc->thread_info, PGNO_BASE_MD + 1, MP_TRUNC_NOCACHE)) != 0) - goto err; - + goto err; + /* Create the first region. */ pgno = PGNO_BASE_MD + 1; if ((ret = __memp_fget(mpf, &pgno, dbc->thread_info, diff --git a/src/heap/heap_stat.c b/src/heap/heap_stat.c index bcf8980d..9f4361a7 100644 --- a/src/heap/heap_stat.c +++ b/src/heap/heap_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -66,6 +66,7 @@ __heap_stat(dbc, spp, flags) sp->heap_magic = meta->dbmeta.magic; sp->heap_version = meta->dbmeta.version; sp->heap_nregions = meta->nregions; + sp->heap_regionsize = meta->region_size; if (LF_ISSET(DB_FAST_STAT)) { sp->heap_nrecs = meta->dbmeta.record_count; @@ -148,6 +149,8 @@ __heap_stat_print(dbc, flags) "Number of records in the database", (u_long)sp->heap_nrecs); __db_dl(env, "Number of database pages", (u_long)sp->heap_pagecnt); __db_dl(env, "Number of database regions", (u_long)sp->heap_nregions); + __db_dl(env, + "Number of pages in a region", (u_long)sp->heap_regionsize); __os_ufree(env, sp); @@ -193,8 +196,8 @@ __heap_stat_callback(dbc, h, cookie, putp) switch (TYPE(h)) { case P_HEAP: - /* - * We can't just use NUM_ENT, otherwise we'd mis-count split + /* + * We can't just use NUM_ENT, otherwise we'd mis-count split * records. */ for (i = 0; i < NUM_ENT(h); i++) { diff --git a/src/heap/heap_stub.c b/src/heap/heap_stub.c index 1cb6fe7b..b4feb2f3 100644 --- a/src/heap/heap_stub.c +++ b/src/heap/heap_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id: */ @@ -91,6 +91,23 @@ __heap_append(dbc, key, data) return (__db_no_heap_am(dbc->env)); } +int +__heap_backup(dbenv, dbp, ip, fp, handle, flags) + DB_ENV *dbenv; + DB *dbp; + DB_THREAD_INFO *ip; + DB_FH *fp; + void *handle; + u_int32_t flags; +{ + COMPQUIET(dbp, NULL); + COMPQUIET(ip, NULL); + COMPQUIET(fp, NULL); + COMPQUIET(handle, NULL); + COMPQUIET(flags, 0); + return (__db_no_heap_am(dbenv->env)); +} + int __heapc_init(dbc) DBC *dbc; diff --git a/src/heap/heap_verify.c b/src/heap/heap_verify.c index d33a4e76..ea15c28b 100644 --- a/src/heap/heap_verify.c +++ b/src/heap/heap_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -52,6 +52,18 @@ __heap_vrfy_meta(dbp, vdp, meta, pgno, flags) "Page %lu: Heap databases must be one-per-file", "%lu"), (u_long)pgno)); + /* + * We have already checked the common fields in __db_vrfy_pagezero. + * However, we used the on-disk metadata page, it may have been stale. + * We now have the page from mpool, so check that. + */ + if ((ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + /* * Check that nregions is correct. The last page in the database must * belong to the nregion-th page. @@ -87,7 +99,7 @@ __heap_vrfy_meta(dbp, vdp, meta, pgno, flags) } } - if (LF_ISSET(DB_SALVAGE)) +err: if (LF_ISSET(DB_SALVAGE)) ret = __db_salvage_markdone(vdp, pgno); return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret); @@ -249,7 +261,8 @@ __heap_vrfy_structure(dbp, vdp, flags) /* * Not much structure to verify. Just make sure region pages are where - * they're supposed to be. + * they're supposed to be. If we don't have FTRUNCATE, there could be + * a zero'd out page where the region page is supposed to be. */ next_region = FIRST_HEAP_RPAGE; high_pgno = 0; @@ -267,7 +280,11 @@ __heap_vrfy_structure(dbp, vdp, flags) "Page %lu: heap database page of incorrect type %lu", "%lu %lu"), (u_long)i, (u_long)pip->type)); isbad = 1; - } else if (i == next_region && pip->type != P_IHEAP) { + } else if (i == next_region && pip->type != P_IHEAP +#ifndef HAVE_FTRUNCATE + && pip->type != P_INVALID +#endif + ) { EPRINT((dbp->env, DB_STR_A("1164", "Page %lu: heap database missing region page (page type %lu)", "%lu %lu"), (u_long)i, (u_long)pip->type)); @@ -280,7 +297,7 @@ __heap_vrfy_structure(dbp, vdp, flags) high_pgno = pip->prev_pgno; next_region += HEAP_REGION_SIZE(dbp) + 1; } else if (pip->type != P_INVALID && i > high_pgno) { - EPRINT((dbp->env, DB_STR_A("1166", + EPRINT((dbp->env, DB_STR_A("1166", "Page %lu heap database page beyond high page in region", "%lu"), (u_long) i)); isbad = 1; diff --git a/src/hmac/hmac.c b/src/hmac/hmac.c index 14df898d..4febfc60 100644 --- a/src/hmac/hmac.c +++ b/src/hmac/hmac.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * Some parts of this code originally written by Adam Stubblefield, * -- astubble@rice.edu. @@ -186,7 +186,7 @@ __db_check_chksum(env, hdr, db_cipher, chksum, data, data_len, is_hmac) } else { if (db_cipher == NULL) { __db_errx(env, DB_STR("0196", - "Encrypted checksum: no encryption key specified")); + "Encrypted checksum: no encryption key specified")); return (EINVAL); } sum_len = DB_MAC_KEY; @@ -200,7 +200,6 @@ __db_check_chksum(env, hdr, db_cipher, chksum, data, data_len, is_hmac) * it out, just like we do in __db_chksum above. * If there is a log header, XOR the prev and len fields. */ -retry: if (hdr == NULL) { memcpy(old, chksum, sum_len); memset(chksum, 0, sum_len); @@ -219,16 +218,6 @@ retry: LOG_HDR_SUM(1, hdr, new); ret = memcmp(chksum, new, sum_len) ? -1 : 0; } - /* - * !!! - * We might be looking at an old log even with the new - * code. So, if we have a hdr, and the checksum doesn't - * match, try again without a hdr. - */ - if (hdr != NULL && ret != 0) { - hdr = NULL; - goto retry; - } return (ret); } diff --git a/src/lock/Design b/src/lock/Design index 8a52d625..f82bc7e8 100644 --- a/src/lock/Design +++ b/src/lock/Design @@ -298,4 +298,4 @@ A: We currently do not support any automatic configuration for FINE_GRAIN locking. When we do, will need to document that atomicity discussion listed above (it is bug-report #553). -Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. diff --git a/src/lock/lock.c b/src/lock/lock.c index 7a55307e..e4627734 100644 --- a/src/lock/lock.c +++ b/src/lock/lock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -454,7 +454,7 @@ __lock_get(env, locker, flags, obj, lock_mode, lock) lt = env->lk_handle; - if (IS_RECOVERING(env)) { + if (IS_RECOVERING(env) && !LF_ISSET(DB_LOCK_IGNORE_REC)) { LOCK_INIT(*lock); return (0); } @@ -626,7 +626,7 @@ again: if (obj == NULL) { * access method when we want to get an entry which is past * the end of the queue. With CDB we have a DB_READ_LOCK and * need to switch it to DB_LOCK_WAIT. Otherwise we insert a - * DB_LOCK_WAIT and and then after releaseing the metadata + * DB_LOCK_WAIT and and then after releasing the metadata * page wait on it and join the waiters queue. This must be * done as a single operation so that another locker cannot * get in and fail to wake us up. @@ -896,6 +896,7 @@ upgrade: lp = R_ADDR(<->reginfo, lock->off); * the txn expiration time. lk_expire is passed * to avoid an extra call to get the time. */ + timespecclear(&sh_locker->lk_expire); if (__clock_expired(env, &sh_locker->lk_expire, &sh_locker->tx_expire)) { newl->status = DB_LSTAT_EXPIRED; @@ -996,7 +997,7 @@ in_abort: newl->status = DB_LSTAT_WAITING; case DB_LSTAT_ABORTED: /* * If we raced with the deadlock detector and it - * mistakenly picked this tranaction to abort again + * mistakenly picked this transaction to abort again * ignore the abort and request the lock again. */ if (F_ISSET(sh_locker, DB_LOCKER_INABORT)) diff --git a/src/lock/lock_alloc.incl b/src/lock/lock_alloc.incl index e14d43b0..edea07d2 100644 --- a/src/lock/lock_alloc.incl +++ b/src/lock/lock_alloc.incl @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/lock/lock_deadlock.c b/src/lock/lock_deadlock.c index 4d5c3c8d..3c00d7f1 100644 --- a/src/lock/lock_deadlock.c +++ b/src/lock/lock_deadlock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -372,7 +372,7 @@ err: if (copymap != NULL) /* * __dd_build -- * Build the lock dependency bit maps. - * Notes on syncronization: + * Notes on synchronization: * LOCK_SYSTEM_LOCK is used to hold objects locked when we have * a single partition. * LOCK_LOCKERS is held while we are walking the lockers list and diff --git a/src/lock/lock_failchk.c b/src/lock/lock_failchk.c index b494dffc..59fb010f 100644 --- a/src/lock/lock_failchk.c +++ b/src/lock/lock_failchk.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/lock/lock_id.c b/src/lock/lock_id.c index 3527380e..24b545d1 100644 --- a/src/lock/lock_id.c +++ b/src/lock/lock_id.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -328,7 +328,7 @@ __lock_getlocker_int(lt, locker, create, retp) * Don't hold lockers when getting the region, * we could deadlock. When creating a locker * there is no race since the id allocation - * is syncrhonized. + * is synchronized. */ UNLOCK_LOCKERS(env, region); LOCK_REGION_LOCK(env); @@ -455,7 +455,7 @@ __lock_addfamilylocker(env, pid, id, is_family) /* * Link the child at the head of the master's list. * The guess is when looking for deadlock that - * the most recent child is the one thats blocked. + * the most recent child is the one that's blocked. */ SH_LIST_INSERT_HEAD( &mlockerp->child_locker, lockerp, child_link, __db_locker); diff --git a/src/lock/lock_list.c b/src/lock/lock_list.c index c644ffe7..1e3d2a55 100644 --- a/src/lock/lock_list.c +++ b/src/lock/lock_list.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -266,8 +266,8 @@ __lock_get_list(env, locker, flags, lock_mode, list) do { if ((ret = __lock_get_internal(lt, locker, flags, &obj_dbt, lock_mode, 0, &ret_lock)) != 0) { - lock->pgno = save_pgno; - goto err; + lock->pgno = save_pgno; + goto err; } if (npgno != 0) GET_PGNO(dp, lock->pgno); diff --git a/src/lock/lock_method.c b/src/lock/lock_method.c index 451b5e1c..0cc2e19d 100644 --- a/src/lock/lock_method.c +++ b/src/lock/lock_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/lock/lock_region.c b/src/lock/lock_region.c index 1b58d835..1aae1815 100644 --- a/src/lock/lock_region.c +++ b/src/lock/lock_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -492,7 +492,7 @@ __lock_region_max(env) /* * __lock_region_size -- - * Return the inital region size. + * Return the initial region size. * PUBLIC: size_t __lock_region_size __P((ENV *, size_t)); */ size_t @@ -546,7 +546,7 @@ __lock_region_size(env, other_alloc) * pick the point 2/3s of the way to the max size. If the max * is not stated then guess that objects will fill 1/2 the memory. * Failing to know how much memory there might we just wind up - * using the default value. If this winds up being less thatn + * using the default value. If this winds up being less than * the init value then we just make the table fit the init value. */ if ((count = dbenv->lk_max_objects) == 0) { diff --git a/src/lock/lock_stat.c b/src/lock/lock_stat.c index 80680266..11b934aa 100644 --- a/src/lock/lock_stat.c +++ b/src/lock/lock_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/lock/lock_stub.c b/src/lock/lock_stub.c index e3043076..3875af55 100644 --- a/src/lock/lock_stub.c +++ b/src/lock/lock_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -620,7 +620,6 @@ __lock_wakeup(env, obj) return (__db_nolocking(env)); } - int __lock_change(env, old_lock, new_lock) ENV *env; diff --git a/src/lock/lock_timer.c b/src/lock/lock_timer.c index a1c673df..943047f0 100644 --- a/src/lock/lock_timer.c +++ b/src/lock/lock_timer.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -103,7 +103,7 @@ __lock_inherit_timeout(env, parent, locker) LOCK_REGION_LOCK(env); /* - * If the parent is not there yet, thats ok. If it + * If the parent is not there yet, that's ok. If it * does not have any timouts set, then avoid creating * the child locker at this point. */ diff --git a/src/lock/lock_util.c b/src/lock/lock_util.c index bb1d775d..f7029cd7 100644 --- a/src/lock/lock_util.c +++ b/src/lock/lock_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -28,7 +28,7 @@ * inode number, and the first 4 bytes on Windows systems are the FileIndexLow * bytes. This is followed by a random number. The inode values tend * to increment fairly slowly and are not good for hashing. So, we use - * the XOR of the page number and the four bytes of the file id randome + * the XOR of the page number and the four bytes of the file id random * number to produce a 32-bit hash value. * * We have no particular reason to believe that this algorithm will produce diff --git a/src/log/log.c b/src/log/log.c index 2d71165c..5808145f 100644 --- a/src/log/log.c +++ b/src/log/log.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -463,7 +463,7 @@ retry: if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) { /* Search for a valid log file name. */ for (cnt = fcnt, clv = logval = 0; --cnt >= 0;) { - if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1) != 0) + if (!IS_LOG_FILE(names[cnt])) continue; /* @@ -603,7 +603,8 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp) LOGP *persist; logfile_validity status; size_t hdrsize, nr, recsize; - int is_hmac, ret; + int chksum_includes_hdr, is_hmac, ret; + u_int32_t logversion; u_int8_t *tmp; char *fname; @@ -613,6 +614,12 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp) persist = NULL; status = DB_LV_NORMAL; tmp = NULL; +#if defined(HAVE_LOG_CHECKSUM) + /* Most log versions include the hdr in the checksum. */ + chksum_includes_hdr = 1; +#else + COMPQUIET(chksum_includes_hdr, 0); +#endif /* Return the file handle to our caller, on request */ if (fhpp != NULL) @@ -697,13 +704,30 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp) __db_errx(env, "log record size mismatch"); goto err; } - /* Check the checksum and decrypt. */ + /* + * The checksum is calculated from the encrypted data, and, + * for recent logs, the fields hdr->{prev,len}. + */ #ifdef HAVE_LOG_CHECKSUM if ((ret = __db_check_chksum(env, hdr, db_cipher, &hdr->chksum[0], (u_int8_t *)persist, hdr->len - hdrsize, is_hmac)) != 0) { - __db_errx(env, "log record checksum mismatch"); - goto err; + /* + * The checksum doesn't verify when the header fields + * are included; try without the header. + */ + + if ((ret = __db_check_chksum(env, NULL, db_cipher, + &hdr->chksum[0], (u_int8_t *)persist, + hdr->len - hdrsize, is_hmac)) != 0) + goto bad_checksum; + /* + * The checksum verifies without the header. Make note + * of that, because it is only acceptable when the log + * version < DB_LOGCHKSUM. Later, when we determine log + * version, we will confirm this. + */ + chksum_includes_hdr = 0; } #endif @@ -739,55 +763,73 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp) goto err; } + logversion = persist->version; /* * Set our status code to indicate whether the log file belongs to an * unreadable or readable old version; leave it alone if and only if * the log file version is the current one. */ - if (persist->version > DB_LOGVERSION) { + if (logversion > DB_LOGVERSION) { /* This is a fatal error--the log file is newer than DB. */ __db_errx(env, DB_STR_A("2531", "Unacceptable log file %s: unsupported log version %lu", - "%s %lu"), fname, (u_long)persist->version); + "%s %lu"), fname, (u_long)logversion); ret = EINVAL; goto err; - } else if (persist->version < DB_LOGOLDVER) { + } else if (logversion < DB_LOGOLDVER) { status = DB_LV_OLD_UNREADABLE; /* This is a non-fatal error, but give some feedback. */ __db_errx(env, DB_STR_A("2532", "Skipping log file %s: historic log version %lu", "%s %lu"), - fname, (u_long)persist->version); + fname, (u_long)logversion); /* * We don't want to set persistent info based on an unreadable * region, so jump to "err". */ goto err; - } else if (persist->version < DB_LOGVERSION) + } else if (logversion < DB_LOGVERSION) status = DB_LV_OLD_READABLE; /* - * Only if we have a current log do we verify the checksum. We could - * not check the checksum before checking the magic and version because - * old log headers put the length and checksum in a different location. - * The checksum was calculated with the swapped byte order, so we need - * to check it with the same bytes. + * We could not check the checksum before checking the magic and version + * because old log headers put the length and checksum in a different + * location. */ - if (!CRYPTO_ON(env)) { +#ifdef HAVE_LOG_CHECKSUM + if (CRYPTO_ON(env)) { + /* + * We might have to declare a checksum failure here, if: + * - the checksum verified only by ignoring the header, and + * - the log version indicates that the header should have + * been included. + */ + if (!chksum_includes_hdr && logversion >= DB_LOGCHKSUM) + goto bad_checksum; + } else { + /* + * The checksum was calculated with the swapped byte order. We + * might need to swap them back; the check needs the same bytes. + */ if (LOG_SWAPPED(env)) __log_persistswap(persist); -#ifdef HAVE_LOG_CHECKSUM + /* + * We have the logversion here, so we know whether to include + * the hdr or not. + */ if ((ret = __db_check_chksum(env, - hdr, db_cipher, &hdr->chksum[0], (u_int8_t *)persist, + logversion >= DB_LOGCHKSUM ? hdr : NULL, db_cipher, + &hdr->chksum[0], (u_int8_t *)persist, hdr->len - hdrsize, is_hmac)) != 0) { +bad_checksum: __db_errx(env, DB_STR("2533", "log record checksum mismatch")); goto err; } -#endif if (LOG_SWAPPED(env)) __log_persistswap(persist); } +#endif /* * If the log is readable so far and we're doing system initialization, @@ -798,10 +840,10 @@ __log_valid(dblp, number, set_persist, fhpp, flags, statusp, versionp) if (set_persist) { lp = dblp->reginfo.primary; lp->log_size = persist->log_size; - lp->persist.version = persist->version; + lp->persist.version = logversion; } if (versionp != NULL) - *versionp = persist->version; + *versionp = logversion; err: if (fname != NULL) __os_free(env, fname); diff --git a/src/log/log_archive.c b/src/log/log_archive.c index 61c8596c..280a2071 100644 --- a/src/log/log_archive.c +++ b/src/log/log_archive.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -17,7 +17,6 @@ static int __absname __P((ENV *, char *, char *, char **)); static int __build_data __P((ENV *, char *, char ***)); static int __cmpfunc __P((const void *, const void *)); -static int __log_archive __P((ENV *, char **[], u_int32_t)); static int __usermem __P((ENV *, char ***)); /* @@ -65,8 +64,9 @@ __log_archive_pp(dbenv, listp, flags) /* * __log_archive -- * ENV->log_archive. Internal. + * PUBLIC: int __log_archive __P((ENV *, char **[], u_int32_t)); */ -static int +int __log_archive(env, listp, flags) ENV *env; char ***listp; diff --git a/src/log/log_compare.c b/src/log/log_compare.c index 4ae6b595..97b59338 100644 --- a/src/log/log_compare.c +++ b/src/log/log_compare.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_debug.c b/src/log/log_debug.c index 55afbe8e..32fb2542 100644 --- a/src/log/log_debug.c +++ b/src/log/log_debug.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_get.c b/src/log/log_get.c index 872f8b73..db30c969 100644 --- a/src/log/log_get.c +++ b/src/log/log_get.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -401,7 +401,7 @@ __logc_get_int(logc, alsn, dbt, flags) db_cipher = env->crypto_handle; dblp = env->lg_handle; lp = dblp->reginfo.primary; - is_hmac = 0; + eof = is_hmac = 0; orig_flags = flags; /* flags may be altered later. */ blen = 0; logfsz = lp->persist.log_size; @@ -602,8 +602,14 @@ nohdr: switch (flags) { * we're reading backwards from another file, then * the first record in that new file should have its * prev field set correctly. + * First check that the file exists. */ - __db_errx(env, DB_STR("2576", + if (eof && logc->bp_lsn.file != nlsn.file) + __db_errx(env, DB_STR_A("2583", + "Log file %d not found, check log directory configuration", "%d"), + nlsn.file); + else + __db_errx(env, DB_STR("2576", "Encountered zero length records while traversing backwards")); ret = __env_panic(env, DB_RUNRECOVERY); goto err; @@ -645,14 +651,19 @@ cksum: /* if ((ret = __db_check_chksum(env, &hdr, db_cipher, hdr.chksum, rp + hdr.size, hdr.len - hdr.size, is_hmac)) != 0) { /* - * We may be dealing with a version that does not - * checksum the header. Try again without the header. + * This might be a log whose checksum does not include the hdr. + * Try again without the header, either for logs whose version + * is pre-DB_LOGCHKSUM, or for the persist record which contains + * the log version. Check for the zero offset first to avoid + * unwanted recursion in __logc_version(). + * * Set the cursor to the LSN we are trying to look at. */ last_lsn = logc->lsn; logc->lsn = nlsn; - if (__logc_version(logc, &version) == 0 && - version < DB_LOGCHKSUM && + if ((logc->lsn.offset == 0 || + (__logc_version(logc, &version) == 0 && + version < DB_LOGCHKSUM)) && __db_check_chksum(env, NULL, db_cipher, hdr.chksum, rp + hdr.size, hdr.len - hdr.size, is_hmac) == 0) { logc->lsn = last_lsn; @@ -1473,7 +1484,7 @@ __log_read_record(env, dbpp, td, recbuf, spec, size, argpp) ap = *argpp; /* * Allocate space for the arg structure and a transaction - * structure which will imeediately follow it. + * structure which will imediately follow it. */ if (ap == NULL && (ret = __os_malloc(env, size + sizeof(DB_TXN), &ap)) != 0) diff --git a/src/log/log_method.c b/src/log/log_method.c index 2b81b03f..d5aec116 100644 --- a/src/log/log_method.c +++ b/src/log/log_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_print.c b/src/log/log_print.c index b7da72c8..d2cda519 100644 --- a/src/log/log_print.c +++ b/src/log/log_print.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -126,6 +126,15 @@ __log_print_record(env, recbuf, lsnp, name, spec, info) case DBREG_REOPEN: s = "REOPEN"; break; + case DBREG_XCHKPNT: + s = "XCHKPNT"; + break; + case DBREG_XOPEN: + s = "XOPEN"; + break; + case DBREG_XREOPEN: + s = "XREOPEN"; + break; default: s = "UNKNOWN"; break; @@ -319,6 +328,9 @@ __log_print_dbregister(env, recbuf, dblp) case DBREG_CHKPNT: case DBREG_OPEN: case DBREG_REOPEN: + case DBREG_XCHKPNT: + case DBREG_XOPEN: + case DBREG_XREOPEN: if (dbp != NULL) { if (memcmp(dbp->fileid, argp->uid.data, DB_FILE_ID_LEN) == 0 && @@ -344,6 +356,8 @@ __log_print_dbregister(env, recbuf, dblp) F_SET(dbp, DB_AM_CHKSUM); if (FLD_ISSET(argp->opcode, DBREG_ENCRYPT)) F_SET(dbp, DB_AM_ENCRYPT); + if (FLD_ISSET(argp->opcode, DBREG_EXCL)) + F2_SET(dbp, DB2_AM_EXCL); dbe->dbp = dbp; break; case DBREG_CLOSE: diff --git a/src/log/log_put.c b/src/log/log_put.c index 357fc40b..8f7e23d8 100644 --- a/src/log/log_put.c +++ b/src/log/log_put.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -737,14 +737,6 @@ __log_newfile(dblp, lsnp, logfile, version) if ((ret = __log_encrypt_record(env, &t, &hdr, (u_int32_t)tsize)) != 0) goto err; -#ifdef HAVE_LOG_CHECKSUM - if (lp->persist.version != DB_LOGVERSION) - __db_chksum(NULL, t.data, t.size, - (CRYPTO_ON(env)) ? db_cipher->mac_key : NULL, hdr.chksum); - else - __db_chksum(&hdr, t.data, t.size, - (CRYPTO_ON(env)) ? db_cipher->mac_key : NULL, hdr.chksum); -#endif if ((ret = __log_putr(dblp, &lsn, &t, lastoff == 0 ? 0 : lastoff - lp->len, &hdr)) != 0) @@ -811,6 +803,7 @@ __log_putr(dblp, lsn, dbt, prev, h) hdr->prev = prev; hdr->len = (u_int32_t)hdr->size + dbt->size; +#ifdef HAVE_LOG_CHECKSUM /* * If we were passed in a nonzero checksum, our caller calculated * the checksum before acquiring the log mutex, as an optimization. @@ -820,8 +813,7 @@ __log_putr(dblp, lsn, dbt, prev, h) * here. */ if (hdr->chksum[0] == 0) { -#ifdef HAVE_LOG_CHECKSUM - if (lp->persist.version != DB_LOGVERSION) + if (lp->persist.version < DB_LOGCHKSUM) __db_chksum(NULL, dbt->data, dbt->size, (CRYPTO_ON(env)) ? db_cipher->mac_key : NULL, hdr->chksum); @@ -829,14 +821,13 @@ __log_putr(dblp, lsn, dbt, prev, h) __db_chksum(hdr, dbt->data, dbt->size, (CRYPTO_ON(env)) ? db_cipher->mac_key : NULL, hdr->chksum); -#endif - } else if (lp->persist.version == DB_LOGVERSION) { + } else if (lp->persist.version >= DB_LOGCHKSUM) /* - * We need to correct for prev and len since they are not - * set before here. + * We need to include hdr->prev and len here, since they were + * still zero at the time of the caller's __db_chksum() call. */ LOG_HDR_SUM(CRYPTO_ON(env), hdr, hdr->chksum); - } +#endif if (lp->db_log_inmemory && (ret = __log_inmem_chkspace(dblp, (u_int32_t)hdr->size + dbt->size)) != 0) @@ -1610,10 +1601,6 @@ __log_rep_put(env, lsnp, rec, flags) if ((ret = __log_encrypt_record(env, dbt, &hdr, rec->size)) != 0) goto err; -#ifdef HAVE_LOG_CHECKSUM - __db_chksum(&hdr, t.data, t.size, - (CRYPTO_ON(env)) ? db_cipher->mac_key : NULL, hdr.chksum); -#endif DB_ASSERT(env, LOG_COMPARE(lsnp, &lp->lsn) == 0); ret = __log_putr(dblp, lsnp, dbt, lp->lsn.offset - lp->len, &hdr); diff --git a/src/log/log_stat.c b/src/log/log_stat.c index 74f4c5aa..37b74c74 100644 --- a/src/log/log_stat.c +++ b/src/log/log_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_verify.c b/src/log/log_verify.c index 41b78219..e7f8f688 100644 --- a/src/log/log_verify.c +++ b/src/log/log_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_verify_int.c b/src/log/log_verify_int.c index 2df21418..abe564c6 100644 --- a/src/log/log_verify_int.c +++ b/src/log/log_verify_int.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1412,6 +1412,15 @@ __lv_dbreg_str(op) case DBREG_REOPEN: p = "DBREG_REOPEN"; break; + case DBREG_XCHKPNT: + p = "DBREG_XCHKPNT"; + break; + case DBREG_XOPEN: + p = "DBREG_XOPEN"; + break; + case DBREG_XREOPEN: + p = "DBREG_XREOPEN"; + break; default: p = DB_STR_P("Unknown dbreg op code"); break; @@ -1594,7 +1603,7 @@ __dbreg_register_verify(env, dbtp, lsnp, notused2, lvhp) } /* - * PREOPEN is only generated when openning an in-memory db. + * PREOPEN is only generated when opening an in-memory db. * Because we need to log the fileid we're allocating, but we * don't have all the details yet, we are preopening the * database and will actually complete the open later. So @@ -1703,7 +1712,8 @@ __dbreg_register_verify(env, dbtp, lsnp, notused2, lvhp) } if ((IS_DBREG_CLOSE(opcode) && - (pflife->lifetime != DBREG_CHKPNT) && + (pflife->lifetime != DBREG_CHKPNT || + pflife->lifetime != DBREG_XCHKPNT) && !IS_DBREG_OPEN(pflife->lifetime))) { __db_errx(env, DB_STR_A("2545", "[%lu][%lu] Wrong dbreg operation sequence for file %s " @@ -3722,7 +3732,7 @@ __txn_child_verify(env, dbtp, lsnp, notused2, lvhp) ptvi->nchild_commit++; /* * The start of this child txn caused lvh->ntxn_active to be - * incremented unecessarily, so decrement it. + * incremented unnecessarily, so decrement it. */ lvh->ntxn_active--; if (ptvi->status != TXN_STAT_ACTIVE) { @@ -4140,7 +4150,7 @@ __lv_on_new_txn (lvh, lsnp, txnp, type, dbregid, fid) vtip = pvti; /* * If this txn id was recycled, this use is legal. A legal - * recyclable txnid is immediately not recycleable after + * recyclable txnid is immediately not recyclable after * it's recycled here. And it's impossible for vtip->status * to be TXN_STAT_ACTIVE, since we have made it TXN_STAT_ABORT * when we detected this txn id recycle just now. @@ -4163,7 +4173,7 @@ __lv_on_new_txn (lvh, lsnp, txnp, type, dbregid, fid) /* * We may goto the else branch if this txn has child txns * before any updates done on its behalf. So we should - * exclude this possiblilty to conclude a failed verification. + * exclude this possibility to conclude a failed verification. */ } else if (vtip->nchild_active + vtip->nchild_commit + vtip->nchild_abort == 0) { diff --git a/src/log/log_verify_stub.c b/src/log/log_verify_stub.c index 32ceb49f..e6589a50 100644 --- a/src/log/log_verify_stub.c +++ b/src/log/log_verify_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/log/log_verify_util.c b/src/log/log_verify_util.c index 2cadd755..88682921 100644 --- a/src/log/log_verify_util.c +++ b/src/log/log_verify_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -254,7 +254,7 @@ err: return (ret); } -/* Seocndary index callback function for DB_LOG_VRFY_INFO->timelsn. */ +/* Secondary index callback function for DB_LOG_VRFY_INFO->timelsn. */ static int __lv_seccbk_fname(secdb, key, data, result) DB *secdb; @@ -289,7 +289,7 @@ out: return (ret); } -/* Seocndary index callback function for DB_LOG_VRFY_INFO->txnpg. */ +/* Secondary index callback function for DB_LOG_VRFY_INFO->txnpg. */ static int __lv_seccbk_txnpg(secdb, key, data, result) DB *secdb; @@ -306,7 +306,7 @@ __lv_seccbk_txnpg(secdb, key, data, result) return (0); } -/* Seocndary index callback function for DB_LOG_VRFY_INFO->timelsn. */ +/* Secondary index callback function for DB_LOG_VRFY_INFO->timelsn. */ static int __lv_seccbk_lsn(secdb, key, data, result) DB *secdb; @@ -1325,7 +1325,8 @@ __add_dbregid(lvh, freg, dbregid, opcode, lsn, dbtype, meta_pgno, addp) if (!IS_DBREG_CLOSE(opcode)) { /* Opening an open dbreg id. */ if (IS_DBREG_OPEN(opcode) && - opcode != DBREG_CHKPNT) { + (opcode != DBREG_CHKPNT && + opcode != DBREG_XCHKPNT)) { tret = 2; goto err; } diff --git a/src/mp/mp_alloc.c b/src/mp/mp_alloc.c index e3441986..dc331215 100644 --- a/src/mp/mp_alloc.c +++ b/src/mp/mp_alloc.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -39,16 +39,16 @@ __memp_alloc(dbmp, infop, mfp, len, offsetp, retp) { BH *bhp, *current_bhp, *mvcc_bhp, *oldest_bhp; BH_FROZEN_PAGE *frozen_bhp; - DB_LSN vlsn; + DB_LSN oldest_reader, vlsn; DB_MPOOL_HASH *dbht, *hp, *hp_end, *hp_saved, *hp_tmp; ENV *env; MPOOL *c_mp; MPOOLFILE *bh_mfp; size_t freed_space; u_int32_t buckets, bucket_priority, buffers, cache_reduction; - u_int32_t high_priority, priority; + u_int32_t dirty_eviction, high_priority, priority, versions; u_int32_t priority_saved, put_counter, lru_generation, total_buckets; - int aggressive, alloc_freeze, b_lock, giveup, got_oldest; + int aggressive, alloc_freeze, b_lock, giveup; int h_locked, need_free, obsolete, ret, write_error; u_int8_t *endp; void *p; @@ -61,8 +61,8 @@ __memp_alloc(dbmp, infop, mfp, len, offsetp, retp) priority_saved = 0; write_error = 0; - buckets = buffers = put_counter = total_buckets = 0; - aggressive = alloc_freeze = giveup = got_oldest = h_locked = 0; + buckets = buffers = put_counter = total_buckets = versions = 0; + aggressive = alloc_freeze = giveup = h_locked = 0; /* * If we're allocating a buffer, and the one we're discarding is the @@ -158,6 +158,7 @@ search: lru_generation = c_mp->lru_generation; ret = 0; + MAX_LSN(oldest_reader); /* * We re-attempt the allocation every time we've freed 3 times what @@ -310,9 +311,17 @@ retry_search: bhp = NULL; * aggressive), and is better than the best candidate * we have found so far in this bucket. */ +#ifdef MPOOL_ALLOC_SEARCH_DYN + if (aggressive == 0 && + ++high_priority >= c_mp->lru_priority) + aggressive = 1; +#endif + if (SH_CHAIN_SINGLETON(current_bhp, vc)) { - if (BH_REFCOUNT(current_bhp) == 0 && - bucket_priority > current_bhp->priority) { + if (BH_REFCOUNT(current_bhp) != 0) + continue; + buffers++; + if (bucket_priority > current_bhp->priority) { bucket_priority = current_bhp->priority; if (bhp != NULL) atomic_dec(env, &bhp->ref); @@ -331,11 +340,19 @@ retry_search: bhp = NULL; mvcc_bhp != NULL; oldest_bhp = mvcc_bhp, mvcc_bhp = SH_CHAIN_PREV(mvcc_bhp, vc, __bh)) { +#ifdef MPOOL_ALLOC_SEARCH_DYN + if (aggressive == 0 && + ++high_priority >= c_mp->lru_priority) + aggressive = 1; +#endif DB_ASSERT(env, mvcc_bhp != SH_CHAIN_PREV(mvcc_bhp, vc, __bh)); - if (aggressive > 1 && - BH_REFCOUNT(mvcc_bhp) == 0 && - !F_ISSET(mvcc_bhp, BH_FROZEN) && + if ((aggressive < 2 && + ++versions < (buffers >> 2)) || + BH_REFCOUNT(mvcc_bhp) != 0) + continue; + buffers++; + if (!F_ISSET(mvcc_bhp, BH_FROZEN) && (bhp == NULL || bhp->priority > mvcc_bhp->priority)) { if (bhp != NULL) @@ -348,16 +365,30 @@ retry_search: bhp = NULL; /* * oldest_bhp is the last buffer on the MVCC chain, and * an obsolete buffer at the end of the MVCC chain gets - * used without further search. - * - * If the buffer isn't obsolete with respect to the - * cached old reader LSN, recalculate the oldest reader - * LSN and check again. + * used without further search. Before checking for + * obsolescence, update the cached oldest reader LSN in + * the bucket if it is older than call's oldest_reader. */ if (BH_REFCOUNT(oldest_bhp) != 0) continue; -retry_obsolete: if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn)) { + if (LOG_COMPARE(&oldest_reader, &hp->old_reader) > 0) { + if (IS_MAX_LSN(oldest_reader) && + (ret = __txn_oldest_reader( + env, &oldest_reader)) != 0) { + MUTEX_UNLOCK(env, hp->mtx_hash); + if (bhp != NULL) + atomic_dec(env, &bhp->ref); + return (ret); + } + if (LOG_COMPARE(&oldest_reader, + &hp->old_reader) > 0) + hp->old_reader = oldest_reader; + } + + if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn)) { + if (aggressive < 2) + buffers++; obsolete = 1; if (bhp != NULL) atomic_dec(env, &bhp->ref); @@ -365,13 +396,6 @@ retry_obsolete: if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn)) { atomic_inc(env, &bhp->ref); goto this_buffer; } - if (!got_oldest) { - if ((ret = __txn_oldest_reader( - env, &hp->old_reader)) != 0) - return (ret); - got_oldest = 1; - goto retry_obsolete; - } } /* @@ -447,9 +471,7 @@ retry_obsolete: if (BH_OBSOLETE(oldest_bhp, hp->old_reader, vlsn)) { goto search; } -this_buffer: buffers++; - - /* +this_buffer: /* * Discard any previously remembered hash bucket, we've got * a winner. */ @@ -481,6 +503,7 @@ this_buffer: buffers++; /* If the page is dirty, write it. */ ret = 0; + dirty_eviction = 0; if (F_ISSET(bhp, BH_DIRTY)) { DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0); ret = __memp_bhwrite(dbmp, hp, bh_mfp, bhp, 0); @@ -494,7 +517,7 @@ this_buffer: buffers++; * buffer again by maximizing its priority. */ if (ret != 0) { - if (ret != EPERM) { + if (ret != EPERM && ret != EAGAIN) { write_error++; __db_errx(env, DB_STR_A("3018", "%s: unwritable page %d remaining in the cache after error %d", @@ -507,13 +530,8 @@ this_buffer: buffers++; goto next_hb; } - STAT_INC(env, mpool, - dirty_eviction, c_mp->stat.st_rw_evict, infop->id); - + dirty_eviction = 1; } - else - STAT_INC(env, mpool, - clean_eviction, c_mp->stat.st_ro_evict, infop->id); /* * Freeze this buffer, if necessary. That is, if the buffer is @@ -592,6 +610,13 @@ this_buffer: buffers++; goto retry_search; } + /* We are certainly freeing this buf; now update statistic. */ + if (dirty_eviction) + STAT_INC(env, mpool, + dirty_eviction, c_mp->stat.st_rw_evict, infop->id); + else + STAT_INC(env, mpool, + clean_eviction, c_mp->stat.st_ro_evict, infop->id); /* * If we need some empty buffer headers for freezing, turn the * buffer we've found into frozen headers and put them on the diff --git a/src/mp/mp_backup.c b/src/mp/mp_backup.c new file mode 100644 index 00000000..f376cda7 --- /dev/null +++ b/src/mp/mp_backup.c @@ -0,0 +1,333 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +#include "dbinc/mp.h" +#ifndef HAVE_ATOMICFILEREAD +#include "dbinc/db_page.h" +#endif + +#ifndef HAVE_ATOMICFILEREAD +static int __memp_check_backup __P((ENV *, + MPOOLFILE *, void *, u_int32_t *, u_int32_t)); +#endif + +/* + * __memp_backup_open -- + * Setup to backup a database file. + * + * PUBLIC: int __memp_backup_open __P((ENV *, DB_MPOOLFILE *, + * PUBLIC: const char *, const char *, u_int32_t, DB_FH **, void**)); + */ +int +__memp_backup_open(env, mpf, dbfile, target, flags, fpp, handlep) + ENV *env; + DB_MPOOLFILE *mpf; + const char *dbfile; + const char *target; + u_int32_t flags; + DB_FH **fpp; + void **handlep; +{ + DB_BACKUP *backup; +#ifndef HAVE_ATOMICFILEREAD + MPOOLFILE *mfp; +#endif + u_int32_t oflags; + size_t len; + int ret; + char *path; + + path = NULL; + *fpp = NULL; + backup = env->backup_handle; + *handlep = NULL; + + if (backup != NULL && backup->open != NULL) + ret = backup->open(env->dbenv, dbfile, target, handlep); + else { + len = strlen(target) + strlen(dbfile) + 2; + if ((ret = __os_malloc(env, len, &path)) != 0) { + __db_err(env, ret, DB_STR_A("0703", + "Cannot allocate space for path: %s", "%s"), + target); + goto err; + } + + if ((ret = __os_concat_path(path, len, target, dbfile)) != 0) + goto err; + + oflags = DB_OSO_CREATE | DB_OSO_TRUNC; + if (LF_ISSET(DB_EXCL)) + FLD_SET(oflags, DB_OSO_EXCL); + if (backup != NULL && F_ISSET(backup, BACKUP_WRITE_DIRECT)) + FLD_SET(oflags, DB_OSO_DIRECT); + ret = __os_open(env, path, 0, oflags, DB_MODE_600, fpp); + } + if (ret != 0) { + __db_err(env, ret, DB_STR_A("0704", + "Cannot open target file: %s", "%s"), path); + goto err; + } + +#ifndef HAVE_ATOMICFILEREAD + mfp = mpf->mfp; + + /* + * Need to register thread with fail check. + */ + MUTEX_LOCK(env, mfp->mtx_write); + if (mfp->backup_in_progress) { + __db_err(env, ret, DB_STR_A("0712", + "%s is already in a backup", "%s"), dbfile); + MUTEX_UNLOCK(env, mfp->mtx_write); + goto err; + } + mfp->backup_in_progress = 1; + env->dbenv->thread_id(env->dbenv, &mfp->pid, &mfp->tid); + MUTEX_UNLOCK(env, mfp->mtx_write); +#else + COMPQUIET(mpf, NULL); +#endif +err: if (path != NULL) + __os_free(env, path); + if (ret != 0) { + if (*fpp != NULL) + (void)__os_closehandle(env, *fpp); + if (backup != NULL && backup->close != NULL) + (void)backup->close(env->dbenv, dbfile, *handlep); + } + return (ret); +} + +/* + * __memp_backup_mpf -- + * Copy a database file while maintaining synchronization with + * mpool write activity. + * + * PUBLIC: int __memp_backup_mpf __P((ENV *, DB_MPOOLFILE *, DB_THREAD_INFO *, + * PUBLIC: db_pgno_t, db_pgno_t, DB_FH *, void *, u_int32_t)); + */ +int +__memp_backup_mpf(env, mpf, ip, first_pgno, last_pgno, fp, handle, flags) + ENV *env; + DB_MPOOLFILE *mpf; + DB_THREAD_INFO *ip; + db_pgno_t first_pgno, last_pgno; + DB_FH *fp; + void *handle; + u_int32_t flags; +{ + DB_BACKUP *backup; + MPOOLFILE *mfp; + db_pgno_t high_pgno, pgno; + off_t t_off; + u_int32_t read_count, write_size; + u_int32_t gigs, off; + size_t len, nr, nw; + u_int8_t *buf; + int ret; + + COMPQUIET(flags, 0); + backup = env->backup_handle; + read_count = 0; + buf = NULL; + mfp = mpf->mfp; + gigs = 0; + off = 0; + + if (backup == NULL || (len = backup->size) == 0) + len = MEGABYTE; + if ((ret = __os_malloc(env, len, &buf)) != 0) + return (ret); + write_size = (u_int32_t)(len / mfp->pagesize); + + if (first_pgno > 0) { + t_off = (off_t)first_pgno * mfp->pagesize; + gigs = (u_int32_t)(t_off / GIGABYTE); + off = (u_int32_t)(t_off - (off_t)gigs * GIGABYTE); + } + + for (pgno = first_pgno; pgno <= last_pgno; pgno = high_pgno + 1) { + high_pgno = pgno + write_size - 1; + if (high_pgno > last_pgno) + high_pgno = last_pgno; + len = ((high_pgno - pgno) + 1) * mfp->pagesize; +#ifndef HAVE_ATOMICFILEREAD + if (ip != NULL) + ip->dbth_state = THREAD_ACTIVE; + MUTEX_LOCK(env, mfp->mtx_write); + + /* Eventually the writers will drain and block on the mutex. */ + while (atomic_read(&mfp->writers) != 0) { + STAT_INC_VERB(env, mpool, backup_spins, + mfp->stat.st_backup_spins, __memp_fn(mpf), pgno); + __os_yield(env, 0, 1000); + } + + mfp->low_pgno = pgno; + mfp->high_pgno = high_pgno; + MUTEX_UNLOCK(env, mfp->mtx_write); + if (ip != NULL) + ip->dbth_state = THREAD_OUT; +#endif + + if ((ret = __os_io(env, DB_IO_READ, mpf->fhp, pgno, + mfp->pagesize, 0, (u_int32_t)len, buf, &nr)) != 0) + break; + + if (nr == 0) + break; + + if (backup != NULL && backup->write != NULL) { + if ((ret = backup->write( + env->dbenv, gigs, off, (u_int32_t)nr, + buf, handle)) != 0) + break; + } else { + if ((ret = __os_io(env, DB_IO_WRITE, fp, pgno, + mfp->pagesize, 0, (u_int32_t)nr, buf, &nw)) != 0) + break; + if (nr != nw) { + ret = EIO; + break; + } + } + + off += (u_int32_t)nr; + if (off >= GIGABYTE) { + gigs++; + off -= GIGABYTE; + } + + if (backup != NULL && backup->read_count != 0) { + if ((read_count += write_size) >= backup->read_count) + __os_yield(env, 0, backup->read_sleep); + } + + /* + * There may be pages not written to the file yet. The + * next read will probably see the end of file. + */ + if (nr != len) + high_pgno = pgno + (db_pgno_t)(nr / mfp->pagesize); + } + DB_ASSERT(env, ret == 0); + __os_free(env, buf); + +#ifndef HAVE_ATOMICFILEREAD + if (ip != NULL) + ip->dbth_state = THREAD_ACTIVE; + MUTEX_LOCK(env, mfp->mtx_write); + mfp->low_pgno = PGNO_INVALID; + mfp->high_pgno = PGNO_INVALID; + MUTEX_UNLOCK(env, mfp->mtx_write); +#else + COMPQUIET(ip, NULL); +#endif + + return (ret); +} + +/* + * __memp_backup_close -- + * Close backup file. + * + * PUBLIC: int __memp_backup_close __P((ENV *, DB_MPOOLFILE *, + * PUBLIC: const char *, DB_FH *, void *HANDLE)); + */ +int +__memp_backup_close(env, mpf, dbfile, fp, handle) + ENV *env; + DB_MPOOLFILE *mpf; + const char *dbfile; + DB_FH *fp; + void *handle; +{ + DB_BACKUP *backup; +#ifndef HAVE_ATOMICFILEREAD + MPOOLFILE *mfp; +#endif + int ret, t_ret; + + backup = env->backup_handle; + ret = t_ret = 0; + +#ifndef HAVE_ATOMICFILEREAD + mfp = mpf->mfp; + MUTEX_LOCK(env, mfp->mtx_write); + mfp->backup_in_progress = 0; + MUTEX_UNLOCK(env, mfp->mtx_write); +#else + COMPQUIET(mpf, NULL); +#endif + if (fp != NULL) + ret = __os_closehandle(env, fp); + if (backup != NULL && backup->close != NULL) + t_ret = backup->close(env->dbenv, dbfile, handle); + return (ret == 0 ? t_ret : ret); +} + +#ifndef HAVE_ATOMICFILEREAD +/* + * __memp_check_backup -- + * check for a dead thread backing up a mp file. + */ +static int +__memp_check_backup(env, mfp, arg, countp, flags) + ENV *env; + MPOOLFILE *mfp; + void *arg; + u_int32_t *countp; + u_int32_t flags; +{ + DB_ENV *dbenv; + char buf[DB_THREADID_STRLEN]; + + COMPQUIET(arg, NULL); + COMPQUIET(countp, NULL); + COMPQUIET(flags, 0); + + dbenv = env->dbenv; + + if (mfp->backup_in_progress == 0 || + dbenv->is_alive(dbenv, mfp->pid, mfp->tid, 0)) + return (0); + + __db_msg(env, DB_STR_A("3042", "Releasing backup of %s for %s.", + "%s %s"), (char *)R_ADDR(env->mp_handle->reginfo, mfp->path_off), + dbenv->thread_id_string(dbenv, mfp->pid, mfp->tid, buf)); + mfp->backup_in_progress = 0; + return (0); +} +#endif + +/* + * __memp_failchk -- + * Remove in process database backups. + * PUBLIC: int __memp_failchk __P((ENV *)); + */ +int +__memp_failchk(env) + ENV *env; +{ +#ifdef HAVE_ATOMICFILEREAD + COMPQUIET(env, NULL); + return (0); +#else + DB_MPOOL *dbmp; + MPOOL *mp; + + dbmp = env->mp_handle; + mp = dbmp->reginfo[0].primary; + + return (__memp_walk_files(env, mp, __memp_check_backup, NULL, NULL, 0)); +#endif +} diff --git a/src/mp/mp_bh.c b/src/mp/mp_bh.c index 19dfcbed..1df8e206 100644 --- a/src/mp/mp_bh.c +++ b/src/mp/mp_bh.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -35,9 +35,10 @@ __memp_bhwrite(dbmp, hp, mfp, bhp, open_extents) DB_MPOOLFILE *dbmfp; DB_MPREG *mpreg; ENV *env; - int ret; + int opened, ret; env = dbmp->env; + opened = 0; /* * If the file has been removed or is a closed temporary file, we're @@ -148,8 +149,15 @@ __memp_bhwrite(dbmp, hp, mfp, bhp, open_extents) */ if ((ret = __memp_fcreate(env, &dbmfp)) != 0) return (ret); - if ((ret = __memp_fopen(dbmfp, mfp, - NULL, NULL, DB_DURABLE_UNKNOWN, 0, mfp->pagesize)) != 0) { + /* + * The open will set MP_FLUSH and so we need to keep + * a checkpoint from closing this before we finish with it. + */ + dbmfp->ref++; + opened = 1; + if ((ret = __memp_fopen(dbmfp, mfp, NULL, + NULL, DB_FLUSH | DB_DURABLE_UNKNOWN, 0, mfp->pagesize)) != 0) { + dbmfp->ref--; (void)__memp_fclose(dbmfp, 0); /* @@ -174,9 +182,25 @@ pgwrite: * the file eventually gets closed. */ MUTEX_LOCK(env, dbmp->mutex); - if (dbmfp->ref == 1) - F_SET(dbmfp, MP_FLUSH); - else + if (!opened && dbmfp->ref == 1) { + /* + * If we are the last reference, then we need to mark + * this as having been used to flush. If this dbmf + * has not been counted as a neutral reference do it. + * + * Getting the mfp mutex while holding the dbmp is + * ok we never do it in the reverse order. + */ + if (!F_ISSET(dbmfp, MP_FLUSH)) { + F_SET(dbmfp, MP_FLUSH); + MUTEX_LOCK(env,dbmfp->mfp->mutex); + if (!F_ISSET(dbmfp, MP_FOR_FLUSH)) { + mfp->neutral_cnt++; + F_SET(dbmfp, MP_FOR_FLUSH); + } + MUTEX_UNLOCK(env, dbmfp->mfp->mutex); + } + } else --dbmfp->ref; MUTEX_UNLOCK(env, dbmp->mutex); @@ -211,7 +235,7 @@ __memp_pgread(dbmfp, bhp, can_create) F_ISSET(bhp, BH_TRASH) || !F_ISSET(bhp, BH_DIRTY)); DB_ASSERT(env, F_ISSET(bhp, BH_EXCLUSIVE)); - /* Mark the buffer as in transistion. */ + /* Mark the buffer as in transition. */ F_SET(bhp, BH_TRASH); /* @@ -372,6 +396,20 @@ __memp_pgwrite(env, dbmfp, hp, bhp) } #endif +#ifndef HAVE_ATOMICFILEREAD + if (mfp->backup_in_progress != 0) { + MUTEX_READLOCK(env, mfp->mtx_write); + if (bhp->pgno >= mfp->low_pgno && bhp->pgno <= mfp->high_pgno) { + MUTEX_UNLOCK(env, mfp->mtx_write); + ret = EAGAIN; + goto err; + } + atomic_inc(env, &mfp->writers); + MUTEX_UNLOCK(env, mfp->mtx_write); + } else + atomic_inc(env, &mfp->writers); +#endif + /* * Call any pgout function. If we have the page exclusive then * we are going to reuse it otherwise make a copy of the page so @@ -394,11 +432,17 @@ __memp_pgwrite(env, dbmfp, hp, bhp) /* Write the page. */ if ((ret = __os_io(env, DB_IO_WRITE, dbmfp->fhp, bhp->pgno, mfp->pagesize, 0, mfp->pagesize, buf, &nw)) != 0) { +#ifndef HAVE_ATOMICFILEREAD + atomic_dec(env, &mfp->writers); +#endif __db_errx(env, DB_STR_A("3015", "%s: write failed for page %lu", "%s %lu"), __memp_fn(dbmfp), (u_long)bhp->pgno); goto err; } +#ifndef HAVE_ATOMICFILEREAD + atomic_dec(env, &mfp->writers); +#endif STAT_INC_VERB(env, mpool, page_out, mfp->stat.st_page_out, __memp_fn(dbmfp), bhp->pgno); if (bhp->pgno > mfp->last_flushed_pgno) { diff --git a/src/mp/mp_fget.c b/src/mp/mp_fget.c index 5d95607e..5f9a4bf9 100644 --- a/src/mp/mp_fget.c +++ b/src/mp/mp_fget.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -483,9 +483,7 @@ freebuf: MUTEX_LOCK(env, hp->mtx_hash); } goto done; } else if (F_ISSET(bhp, BH_FREED | BH_TRASH)) { -revive: DB_ASSERT(env, F_ISSET(bhp, BH_TRASH) || - flags == DB_MPOOL_CREATE || flags == DB_MPOOL_NEW); - if (F_ISSET(bhp, BH_FREED)) +revive: if (F_ISSET(bhp, BH_FREED)) makecopy = makecopy || (mvcc && !BH_OWNED_BY(env, bhp, txn)) || F_ISSET(bhp, BH_FROZEN); @@ -495,6 +493,16 @@ revive: DB_ASSERT(env, F_ISSET(bhp, BH_TRASH) || mfp->last_pgno = *pgnoaddr; MUTEX_UNLOCK(env, mfp->mutex); } + /* We can race with a thread trying to free this. */ + if (F_ISSET(bhp, BH_TRASH) && + *pgnoaddr <= mfp->last_pgno) + break; + + /* Otherwise this page does not currently exist. */ + if (flags != DB_MPOOL_CREATE && flags != DB_MPOOL_NEW) { + ret = DB_PAGE_NOTFOUND; + goto done; + } } if (mvcc) { /* @@ -1153,7 +1161,7 @@ alloc: /* Allocate a new buffer header and data space. */ #ifdef DIAGNOSTIC if (dirty && ip->dbth_locker != INVALID_ROFF && ip->dbth_check_off == 0) { - lt = env->lk_handle; + lt = env->lk_handle; locker = (DB_LOCKER *) (R_ADDR(<->reginfo, ip->dbth_locker)); DB_ASSERT(env, __db_has_pagelock(env, locker, dbmfp, @@ -1164,7 +1172,7 @@ alloc: /* Allocate a new buffer header and data space. */ } /* * During recovery we can read past the end of the file. Also - * last_pgno is not versioned, so if this is an older version + * last_pgno is not versioned, so if this is an older version * that is ok as well. */ DB_ASSERT(env, IS_RECOVERING(env) || diff --git a/src/mp/mp_fmethod.c b/src/mp/mp_fmethod.c index 0773d470..41bd638c 100644 --- a/src/mp/mp_fmethod.c +++ b/src/mp/mp_fmethod.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -38,10 +38,12 @@ __memp_fcreate_pp(dbenv, retp, flags) env = dbenv->env; /* Validate arguments. */ - if ((ret = __db_fchk(env, "DB_ENV->memp_fcreate", flags, 0)) != 0) + if ((ret = + __db_fchk(env, "DB_ENV->memp_fcreate", flags, DB_VERIFY)) != 0) return (ret); - if (REP_ON(env)) { + /* We look the other way on mpool operations if we're verifying. */ + if (REP_ON(env) && !LF_ISSET(DB_VERIFY)) { __db_errx(env, DB_STR("3029", "DB_ENV->memp_fcreate: method not permitted when replication is configured")); return (EINVAL); diff --git a/src/mp/mp_fopen.c b/src/mp/mp_fopen.c index 282025c1..ef7f886a 100644 --- a/src/mp/mp_fopen.c +++ b/src/mp/mp_fopen.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -47,15 +47,18 @@ __memp_fopen_pp(dbmfp, path, flags, mode, pagesize) return (ret); /* - * Require a non-zero, power-of-two pagesize, smaller than the - * clear length. + * Require a power-of-two pagesize, smaller than the clear length. A + * non-zero page size is only allowed if opening an existing, in-memory + * db. */ - if (pagesize == 0 || !POWER_OF_TWO(pagesize)) { + if (!POWER_OF_TWO(pagesize) || + (pagesize == 0 && (LF_ISSET(DB_CREATE) || + !FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)))) { __db_errx(env, DB_STR("3033", "DB_MPOOLFILE->open: page sizes must be a power-of-2")); return (EINVAL); } - if (dbmfp->clear_len > pagesize) { + if (pagesize != 0 && dbmfp->clear_len > pagesize) { __db_errx(env, DB_STR("3034", "DB_MPOOLFILE->open: clear length larger than page size")); return (EINVAL); @@ -82,6 +85,12 @@ __memp_fopen_pp(dbmfp, path, flags, mode, pagesize) return (ret); } +/* + * Generate the number of user opens. If there is no backing file + * there is an extra open count to keep the in memory db around. + */ +#define MFP_OPEN_CNT(mfp) ((mfp)->mpf_cnt - ((mfp)->neutral_cnt + \ + (u_int32_t)(mfp)->no_backing_file)) /* * __memp_fopen -- * DB_MPOOLFILE->open. @@ -109,7 +118,7 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) size_t maxmap; db_pgno_t last_pgno; u_int32_t bucket, mbytes, bytes, oflags, pagesize; - int refinc, ret; + int refinc, ret, isdir; char *rpath; /* If this handle is already open, return. */ @@ -122,7 +131,7 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) mp = dbmp->reginfo[0].primary; alloc_mfp = NULL; mbytes = bytes = 0; - refinc = ret = 0; + refinc = ret = isdir = 0; rpath = NULL; /* @@ -147,6 +156,33 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) if (path == NULL) goto alloc; + /* + * If fileid is not set but the file exists on the disk, + * we try to use __os_fileid to set it. We do this + * because we want to use the fileid to check if we have + * opened the mpoolfile as early as possible. + * + * Note: DB layer always calls __memp_fopen with fileid set, + * so this is only for using mpool api to open a file. + */ + + if (!FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) && + !F_ISSET(dbmfp, MP_FILEID_SET)) { + if ((ret = __db_appname(env, + DB_APP_DATA, path, dirp, &rpath)) != 0) + goto err; + ret = __os_exists(env, rpath, &isdir); + if (ret == 0 && isdir) { + ret = EINVAL; + goto err; + } else if (ret == 0) { + if ((ret = __os_fileid(env, + rpath, 0, dbmfp->fileid)) != 0) + goto err; + F_SET(dbmfp, MP_FILEID_SET); + } + } + /* * Hash to the proper file table entry and walk it. * @@ -165,27 +201,40 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) * we ensure that it's never found again, and we create * a new entry for the current request. */ + if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) || + F_ISSET(dbmfp, MP_FILEID_SET)) { + if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) + bucket = FNBUCKET(path, strlen(path)); + else + bucket = FNBUCKET(dbmfp->fileid, + DB_FILE_ID_LEN); - if (FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE)) - bucket = FNBUCKET(path, strlen(path)); - else - bucket = FNBUCKET(dbmfp->fileid, DB_FILE_ID_LEN); - hp += bucket; - - /* - * If we are passed a FILEID find the MPOOLFILE and inc - * its ref count. That way it cannot go away while we - * open it. - */ - if (F_ISSET(dbmfp, MP_FILEID_SET)) { + hp += bucket; + /* + * If we find the MPOOLFILE and inc its ref count. + * That way it cannot go away while we open it. + */ MUTEX_LOCK(env, hp->mtx_hash); ret = - __memp_mpf_find(env, dbmfp, hp, path, flags,&mfp); + __memp_mpf_find(env, dbmfp, hp, path, flags, &mfp); + if (ret == 0 && mfp != NULL) { + refinc = 1; + + if (LF_ISSET(DB_MULTIVERSION)) { + if (MFP_OPEN_CNT(mfp) > (u_int32_t) + (LF_ISSET(DB_RDONLY) ? 0 : 1) && + atomic_read( + &mfp->multiversion) == 0) { + MUTEX_UNLOCK(env, hp->mtx_hash); + goto mvcc_err; + } + atomic_inc(env, &mfp->multiversion); + F_SET(dbmfp, MP_MULTIVERSION); + } + } MUTEX_UNLOCK(env, hp->mtx_hash); if (ret != 0) goto err; - if (mfp != NULL) - refinc = 1; } } else { /* @@ -195,7 +244,31 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) */ MUTEX_LOCK(env, mfp->mutex); if (!mfp->deadfile) { + if (LF_ISSET(DB_MULTIVERSION)) { + MUTEX_UNLOCK(env, mfp->mutex); + if (MFP_OPEN_CNT(mfp) > 0 && + atomic_read(&mfp->multiversion) == 0) { +mvcc_err: __db_errx(env, DB_STR("3041", +"DB_MULTIVERSION cannot be specified on a database file which is already open")); + ret = EINVAL; + goto err; + } + + atomic_inc(env, &mfp->multiversion); + F_SET(dbmfp, MP_MULTIVERSION); + } + /* + * Increment the reference count. We also track + * those references that don't effect the ability + * to convert the handle to either NOT_DURABLE or + * MVCC. These are readonly opens or threads that + * are using the handle just to flush a buffer. + */ ++mfp->mpf_cnt; + if (LF_ISSET(DB_FLUSH | DB_RDONLY)) + ++mfp->neutral_cnt; + if (LF_ISSET(DB_FLUSH)) + F_SET(dbmfp, MP_FOR_FLUSH); refinc = 1; } MUTEX_UNLOCK(env, mfp->mutex); @@ -206,10 +279,16 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) * the file to flush a buffer races with the Db::remove method. * The error will be ignored, so don't output an error message. */ - if (mfp->deadfile) - return (EINVAL); + if (mfp->deadfile) { + ret = EINVAL; + goto err; + } } + if (LF_ISSET(DB_RDONLY)) + F_SET(dbmfp, MP_READONLY); + if (LF_ISSET(DB_FLUSH)) + F_SET(dbmfp, MP_FLUSH); /* * Share the underlying file descriptor if that's possible. */ @@ -222,6 +301,7 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) ++tmp_dbmfp->fhp->ref; dbmfp->fhp = tmp_dbmfp->fhp; dbmfp->addr = tmp_dbmfp->addr; + dbmfp->len = tmp_dbmfp->len; break; } MUTEX_UNLOCK(env, dbmp->mutex); @@ -240,10 +320,8 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) oflags |= DB_OSO_CREATE; if (LF_ISSET(DB_DIRECT)) oflags |= DB_OSO_DIRECT; - if (LF_ISSET(DB_RDONLY)) { - F_SET(dbmfp, MP_READONLY); + if (LF_ISSET(DB_RDONLY)) oflags |= DB_OSO_RDONLY; - } /* * XXX @@ -266,12 +344,20 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) * the path name stored in the region, __memp_nameop may * be simultaneously renaming the file. */ + + ret = 0; if (mfp != NULL) { MPOOL_SYSTEM_LOCK(env); path = R_ADDR(dbmp->reginfo, mfp->path_off); + if (rpath != NULL) { + __os_free(env, rpath); + rpath = NULL; + } } - if ((ret = __db_appname(env, - DB_APP_DATA, path, dirp, &rpath)) == 0) + if (rpath == NULL) + ret = __db_appname(env, + DB_APP_DATA, path, dirp, &rpath); + if (ret == 0) ret = __os_open(env, rpath, (u_int32_t)pagesize, oflags, mode, &dbmfp->fhp); if (mfp != NULL) @@ -305,6 +391,8 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) * truncated file; if the file size is not a multiple of the * page size, round down to a page, we'll take care of the * partial page outside the mpool system. + * + * Pagesize of 0 is only allowed for in-mem dbs. */ DB_ASSERT(env, pagesize != 0); if (bytes % pagesize != 0) { @@ -330,6 +418,8 @@ __memp_fopen(dbmfp, mfp, path, dirp, flags, mode, pgsize) __os_fileid(env, rpath, 0, dbmfp->fileid)) != 0) goto err; F_SET(dbmfp, MP_FILEID_SET); + bucket = FNBUCKET(dbmfp->fileid, DB_FILE_ID_LEN); + hp += bucket; goto alloc; } } @@ -353,6 +443,7 @@ check: MUTEX_LOCK(env, hp->mtx_hash); alloc_mfp = NULL; SH_TAILQ_INSERT_HEAD(&hp->hash_bucket, mfp, q, __mpoolfile); } else if (mfp != NULL) { + refinc = 1; /* * Some things about a file cannot be changed: the clear length, * page size, or LSN location. However, if this is an attempt @@ -383,6 +474,15 @@ check: MUTEX_LOCK(env, hp->mtx_hash); goto err; } } + if (mfp != NULL && LF_ISSET(DB_MULTIVERSION)) { + if (MFP_OPEN_CNT(mfp) > 1 && + atomic_read(&mfp->multiversion) == 0) { + MUTEX_UNLOCK(env, hp->mtx_hash); + goto mvcc_err; + } + atomic_inc(env, &mfp->multiversion); + F_SET(dbmfp, MP_MULTIVERSION); + } MUTEX_UNLOCK(env, hp->mtx_hash); if (alloc_mfp != NULL) { @@ -402,18 +502,7 @@ check: MUTEX_LOCK(env, hp->mtx_hash); goto err; } -alloc: /* - * Get the file ID if we weren't given one. Generated file - * ID's don't use timestamps, otherwise there'd be no - * chance of any other process joining the party. - */ - if (path != NULL && - !FLD_ISSET(dbmfp->config_flags, DB_MPOOL_NOFILE) && - !F_ISSET(dbmfp, MP_FILEID_SET) && (ret = - __os_fileid(env, rpath, 0, dbmfp->fileid)) != 0) - goto err; - - if ((ret = __memp_mpf_alloc(dbmp, +alloc: if ((ret = __memp_mpf_alloc(dbmp, dbmfp, path, pagesize, flags, &alloc_mfp)) != 0) goto err; @@ -440,6 +529,12 @@ alloc: /* goto check; mfp = alloc_mfp; + + if (LF_ISSET(DB_MULTIVERSION)) { + atomic_inc(env, &mfp->multiversion); + F_SET(dbmfp, MP_MULTIVERSION); + } + /* This is a temp, noone else can see it, put it at the end. */ MUTEX_LOCK(env, hp->mtx_hash); SH_TAILQ_INSERT_TAIL(&hp->hash_bucket, mfp, q); @@ -465,11 +560,6 @@ have_mfp: } } - if (LF_ISSET(DB_MULTIVERSION)) { - atomic_inc(env, &mfp->multiversion); - F_SET(dbmfp, MP_MULTIVERSION); - } - /* * All paths to here have initialized the mfp variable to reference * the selected (or allocated) MPOOLFILE. @@ -551,6 +641,10 @@ err: if (refinc) { */ MUTEX_LOCK(env, mfp->mutex); --mfp->mpf_cnt; + if (LF_ISSET(DB_FLUSH | DB_RDONLY)) { + DB_ASSERT(env, mfp->neutral_cnt != 0); + --mfp->neutral_cnt; + } MUTEX_UNLOCK(env, mfp->mutex); } @@ -640,6 +734,10 @@ __memp_mpf_find(env, dbmfp, hp, path, flags, mfpp) continue; } ++mfp->mpf_cnt; + if (LF_ISSET(DB_FLUSH | DB_RDONLY)) + ++mfp->neutral_cnt; + if (LF_ISSET(DB_FLUSH)) + F_SET(dbmfp, MP_FOR_FLUSH); MUTEX_UNLOCK(env, mfp->mutex); /* Initialize any fields that are not yet set. */ @@ -679,6 +777,10 @@ __memp_mpf_alloc(dbmp, dbmfp, path, pagesize, flags, retmfp) goto err; memset(mfp, 0, sizeof(MPOOLFILE)); mfp->mpf_cnt = 1; + if (LF_ISSET(DB_FLUSH | DB_RDONLY)) + mfp->neutral_cnt = 1; + if (LF_ISSET(DB_FLUSH)) + F_SET(dbmfp, MP_FOR_FLUSH); mfp->ftype = dbmfp->ftype; mfp->pagesize = pagesize; mfp->lsn_off = dbmfp->lsn_offset; @@ -752,6 +854,11 @@ __memp_mpf_alloc(dbmp, dbmfp, path, pagesize, flags, retmfp) if ((ret = __mutex_alloc(env, MTX_MPOOLFILE_HANDLE, 0, &mfp->mutex)) != 0) goto err; +#ifndef HAVE_ATOMICFILEREAD + if ((ret = __mutex_alloc(env, + MTX_MPOOLFILE_HANDLE, DB_MUTEX_SHARED, &mfp->mtx_write)) != 0) + goto err; +#endif *retmfp = mfp; err: return (ret); @@ -845,7 +952,7 @@ __memp_fclose(dbmfp, flags) } /* Discard any mmap information. */ - if (dbmfp->addr != NULL && + if (dbmfp->addr != NULL && dbmfp->fhp != NULL && (ret = __os_unmapfile(env, dbmfp->addr, dbmfp->len)) != 0) __db_err(env, ret, "%s", __memp_fn(dbmfp)); @@ -890,6 +997,12 @@ __memp_fclose(dbmfp, flags) MUTEX_LOCK(env, mfp->mutex); if (F_ISSET(dbmfp, MP_MULTIVERSION)) atomic_dec(env, &mfp->multiversion); + if (F_ISSET(dbmfp, MP_READONLY) || + (LF_ISSET(DB_FLUSH) && F_ISSET(dbmfp, MP_FOR_FLUSH))) { + DB_ASSERT(env, mfp->neutral_cnt != 0); + --mfp->neutral_cnt; + } + DB_ASSERT(env, mfp->neutral_cnt < mfp->mpf_cnt); if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) { if (LF_ISSET(DB_MPOOL_DISCARD) || F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) { @@ -907,7 +1020,7 @@ __memp_fclose(dbmfp, flags) __os_free(env, rpath); } } - if (mfp->mpf_cnt == 0) { + if (MFP_OPEN_CNT(mfp) == 0) { F_CLR(mfp, MP_NOT_DURABLE); F_SET(mfp, MP_DURABLE_UNKNOWN); } @@ -986,6 +1099,10 @@ __memp_mf_discard(dbmp, mfp, hp_locked) MUTEX_UNLOCK(env, mfp->mutex); if ((t_ret = __mutex_free(env, &mfp->mutex)) != 0 && ret == 0) ret = t_ret; +#ifndef HAVE_ATOMICFILEREAD + if ((ret = __mutex_free(env, &mfp->mtx_write)) != 0 && ret == 0) + ret = t_ret; +#endif /* * Lock the bucket and delete from the list of MPOOLFILEs. diff --git a/src/mp/mp_fput.c b/src/mp/mp_fput.c index 03ed2c3a..7a900fd0 100644 --- a/src/mp/mp_fput.c +++ b/src/mp/mp_fput.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_fset.c b/src/mp/mp_fset.c index 3482dafa..1129853f 100644 --- a/src/mp/mp_fset.c +++ b/src/mp/mp_fset.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_method.c b/src/mp/mp_method.c index 7d6a55d5..7afae248 100644 --- a/src/mp/mp_method.c +++ b/src/mp/mp_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_mvcc.c b/src/mp/mp_mvcc.c index 1633ccc3..47531528 100644 --- a/src/mp/mp_mvcc.c +++ b/src/mp/mp_mvcc.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_region.c b/src/mp/mp_region.c index 65d43a2f..07134de7 100644 --- a/src/mp/mp_region.c +++ b/src/mp/mp_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -567,7 +567,7 @@ __memp_env_refresh(env) not_priv: /* Discard DB_MPOOLFILEs. */ while ((dbmfp = TAILQ_FIRST(&dbmp->dbmfq)) != NULL) - if ((t_ret = __memp_fclose(dbmfp, 0)) != 0 && ret == 0) + if ((t_ret = __memp_fclose(dbmfp, DB_FLUSH)) != 0 && ret == 0) ret = t_ret; /* Discard DB_MPREGs. */ diff --git a/src/mp/mp_register.c b/src/mp/mp_register.c index 76781546..dc7015a7 100644 --- a/src/mp/mp_register.c +++ b/src/mp/mp_register.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_resize.c b/src/mp/mp_resize.c index 727ae020..97719554 100644 --- a/src/mp/mp_resize.c +++ b/src/mp/mp_resize.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mp/mp_stat.c b/src/mp/mp_stat.c index b3679994..246b44d7 100644 --- a/src/mp/mp_stat.c +++ b/src/mp/mp_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -521,6 +521,10 @@ __memp_print_stats(env, flags) __db_dl(env, "Pages written from the cache to the backing file", (u_long)(*tfsp)->st_page_out); + if ((*tfsp)->st_backup_spins != 0) + __db_dl(env, + "Spins while trying to backup the file", + (u_long)(*tfsp)->st_backup_spins); } __os_ufree(env, fsp); @@ -653,6 +657,7 @@ __memp_print_files(env, mfp, argp, countp, flags) MUTEX_LOCK(env, mfp->mutex); STAT_ULONG("Revision count", mfp->revision); STAT_ULONG("Reference count", mfp->mpf_cnt); + STAT_ULONG("Sync/read only open count", mfp->neutral_cnt); STAT_ULONG("Block count", mfp->block_cnt); STAT_ULONG("Last page number", mfp->last_pgno); STAT_ULONG("Original last page number", mfp->orig_last_pgno); diff --git a/src/mp/mp_sync.c b/src/mp/mp_sync.c index 2e197d58..fa06b1d4 100644 --- a/src/mp/mp_sync.c +++ b/src/mp/mp_sync.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -539,10 +539,6 @@ __memp_sync_int(env, dbmfp, trickle_max, flags, wrote_totalp, interruptedp) continue; } - /* we will dispose of this buffer. */ - --remaining; - bharray[i].track_hp = NULL; - /* * If we've switched files, check to see if we're configured * to close file descriptors. @@ -568,6 +564,12 @@ __memp_sync_int(env, dbmfp, trickle_max, flags, wrote_totalp, interruptedp) ++wrote_cnt; ++wrote_total; } else { + /* The buffer is being backed up, try again. */ + if (t_ret == EAGAIN) { + atomic_dec(env, &bhp->ref); + MUTEX_UNLOCK(env, bhp->mtx_buf); + continue; + } if (ret == 0) ret = t_ret; __db_errx(env, DB_STR_A("3027", @@ -577,6 +579,10 @@ __memp_sync_int(env, dbmfp, trickle_max, flags, wrote_totalp, interruptedp) } } + /* we disposed of this buffer. */ + --remaining; + bharray[i].track_hp = NULL; + /* Discard our buffer reference. */ DB_ASSERT(env, atomic_read(&bhp->ref) > 0); atomic_dec(env, &bhp->ref); @@ -674,6 +680,7 @@ __memp_sync_file(env, mfp, argp, countp, flags) return (0); } ++mfp->mpf_cnt; + ++mfp->neutral_cnt; MUTEX_UNLOCK(env, mfp->mutex); /* @@ -753,6 +760,8 @@ __memp_sync_file(env, mfp, argp, countp, flags) ret = t_ret; --mfp->mpf_cnt; + DB_ASSERT(env, mfp->neutral_cnt != 0); + --mfp->neutral_cnt; /* Unlock the MPOOLFILE. */ MUTEX_UNLOCK(env, mfp->mutex); @@ -919,7 +928,7 @@ retry: MUTEX_LOCK(env, dbmp->mutex); if ((ret = __os_fsync(env, dbmfp->fhp)) != 0) return (ret); } - if ((ret = __memp_fclose(dbmfp, 0)) != 0) + if ((ret = __memp_fclose(dbmfp, DB_FLUSH)) != 0) return (ret); goto retry; } diff --git a/src/mp/mp_trickle.c b/src/mp/mp_trickle.c index abb4519e..fba528b3 100644 --- a/src/mp/mp_trickle.c +++ b/src/mp/mp_trickle.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mutex/mut_alloc.c b/src/mutex/mut_alloc.c index a15deab2..5df3de53 100644 --- a/src/mutex/mut_alloc.c +++ b/src/mutex/mut_alloc.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mutex/mut_failchk.c b/src/mutex/mut_failchk.c index 8529ad9e..1425389f 100644 --- a/src/mutex/mut_failchk.c +++ b/src/mutex/mut_failchk.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -27,10 +27,13 @@ __mut_failchk(env) db_mutex_t i; int ret; char buf[DB_THREADID_STRLEN]; + db_threadid_t unused; if (F_ISSET(env, ENV_PRIVATE)) return (0); + DB_THREADID_INIT(unused); + dbenv = env->dbenv; mtxmgr = env->mutex_handle; mtxregion = mtxmgr->reginfo.primary; @@ -53,12 +56,12 @@ __mut_failchk(env) * we cannot reclaim the mutex if the process is still alive. */ if (dbenv->is_alive( - dbenv, mutexp->pid, 0, DB_MUTEX_PROCESS_ONLY)) + dbenv, mutexp->pid, unused, DB_MUTEX_PROCESS_ONLY)) continue; __db_msg(env, DB_STR_A("2017", "Freeing mutex for process: %s", "%s"), - dbenv->thread_id_string(dbenv, mutexp->pid, 0, buf)); + dbenv->thread_id_string(dbenv, mutexp->pid, unused, buf)); /* Unlock and free the mutex. */ if (F_ISSET(mutexp, DB_MUTEX_LOCKED)) diff --git a/src/mutex/mut_fcntl.c b/src/mutex/mut_fcntl.c index e22282f5..0694aa59 100644 --- a/src/mutex/mut_fcntl.c +++ b/src/mutex/mut_fcntl.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mutex/mut_method.c b/src/mutex/mut_method.c index dda4b67b..cb666082 100644 --- a/src/mutex/mut_method.c +++ b/src/mutex/mut_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mutex/mut_pthread.c b/src/mutex/mut_pthread.c index 944e26cb..1ec4fb9c 100644 --- a/src/mutex/mut_pthread.c +++ b/src/mutex/mut_pthread.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -574,7 +574,8 @@ __db_hybrid_mutex_suspend(env, mutex, timespec, exclusive) MUTEX_MEMBAR(mutexp->wait); while (exclusive ? MUTEXP_IS_BUSY(mutexp) : atomic_read(&mutexp->sharecount) == MUTEX_SHARE_ISEXCLUSIVE) { - t_ret = __db_pthread_mutex_condwait(env, mutex, mutexp, timespec); + t_ret = __db_pthread_mutex_condwait(env, + mutex, mutexp, timespec); if (t_ret != 0) { if (t_ret == DB_TIMEOUT) break; diff --git a/src/mutex/mut_region.c b/src/mutex/mut_region.c index 4e022973..26ae0a03 100644 --- a/src/mutex/mut_region.c +++ b/src/mutex/mut_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -460,9 +460,8 @@ __mutex_resource_return(env, infop) (size -= sizeof(*mutexp)) < sizeof(*mutexp)) { mutexp = __env_get_chunk(&mtxmgr->reginfo, &chunk, &size); - mutexp = ALIGNP_INC(mutexp, - mtxregion->stat.st_mutex_align); } + mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } env->mutex_handle = orig_handle; } diff --git a/src/mutex/mut_stat.c b/src/mutex/mut_stat.c index 84bf5707..b64207fa 100644 --- a/src/mutex/mut_stat.c +++ b/src/mutex/mut_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -190,9 +190,8 @@ __mutex_print_summary(env) (size -= sizeof(*mutexp)) < sizeof(*mutexp)) { mutexp = __env_get_chunk(&mtxmgr->reginfo, &chunk, &size); - mutexp = - ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } + mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } __db_msg(env, "Mutex counts"); __db_msg(env, "%d\tUnallocated", counts[0]); @@ -303,30 +302,29 @@ __mutex_print_all(env, flags) } else mutexp = MUTEXP_SET(env, 1); for (i = 1; i <= mtxregion->stat.st_mutex_cnt; ++i) { - if (!F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) - continue; + if (F_ISSET(mutexp, DB_MUTEX_ALLOCATED)) { + __db_msgadd(env, mbp, "%5lu\t", (u_long)i); - __db_msgadd(env, mbp, "%5lu\t", (u_long)i); + __mutex_print_debug_stats(env, mbp, + F_ISSET(env, ENV_PRIVATE) ? + (db_mutex_t)mutexp : i, flags); - __mutex_print_debug_stats(env, mbp, - F_ISSET(env, ENV_PRIVATE) ? (db_mutex_t)mutexp : i, flags); + if (mutexp->alloc_id != 0) + __db_msgadd(env, mbp, + ", %s", __mutex_print_id(mutexp->alloc_id)); - if (mutexp->alloc_id != 0) - __db_msgadd(env, - mbp, ", %s", __mutex_print_id(mutexp->alloc_id)); + __db_prflags(env, mbp, mutexp->flags, fn, " (", ")"); - __db_prflags(env, mbp, mutexp->flags, fn, " (", ")"); - - DB_MSGBUF_FLUSH(env, mbp); + DB_MSGBUF_FLUSH(env, mbp); + } mutexp++; if (F_ISSET(env, ENV_PRIVATE) && (size -= sizeof(*mutexp)) < sizeof(*mutexp)) { mutexp = __env_get_chunk(&mtxmgr->reginfo, &chunk, &size); - mutexp = - ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } + mutexp = ALIGNP_INC(mutexp, mtxregion->stat.st_mutex_align); } return (0); @@ -463,6 +461,7 @@ __mutex_print_id(alloc_id) case MTX_ATOMIC_EMULATION: return ("atomic emulation"); case MTX_DB_HANDLE: return ("db handle"); case MTX_ENV_DBLIST: return ("env dblist"); + case MTX_ENV_EXCLDBLIST: return ("env exclusive dblist"); case MTX_ENV_HANDLE: return ("env handle"); case MTX_ENV_REGION: return ("env region"); case MTX_LOCK_REGION: return ("lock region"); diff --git a/src/mutex/mut_stub.c b/src/mutex/mut_stub.c index 6b345502..61ecc80c 100644 --- a/src/mutex/mut_stub.c +++ b/src/mutex/mut_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/mutex/mut_tas.c b/src/mutex/mut_tas.c index cab86510..0899d237 100644 --- a/src/mutex/mut_tas.c +++ b/src/mutex/mut_tas.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -377,7 +377,7 @@ loop: /* Attempt to acquire the resource for N spins. */ } MEMBAR_ENTER(); - /* For shared lactches the threadid is the last requestor's id. + /* For shared latches the threadid is the last requestor's id. */ dbenv->thread_id(dbenv, &mutexp->pid, &mutexp->tid); diff --git a/src/mutex/mut_win32.c b/src/mutex/mut_win32.c index a4ddcce6..07d5a8dd 100644 --- a/src/mutex/mut_win32.c +++ b/src/mutex/mut_win32.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -71,7 +71,7 @@ static __inline int get_handle(env, mutexp, eventp) * __db_win32_mutex_lock_int * Internal function to lock a win32 mutex * - * If the wait paramter is 0, this function will return DB_LOCK_NOTGRANTED + * If the wait parameter is 0, this function will return DB_LOCK_NOTGRANTED * rather than wait. * */ diff --git a/src/mutex/test_mutex.c b/src/mutex/test_mutex.c index b0aa6418..24c18016 100644 --- a/src/mutex/test_mutex.c +++ b/src/mutex/test_mutex.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * Standalone mutex tester for Berkeley DB mutexes. * diff --git a/src/mutex/uts4_cc.s b/src/mutex/uts4_cc.s index b4b4e358..4f59e9c8 100644 --- a/src/mutex/uts4_cc.s +++ b/src/mutex/uts4_cc.s @@ -1,6 +1,6 @@ / See the file LICENSE for redistribution information. / - / Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + / Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. / / $Id$ / diff --git a/src/os/os_abort.c b/src/os/os_abort.c index 191ed819..68b4bc05 100644 --- a/src/os/os_abort.c +++ b/src/os/os_abort.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_abs.c b/src/os/os_abs.c index 0b49f8e4..4a1a5abd 100644 --- a/src/os/os_abs.c +++ b/src/os/os_abs.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_addrinfo.c b/src/os/os_addrinfo.c index ca30789d..205f41ec 100644 --- a/src/os/os_addrinfo.c +++ b/src/os/os_addrinfo.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_alloc.c b/src/os/os_alloc.c index 8f74e138..fb7bf109 100644 --- a/src/os/os_alloc.c +++ b/src/os/os_alloc.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_clock.c b/src/os/os_clock.c index 9457a516..25eeb704 100644 --- a/src/os/os_clock.c +++ b/src/os/os_clock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_config.c b/src/os/os_config.c index 7b8f5ee4..c455a349 100644 --- a/src/os/os_config.c +++ b/src/os/os_config.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_cpu.c b/src/os/os_cpu.c index 0bf8429f..6b7f9f1e 100644 --- a/src/os/os_cpu.c +++ b/src/os/os_cpu.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_ctime.c b/src/os/os_ctime.c index c6652108..3f656c32 100644 --- a/src/os/os_ctime.c +++ b/src/os/os_ctime.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_dir.c b/src/os/os_dir.c index 01349f1b..42bad194 100644 --- a/src/os/os_dir.c +++ b/src/os/os_dir.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_errno.c b/src/os/os_errno.c index 6884a9a6..a8219f90 100644 --- a/src/os/os_errno.c +++ b/src/os/os_errno.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_fid.c b/src/os/os_fid.c index 2caa1977..f2d80e25 100644 --- a/src/os/os_fid.c +++ b/src/os/os_fid.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_flock.c b/src/os/os_flock.c index 6f0fef85..904d5efe 100644 --- a/src/os/os_flock.c +++ b/src/os/os_flock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_fsync.c b/src/os/os_fsync.c index 7583be01..4b757b2c 100644 --- a/src/os/os_fsync.c +++ b/src/os/os_fsync.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_getenv.c b/src/os/os_getenv.c index d82fa511..05972112 100644 --- a/src/os/os_getenv.c +++ b/src/os/os_getenv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_handle.c b/src/os/os_handle.c index eaf08178..8ae9dc7f 100644 --- a/src/os/os_handle.c +++ b/src/os/os_handle.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_map.c b/src/os/os_map.c index 3be8ef11..0528f473 100644 --- a/src/os/os_map.c +++ b/src/os/os_map.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_mkdir.c b/src/os/os_mkdir.c index 16992e0f..800d445c 100644 --- a/src/os/os_mkdir.c +++ b/src/os/os_mkdir.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_open.c b/src/os/os_open.c index 23c5cb88..5090c8e1 100644 --- a/src/os/os_open.c +++ b/src/os/os_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_path.c b/src/os/os_path.c new file mode 100644 index 00000000..478fdf45 --- /dev/null +++ b/src/os/os_path.c @@ -0,0 +1,27 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +#include "db_config.h" + +#include "db_int.h" +/* + * __os_concat_path -- + * Concatenate two elements of a path. + * PUBLIC: int __os_concat_path __P((char *, + * PUBLIC: size_t, const char *, const char *)); + */ +int __os_concat_path(dest, destsize, path, file) + char *dest; + size_t destsize; + const char *path, *file; +{ + if ((size_t)snprintf(dest, destsize, + "%s%c%s", path, PATH_SEPARATOR[0], file) >= destsize) + return (EINVAL); + return (0); +} diff --git a/src/os/os_pid.c b/src/os/os_pid.c index 742534cd..b1b94d60 100644 --- a/src/os/os_pid.c +++ b/src/os/os_pid.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -40,18 +40,24 @@ __os_id(dbenv, pidp, tidp) *pidp = dbenv->env->pid_cache; } +/* + * When building on MinGW, we define both HAVE_PTHREAD_SELF and DB_WIN32, + * and we are using pthreads instead of Windows threads implementation. + * So here, we need to check the thread implementations before checking + * the platform. + */ if (tidp != NULL) { -#if defined(DB_WIN32) - *tidp = GetCurrentThreadId(); +#if defined(HAVE_PTHREAD_SELF) + *tidp = pthread_self(); #elif defined(HAVE_MUTEX_UI_THREADS) *tidp = thr_self(); -#elif defined(HAVE_PTHREAD_SELF) - *tidp = pthread_self(); +#elif defined(DB_WIN32) + *tidp = GetCurrentThreadId(); #else /* * Default to just getpid. */ - *tidp = 0; + DB_THREADID_INIT(*tidp); #endif } } diff --git a/src/os/os_rename.c b/src/os/os_rename.c index e56c32ac..63aac7bb 100644 --- a/src/os/os_rename.c +++ b/src/os/os_rename.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_root.c b/src/os/os_root.c index b1e48f4d..77e7a72c 100644 --- a/src/os/os_root.c +++ b/src/os/os_root.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_rpath.c b/src/os/os_rpath.c index 264a82b8..16f3e54c 100644 --- a/src/os/os_rpath.c +++ b/src/os/os_rpath.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_rw.c b/src/os/os_rw.c index b786344f..c0967514 100644 --- a/src/os/os_rw.c +++ b/src/os/os_rw.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_seek.c b/src/os/os_seek.c index eef9e3d8..4676d33a 100644 --- a/src/os/os_seek.c +++ b/src/os/os_seek.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_stack.c b/src/os/os_stack.c index f94f1071..037080f3 100644 --- a/src/os/os_stack.c +++ b/src/os/os_stack.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_stat.c b/src/os/os_stat.c index e22e0163..43c66075 100644 --- a/src/os/os_stat.c +++ b/src/os/os_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_tmpdir.c b/src/os/os_tmpdir.c index c9b6742e..06d35ba9 100644 --- a/src/os/os_tmpdir.c +++ b/src/os/os_tmpdir.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_truncate.c b/src/os/os_truncate.c index a37e787c..f559e9cb 100644 --- a/src/os/os_truncate.c +++ b/src/os/os_truncate.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_uid.c b/src/os/os_uid.c index 5ab6c34c..2e5c9f87 100644 --- a/src/os/os_uid.c +++ b/src/os/os_uid.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_unlink.c b/src/os/os_unlink.c index be262fe1..f9a0b688 100644 --- a/src/os/os_unlink.c +++ b/src/os/os_unlink.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/os/os_yield.c b/src/os/os_yield.c index ee86bd3c..f0e170f0 100644 --- a/src/os/os_yield.c +++ b/src/os/os_yield.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam.c b/src/qam/qam.c index 17911878..e81d4795 100644 --- a/src/qam/qam.c +++ b/src/qam/qam.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -842,7 +842,7 @@ dolock: if (!with_delete || inorder || retrying) { #ifdef QDEBUG if (DBC_LOGGING(dbc)) (void)__log_printf(env, - dbc->txn, "Queue S: %x %d %d", + dbc->txn, "Queue S: %x %u %u", dbc->locker ? dbc->locker->id : 0, cp->recno, first); #endif @@ -923,7 +923,7 @@ release_retry: /* Release locks and retry, if possible. */ #ifdef QDEBUG if (with_delete && DBC_LOGGING(dbc)) { (void)__log_printf(dbp->env, dbc->txn, - "Queue E: %x %d %d", + "Queue E: %x %u %u", dbc->locker ? dbc->locker->id : 0, cp->recno, first); } @@ -953,7 +953,7 @@ release_retry: /* Release locks and retry, if possible. */ is_first = 0; else if (first == cp->recno) /* we have verified that this record is gone. */ - first++; + QAM_INC_RECNO(first); if (QAM_BEFORE_FIRST(meta, cp->recno) && DONT_NEED_LOCKS(dbc)) flags = DB_FIRST; @@ -1000,7 +1000,7 @@ release_retry: /* Release locks and retry, if possible. */ if (DBC_LOGGING(dbc)) { #ifdef QDEBUG (void)__log_printf(dbp->env, dbc->txn, - "Queue I: %x %d %d %d", + "Queue I: %x %u %u %u", dbc->locker ? dbc->locker->id : 0, cp->recno, first, meta->cur_recno); #endif @@ -1152,7 +1152,7 @@ release_retry: /* Release locks and retry, if possible. */ #ifdef QDEBUG if (DBC_LOGGING(dbc)) (void)__log_printf(env, - dbc->txn, "Queue D: %x %d %d %d", + dbc->txn, "Queue D: %x %u %u %u", dbc->locker ? dbc->locker->id : 0, cp->recno, first, meta->first_recno); #endif @@ -1277,7 +1277,7 @@ __qam_consume(dbc, meta, first) #ifdef QDEBUG if (DBC_LOGGING(dbc)) (void)__log_printf(dbp->env, dbc->txn, - "Queue R: %x %d %d %d", + "Queue R: %x %u %u %u", dbc->locker ? dbc->locker->id : 0, cp->pgno, first, meta->first_recno); #endif @@ -1342,7 +1342,7 @@ done: if (DBC_LOGGING(dbc)) { #ifdef QDEBUG (void)__log_printf(dbp->env, dbc->txn, - "Queue M: %x %d %d %d", + "Queue M: %x %u %u %u", dbc->locker ? dbc->locker->id : 0, cp->recno, first, meta->first_recno); #endif diff --git a/src/qam/qam.src b/src/qam/qam.src index 03fb912c..a8e2e4e0 100644 --- a/src/qam/qam.src +++ b/src/qam/qam.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_conv.c b/src/qam/qam_conv.c index 96209362..beb7c973 100644 --- a/src/qam/qam_conv.c +++ b/src/qam/qam_conv.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_files.c b/src/qam/qam_files.c index b94beef2..e9a9ff07 100644 --- a/src/qam/qam_files.c +++ b/src/qam/qam_files.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -891,3 +891,49 @@ __qam_lsn_reset(dbp, ip) __os_free(dbp->env, filelist); return (ret); } + +/* + * __qam_backup_extents-- + * Routine to safely copy the active queue extents of a database. + * PUBLIC: int __qam_backup_extents __P((DB *, + * PUBLIC: DB_THREAD_INFO *, const char *, u_int32_t)); + */ +int +__qam_backup_extents(dbp, ip, target, flags) + DB *dbp; + DB_THREAD_INFO *ip; + const char *target; + u_int32_t flags; +{ + DB_FH *filep; + QUEUE *qp; + QUEUE_FILELIST *fp, *filelist; + int ret, t_ret; + char buf[DB_MAXPATHLEN]; + void *handle; + + if ((ret = __qam_gen_filelist(dbp, ip, &filelist)) != 0) + return (ret); + + if (filelist == NULL) + return (0); + + qp = dbp->q_internal; + + for (fp = filelist; fp->mpf != NULL; fp++) { + QAM_EXNAME(qp, fp->id, buf, sizeof(buf)); + if ((ret = __memp_backup_open(dbp->dbenv->env, + fp->mpf, buf, target, flags, &filep, &handle)) == 0) + ret = __memp_backup_mpf(dbp->dbenv->env, fp->mpf, ip, + 0, fp->mpf->mfp->last_pgno, filep, handle, flags); + if ((t_ret = __memp_backup_close(dbp->dbenv->env, + fp->mpf, buf, filep, handle)) != 0 && ret == 0) + ret = t_ret; + if (ret != 0) + break; + } + + __os_free(dbp->env, filelist); + + return (ret); +} diff --git a/src/qam/qam_method.c b/src/qam/qam_method.c index 681cede9..0867e5dd 100644 --- a/src/qam/qam_method.c +++ b/src/qam/qam_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_open.c b/src/qam/qam_open.c index e619fa2f..69f6cb75 100644 --- a/src/qam/qam_open.c +++ b/src/qam/qam_open.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_rec.c b/src/qam/qam_rec.c index c6ab9de6..c9ff6c83 100644 --- a/src/qam/qam_rec.c +++ b/src/qam/qam_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_stat.c b/src/qam/qam_stat.c index 7ee43435..15c41bb5 100644 --- a/src/qam/qam_stat.c +++ b/src/qam/qam_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_stub.c b/src/qam/qam_stub.c index 6879961b..f5140079 100644 --- a/src/qam/qam_stub.c +++ b/src/qam/qam_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_upgrade.c b/src/qam/qam_upgrade.c index 3ea48238..ac96c889 100644 --- a/src/qam/qam_upgrade.c +++ b/src/qam/qam_upgrade.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/qam/qam_verify.c b/src/qam/qam_verify.c index 295f9d83..af5ab5db 100644 --- a/src/qam/qam_verify.c +++ b/src/qam/qam_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -59,6 +59,18 @@ __qam_vrfy_meta(dbp, vdp, meta, pgno, flags) "Page %lu: queue databases must be one-per-file", "%lu"), (u_long)pgno)); + /* + * We have already checked the common fields in __db_vrfy_pagezero. + * However, we used the on-disk metadata page, it may have been stale. + * We now have the page from mpool, so check that. + */ + if ((ret = __db_vrfy_meta(dbp, vdp, &meta->dbmeta, pgno, flags)) != 0) { + if (ret == DB_VERIFY_BAD) + isbad = 1; + else + goto err; + } + /* * Because the metapage pointers are rolled forward by * aborting transactions, the extent of the queue may @@ -136,25 +148,30 @@ __qam_vrfy_meta(dbp, vdp, meta, pgno, flags) __os_free(env, buf); buf = NULL; - len = strlen(QUEUE_EXTENT_HEAD) + strlen(qp->name) + 1; - if ((ret = __os_malloc(env, len, &buf)) != 0) - goto err; - len = (size_t)snprintf(buf, len, QUEUE_EXTENT_HEAD, qp->name); - for (i = nextents = 0; i < count; i++) { - if (strncmp(names[i], buf, len) == 0) { - /* Only save extents out of bounds. */ - extid = (db_pgno_t)strtoul(&names[i][len], NULL, 10); - if (qp->page_ext != 0 && - (last > first ? - (extid >= first && extid <= last) : - (extid >= first || extid <= last))) - continue; - if (extents == NULL && (ret = __os_malloc( - env, (size_t)(count - i) * sizeof(extid), - &extents)) != 0) - goto err; - extents[nextents] = extid; - nextents++; + /* In-memory dbs cannot have extents. */ + nextents = 0; + if (!F_ISSET(dbp, DB_AM_INMEM)) { + len = strlen(QUEUE_EXTENT_HEAD) + strlen(qp->name) + 1; + if ((ret = __os_malloc(env, len, &buf)) != 0) + goto err; + len = (size_t)snprintf(buf, len, QUEUE_EXTENT_HEAD, qp->name); + for (i = 0; i < count; i++) { + if (strncmp(names[i], buf, len) == 0) { + /* Only save extents out of bounds. */ + extid = (db_pgno_t)strtoul( + &names[i][len], NULL, 10); + if (qp->page_ext != 0 && + (last > first ? + (extid >= first && extid <= last) : + (extid >= first || extid <= last))) + continue; + if (extents == NULL && (ret = __os_malloc( + env, (size_t)(count - i) * sizeof(extid), + &extents)) != 0) + goto err; + extents[nextents] = extid; + nextents++; + } } } if (nextents > 0) @@ -382,7 +399,7 @@ __qam_vrfy_structure(dbp, vdp, flags) (ret = __db_vrfy_getpageinfo(vdp, i, &pip)) != 0) return (ret); if (!F_ISSET(pip, VRFY_IS_ALLZEROES) && - pip->type != P_QAMDATA) { + pip->type != P_QAMDATA && !F_ISSET(pip, VRFY_NONEXISTENT)) { EPRINT((dbp->env, DB_STR_A("1153", "Page %lu: queue database page of incorrect type %lu", "%lu %lu"), (u_long)i, (u_long)pip->type)); diff --git a/src/rep/mlease.html b/src/rep/mlease.html index 28bcd50c..7d44b465 100644 --- a/src/rep/mlease.html +++ b/src/rep/mlease.html @@ -1,5 +1,5 @@ - + lsn.file, bp); DB_NTOHL_COPYIN(env, argp->lsn.offset, bp); DB_NTOHL_COPYIN(env, argp->bulkdata.size, bp); - argp->bulkdata.data = bp; + if (argp->bulkdata.size == 0) + argp->bulkdata.data = NULL; + else + argp->bulkdata.data = bp; needed += (size_t)argp->bulkdata.size; if (max < needed) goto too_few; @@ -207,7 +210,8 @@ __rep_fileinfo_marshal(env, version, argp, bp, max, lenp) if (max < __REP_FILEINFO_SIZE + (size_t)argp->uid.size - + (size_t)argp->info.size) + + (size_t)argp->info.size + + (size_t)argp->dir.size) return (ENOMEM); start = bp; @@ -267,6 +271,15 @@ __rep_fileinfo_marshal(env, version, argp, bp, max, lenp) memcpy(bp, argp->info.data, argp->info.size); bp += argp->info.size; } + if (copy_only) { + memcpy(bp, &argp->dir.size, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->dir.size); + if (argp->dir.size > 0) { + memcpy(bp, argp->dir.data, argp->dir.size); + bp += argp->dir.size; + } *lenp = (size_t)(bp - start); return (0); @@ -339,7 +352,10 @@ __rep_fileinfo_unmarshal(env, version, argpp, bp, max, nextp) bp += sizeof(u_int32_t); } else DB_NTOHL_COPYIN(env, argp->uid.size, bp); - argp->uid.data = bp; + if (argp->uid.size == 0) + argp->uid.data = NULL; + else + argp->uid.data = bp; needed += (size_t)argp->uid.size; if (max < needed) goto too_few; @@ -349,7 +365,205 @@ __rep_fileinfo_unmarshal(env, version, argpp, bp, max, nextp) bp += sizeof(u_int32_t); } else DB_NTOHL_COPYIN(env, argp->info.size, bp); - argp->info.data = bp; + if (argp->info.size == 0) + argp->info.data = NULL; + else + argp->info.data = bp; + needed += (size_t)argp->info.size; + if (max < needed) + goto too_few; + bp += argp->info.size; + if (copy_only) { + memcpy(&argp->dir.size, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->dir.size, bp); + if (argp->dir.size == 0) + argp->dir.data = NULL; + else + argp->dir.data = bp; + needed += (size_t)argp->dir.size; + if (max < needed) + goto too_few; + bp += argp->dir.size; + + if (nextp != NULL) + *nextp = bp; + *argpp = argp; + return (0); + +too_few: + __db_errx(env, DB_STR("3675", + "Not enough input bytes to fill a __rep_fileinfo message")); + return (EINVAL); +} + +/* + * PUBLIC: int __rep_fileinfo_v6_marshal __P((ENV *, u_int32_t, + * PUBLIC: __rep_fileinfo_v6_args *, u_int8_t *, size_t, size_t *)); + */ +int +__rep_fileinfo_v6_marshal(env, version, argp, bp, max, lenp) + ENV *env; + u_int32_t version; + __rep_fileinfo_v6_args *argp; + u_int8_t *bp; + size_t *lenp, max; +{ + int copy_only; + u_int8_t *start; + + if (max < __REP_FILEINFO_V6_SIZE + + (size_t)argp->uid.size + + (size_t)argp->info.size) + return (ENOMEM); + start = bp; + + copy_only = 0; + if (version < DB_REPVERSION_47) + copy_only = 1; + if (copy_only) { + memcpy(bp, &argp->pgsize, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->pgsize); + if (copy_only) { + memcpy(bp, &argp->pgno, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->pgno); + if (copy_only) { + memcpy(bp, &argp->max_pgno, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->max_pgno); + if (copy_only) { + memcpy(bp, &argp->filenum, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->filenum); + if (copy_only) { + memcpy(bp, &argp->finfo_flags, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->finfo_flags); + if (copy_only) { + memcpy(bp, &argp->type, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->type); + if (copy_only) { + memcpy(bp, &argp->db_flags, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->db_flags); + if (copy_only) { + memcpy(bp, &argp->uid.size, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->uid.size); + if (argp->uid.size > 0) { + memcpy(bp, argp->uid.data, argp->uid.size); + bp += argp->uid.size; + } + if (copy_only) { + memcpy(bp, &argp->info.size, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_HTONL_COPYOUT(env, bp, argp->info.size); + if (argp->info.size > 0) { + memcpy(bp, argp->info.data, argp->info.size); + bp += argp->info.size; + } + + *lenp = (size_t)(bp - start); + return (0); +} + +/* + * PUBLIC: int __rep_fileinfo_v6_unmarshal __P((ENV *, u_int32_t, + * PUBLIC: __rep_fileinfo_v6_args **, u_int8_t *, size_t, u_int8_t **)); + */ +int +__rep_fileinfo_v6_unmarshal(env, version, argpp, bp, max, nextp) + ENV *env; + u_int32_t version; + __rep_fileinfo_v6_args **argpp; + u_int8_t *bp; + size_t max; + u_int8_t **nextp; +{ + size_t needed; + __rep_fileinfo_v6_args *argp; + int ret; + int copy_only; + + needed = __REP_FILEINFO_V6_SIZE; + if (max < needed) + goto too_few; + if ((ret = __os_malloc(env, sizeof(*argp), &argp)) != 0) + return (ret); + + copy_only = 0; + if (version < DB_REPVERSION_47) + copy_only = 1; + if (copy_only) { + memcpy(&argp->pgsize, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->pgsize, bp); + if (copy_only) { + memcpy(&argp->pgno, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->pgno, bp); + if (copy_only) { + memcpy(&argp->max_pgno, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->max_pgno, bp); + if (copy_only) { + memcpy(&argp->filenum, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->filenum, bp); + if (copy_only) { + memcpy(&argp->finfo_flags, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->finfo_flags, bp); + if (copy_only) { + memcpy(&argp->type, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->type, bp); + if (copy_only) { + memcpy(&argp->db_flags, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->db_flags, bp); + if (copy_only) { + memcpy(&argp->uid.size, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->uid.size, bp); + if (argp->uid.size == 0) + argp->uid.data = NULL; + else + argp->uid.data = bp; + needed += (size_t)argp->uid.size; + if (max < needed) + goto too_few; + bp += argp->uid.size; + if (copy_only) { + memcpy(&argp->info.size, bp, sizeof(u_int32_t)); + bp += sizeof(u_int32_t); + } else + DB_NTOHL_COPYIN(env, argp->info.size, bp); + if (argp->info.size == 0) + argp->info.data = NULL; + else + argp->info.data = bp; needed += (size_t)argp->info.size; if (max < needed) goto too_few; @@ -362,7 +576,7 @@ __rep_fileinfo_unmarshal(env, version, argpp, bp, max, nextp) too_few: __db_errx(env, DB_STR("3675", - "Not enough input bytes to fill a __rep_fileinfo message")); + "Not enough input bytes to fill a __rep_fileinfo_v6 message")); return (EINVAL); } diff --git a/src/rep/rep_backup.c b/src/rep/rep_backup.c index a125c90a..cfde7622 100644 --- a/src/rep/rep_backup.c +++ b/src/rep/rep_backup.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -77,7 +77,8 @@ static int __rep_unlink_by_list __P((ENV *, u_int32_t, static FILE_WALK_FN __rep_unlink_file; static int __rep_walk_filelist __P((ENV *, u_int32_t, u_int8_t *, u_int32_t, u_int32_t, FILE_WALK_FN *, void *)); -static int __rep_walk_dir __P((ENV *, const char *, FILE_LIST_CTX*)); +static int __rep_walk_dir __P((ENV *, const char *, const char *, + FILE_LIST_CTX*)); static int __rep_write_page __P((ENV *, DB_THREAD_INFO *, REP *, __rep_fileinfo_args *)); @@ -236,7 +237,8 @@ __rep_find_dbs(env, context) /* * If we have a data directory, walk it get a list of the - * replicated user databases. + * replicated user databases. If the application has a metadata_dir, + * this will also find any persistent internal system databases. */ if (dbenv->db_data_dir != NULL) { for (ddir = dbenv->db_data_dir; *ddir != NULL; ++ddir) { @@ -244,24 +246,24 @@ __rep_find_dbs(env, context) DB_APP_NONE, *ddir, NULL, &real_dir)) != 0) break; if ((ret = __rep_walk_dir(env, - real_dir, context)) != 0) + real_dir, *ddir, context)) != 0) break; __os_free(env, real_dir); real_dir = NULL; } } /* - * Walk the environment directory to get a list of the - * replication subsystem's persistent internal system databases. - * If the application does not have a separate data directory, - * then the walk_dir will return all the user databases as well. + * Walk the environment directory. If the application doesn't + * have a metadata_dir, this will return persistent internal system + * databases. If the application doesn't have a separate data + * directory, this will also return all user databases. */ if (ret == 0) - ret = __rep_walk_dir(env, env->db_home, context); + ret = __rep_walk_dir(env, env->db_home, NULL, context); /* Now, collect any in-memory named databases. */ if (ret == 0) - ret = __rep_walk_dir(env, NULL, context); + ret = __rep_walk_dir(env, NULL, NULL, context); if (real_dir != NULL) __os_free(env, real_dir); @@ -277,9 +279,9 @@ __rep_find_dbs(env, context) * walk the list of in-memory named files. */ static int -__rep_walk_dir(env, dir, context) +__rep_walk_dir(env, dir, datadir, context) ENV *env; - const char *dir; + const char *dir, *datadir; FILE_LIST_CTX *context; { __rep_fileinfo_args tmpfp; @@ -295,7 +297,8 @@ __rep_walk_dir(env, dir, context) return (ret); } else { VPRINT(env, (env, DB_VERB_REP_SYNC, - "Walk_dir: Getting info for dir: %s", dir)); + "Walk_dir: Getting info for datadir %s, dir: %s", + datadir == NULL ? "NULL" : datadir, dir)); if ((ret = __os_dirlist(env, dir, 0, &names, &cnt)) != 0) return (ret); } @@ -360,12 +363,27 @@ __rep_walk_dir(env, dir, context) */ tmpfp.filenum = context->count++; + if (datadir != NULL) + DB_SET_DBT(tmpfp.dir, datadir, strlen(datadir) + 1); + else { + DB_SET_DBT(tmpfp.dir, NULL, 0); + } DB_SET_DBT(tmpfp.info, names[i], strlen(names[i]) + 1); DB_SET_DBT(tmpfp.uid, uid, DB_FILE_ID_LEN); retry: avail = (size_t)(&context->buf[context->size] - context->fillptr); - ret = __rep_fileinfo_marshal(env, context->version, - &tmpfp, context->fillptr, avail, &len); + if (context->version < DB_REPVERSION_53) + /* + * It is safe to cast to the old struct + * because the first part of the current + * struct matches the old struct. + */ + ret = __rep_fileinfo_v6_marshal(env, context->version, + (__rep_fileinfo_v6_args *)&tmpfp, + context->fillptr, avail, &len); + else + ret = __rep_fileinfo_marshal(env, context->version, + &tmpfp, context->fillptr, avail, &len); if (ret == ENOMEM) { /* * Here, 'len' is the total space in use in the buffer. @@ -406,13 +424,13 @@ __rep_is_replicated_db(name, dir) { if (strcmp(name, "DB_CONFIG") == 0 || strcmp(name, "pragma") == 0) return (0); - if (strncmp(name, LFPREFIX, sizeof(LFPREFIX) - 1) == 0) + if (IS_LOG_FILE(name)) return (0); /* * Remaining things that don't have a "__db" prefix are eligible. */ - if (strncmp(name, DB_REGION_PREFIX, sizeof(DB_REGION_PREFIX) - 1) != 0) + if (!IS_DB_FILE(name)) return (1); /* Here, we know we have a "__db" name. */ @@ -428,7 +446,7 @@ __rep_is_replicated_db(name, dir) strcmp(name, REPLSNHIST) == 0) return (1); } else { - if (strcmp(name, REPSYSDBNAME) == 0) + if (IS_REP_FILE(name)) return (1); } @@ -468,7 +486,6 @@ __rep_get_fileinfo(env, file, subdb, rfp, uid) DB *dbp; DBC *dbc; DBMETA *dbmeta; - DB_MPOOLFILE *mpf; DB_THREAD_INFO *ip; PAGE *pagep; int lorder, ret, t_ret; @@ -476,12 +493,16 @@ __rep_get_fileinfo(env, file, subdb, rfp, uid) dbp = NULL; dbc = NULL; pagep = NULL; - mpf = NULL; ENV_GET_THREAD_INFO(env, ip); if ((ret = __db_create_internal(&dbp, env, 0)) != 0) goto err; + /* + * Use DB_AM_RECOVER to prevent getting locks, otherwise exclusive + * database handles would block the master from handling UPDATE_REQ. + */ + F_SET(dbp, DB_AM_RECOVER); if ((ret = __db_open(dbp, ip, NULL, file, subdb, DB_UNKNOWN, DB_RDONLY | (F_ISSET(env, ENV_THREAD) ? DB_THREAD : 0), 0, PGNO_BASE_MD)) != 0) @@ -524,9 +545,11 @@ __rep_get_fileinfo(env, file, subdb, rfp, uid) if (ret != 0) goto err; err: - if (pagep != NULL && (t_ret = - __memp_fput(mpf, ip, pagep, dbc->priority)) != 0 && ret == 0) - ret = t_ret; + /* + * Check status of pagep in case any new error paths out leave + * a valid page. All current paths out have pagep NULL. + */ + DB_ASSERT(env, pagep == NULL); if (dbc != NULL && (t_ret = __dbc_close(dbc)) != 0 && ret == 0) ret = t_ret; if (dbp != NULL && (t_ret = __db_close(dbp, NULL, 0)) != 0 && ret == 0) @@ -549,19 +572,39 @@ __rep_page_req(env, ip, eid, rp, rec) __rep_control_args *rp; DBT *rec; { - __rep_fileinfo_args *msgfp; + __rep_fileinfo_args *msgfp, msgf; + __rep_fileinfo_v6_args *msgfpv6; DB_MPOOLFILE *mpf; DB_REP *db_rep; REP *rep; int ret, t_ret; u_int8_t *next; + void *msgfree; db_rep = env->rep_handle; rep = db_rep->region; - if ((ret = __rep_fileinfo_unmarshal(env, rp->rep_version, - &msgfp, rec->data, rec->size, &next)) != 0) - return (ret); + if (rp->rep_version < DB_REPVERSION_53) { + /* + * Build a current struct by copying in the older + * version struct and then setting up the data_dir. + * This is safe because all old fields are in the + * same location in the current struct. + */ + if ((ret = __rep_fileinfo_v6_unmarshal(env, rp->rep_version, + &msgfpv6, rec->data, rec->size, &next)) != 0) + return (ret); + memcpy(&msgf, msgfpv6, sizeof(__rep_fileinfo_v6_args)); + msgf.dir.data = NULL; + msgf.dir.size = 0; + msgfp = &msgf; + msgfree = msgfpv6; + } else { + if ((ret = __rep_fileinfo_unmarshal(env, rp->rep_version, + &msgfp, rec->data, rec->size, &next)) != 0) + return (ret); + msgfree = msgfp; + } DB_TEST_SET(env->test_abort, DB_TEST_NO_PAGES); RPRINT(env, (env, DB_VERB_REP_SYNC, @@ -591,7 +634,7 @@ __rep_page_req(env, ip, eid, rp, rec) ret = t_ret; err: DB_TEST_RECOVERY_LABEL - __os_free(env, msgfp); + __os_free(env, msgfree); return (ret); } @@ -656,7 +699,8 @@ __rep_page_sendpages(env, ip, eid, rp, msgfp, mpf, dbp) if ((ret = __db_cursor(qdbp, ip, NULL, &qdbc, 0)) != 0) goto err; } - msgsz = __REP_FILEINFO_SIZE + DB_FILE_ID_LEN + msgfp->pgsize; + msgsz = __REP_FILEINFO_SIZE + DB_FILE_ID_LEN + msgfp->pgsize + + msgfp->dir.size; if ((ret = __os_calloc(env, 1, msgsz, &buf)) != 0) goto err; memset(&msgdbt, 0, sizeof(msgdbt)); @@ -689,7 +733,7 @@ __rep_page_sendpages(env, ip, eid, rp, msgfp, mpf, dbp) * If queue returns ENOENT or if queue is not configured * convert it into PAGE_NOTFOUND. Queue might return * ENOENT if an entire extent file does not exist in the - * "middle" of the database. + * "middle" of the database. */ #ifdef HAVE_QUEUE if ((ret = __qam_fget(qdbc, &p, 0, &pagep)) == ENOENT) @@ -704,9 +748,21 @@ __rep_page_sendpages(env, ip, eid, rp, msgfp, mpf, dbp) RPRINT(env, (env, DB_VERB_REP_SYNC, "sendpages: PAGE_FAIL on page %lu", (u_long)p)); - if ((ret = __rep_fileinfo_marshal(env, - rp->rep_version, msgfp, buf, - msgsz, &len)) != 0) + if (rp->rep_version < DB_REPVERSION_53) + /* + * It is safe to cast to the old struct + * because the first part of the current + * struct matches the old struct. + */ + ret = __rep_fileinfo_v6_marshal(env, + rp->rep_version, + (__rep_fileinfo_v6_args *)msgfp, + buf, msgsz, &len); + else + ret = __rep_fileinfo_marshal(env, + rp->rep_version, msgfp, buf, + msgsz, &len); + if (ret != 0) goto err; LOG_SYSTEM_LOCK(env); lsn = ((LOG *)dblp->reginfo.primary)->lsn; @@ -740,8 +796,19 @@ __rep_page_sendpages(env, ip, eid, rp, msgfp, mpf, dbp) RPRINT(env, (env, DB_VERB_REP_SYNC, "sendpages: %lu, page lsn [%lu][%lu]", (u_long)p, (u_long)pagep->lsn.file, (u_long)pagep->lsn.offset)); - ret = __rep_fileinfo_marshal(env, rp->rep_version, - msgfp, buf, msgsz, &len); + if (rp->rep_version < DB_REPVERSION_53) + /* + * It is safe to cast to the old struct + * because the first part of the current + * struct matches the old struct. + */ + ret = __rep_fileinfo_v6_marshal(env, + rp->rep_version, + (__rep_fileinfo_v6_args *)msgfp, + buf, msgsz, &len); + else + ret = __rep_fileinfo_marshal(env, rp->rep_version, + msgfp, buf, msgsz, &len); if (msgfp->type != (u_int32_t)DB_QUEUE || p == 0) t_ret = __memp_fput(mpf, ip, pagep, DB_PRIORITY_UNCHANGED); @@ -1113,7 +1180,7 @@ __rep_remove_nimdbs(env) context.version = DB_REPVERSION; /* NB: "NULL" asks walk_dir to consider only in-memory DBs */ - if ((ret = __rep_walk_dir(env, NULL, &context)) != 0) + if ((ret = __rep_walk_dir(env, NULL, NULL, &context)) != 0) goto out; if ((ret = __rep_closefiles(env)) != 0) @@ -1216,7 +1283,7 @@ __rep_remove_all(env, msg_version, rec) */ if (!FLD_ISSET(rep->config, REP_C_INMEM)) { if ((ret = __db_appname(env, - DB_APP_NONE, REP_INITNAME, NULL, &fname)) != 0) + DB_APP_META, REP_INITNAME, NULL, &fname)) != 0) goto out; /* Sanity check that the write size fits into 32 bits. */ DB_ASSERT(env, (size_t)(context.fillptr - context.buf) == @@ -1435,11 +1502,20 @@ __rep_remove_file(env, rfp, unused) MAKE_INMEM(dbp); F_SET(dbp, DB_AM_RECOVER); /* Skirt locking. */ ret = __db_inmem_remove(dbp, NULL, name); - } else - ret = __fop_remove(env, - NULL, rfp->uid.data, name, NULL, + } else if ((ret = __fop_remove(env, + NULL, rfp->uid.data, name, (const char **)&rfp->dir.data, __rep_is_internal_rep_file(rfp->info.data) ? - DB_APP_NONE : DB_APP_DATA, 0); + DB_APP_META : DB_APP_DATA, 0)) != 0) + /* + * If fop_remove fails, it could be because + * the client has a different data_dir + * structure than the master. Retry with the + * local, default settings. + */ + ret = __fop_remove(env, + NULL, rfp->uid.data, name, NULL, + __rep_is_internal_rep_file(rfp->info.data) ? + DB_APP_META : DB_APP_DATA, 0); #ifdef HAVE_QUEUE out: #endif @@ -1536,10 +1612,12 @@ __rep_page(env, ip, eid, rp, rec) DB_REP *db_rep; DBT key, data; REP *rep; - __rep_fileinfo_args *msgfp; + __rep_fileinfo_args *msgfp, msgf; + __rep_fileinfo_v6_args *msgfpv6; db_recno_t recno; int ret; char *msg; + void *msgfree; ret = 0; db_rep = env->rep_handle; @@ -1569,9 +1647,27 @@ __rep_page(env, ip, eid, rp, rec) (u_long)rep->first_lsn.offset)); return (DB_REP_PAGEDONE); } - if ((ret = __rep_fileinfo_unmarshal(env, rp->rep_version, - &msgfp, rec->data, rec->size, NULL)) != 0) - return (ret); + if (rp->rep_version < DB_REPVERSION_53) { + /* + * Build a current struct by copying in the older + * version struct and then setting up the data_dir. + * This is safe because all old fields are in the + * same location in the current struct. + */ + if ((ret = __rep_fileinfo_v6_unmarshal(env, rp->rep_version, + &msgfpv6, rec->data, rec->size, NULL)) != 0) + return (ret); + memcpy(&msgf, msgfpv6, sizeof(__rep_fileinfo_v6_args)); + msgf.dir.data = NULL; + msgf.dir.size = 0; + msgfp = &msgf; + msgfree = msgfpv6; + } else { + if ((ret = __rep_fileinfo_unmarshal(env, rp->rep_version, + &msgfp, rec->data, rec->size, NULL)) != 0) + return (ret); + msgfree = msgfp; + } MUTEX_LOCK(env, rep->mtx_clientdb); REP_SYSTEM_LOCK(env); /* @@ -1648,12 +1744,12 @@ __rep_page(env, ip, eid, rp, rec) if (rp->rectype != REP_PAGE_FAIL) { VPRINT(env, (env, DB_VERB_REP_SYNC, "%s: Write page %lu into mpool", msg, (u_long)msgfp->pgno)); - if ((ret = __rep_write_page(env, ip, rep, msgfp)) != 0) { + if ((ret = __rep_write_page(env, ip, rep, msgfp)) != 0) { /* * We got an error storing the page, therefore, we need * remove this page marker from the page database too. * !!! - * I'm ignoring errors from the delete because we want + * I'm ignoring errors from the delete because we want * to return the original error. If we cannot write the * page and we cannot delete the item we just put, * what should we do? Panic the env and return @@ -1684,7 +1780,7 @@ __rep_page(env, ip, eid, rp, rec) err: REP_SYSTEM_UNLOCK(env); MUTEX_UNLOCK(env, rep->mtx_clientdb); - __os_free(env, msgfp); + __os_free(env, msgfree); return (ret); } @@ -1735,10 +1831,27 @@ __rep_write_page(env, ip, rep, msgfp) "rep_write_page: Calling fop_create for %s", (char *)rfp->info.data)); if ((ret = __fop_create(env, NULL, NULL, - rfp->info.data, NULL, + rfp->info.data, (const char **)&rfp->dir.data, __rep_is_internal_rep_file(rfp->info.data) ? - DB_APP_NONE : DB_APP_DATA, env->db_mode, 0)) != 0) - goto err; + DB_APP_META : DB_APP_DATA, env->db_mode, 0)) != 0) { + /* + * If fop_create fails, it could be because + * the client has a different data_dir + * structure than the master. Retry with the + * local, default settings. + */ + RPRINT(env, (env, DB_VERB_REP_SYNC, + "rep_write_page: fop_create ret %d. Retry for %s, master datadir %s", + ret, (char *)rfp->info.data, + rfp->dir.data == NULL ? "NULL" : + (char *)rfp->dir.data)); + if ((ret = __fop_create(env, NULL, NULL, + rfp->info.data, NULL, + __rep_is_internal_rep_file(rfp->info.data) ? + DB_APP_META : DB_APP_DATA, + env->db_mode, 0)) != 0) + goto err; + } } if ((ret = @@ -2294,10 +2407,12 @@ __rep_nextfile(env, eid, rep) LOG *lp; REGENV *renv; REGINFO *infop; - __rep_fileinfo_args *curinfo, *rfp; + __rep_fileinfo_args *curinfo, *rfp, rf; + __rep_fileinfo_v6_args *rfpv6; int *curbuf, ret; u_int8_t *buf, *info_ptr, lrbuf[__REP_LOGREQ_SIZE], *nextinfo; size_t len, msgsz; + void *rffree; infop = env->reginfo; renv = infop->primary; @@ -2315,28 +2430,47 @@ __rep_nextfile(env, eid, rep) /* Set curinfo to next file and examine it. */ info_ptr = R_ADDR(infop, rep->originfo_off + (rep->originfolen - rep->infolen)); - if ((ret = __rep_fileinfo_unmarshal(env, - rep->infoversion, &rfp, info_ptr, - rep->infolen, &nextinfo)) != 0) { - RPRINT(env, (env, DB_VERB_REP_SYNC, - "NEXTINFO: Fileinfo read: %s", db_strerror(ret))); - return (ret); + if (rep->infoversion < DB_REPVERSION_53) { + /* + * Build a current struct by copying in the older + * version struct and then setting up the data_dir. + * This is safe because all old fields are in the + * same location in the current struct. + */ + if ((ret = __rep_fileinfo_v6_unmarshal(env, + rep->infoversion, &rfpv6, + info_ptr, rep->infolen, &nextinfo)) != 0) + return (ret); + memcpy(&rf, rfpv6, sizeof(__rep_fileinfo_v6_args)); + rf.dir.data = NULL; + rf.dir.size = 0; + rfp = &rf; + rffree = rfpv6; + } else { + if ((ret = __rep_fileinfo_unmarshal(env, + rep->infoversion, &rfp, info_ptr, + rep->infolen, &nextinfo)) != 0) { + RPRINT(env, (env, DB_VERB_REP_SYNC, + "NEXTINFO: Fileinfo read: %s", + db_strerror(ret))); + return (ret); + } + rffree = rfp; } rep->infolen -= (u_int32_t)(nextinfo - info_ptr); MUTEX_LOCK(env, renv->mtx_regenv); ret = __env_alloc(infop, sizeof(__rep_fileinfo_args) + - rfp->uid.size + rfp->info.size, &curbuf); + rfp->uid.size + rfp->info.size + rfp->dir.size, &curbuf); MUTEX_UNLOCK(env, renv->mtx_regenv); if (ret != 0) { - __os_free(env, rfp); + __os_free(env, rffree); return (ret); - } - else + } else rep->curinfo_off = R_OFFSET(infop, curbuf); /* Copy fileinfo basic structure into curinfo. */ memcpy(R_ADDR(infop, rep->curinfo_off), (u_int8_t*)rfp, sizeof(__rep_fileinfo_args)); - /* Set up curinfo pointers to uid and info DBT data. */ + /* Set up curinfo pointers to the various DBT data fields. */ GET_CURINFO(rep, infop, curinfo); /* Copy uid and info DBT data from originfo buffer. */ if (rfp->uid.size > 0) @@ -2345,7 +2479,10 @@ __rep_nextfile(env, eid, rep) if (rfp->info.size > 0) memcpy(curinfo->info.data, rfp->info.data, rfp->info.size); - __os_free(env, rfp); + if (rfp->dir.size > 0) + memcpy(curinfo->dir.data, + rfp->dir.data, rfp->dir.size); + __os_free(env, rffree); /* Skip over regular DB's in "abbreviated" internal inits. */ if (F_ISSET(rep, REP_F_ABBREVIATED) && @@ -2373,12 +2510,28 @@ __rep_nextfile(env, eid, rep) "Next file %d: pgsize %lu, maxpg %lu", curinfo->filenum, (u_long)curinfo->pgsize, (u_long)curinfo->max_pgno)); - msgsz = __REP_FILEINFO_SIZE + + RPRINT(env, (env, DB_VERB_REP_SYNC, + "name %s dir %s", + curinfo->info.size > 0 ? (char *) curinfo->info.data : + "NULL", curinfo->dir.size > 0 ? + (char *)curinfo->dir.data : "NULL")); + msgsz = __REP_FILEINFO_SIZE + curinfo->dir.size + curinfo->uid.size + curinfo->info.size; if ((ret = __os_calloc(env, 1, msgsz, &buf)) != 0) return (ret); - if ((ret = __rep_fileinfo_marshal(env, rep->infoversion, - curinfo, buf, msgsz, &len)) != 0) { + if (rep->infoversion < DB_REPVERSION_53) + /* + * It is safe to cast to the old struct + * because the first part of the current + * struct matches the old struct. + */ + ret = __rep_fileinfo_v6_marshal(env, rep->infoversion, + (__rep_fileinfo_v6_args *)curinfo, buf, + msgsz, &len); + else + ret = __rep_fileinfo_marshal(env, rep->infoversion, + curinfo, buf, msgsz, &len); + if (ret != 0) { __os_free(env, buf); return (ret); } @@ -2625,7 +2778,7 @@ __rep_pggap_req(env, rep, reqfp, gapflags) tmpfp->pgno++; else tmpfp->pgno = rep->ready_pg; - msgsz = __REP_FILEINFO_SIZE + + msgsz = __REP_FILEINFO_SIZE + tmpfp->dir.size + tmpfp->uid.size + tmpfp->info.size; if ((ret = __os_calloc(env, 1, msgsz, &buf)) != 0) goto err; @@ -2682,8 +2835,19 @@ __rep_pggap_req(env, rep, reqfp, gapflags) * change. The only thing this should do is change * the pgno field. Everything else remains the same. */ - if ((ret = __rep_fileinfo_marshal(env, rep->infoversion, - tmpfp, buf, msgsz, &len)) == 0) { + if (rep->infoversion < DB_REPVERSION_53) + /* + * It is safe to cast to the old struct + * because the first part of the current + * struct matches the old struct. + */ + ret = __rep_fileinfo_v6_marshal(env, rep->infoversion, + (__rep_fileinfo_v6_args *)tmpfp, buf, + msgsz, &len); + else + ret = __rep_fileinfo_marshal(env, rep->infoversion, + tmpfp, buf, msgsz, &len); + if (ret == 0) { DB_INIT_DBT(max_pg_dbt, buf, len); DB_ASSERT(env, len == max_pg_dbt.size); (void)__rep_send_message(env, master, @@ -2715,13 +2879,13 @@ __rep_finfo_alloc(env, rfpsrc, rfpp) __rep_fileinfo_args *rfp; size_t size; int ret; - void *uidp, *infop; + void *dirp, *infop, *uidp; /* - * Allocate enough for the structure and the two DBT data areas. + * Allocate enough for the structure and the DBT data areas. */ size = sizeof(__rep_fileinfo_args) + rfpsrc->uid.size + - rfpsrc->info.size; + rfpsrc->info.size + rfpsrc->dir.size; if ((ret = __os_malloc(env, size, &rfp)) != 0) return (ret); @@ -2737,6 +2901,13 @@ __rep_finfo_alloc(env, rfpsrc, rfpp) infop = (u_int8_t *)uidp + rfpsrc->uid.size; rfp->info.data = infop; memcpy(infop, rfpsrc->info.data, rfpsrc->info.size); + + dirp = (u_int8_t *)infop + rfpsrc->info.size; + if (rfpsrc->dir.size > 0) { + rfp->dir.data = dirp; + memcpy(dirp, rfpsrc->dir.data, rfpsrc->dir.size); + } else + rfp->dir.data = NULL; *rfpp = rfp; return (ret); } @@ -2964,7 +3135,7 @@ __rep_remove_init_file(env) return (0); if ((ret = __db_appname(env, - DB_APP_NONE, REP_INITNAME, NULL, &name)) != 0) + DB_APP_META, REP_INITNAME, NULL, &name)) != 0) return (ret); (void)__os_unlink(env, name, 0); __os_free(env, name); @@ -3004,7 +3175,7 @@ __rep_reset_init(env) dbt.data = NULL; if ((ret = __db_appname(env, - DB_APP_NONE, REP_INITNAME, NULL, &init_name)) != 0) + DB_APP_META, REP_INITNAME, NULL, &init_name)) != 0) return (ret); if ((ret = __os_open( @@ -3348,26 +3519,50 @@ __rep_walk_filelist(env, version, files, size, count, fn, arg) FILE_WALK_FN *fn; void *arg; { - __rep_fileinfo_args *rfp; + __rep_fileinfo_args *rfp, rf; + __rep_fileinfo_v6_args *rfpv6; u_int8_t *next; int ret; + void *rffree; ret = 0; rfp = NULL; + rfpv6 = NULL; + rffree = NULL; while (count-- > 0) { - if ((ret = __rep_fileinfo_unmarshal(env, version, - &rfp, files, size, &next)) != 0) - break; + if (version < DB_REPVERSION_53) { + /* + * Build a current struct by copying in the older + * version struct and then setting up the data_dir. + * This is safe because all old fields are in the + * same location in the current struct. + */ + if ((ret = __rep_fileinfo_v6_unmarshal(env, version, + &rfpv6, files, size, &next)) != 0) + break; + memcpy(&rf, rfpv6, sizeof(__rep_fileinfo_v6_args)); + rf.dir.data = NULL; + rf.dir.size = 0; + rfp = &rf; + rffree = rfpv6; + } else { + if ((ret = __rep_fileinfo_unmarshal(env, version, + &rfp, files, size, &next)) != 0) + break; + rffree = rfp; + } size -= (u_int32_t)(next - files); files = next; if ((ret = (*fn)(env, rfp, arg)) != 0) break; - __os_free(env, rfp); + __os_free(env, rffree); rfp = NULL; + rfpv6 = NULL; + rffree = NULL; } - if (rfp != NULL) - __os_free(env, rfp); + if (rffree != NULL) + __os_free(env, rffree); return (ret); } diff --git a/src/rep/rep_elect.c b/src/rep/rep_elect.c index fd86cdf0..9e8c5249 100644 --- a/src/rep/rep_elect.c +++ b/src/rep/rep_elect.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -212,6 +212,9 @@ master: LOG_SYSTEM_LOCK(env); FLD_SET(rep->elect_flags, REP_E_PHASE0); egen = rep->egen; REP_SYSTEM_UNLOCK(env); + VPRINT(env, (env, DB_VERB_REP_ELECT, + "PHASE0 waittime from rep_lease_waittime: %lu", + (u_long)timeout)); (void)__rep_send_message(env, DB_EID_BROADCAST, REP_MASTER_REQ, NULL, NULL, 0, 0); @@ -246,8 +249,12 @@ master: LOG_SYSTEM_LOCK(env); "after PHASE0 wait, flags 0x%x, elect_flags 0x%x", rep->flags, rep->elect_flags)); if (!FLD_ISSET(repflags, REP_E_PHASE0) || - __rep_islease_granted(env) || egen != rep->egen) + __rep_islease_granted(env) || egen != rep->egen) { + VPRINT(env, (env, DB_VERB_REP_ELECT, + "PHASE0 Done: repflags 0x%x, egen %d rep->egen %d, lease_granted %d", + repflags, egen, rep->egen, __rep_islease_granted(env))); goto unlck_lv; + } F_SET(rep, REP_F_LEASE_EXPIRED); } @@ -917,8 +924,6 @@ __rep_vote2(env, rp, rec, eid) LOG_SYSTEM_LOCK(env); lsn = lp->lsn; LOG_SYSTEM_UNLOCK(env); - STAT_INC(env, - rep, election_won, rep->stat.st_elections_won, rep->egen); (void)__rep_send_message(env, DB_EID_BROADCAST, REP_NEWMASTER, &lsn, NULL, 0, 0); if (IS_USING_LEASES(env)) diff --git a/src/rep/rep_lease.c b/src/rep/rep_lease.c index 5fcf3c68..047c39a7 100644 --- a/src/rep/rep_lease.c +++ b/src/rep/rep_lease.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/rep/rep_log.c b/src/rep/rep_log.c index 77fca9d5..42300685 100644 --- a/src/rep/rep_log.c +++ b/src/rep/rep_log.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -604,20 +604,36 @@ __rep_logreq(env, rp, rec, eid) oldfilelsn.offset += logc->len; } else if (ret == DB_NOTFOUND) { /* - * If logc_get races with log_archive, it might return + * If logc_get races with log_archive or the user removing + * files from an earlier call to log_archive, it might return * DB_NOTFOUND. We expect there to be some log record * that is the first one. Loop until we either get * a log record or some error. Since we only expect - * to get this racing log_archive, bound it to a few + * to get this racing log file removal, bound it to a few * tries. */ count = 0; do { ret = __logc_get(logc, &firstlsn, &data_dbt, DB_FIRST); + /* + * If we've raced this many tries and we're still + * getting DB_NOTFOUND, then pause a bit to disrupt + * the timing cycle that we appear to be in. + */ + if (count > 5) + __os_yield(env, 0, 50000); count++; } while (ret == DB_NOTFOUND && count < 10); - if (ret != 0) + if (ret != 0) { + /* + * If we're master we don't want to return DB_NOTFOUND. + * We'll just ignore the error and this message. + * It will get rerequested if needed. + */ + if (ret == DB_NOTFOUND && F_ISSET(rep, REP_F_MASTER)) + ret = 0; goto err; + } if (LOG_COMPARE(&firstlsn, &rp->lsn) > 0) { /* Case 3 */ if (F_ISSET(rep, REP_F_CLIENT)) { diff --git a/src/rep/rep_method.c b/src/rep/rep_method.c index 9559711c..f9f1924c 100644 --- a/src/rep/rep_method.c +++ b/src/rep/rep_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1076,7 +1076,8 @@ __rep_open_sysdb(env, ip, txn, dbname, flags, dbpp) if ((ret = __db_create_internal(&dbp, env, 0)) != 0) return (ret); - myflags = DB_INTERNAL_DB | (F_ISSET(env, ENV_THREAD) ? DB_THREAD : 0); + myflags = DB_INTERNAL_PERSISTENT_DB | + (F_ISSET(env, ENV_THREAD) ? DB_THREAD : 0); /* * First, try opening it as a sub-database within a disk-resident @@ -1213,7 +1214,7 @@ __rep_client_dbinit(env, startup, which) if ((ret = __db_set_flags(dbp, DB_TXN_NOT_DURABLE)) != 0) goto err; - flags = DB_NO_AUTO_COMMIT | DB_CREATE | DB_INTERNAL_DB | + flags = DB_NO_AUTO_COMMIT | DB_CREATE | DB_INTERNAL_TEMPORARY_DB | (F_ISSET(env, ENV_THREAD) ? DB_THREAD : 0); if ((ret = __db_open(dbp, ip, NULL, fname, subdb, @@ -2825,7 +2826,7 @@ __rep_check_applied(env, ip, commit_info, reasonp) reasonp->why = AWAIT_HISTORY; reasonp->u.lsn = lsn; } else if (ret != 0) - goto out; /* Second read returned unexpeced error. */ + goto out; /* Second read returned unexpected error. */ /* * We now have the history info for the gen of the txn, and for @@ -3006,8 +3007,10 @@ __rep_conv_vers(env, log_ver) * We can't use a switch statement, some of the DB_LOGVERSION_XX * constants are the same */ - if (log_ver == DB_LOGVERSION) - return (DB_REPVERSION); + if (log_ver == DB_LOGVERSION_53) + return (DB_REPVERSION_53); + if (log_ver == DB_LOGVERSION_52) + return (DB_REPVERSION_52); /* 5.0 and 5.1 had identical log and rep versions. */ if (log_ver == DB_LOGVERSION_51) return (DB_REPVERSION_51); @@ -3023,5 +3026,7 @@ __rep_conv_vers(env, log_ver) return (DB_REPVERSION_45); if (log_ver == DB_LOGVERSION_44) return (DB_REPVERSION_44); + if (log_ver == DB_LOGVERSION) + return (DB_REPVERSION); return (DB_REPVERSION_INVALID); } diff --git a/src/rep/rep_record.c b/src/rep/rep_record.c index 568b60e0..f4691974 100644 --- a/src/rep/rep_record.c +++ b/src/rep/rep_record.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1292,11 +1292,18 @@ gap_check: if (ret == DB_KEYEXIST) ret = 0; - if (ret != 0) + if (ret != 0 && ret != ENOMEM) goto done; - if (IS_ZERO_LSN(lp->waiting_lsn) || - LOG_COMPARE(&rp->lsn, &lp->waiting_lsn) < 0) { + /* + * If we are using in-memory, and got ENOMEM, it is + * not an error. But in that case we want to skip + * comparing the message LSN since we're not storing it. + * However, we do want continue to check if we need to + * send a request for the gap. + */ + if (ret == 0 && (IS_ZERO_LSN(lp->waiting_lsn) || + LOG_COMPARE(&rp->lsn, &lp->waiting_lsn) < 0)) { /* * If this is a new gap, then reset the rcvd_ts so * that an out-of-order record after an idle period @@ -1416,16 +1423,13 @@ err: /* REP_SYSTEM_UNLOCK(env); /* * If we've processed beyond the needed LSN for a pending - * start sync, start it now. We can compare >= here - * because ready_lsn is the next record we expect. - * Since ckp_lsn can point to the last commit record itself, - * but if it does and ready_lsn == commit (i.e. we haven't - * written the commit yet), we can still start to sync - * because we're guaranteed no additional buffers can - * be dirtied. + * start sync, start it now. We must compare > here + * because ready_lsn is the next record we expect and if + * the last record is a commit, that will dirty pages on + * a client as that txn is applied. */ if (!IS_ZERO_LSN(rep->ckp_lsn) && - LOG_COMPARE(&lp->ready_lsn, &rep->ckp_lsn) >= 0) { + LOG_COMPARE(&lp->ready_lsn, &rep->ckp_lsn) > 0) { save_lsn = rep->ckp_lsn; ZERO_LSN(rep->ckp_lsn); } else @@ -1610,7 +1614,7 @@ __rep_process_txn(env, rec) locker->priority = DB_LOCK_MAXPRIORITY; if ((ret = - __lock_get_list(env, locker, 0, DB_LOCK_WRITE, lock_dbt)) != 0) + __lock_get_list(env, locker, 0, DB_LOCK_WRITE, lock_dbt)) != 0) goto err; /* Phase 1. Get a list of the LSNs in this transaction, and sort it. */ @@ -2457,7 +2461,7 @@ __rep_check_missing(env, gen, master_perm_lsn) * Prevent message lockout by counting ourself here. * Setting rep->msg_th will prevent a major system * change, such as a role change or running recovery, from - * occuring before sending out any rerequests. + * occurring before sending out any rerequests. */ rep->msg_th++; REP_SYSTEM_UNLOCK(env); diff --git a/src/rep/rep_region.c b/src/rep/rep_region.c index 0348894b..f1d69dff 100644 --- a/src/rep/rep_region.c +++ b/src/rep/rep_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -261,7 +261,9 @@ __rep_env_refresh(env) */ if (F_ISSET(env, ENV_PRIVATE)) { if (rep != NULL) { - ret = __mutex_free(env, &rep->mtx_region); + if ((t_ret = __mutex_free(env, + &rep->mtx_region)) != 0 && ret == 0) + ret = t_ret; if ((t_ret = __mutex_free(env, &rep->mtx_clientdb)) != 0 && ret == 0) ret = t_ret; @@ -454,7 +456,7 @@ __rep_egen_init(env, rep) char *p; if ((ret = __db_appname(env, - DB_APP_NONE, REP_EGENNAME, NULL, &p)) != 0) + DB_APP_META, REP_EGENNAME, NULL, &p)) != 0) return (ret); /* * If the file doesn't exist, create it now and initialize with 1. @@ -509,7 +511,7 @@ __rep_write_egen(env, rep, egen) } if ((ret = __db_appname(env, - DB_APP_NONE, REP_EGENNAME, NULL, &p)) != 0) + DB_APP_META, REP_EGENNAME, NULL, &p)) != 0) return (ret); if ((ret = __os_open( env, p, 0, DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &fhp)) == 0) { @@ -540,7 +542,7 @@ __rep_gen_init(env, rep) char *p; if ((ret = __db_appname(env, - DB_APP_NONE, REP_GENNAME, NULL, &p)) != 0) + DB_APP_META, REP_GENNAME, NULL, &p)) != 0) return (ret); if (__os_exists(env, p, NULL) != 0) { @@ -594,7 +596,7 @@ __rep_write_gen(env, rep, gen) } if ((ret = __db_appname(env, - DB_APP_NONE, REP_GENNAME, NULL, &p)) != 0) + DB_APP_META, REP_GENNAME, NULL, &p)) != 0) return (ret); if ((ret = __os_open( env, p, 0, DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &fhp)) == 0) { diff --git a/src/rep/rep_stat.c b/src/rep/rep_stat.c index c0dbecd0..addfee25 100644 --- a/src/rep/rep_stat.c +++ b/src/rep/rep_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -404,7 +404,7 @@ __rep_print_stats(env, flags) "Master generation number of the winner of the current or last election", (u_long)sp->st_election_gen); __db_dl(env, - "Master data generation number of the winner of the current or last election", + "Master data generation number of the winner of the current or last election", (u_long)sp->st_election_datagen); __db_msg(env, "%lu/%lu\tMaximum LSN of the winner of the current or last election", diff --git a/src/rep/rep_stub.c b/src/rep/rep_stub.c index 440feef2..2d96ea59 100644 --- a/src/rep/rep_stub.c +++ b/src/rep/rep_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/rep/rep_util.c b/src/rep/rep_util.c index 70b76dcc..0dfe6122 100644 --- a/src/rep/rep_util.c +++ b/src/rep/rep_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -1184,6 +1184,16 @@ __db_rep_enter(dbp, checkgen, checklock, return_now) if (F_ISSET(renv, DB_REGENV_REPLOCKED)) return (EINVAL); } + + /* + * Return a dead handle if an internal handle is trying to + * get an exclusive lock on this database. + */ + if (checkgen && dbp->mpf->mfp && IS_REP_CLIENT(env)) { + if (dbp->mpf->mfp->excl_lockout) + return (DB_REP_HANDLE_DEAD); + } + REP_SYSTEM_LOCK(env); /* * !!! @@ -1821,6 +1831,44 @@ __rep_msg_to_old(version, rectype) 29, /* REP_VERIFY_REQ */ 30, /* REP_VOTE1 */ 31 /* REP_VOTE2 */ + }, + /* + * From 5.3 message number To 4.7 message number. There are + * NO message differences between 4.7 and 5.3. The + * content of fileinfo changed. + */ + { REP_INVALID, /* NO message 0 */ + 1, /* REP_ALIVE */ + 2, /* REP_ALIVE_REQ */ + 3, /* REP_ALL_REQ */ + 4, /* REP_BULK_LOG */ + 5, /* REP_BULK_PAGE */ + 6, /* REP_DUPMASTER */ + 7, /* REP_FILE */ + 8, /* REP_FILE_FAIL */ + 9, /* REP_FILE_REQ */ + 10, /* REP_LEASE_GRANT */ + 11, /* REP_LOG */ + 12, /* REP_LOG_MORE */ + 13, /* REP_LOG_REQ */ + 14, /* REP_MASTER_REQ */ + 15, /* REP_NEWCLIENT */ + 16, /* REP_NEWFILE */ + 17, /* REP_NEWMASTER */ + 18, /* REP_NEWSITE */ + 19, /* REP_PAGE */ + 20, /* REP_PAGE_FAIL */ + 21, /* REP_PAGE_MORE */ + 22, /* REP_PAGE_REQ */ + 23, /* REP_REREQUEST */ + 24, /* REP_START_SYNC */ + 25, /* REP_UPDATE */ + 26, /* REP_UPDATE_REQ */ + 27, /* REP_VERIFY */ + 28, /* REP_VERIFY_FAIL */ + 29, /* REP_VERIFY_REQ */ + 30, /* REP_VOTE1 */ + 31 /* REP_VOTE2 */ } }; return (table[version][rectype]); @@ -1989,6 +2037,44 @@ __rep_msg_from_old(version, rectype) 29, /* 29, REP_VERIFY_REQ */ 30, /* 30, REP_VOTE1 */ 31 /* 31, REP_VOTE2 */ + }, + /* + * From 4.7 message number To 5.3 message number. There are + * NO message differences between them. The fileinfo contents + * changed. + */ + { REP_INVALID, /* NO message 0 */ + 1, /* 1, REP_ALIVE */ + 2, /* 2, REP_ALIVE_REQ */ + 3, /* 3, REP_ALL_REQ */ + 4, /* 4, REP_BULK_LOG */ + 5, /* 5, REP_BULK_PAGE */ + 6, /* 6, REP_DUPMASTER */ + 7, /* 7, REP_FILE */ + 8, /* 8, REP_FILE_FAIL */ + 9, /* 9, REP_FILE_REQ */ + 10, /* 10, REP_LEASE_GRANT */ + 11, /* 11, REP_LOG */ + 12, /* 12, REP_LOG_MORE */ + 13, /* 13, REP_LOG_REQ */ + 14, /* 14, REP_MASTER_REQ */ + 15, /* 15, REP_NEWCLIENT */ + 16, /* 16, REP_NEWFILE */ + 17, /* 17, REP_NEWMASTER */ + 18, /* 18, REP_NEWSITE */ + 19, /* 19, REP_PAGE */ + 20, /* 20, REP_PAGE_FAIL */ + 21, /* 21, REP_PAGE_MORE */ + 22, /* 22, REP_PAGE_REQ */ + 23, /* 22, REP_REREQUEST */ + 24, /* 24, REP_START_SYNC */ + 25, /* 25, REP_UPDATE */ + 26, /* 26, REP_UPDATE_REQ */ + 27, /* 27, REP_VERIFY */ + 28, /* 28, REP_VERIFY_FAIL */ + 29, /* 29, REP_VERIFY_REQ */ + 30, /* 30, REP_VOTE1 */ + 31 /* 31, REP_VOTE2 */ } }; return (table[version][rectype]); diff --git a/src/rep/rep_verify.c b/src/rep/rep_verify.c index a66eb1fd..5238f900 100644 --- a/src/rep/rep_verify.c +++ b/src/rep/rep_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/repmgr/repmgr.src b/src/repmgr/repmgr.src index 28f41f42..68d8c239 100644 --- a/src/repmgr/repmgr.src +++ b/src/repmgr/repmgr.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. */ DBPRIVATE diff --git a/src/repmgr/repmgr_automsg.c b/src/repmgr/repmgr_automsg.c index 8fe4548e..90af08ff 100644 --- a/src/repmgr/repmgr_automsg.c +++ b/src/repmgr/repmgr_automsg.c @@ -433,7 +433,10 @@ __repmgr_membership_key_unmarshal(env, argp, bp, max, nextp) if (max < needed) goto too_few; DB_NTOHL_COPYIN(env, argp->host.size, bp); - argp->host.data = bp; + if (argp->host.size == 0) + argp->host.data = NULL; + else + argp->host.data = bp; needed += (size_t)argp->host.size; if (max < needed) goto too_few; @@ -580,7 +583,10 @@ __repmgr_gm_fwd_unmarshal(env, argp, bp, max, nextp) if (max < needed) goto too_few; DB_NTOHL_COPYIN(env, argp->host.size, bp); - argp->host.data = bp; + if (argp->host.size == 0) + argp->host.data = NULL; + else + argp->host.data = bp; needed += (size_t)argp->host.size; if (max < needed) goto too_few; @@ -687,7 +693,10 @@ __repmgr_site_info_unmarshal(env, argp, bp, max, nextp) if (max < needed) goto too_few; DB_NTOHL_COPYIN(env, argp->host.size, bp); - argp->host.data = bp; + if (argp->host.size == 0) + argp->host.data = NULL; + else + argp->host.data = bp; needed += (size_t)argp->host.size; if (max < needed) goto too_few; diff --git a/src/repmgr/repmgr_elect.c b/src/repmgr/repmgr_elect.c index 4ec77055..3a84694a 100644 --- a/src/repmgr/repmgr_elect.c +++ b/src/repmgr/repmgr_elect.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -37,9 +37,9 @@ __repmgr_init_election(env, flags) COMPQUIET(th, NULL); db_rep = env->rep_handle; - if (db_rep->finished) { + if (db_rep->repmgr_status == stopped) { RPRINT(env, (env, DB_VERB_REPMGR_MISC, - "ignoring elect thread request %#lx; repmgr is finished", + "ignoring elect thread request %#lx; repmgr is stopped", (u_long)flags)); return (0); } @@ -121,7 +121,8 @@ __repmgr_elect_main(env, th) struct timespec deadline; #endif db_timespec failtime, now, repstart_time, target, wait_til; - db_timeout_t response_time; + db_timeout_t delay_time, response_time, tmp_time; + u_long sec, usec; u_int32_t flags; int done_repstart, ret, suppress_election; enum { ELECTION, REPSTART } action; @@ -135,6 +136,40 @@ __repmgr_elect_main(env, th) if (LF_ISSET(ELECT_F_EVENT_NOTIFY)) DB_EVENT(env, DB_EVENT_REP_MASTER_FAILURE, NULL); + /* + * If leases are enabled, delay the election to allow any straggler + * messages to get processed that might grant our lease again and + * fool the base code into thinking the master is still there. + * Any delay here offsets the time election code will wait for a + * lease grant to expire. So with leases we're not adding more delay. + */ + if (FLD_ISSET(db_rep->region->config, REP_C_LEASE)) { + /* + * Use the smallest of the lease timeout, ack timeout, + * or connection retry timeout. We want to give straggler + * messages a chance to get processed, but get an election + * underway as soon as possible to find a master. + */ + if ((ret = __rep_get_timeout(env->dbenv, + DB_REP_LEASE_TIMEOUT, &delay_time)) != 0) + goto out; + if ((ret = __rep_get_timeout(env->dbenv, + DB_REP_ACK_TIMEOUT, &tmp_time)) != 0) + goto out; + if (tmp_time < delay_time) + delay_time = tmp_time; + if ((ret = __rep_get_timeout(env->dbenv, + DB_REP_CONNECTION_RETRY, &tmp_time)) != 0) + goto out; + if (tmp_time < delay_time) + delay_time = tmp_time; + sec = delay_time / US_PER_SEC; + usec = delay_time % US_PER_SEC; + RPRINT(env, (env, DB_VERB_REPMGR_MISC, + "Election with leases pause sec %lu, usec %lu", sec, usec)); + __os_yield(env, sec, usec); + } + /* * As a freshly started thread, lay claim to the title of being * "preferred". If an older thread is sleeping for retry, when it wakes @@ -187,7 +222,7 @@ __repmgr_elect_main(env, th) for (;;) { ret = 0; - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) goto unlock; /* @@ -359,7 +394,7 @@ __repmgr_compute_response_time(env) * to give it a chance to respond with a NEWMASTER message. This is * particularly an issue at start-up time, when we're likely to have * several "new connection establishment" events bombarding us with lots - * of rep_start requests in quick successtion. + * of rep_start requests in quick succession. * * We don't have a separate user configuration for rep_start response, * but it's reasonable to expect it to be similar to either the ack diff --git a/src/repmgr/repmgr_method.c b/src/repmgr/repmgr_method.c index d28ff8f4..229cf650 100644 --- a/src/repmgr/repmgr_method.c +++ b/src/repmgr/repmgr_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -102,10 +102,16 @@ __repmgr_start(dbenv, nthreads, flags) return (EINVAL); } - if (db_rep->finished) { - __db_errx(env, DB_STR("3638", "repmgr is shutting down")); - return (EINVAL); + /* Check if it is a shut-down site, if so, clean the resources. */ + if (db_rep->repmgr_status == stopped) { + if ((ret = __repmgr_stop(env)) != 0) { + __db_errx(env, DB_STR("3638", + "Could not clean up repmgr")); + return (ret); + } + db_rep->repmgr_status = ready; } + db_rep->init_policy = flags; if ((ret = __rep_set_transport_int(env, db_rep->self_eid, __repmgr_send)) != 0) @@ -182,7 +188,8 @@ __repmgr_start(dbenv, nthreads, flags) } else ret = __repmgr_join_group(env); ENV_LEAVE(env, ip); - } + } else if (ret == DB_DELETED) + ret = DB_REP_UNAVAIL; } if (ret != 0) return (ret); @@ -190,11 +197,20 @@ __repmgr_start(dbenv, nthreads, flags) DB_ASSERT(env, start_master || SITE_FROM_EID(db_rep->self_eid)->membership == SITE_PRESENT); + /* + * If we're the first repmgr_start() call, we will have to start threads. + * Therefore, we require a flags value (to tell us how). + */ + if (db_rep->repmgr_status != running && flags == 0) { + __db_errx(env, DB_STR("3639", + "a non-zero flags value is required for initial repmgr_start() call")); + return (EINVAL); + } + /* * Figure out the current situation. The current invocation of * repmgr_start() is either the first one (on the given env handle), or - * a subsequent one. If we've already got a select thread running, then - * this must be a subsequent one. + * a subsequent one. * * Then, in case there could be multiple processes, we're either the * main listener process or a subordinate process. On a "subsequent" @@ -207,12 +223,12 @@ __repmgr_start(dbenv, nthreads, flags) */ LOCK_MUTEX(db_rep->mutex); locked = TRUE; - if (db_rep->mgr_started) { + if (db_rep->repmgr_status == running) { first = FALSE; is_listener = !IS_SUBORDINATE(db_rep); } else { first = TRUE; - db_rep->mgr_started = TRUE; + db_rep->repmgr_status = running; ENV_ENTER(env, ip); MUTEX_LOCK(env, rep->mtx_repmgr); @@ -225,18 +241,6 @@ __repmgr_start(dbenv, nthreads, flags) } MUTEX_UNLOCK(env, rep->mtx_repmgr); ENV_LEAVE(env, ip); - - /* - * Since we're the first repmgr_start() call, we will have to - * start threads. Therefore, we require a flags value (to tell - * us how). - */ - if (flags == 0) { - __db_errx(env, DB_STR("3639", - "a non-zero flags value is required for initial repmgr_start() call")); - ret = EINVAL; - goto err; - } } UNLOCK_MUTEX(db_rep->mutex); locked = FALSE; @@ -383,8 +387,8 @@ err: (void)__repmgr_stop_threads(env); UNLOCK_MUTEX(db_rep->mutex); locked = FALSE; - (void)__repmgr_await_threads(env); } + (void)__repmgr_await_threads(env); if (!locked) LOCK_MUTEX(db_rep->mutex); (void)__repmgr_net_close(env); @@ -618,7 +622,7 @@ __repmgr_autostart(env) db_rep->self_eid, __repmgr_send)) != 0) goto out; - if (db_rep->selector == NULL && !db_rep->finished) + if (db_rep->selector == NULL && db_rep->repmgr_status != running) ret = __repmgr_start_selector(env); out: @@ -662,20 +666,57 @@ __repmgr_start_selector(env) /* * PUBLIC: int __repmgr_close __P((ENV *)); + * + * Close repmgr during env close. It stops repmgr, frees sites array and + * its addresses. */ int __repmgr_close(env) ENV *env; { DB_REP *db_rep; + REPMGR_SITE *site; + int ret; + u_int i; + + db_rep = env->rep_handle; + ret = 0; + + ret = __repmgr_stop(env); + if (db_rep->sites != NULL) { + for (i = 0; i < db_rep->site_cnt; i++) { + site = &db_rep->sites[i]; + DB_ASSERT(env, TAILQ_EMPTY(&site->sub_conns)); + __repmgr_cleanup_netaddr(env, &site->net_addr); + } + __os_free(env, db_rep->sites); + db_rep->sites = NULL; + } + + return (ret); +} + +/* + * PUBLIC: int __repmgr_stop __P((ENV *)); + * + * Stop repmgr either when closing the env or removing the current repmgr from + * replication group. It stops threads if necessary, frees resources allocated + * after __repmgr_start, and cleans up site membership. + */ +int +__repmgr_stop(env) + ENV *env; +{ + DB_REP *db_rep; + REPMGR_SITE *site; int ret, t_ret; + u_int i; ret = 0; db_rep = env->rep_handle; + if (db_rep->selector != NULL) { - if (!db_rep->finished) { - RPRINT(env, (env, DB_VERB_REPMGR_MISC, - "Stopping repmgr threads")); + if (db_rep->repmgr_status != stopped) { LOCK_MUTEX(db_rep->mutex); ret = __repmgr_stop_threads(env); UNLOCK_MUTEX(db_rep->mutex); @@ -685,12 +726,24 @@ __repmgr_close(env) RPRINT(env, (env, DB_VERB_REPMGR_MISC, "Repmgr threads are finished")); } - - if ((t_ret = __repmgr_net_close(env)) != 0 && ret == 0) - ret = t_ret; - + __repmgr_net_destroy(env, db_rep); if ((t_ret = __repmgr_deinit(env)) != 0 && ret == 0) ret = t_ret; + if ((t_ret = __repmgr_queue_destroy(env)) != 0 && ret == 0) + ret = t_ret; + if (db_rep->restored_list != NULL) { + __os_free(env, db_rep->restored_list); + db_rep->restored_list = NULL; + } + /* + * Clean up current site membership and state, so that the obsolete + * membership won't mislead us for the next repmgr start. + */ + for (i = 0; i < db_rep->site_cnt; i++) { + site = &db_rep->sites[i]; + site->state = SITE_IDLE; + site->membership = 0; + } return (ret); } @@ -810,14 +863,6 @@ __repmgr_env_destroy(env, db_rep) ENV *env; DB_REP *db_rep; { - if (db_rep->restored_list != NULL) - __os_free(env, db_rep->restored_list); - (void)__repmgr_queue_destroy(env); - __repmgr_net_destroy(env, db_rep); - if (db_rep->messengers != NULL) { - __os_free(env, db_rep->messengers); - db_rep->messengers = NULL; - } if (db_rep->mutex != NULL) { (void)__repmgr_destroy_mutex(env, db_rep->mutex); db_rep->mutex = NULL; @@ -838,7 +883,8 @@ __repmgr_stop_threads(env) db_rep = env->rep_handle; - db_rep->finished = TRUE; + db_rep->repmgr_status = stopped; + RPRINT(env, (env, DB_VERB_REPMGR_MISC, "Stopping repmgr threads")); if ((ret = __repmgr_signal(&db_rep->check_election)) != 0) return (ret); @@ -1023,8 +1069,8 @@ __repmgr_channel(dbenv, eid, dbchannelp, flags) * Note that repmgr_start() checks DB_INIT_REP, ENV_THREAD and * APP_IS_BASEAPI. */ - if (db_rep->finished) { - __db_errx(env, DB_STR("3651", "repmgr is shutting down")); + if (db_rep->repmgr_status == stopped) { + __db_errx(env, DB_STR("3651", "repmgr is stopped")); return (EINVAL); } @@ -2601,11 +2647,12 @@ site_by_addr(env, host, port, sitep) } else locked = FALSE; ret = __repmgr_find_site(env, host, port, &eid); + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); /* * Point to the stable, permanent copy of the host name. That's the one * we want the DB_SITE handle to point to; just like site_by_eid() does. - */ + */ host = site->net_addr.host; if (locked) { ENV_LEAVE(env, ip); @@ -2747,6 +2794,7 @@ __repmgr_get_config(dbsite, which, valuep) if ((ret = refresh_site(dbsite)) != 0) return (ret); LOCK_MUTEX(db_rep->mutex); + DB_ASSERT(env, IS_VALID_EID(dbsite->eid)); site = SITE_FROM_EID(dbsite->eid); if (REP_ON(env)) { rep = db_rep->region; @@ -2799,12 +2847,10 @@ __repmgr_site_config(dbsite, which, value) } break; case DB_GROUP_CREATOR: - if (IS_VALID_EID(db_rep->self_eid) && - dbsite->eid != db_rep->self_eid) { - __db_errx(env, DB_STR("3664", - "Site config value not applicable to remote site")); - return (EINVAL); - } + /* + * Ignore if this is set on remote site. Users will often + * copy and edit a DB_CONFIG for all sites. + */ break; case DB_LEGACY: /* Applicable to either local or remote site. */ @@ -2823,6 +2869,7 @@ __repmgr_site_config(dbsite, which, value) return (EINVAL); } + DB_ASSERT(env, IS_VALID_EID(dbsite->eid)); if (REP_ON(env)) { rep = db_rep->region; infop = env->reginfo; @@ -2877,11 +2924,11 @@ set_local_site(dbsite, value) COMPQUIET(ip, NULL); env = dbsite->env; db_rep = env->rep_handle; + ret = 0; locked = FALSE; if (REP_ON(env)) { rep = db_rep->region; - LOCK_MUTEX(db_rep->mutex); ENV_ENTER(env, ip); MUTEX_LOCK(env, rep->mtx_repmgr); @@ -2890,7 +2937,6 @@ set_local_site(dbsite, value) if (IS_VALID_EID(rep->self_eid)) db_rep->self_eid = rep->self_eid; } - ret = 0; if (!value && db_rep->self_eid == dbsite->eid) { __db_errx(env, DB_STR("3666", "A previously given local site may not be unset")); @@ -2901,6 +2947,7 @@ set_local_site(dbsite, value) "A (different) local site has already been set")); ret = EINVAL; } else { + DB_ASSERT(env, IS_VALID_EID(dbsite->eid)); site = SITE_FROM_EID(dbsite->eid); if (FLD_ISSET(site->config, DB_BOOTSTRAP_HELPER | DB_REPMGR_PEER)) { @@ -2988,15 +3035,15 @@ __repmgr_remove_site(dbsite) db_rep = env->rep_handle; rep = db_rep->region; - if (db_rep->finished || !SELECTOR_RUNNING(db_rep)) { - __db_errx(env, DB_STR("3669", - "repmgr threads are not running")); + if (db_rep->repmgr_status != running || !SELECTOR_RUNNING(db_rep)) { + __db_errx(env, DB_STR("3669", "repmgr is not running")); return (EINVAL); } if (!IS_VALID_EID((master = rep->master_id))) return (DB_REP_UNAVAIL); LOCK_MUTEX(db_rep->mutex); + DB_ASSERT(env, IS_VALID_EID(master)); addr = SITE_FROM_EID(master)->net_addr; UNLOCK_MUTEX(db_rep->mutex); diff --git a/src/repmgr/repmgr_msg.c b/src/repmgr/repmgr_msg.c index 7e8d3331..13537823 100644 --- a/src/repmgr/repmgr_msg.c +++ b/src/repmgr/repmgr_msg.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -43,7 +43,7 @@ static int serve_repmgr_request __P((ENV *, REPMGR_MESSAGE *)); * "present". Otherwise ("deleting") the goal is to not even appear in the * database at all (0). */ -#define NEXT_STATUS(s) ((s) == SITE_ADDING ? SITE_PRESENT : 0) +#define NEXT_STATUS(s) (u_int32_t)((s) == SITE_ADDING ? SITE_PRESENT : 0) /* * PUBLIC: void *__repmgr_msg_thread __P((void *)); @@ -92,11 +92,13 @@ message_loop(env, th) * or GMDB operations, so that we can limit the number * of them, in order to avoid starving more important * rep messages. - */ + */ db_rep->non_rep_th++; incremented = TRUE; } if (msg->msg_hdr.type == REPMGR_REP_MESSAGE) { + DB_ASSERT(env, + IS_VALID_EID(msg->v.repmsg.originating_eid)); site = SITE_FROM_EID(msg->v.repmsg.originating_eid); membership = site->membership; } @@ -164,7 +166,7 @@ message_loop(env, th) /* * A return of DB_REP_UNAVAIL from __repmgr_queue_get() merely means we * should finish gracefully. - */ + */ if (ret == DB_REP_UNAVAIL) ret = 0; out: @@ -471,8 +473,7 @@ send_permlsn(env, generation, lsn) REP *rep; REPMGR_CONNECTION *conn; REPMGR_SITE *site; - int ack, bcast, master, policy, ret; - u_int eid; + int ack, bcast, eid, master, policy, ret; db_rep = env->rep_handle; rep = db_rep->region; @@ -519,10 +520,18 @@ send_permlsn(env, generation, lsn) * Send to master first, since we need to send to all its connections. */ if (site != NULL && (bcast || ack)) { - if (IS_SITE_AVAILABLE(site) && - (ret = send_permlsn_conn(env, - site->ref.conn, generation, lsn)) != 0) - goto unlock; + if (site->state == SITE_CONNECTED) { + if ((conn = site->ref.conn.in) != NULL && + conn->state == CONN_READY && + (ret = send_permlsn_conn(env, + conn, generation, lsn)) != 0) + goto unlock; + if ((conn = site->ref.conn.out) != NULL && + conn->state == CONN_READY && + (ret = send_permlsn_conn(env, + conn, generation, lsn)) != 0) + goto unlock; + } TAILQ_FOREACH(conn, &site->sub_conns, entries) { if ((ret = send_permlsn_conn(env, conn, generation, lsn)) != 0) @@ -535,16 +544,24 @@ send_permlsn(env, generation, lsn) * that, above). */ FOR_EACH_REMOTE_SITE_INDEX(eid) { - if ((int)eid == master) + if (eid == master) continue; site = SITE_FROM_EID(eid); /* - * Send the ack out on primary connection only. + * Send the ack out on primary connections only. */ - if (site->state == SITE_CONNECTED && - (ret = send_permlsn_conn(env, - site->ref.conn, generation, lsn)) != 0) - goto unlock; + if (site->state == SITE_CONNECTED) { + if ((conn = site->ref.conn.in) != NULL && + conn->state == CONN_READY && + (ret = send_permlsn_conn(env, + conn, generation, lsn)) != 0) + goto unlock; + if ((conn = site->ref.conn.out) != NULL && + conn->state == CONN_READY && + (ret = send_permlsn_conn(env, + conn, generation, lsn)) != 0) + goto unlock; + } } } @@ -891,7 +908,7 @@ resolve_limbo_int(env, ip) * there's nothing for us to do. */ eid = db_rep->limbo_victim; - if (eid == DB_EID_INVALID) + if (!IS_VALID_EID(eid)) goto out; site = SITE_FROM_EID(eid); addr = site->net_addr; @@ -1187,7 +1204,7 @@ rescind_pending(env, ip, eid, cur_status, new_status) db_rep = env->rep_handle; -retry: +retry: if ((ret = __repmgr_setup_gmdb_op(env, ip, NULL, 0)) != 0) return (ret); diff --git a/src/repmgr/repmgr_net.c b/src/repmgr/repmgr_net.c index 24f7c1c3..54e3d066 100644 --- a/src/repmgr/repmgr_net.c +++ b/src/repmgr/repmgr_net.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -48,11 +48,20 @@ struct sending_msg { REPMGR_FLAT *fmsg; }; -/* Context for a thread waiting for client acks for PERM message. */ +/* + * Context for a thread waiting for client acks for PERM message. Passed from + * the send() function to the got_acks() predicate function, via + * __repmgr_await_cond(). The got_acks() function computes two potentially + * independent results: (1) do we have enough acks to stop waiting for more (the + * function return value, which triggers the behavior of await_cond()); and (2) + * whether the PERM message should be considered durable. + */ struct repmgr_permanence { DB_LSN lsn; /* LSN whose ack this thread is waiting for. */ - u_int threshold; /* Number of client acks needed. */ + u_int threshold; /* Number of client acks to wait for. */ + u_int quorum; /* Durability threshold for QUORUM policy. */ int policy; /* Ack policy to be used for this txn. */ + int is_durable; /* Result flag. */ }; #ifdef CONFIG_TEST @@ -60,7 +69,7 @@ static u_int fake_port __P((ENV *, u_int)); #endif static int final_cleanup __P((ENV *, REPMGR_CONNECTION *, void *)); static int flatten __P((ENV *, struct sending_msg *)); -static int is_permanent __P((ENV *, void *)); +static int got_acks __P((ENV *, void *)); static int __repmgr_finish_connect __P((ENV *, socket_t s, REPMGR_CONNECTION **)); static int __repmgr_propose_version __P((ENV *, REPMGR_CONNECTION *)); @@ -71,8 +80,10 @@ static int __repmgr_send_internal __P((ENV *, REPMGR_CONNECTION *, struct sending_msg *, db_timeout_t)); static int enqueue_msg __P((ENV *, REPMGR_CONNECTION *, struct sending_msg *, size_t)); -static REPMGR_SITE *__repmgr_available_site __P((ENV *, int)); +static REPMGR_SITE *connected_site __P((ENV *, int)); static REPMGR_SITE *__repmgr_find_available_peer __P((ENV *)); +static int send_connection __P((ENV *, u_int, + REPMGR_CONNECTION *, struct sending_msg *, int *)); /* * Connects to the given network address, using blocking operations. Any thread @@ -173,7 +184,8 @@ __repmgr_finish_connect(env, s, connp) if ((ret = __repmgr_new_connection(env, &conn, s, CONN_CONNECTED)) != 0) return (ret); - if ((ret = __repmgr_propose_version(env, conn)) == 0) + if ((ret = __repmgr_set_keepalive(env, conn)) == 0 && + (ret = __repmgr_propose_version(env, conn)) == 0) *connp = conn; else (void)__repmgr_destroy_conn(env, conn); @@ -258,22 +270,21 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) struct repmgr_permanence perm; db_timeout_t maxblock; u_int32_t available, nclients, needed, npeers_sent, nsites_sent, quorum; - int policy, ret, t_ret; + int missed_peer, policy, ret, t_ret; env = dbenv->env; db_rep = env->rep_handle; rep = db_rep->region; ret = 0; - COMPQUIET(quorum, 0); LOCK_MUTEX(db_rep->mutex); /* - * If we're already "finished", we can't send anything. This covers the + * If we're already "stopped", we can't send anything. This covers the * case where a bulk buffer is flushed at env close, or perhaps an * unexpected __repmgr_thread_failure. */ - if (db_rep->finished) { + if (db_rep->repmgr_status == stopped) { ret = DB_REP_UNAVAIL; goto out; } @@ -287,8 +298,9 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) goto out; if (eid == DB_EID_BROADCAST) { - if ((ret = __repmgr_send_broadcast(env, REPMGR_REP_MESSAGE, - control, rec, &nsites_sent, &npeers_sent)) != 0) + if ((ret = __repmgr_send_broadcast(env, + REPMGR_REP_MESSAGE, control, rec, + &nsites_sent, &npeers_sent, &missed_peer)) != 0) goto out; } else { DB_ASSERT(env, IS_KNOWN_REMOTE_SITE(eid)); @@ -312,16 +324,13 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) (site = __repmgr_find_available_peer(env)) != NULL) { VPRINT(env, (env, DB_VERB_REPMGR_MISC, "sending request to peer")); - } else if ((site = __repmgr_available_site(env, eid)) == - NULL) { + } else if ((site = connected_site(env, eid)) == NULL) { RPRINT(env, (env, DB_VERB_REPMGR_MISC, "ignoring message sent to unavailable site")); ret = DB_REP_UNAVAIL; goto out; } - conn = site->ref.conn; - /* * In case the connection is clogged up and we have to wait for * space on the output queue, how long shall we wait? We could @@ -339,28 +348,59 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) maxblock = OUT_QUEUE_LIMIT * (rep->ack_timeout == 0 ? DB_REPMGR_DEFAULT_ACK_TIMEOUT : rep->ack_timeout); - if ((ret = __repmgr_send_one(env, conn, REPMGR_REP_MESSAGE, - control, rec, maxblock)) == DB_REP_UNAVAIL && - (t_ret = __repmgr_bust_connection(env, conn)) != 0) - ret = t_ret; + + /* + * Assign the conn struct pointer to a local variable ("conn"), + * because the pointer in the site struct (ref.conn.in or + * ref.conn.out) could get clobbered if the connection gets + * busted in another thread during our send_one() call. That + * could happen if the outgoing half of the connection is + * clogged and we decide to await_drain(). + */ +#undef SEND_ONE_CONNECTION +#define SEND_ONE_CONNECTION(c) \ + do { \ + if ((conn = (c)) != NULL && \ + IS_READY_STATE(conn->state) && \ + (ret = __repmgr_send_one(env, \ + conn, REPMGR_REP_MESSAGE, \ + control, rec, maxblock)) == DB_REP_UNAVAIL && \ + (t_ret = \ + __repmgr_bust_connection(env, conn)) != 0) \ + ret = t_ret; \ + } while (0) + + SEND_ONE_CONNECTION(site->ref.conn.in); + if (ret != 0 && ret != DB_REP_UNAVAIL) + goto out; + SEND_ONE_CONNECTION(site->ref.conn.out); if (ret != 0) goto out; +#undef SEND_ONE_CONNECTION nsites_sent = 1; npeers_sent = F_ISSET(site, SITE_ELECTABLE) ? 1 : 0; + missed_peer = FALSE; } /* - * Right now, nsites and npeers represent the (maximum) number of sites - * we've attempted to begin sending the message to. Of course we - * haven't really received any ack's yet. But since we've only sent to - * nsites/npeers other sites, that's the maximum number of ack's we - * could possibly expect. If even that number fails to satisfy our PERM - * policy, there's no point waiting for something that will never - * happen. + * Traditionally, each ack policy determines how many acks are needed to + * constitute successful durability. We would simply wait until we + * collected that many acks, and if we got them it was success, or if we + * timed out it was failure. And if we knew from the start that we + * hadn't even sent the message to enough sites to meet the "needed" + * threshold, then there was no point in waiting. + * It's a different story for the ALL_AVAILABLE policy. There the + * decision to continue awaiting more acks is decoupled from the + * durability question: we want to wait until we get acks from all sites + * we sent to (though still within the timeout limit). + * So now we have to think of "needed" in a slightly more general + * way: it's the threshold that controls how many acks we keep waiting + * for. It's usually still also controls the determination of the + * durability result; except not for ALL_AVAILABLE. */ if (LF_ISSET(DB_REP_PERMANENT)) { - /* Adjust so as not to count the local site. */ + /* Adjust so as not to count the local site, which is master. */ nclients = db_rep->region->config_nsites -1; /* @@ -389,6 +429,7 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) case none: break; } + quorum = 0; switch (policy) { case DB_REPMGR_ACKS_NONE: needed = 0; @@ -458,29 +499,62 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) FLD_ISSET(db_rep->region->config, REP_C_2SITE_STRICT) || db_rep->active_gmdb_update == gmdb_primary) - needed = nclients / 2; + quorum = nclients / 2; else - needed = nclients; + quorum = nclients; + if (policy == DB_REPMGR_ACKS_ALL_AVAILABLE) { - quorum = needed; - needed = available = nsites_sent; + if (nsites_sent > 0) + needed = available = nsites_sent; + else { + ret = quorum > 0 ? DB_REP_UNAVAIL : 0; + goto out; + } } else { + DB_ASSERT(env, policy == DB_REPMGR_ACKS_QUORUM); + needed = quorum; available = npeers_sent; - quorum = 0; + if (npeers_sent < quorum && !missed_peer) { + /* + * If we sent to all peers, it doesn't + * matter how few there were. This + * derives from the definition of the + * QUORUM policy: no possible subsequent + * election can fail to include the + * transaction. If all electable sites + * have the transaction, then it can't + * be lost in an election, no matter how + * few there are. + */ + needed = npeers_sent; + } } break; default: - COMPQUIET(available, 0); - COMPQUIET(needed, 0); - (void)__db_unknown_path(env, "__repmgr_send"); - break; + ret = __db_unknown_path(env, "__repmgr_send"); + goto out; } - if (needed == 0) - goto out; - if (available < needed) { - ret = DB_REP_UNAVAIL; - goto out; + if (policy != DB_REPMGR_ACKS_ALL_AVAILABLE) { + /* + * Skip the waiting if it is unnecessary, or if it would + * be futile. For most ack policies, these decisions + * are straightforward, and can be computed in the + * following generic way. For ALL_AVAILABLE, skipping + * is also possible, but it is decided earlier (above, + * inside the "switch" statement). + * + * Note that for ALL, there is a surprising side-effect + * if even one client is down. It will not wait for + * any acks and the running clients can fall further + * and further behind the master. + */ + if (needed == 0) + goto out; + if (available < needed) { + ret = DB_REP_UNAVAIL; + goto out; + } } /* In ALL_PEERS case, display of "needed" might be confusing. */ @@ -489,17 +563,12 @@ __repmgr_send(dbenv, control, rec, lsnp, eid, flags) perm.lsn = *lsnp; perm.threshold = needed; perm.policy = policy; - ret = __repmgr_await_cond(env, is_permanent, + perm.quorum = quorum; + perm.is_durable = FALSE; + ret = __repmgr_await_cond(env, got_acks, &perm, rep->ack_timeout, &db_rep->ack_waiters); - /* - * If using ACKS_ALL_AVAILABLE and all possible sites acked, - * only return success if we have a quorum minimum available - * to ensure data integrity. - */ - if (ret == 0 && - policy == DB_REPMGR_ACKS_ALL_AVAILABLE && - available < quorum) - ret = DB_REP_UNAVAIL; + if (ret == 0 || ret == DB_TIMEOUT) + ret = perm.is_durable ? 0 : DB_REP_UNAVAIL; } out: UNLOCK_MUTEX(db_rep->mutex); @@ -561,7 +630,7 @@ out: UNLOCK_MUTEX(db_rep->mutex); } static REPMGR_SITE * -__repmgr_available_site(env, eid) +connected_site(env, eid) ENV *env; int eid; { @@ -569,8 +638,9 @@ __repmgr_available_site(env, eid) REPMGR_SITE *site; db_rep = env->rep_handle; + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); - if (IS_SITE_HANDSHAKEN(site)) + if (site->state == SITE_CONNECTED) return (site); return (NULL); } @@ -602,7 +672,8 @@ __repmgr_sync_siteaddr(env) added = db_rep->site_cnt; if ((ret = __repmgr_copy_in_added_sites(env)) == 0) - ret = __repmgr_init_new_sites(env, added, db_rep->site_cnt); + ret = __repmgr_init_new_sites(env, (int)added, + (int)db_rep->site_cnt); MUTEX_UNLOCK(env, rep->mtx_repmgr); return (ret); @@ -617,32 +688,24 @@ __repmgr_sync_siteaddr(env) * !!! * Caller must hold env->mutex. * PUBLIC: int __repmgr_send_broadcast __P((ENV *, u_int, - * PUBLIC: const DBT *, const DBT *, u_int *, u_int *)); + * PUBLIC: const DBT *, const DBT *, u_int *, u_int *, int *)); */ int -__repmgr_send_broadcast(env, type, control, rec, nsitesp, npeersp) +__repmgr_send_broadcast(env, type, control, rec, nsitesp, npeersp, missingp) ENV *env; u_int type; const DBT *control, *rec; u_int *nsitesp, *npeersp; + int *missingp; { DB_REP *db_rep; REP *rep; struct sending_msg msg; - REPMGR_CONNECTION *conn; REPMGR_SITE *site; REPMGR_IOVECS iovecs; u_int8_t msg_hdr_buf[__REPMGR_MSG_HDR_SIZE]; - u_int eid, nsites, npeers; - int full_member, ret; - - static const u_int version_max_msg_type[] = { - 0, - REPMGR_MAX_V1_MSG_TYPE, - REPMGR_MAX_V2_MSG_TYPE, - REPMGR_MAX_V3_MSG_TYPE, - REPMGR_MAX_V4_MSG_TYPE - }; + u_int nsites, npeers; + int eid, full_member, has_missing_peer, ret, sent1, sent2; db_rep = env->rep_handle; rep = db_rep->region; @@ -659,11 +722,13 @@ __repmgr_send_broadcast(env, type, control, rec, nsitesp, npeersp) msg.iovecs = &iovecs; setup_sending_msg(env, &msg, msg_hdr_buf, type, control, rec); nsites = npeers = 0; + has_missing_peer = FALSE; /* Send to (only the main connection with) every site. */ FOR_EACH_REMOTE_SITE_INDEX(eid) { - if ((site = __repmgr_available_site(env, (int)eid)) == NULL) - continue; + sent1 = sent2 = FALSE; + site = SITE_FROM_EID(eid); + /* * Exclude non-member sites, unless we're the master, since it's * useful to keep letting a removed site see updates so that it @@ -675,71 +740,118 @@ __repmgr_send_broadcast(env, type, control, rec, nsitesp, npeersp) else { full_member = FALSE; if (rep->master_id != db_rep->self_eid) - continue; + goto next; } - conn = site->ref.conn; - - DB_ASSERT(env, IS_KNOWN_REMOTE_SITE(conn->eid) && - conn->version > 0 && - conn->version <= DB_REPMGR_VERSION); /* - * Skip if the type of message we're sending is beyond the range - * of known message types for this connection's version. - * - * !!! - * Don't be misled by the apparent generality of this simple - * test. It works currently, because the only kinds of messages - * that we broadcast are REP_MESSAGE and HEARTBEAT. But in the - * future other kinds of messages might require more intricate - * per-connection-version customization (for example, - * per-version message format conversion, addition of new - * fields, etc.). + * Send message on either or both main connections, as + * available. */ - if (type > version_max_msg_type[conn->version]) - continue; - + if ((ret = send_connection(env, type, + site->ref.conn.in, &msg, &sent1)) != 0) + return (ret); + if ((ret = send_connection(env, type, + site->ref.conn.out, &msg, &sent2)) != 0) + return (ret); +next: /* - * Broadcast messages are either application threads committing - * transactions, or replication status message that we can - * afford to lose. So don't allow blocking for them (pass - * maxblock argument as 0). + * Count how many full-fledged member sites we sent to, and how + * many of those were electable peers. These values will be + * used by the caller to manage waiting for acks. Ignore + * non-full-fledged member sites because we don't accept acks + * from them. */ - if ((ret = __repmgr_send_internal(env, conn, &msg, 0)) == 0) { - if (full_member) { - /* - * Since the purpose of the counting is to - * manage waiting for acks, only count sites we - * send to from which we can reasonably expect - * to get an ack. When a site is not a fully - * "present" member of the group we can't accept - * an ack from it. - */ + if (full_member) { + if (sent1 || sent2) { nsites++; if (F_ISSET(site, SITE_ELECTABLE)) npeers++; + } else { + /* + * Keep track of whether any of the sites we + * failed to send to was an electable peer. If + * we don't know a site's electability yet, we + * assume the worst in order to be safe. + */ + if (!F_ISSET(site, SITE_HAS_PRIO) || + F_ISSET(site, SITE_ELECTABLE)) + has_missing_peer = TRUE; } - } else if (ret == DB_TIMEOUT) { - /* - * Couldn't send because of a full output queue. - * Incrementing counters would be wrong, but it's - * otherwise OK in the sense that the connection isn't - * definitively known to be broken, and rep protocol - * always allows us to drop a message if we have to. - */ - ret = 0; - } else if (ret == DB_REP_UNAVAIL) { - if ((ret = __repmgr_bust_connection(env, conn)) != 0) - return (ret); - } else - return (ret); + } } *nsitesp = nsites; *npeersp = npeers; + *missingp = has_missing_peer; return (0); } +static int +send_connection(env, type, conn, msg, sent) + ENV *env; + u_int type; + REPMGR_CONNECTION *conn; + struct sending_msg *msg; + int *sent; +{ + DB_REP *db_rep; + int ret; + + static const u_int version_max_msg_type[] = { + 0, + REPMGR_MAX_V1_MSG_TYPE, + REPMGR_MAX_V2_MSG_TYPE, + REPMGR_MAX_V3_MSG_TYPE, + REPMGR_MAX_V4_MSG_TYPE + }; + + db_rep = env->rep_handle; + *sent = FALSE; + if (conn == NULL || !IS_READY_STATE(conn->state)) + return (0); + + DB_ASSERT(env, IS_KNOWN_REMOTE_SITE(conn->eid) && + conn->version > 0 && + conn->version <= DB_REPMGR_VERSION); + + /* + * Skip if the type of message we're sending is beyond the range + * of known message types for this connection's version. + * + * !!! + * Don't be misled by the apparent generality of this simple + * test. It works currently, because the only kinds of messages + * that we broadcast are REP_MESSAGE and HEARTBEAT. But in the + * future other kinds of messages might require more intricate + * per-connection-version customization (for example, + * per-version message format conversion, addition of new + * fields, etc.). + */ + if (type > version_max_msg_type[conn->version]) + return (0); + + /* + * Broadcast messages are either application threads committing + * transactions, or replication status message that we can + * afford to lose. So don't allow blocking for them (pass + * maxblock argument as 0). + */ + if ((ret = __repmgr_send_internal(env, conn, msg, 0)) == 0) + *sent = TRUE; + else if (ret == DB_TIMEOUT) { + /* + * Couldn't send because of a full output queue. + * Indicating that we sent it would be wrong, but it's + * otherwise OK in the sense that the connection isn't + * definitively known to be broken, and rep protocol + * always allows us to drop a message if we have to. + */ + ret = 0; + } else if (ret == DB_REP_UNAVAIL) + ret = __repmgr_bust_connection(env, conn); + return (ret); +} + /* * __repmgr_send_one -- * Send a message to a site, or if you can't just yet, make a copy of it @@ -880,8 +992,8 @@ __repmgr_send_internal(env, conn, msg, maxblock) conn->ref_count--; VPRINT(env, (env, DB_VERB_REPMGR_MISC, "drain returned %d (%d,%d)", ret, - db_rep->finished, conn->out_queue_length)); - if (db_rep->finished) + db_rep->repmgr_status, conn->out_queue_length)); + if (db_rep->repmgr_status == stopped) return (DB_TIMEOUT); if (ret != 0) return (ret); @@ -989,32 +1101,35 @@ __repmgr_write_iovecs(env, conn, iovecs, writtenp) } /* - * Count up how many sites have ack'ed the given LSN. Returns TRUE if enough - * sites have ack'ed; FALSE otherwise. + * Count up how many sites have ack'ed the given LSN. + * + * Computes two results: the main result (function's return code) is a boolean + * flag indicating whether we've gotten all the acks we need and can therefore + * stop waiting for more. The perm->is_durable field determines whether we got + * enough acks to consider the transaction durably replicated. These two + * results are almost always the same, except when using the ALL_AVAILABLE + * policy. * * !!! * Caller must hold the mutex. */ static int -is_permanent(env, context) +got_acks(env, context) ENV *env; void *context; { DB_REP *db_rep; REPMGR_SITE *site; struct repmgr_permanence *perm; - u_int eid, nsites, npeers; - int is_perm, has_missing_peer, policy; + u_int sites_acked, peers_acked; + int done, eid, has_unacked_peer, is_perm, policy; db_rep = env->rep_handle; perm = context; policy = perm->policy; - if (policy == DB_REPMGR_ACKS_NONE) - return (TRUE); - - nsites = npeers = 0; - has_missing_peer = FALSE; + sites_acked = peers_acked = 0; + has_unacked_peer = FALSE; FOR_EACH_REMOTE_SITE_INDEX(eid) { site = SITE_FROM_EID(eid); if (site->membership != SITE_PRESENT) @@ -1024,42 +1139,50 @@ is_permanent(env, context) * Never connected to this site: since we can't know * whether it's a peer, assume the worst. */ - has_missing_peer = TRUE; + has_unacked_peer = TRUE; continue; } if (LOG_COMPARE(&site->max_ack, &perm->lsn) >= 0) { - nsites++; + sites_acked++; if (F_ISSET(site, SITE_ELECTABLE)) - npeers++; + peers_acked++; } else { /* This site hasn't ack'ed the message. */ if (F_ISSET(site, SITE_ELECTABLE)) - has_missing_peer = TRUE; + has_unacked_peer = TRUE; } } VPRINT(env, (env, DB_VERB_REPMGR_MISC, "checking perm result, %lu, %lu, %d", - (u_long)nsites, (u_long)npeers, has_missing_peer)); + (u_long)sites_acked, (u_long)peers_acked, has_unacked_peer)); switch (policy) { case DB_REPMGR_ACKS_ALL: - case DB_REPMGR_ACKS_ALL_AVAILABLE: case DB_REPMGR_ACKS_ONE: - is_perm = (nsites >= perm->threshold); + is_perm = (sites_acked >= perm->threshold); break; case DB_REPMGR_ACKS_ONE_PEER: + is_perm = (peers_acked >= perm->threshold); + break; case DB_REPMGR_ACKS_QUORUM: - is_perm = (npeers >= perm->threshold); + case DB_REPMGR_ACKS_ALL_AVAILABLE: + is_perm = (peers_acked >= perm->quorum) || !has_unacked_peer; break; case DB_REPMGR_ACKS_ALL_PEERS: - is_perm = !has_missing_peer; + is_perm = !has_unacked_peer; break; default: is_perm = FALSE; - (void)__db_unknown_path(env, "is_permanent"); + (void)__db_unknown_path(env, "got_acks"); } - return (is_perm); + if (is_perm) + perm->is_durable = TRUE; + if (policy == DB_REPMGR_ACKS_ALL_AVAILABLE) + done = sites_acked >= perm->threshold; + else + done = is_perm; + return (done); } /* @@ -1068,6 +1191,8 @@ is_permanent(env, context) * that happens later, in the select() thread main loop. See further * explanation at function __repmgr_disable_connection(). * + * Idempotent. + * * PUBLIC: int __repmgr_bust_connection __P((ENV *, REPMGR_CONNECTION *)); * * !!! @@ -1082,76 +1207,107 @@ __repmgr_bust_connection(env, conn) REP *rep; REPMGR_SITE *site; u_int32_t flags; - int ret, subordinate_conn, eid; + int ret, eid; db_rep = env->rep_handle; rep = db_rep->region; - ret = 0; + if (conn->state == CONN_DEFUNCT) + return (0); eid = conn->eid; if ((ret = __repmgr_disable_connection(env, conn)) != 0) return (ret); /* - * Take any/all appropriate recovery steps, depending on the nature of - * the connection, whom it was with, and our current role. + * When we have lost the connection to another site, take any/all + * appropriate recovery steps. But what does it mean to lose "the" + * connection, now that we actually have various different kinds of + * connection? + * + * 1. We're only talking about "rep" connections. Connections backing + * user channels aren't of concern here. + * 2. Subordinate connections are also not of concern here. + * 3. If we have two "main" connections with a given remote site (one + * incoming and the other outgoing), then if we lose one we still + * have the other. So, we still "have a connection" with the remote + * site. + * + * Finally, the appropriate recovery steps also depend on the current + * replication role (master/client) of both the local site and the + * remote site. */ - if (conn->type == REP_CONNECTION && IS_KNOWN_REMOTE_SITE(eid)) { - site = SITE_FROM_EID(eid); - subordinate_conn = (conn != site->ref.conn); + if (conn->type != REP_CONNECTION || !IS_KNOWN_REMOTE_SITE(eid)) + goto out; - if (!subordinate_conn && - (ret = __repmgr_schedule_connection_attempt(env, - (u_int)eid, FALSE)) != 0) - return (ret); + site = SITE_FROM_EID(eid); + /* + * When closing one of our main connections ("in" or "out"), if we still + * have the other one present, then we still consider ourselves to be + * connected, so there's nothing more to do. But if we have now become + * "not connected", we have some recovery steps to do. (Note that we + * don't care at all about subordinate connections, for the purposes of + * recovery steps.) + */ + if (conn == site->ref.conn.in) { + site->ref.conn.in = NULL; + if (site->ref.conn.out != NULL) /* We're still connected. */ + goto out; + } else if (conn == site->ref.conn.out) { + site->ref.conn.out = NULL; + if (site->ref.conn.in != NULL) + goto out; + } else /* Subordinate connection. */ + goto out; + if ((ret = __repmgr_schedule_connection_attempt(env, eid, FALSE)) != 0) + goto out; + + /* + * If the failed connection was the one between us and the + * master, assume that the master may have failed, and call for + * an election. But only do this for the connection to the main + * master process, not a subordinate one. And only do it if + * we're our site's main process, not a subordinate one. And + * skip it if the application has configured us not to do + * elections. + */ + if (!IS_SUBORDINATE(db_rep) && eid == rep->master_id) { /* - * If the failed connection was the one between us and the - * master, assume that the master may have failed, and call for - * an election. But only do this for the connection to the main - * master process, not a subordinate one. And only do it if - * we're our site's main process, not a subordinate one. And - * skip it if the application has configured us not to do - * elections. + * Even if we're not doing elections, defer the event + * notification to later execution in the election + * thread. We don't want to fire an event in the select + * thread, and certainly not while holding the mutex. */ - if (!IS_SUBORDINATE(db_rep) && - !subordinate_conn && eid == rep->master_id) { - /* - * Even if we're not doing elections, defer the event - * notification to later execution in the election - * thread. We don't want to fire an event in the select - * thread, and certainly not while holding the mutex. - */ - flags = ELECT_F_EVENT_NOTIFY; - if (FLD_ISSET(db_rep->region->config, REP_C_ELECTIONS)) - LF_SET(ELECT_F_IMMED | ELECT_F_FAST); - else - RPRINT(env, (env, DB_VERB_REPMGR_MISC, - "Master failure, but no elections")); - - if ((ret = __repmgr_init_election(env, flags)) != 0) - return (ret); - } - - /* - * If we're the master site, and we lose a main connection to a - * client (whether we're the main replication process or a - * subordinate process), then the client is going to have - * trouble receiving live log records from us. So, set the - * temporary log archive block timer, to give the client a - * fighting chance to restart/recover/reconnect. (We don't care - * about the client's subordinate connections to us -- i.e., - * connections with a subordinate process at the client site -- - * because those sites can only be reading, not applying updates - * from us.) - */ - if (!subordinate_conn && rep->master_id == db_rep->self_eid) { + flags = ELECT_F_EVENT_NOTIFY; + if (FLD_ISSET(db_rep->region->config, REP_C_ELECTIONS)) + LF_SET(ELECT_F_IMMED | ELECT_F_FAST); + else RPRINT(env, (env, DB_VERB_REPMGR_MISC, - "Repmgr: bust connection. Block archive")); - MASTER_UPDATE(env, (REGENV *)env->reginfo->primary); - } + "Master failure, but no elections")); + + if ((ret = __repmgr_init_election(env, flags)) != 0) + goto out; } - return (0); + + /* + * If we're the master site, and we lose a main connection to a + * client (whether we're the main replication process or a + * subordinate process), then the client is going to have + * trouble receiving live log records from us. So, set the + * temporary log archive block timer, to give the client a + * fighting chance to restart/recover/reconnect. (We don't care + * about the client's subordinate connections to us -- i.e., + * connections with a subordinate process at the client site -- + * because those sites can only be reading, not applying updates + * from us.) + */ + if (rep->master_id == db_rep->self_eid) { + RPRINT(env, (env, DB_VERB_REPMGR_MISC, + "Repmgr: bust connection. Block archive")); + MASTER_UPDATE(env, (REGENV *)env->reginfo->primary); + } +out: + return (ret); } /* @@ -1197,7 +1353,8 @@ __repmgr_disable_connection(env, conn) eid = conn->eid; if (IS_VALID_EID(eid)) { site = SITE_FROM_EID(eid); - if (conn != site->ref.conn) + if (conn != site->ref.conn.in && + conn != site->ref.conn.out) /* It's a subordinate connection. */ TAILQ_REMOVE(&site->sub_conns, conn, entries); TAILQ_INSERT_TAIL(&db_rep->connections, conn, entries); @@ -1498,6 +1655,7 @@ __repmgr_find_available_peer(env) { DB_REP *db_rep; REP *rep; + REPMGR_CONNECTION *conn; REPMGR_SITE *site; u_int i; @@ -1507,7 +1665,11 @@ __repmgr_find_available_peer(env) site = &db_rep->sites[i]; if (FLD_ISSET(site->config, DB_REPMGR_PEER) && EID_FROM_SITE(site) != rep->master_id && - IS_SITE_AVAILABLE(site)) + site->state == SITE_CONNECTED && + (((conn = site->ref.conn.in) != NULL && + conn->state == CONN_READY) || + ((conn = site->ref.conn.out) != NULL && + conn->state == CONN_READY))) return (site); } return (NULL); @@ -1635,6 +1797,7 @@ __repmgr_listen(env) if (bind(s, ai->ai_addr, (socklen_t)ai->ai_addrlen) != 0) { why = DB_STR("3586", "can't bind socket to listening address"); + ret = net_errno; (void)closesocket(s); s = INVALID_SOCKET; continue; @@ -1655,7 +1818,8 @@ __repmgr_listen(env) goto out; } - ret = net_errno; + if (ret == 0) + ret = net_errno; __db_err(env, ret, "%s", why); clean: if (s != INVALID_SOCKET) (void)closesocket(s); @@ -1673,12 +1837,21 @@ __repmgr_net_close(env) { DB_REP *db_rep; REP *rep; + REPMGR_SITE *site; + u_int eid; int ret; db_rep = env->rep_handle; rep = db_rep->region; - ret = __repmgr_each_connection(env, final_cleanup, NULL, FALSE); + if ((ret = __repmgr_each_connection(env, final_cleanup, NULL, + FALSE)) == 0) { + FOR_EACH_REMOTE_SITE_INDEX(eid) { + site = SITE_FROM_EID(eid); + site->ref.conn.in = NULL; + site->ref.conn.out = NULL; + } + } if (db_rep->listen_fd != INVALID_SOCKET) { if (closesocket(db_rep->listen_fd) == SOCKET_ERROR && ret == 0) @@ -1708,7 +1881,8 @@ final_cleanup(env, conn, unused) if (conn->type == REP_CONNECTION && IS_VALID_EID(conn->eid)) { site = SITE_FROM_EID(conn->eid); - if (site->state == SITE_CONNECTED && conn == site->ref.conn) { + if (site->state == SITE_CONNECTED && + (conn == site->ref.conn.in || conn == site->ref.conn.out)) { /* Not on any list, so no need to do anything. */ } else TAILQ_REMOVE(&site->sub_conns, conn, entries); @@ -1732,11 +1906,6 @@ __repmgr_net_destroy(env, db_rep) DB_REP *db_rep; { REPMGR_RETRY *retry; - REPMGR_SITE *site; - u_int i; - - if (db_rep->sites == NULL) - return; while (!TAILQ_EMPTY(&db_rep->retries)) { retry = TAILQ_FIRST(&db_rep->retries); @@ -1745,14 +1914,6 @@ __repmgr_net_destroy(env, db_rep) } DB_ASSERT(env, TAILQ_EMPTY(&db_rep->connections)); - - for (i = 0; i < db_rep->site_cnt; i++) { - site = &db_rep->sites[i]; - DB_ASSERT(env, TAILQ_EMPTY(&site->sub_conns)); - __repmgr_cleanup_netaddr(env, &site->net_addr); - } - __os_free(env, db_rep->sites); - db_rep->sites = NULL; } #ifdef CONFIG_TEST @@ -1771,7 +1932,7 @@ __repmgr_net_destroy(env, db_rep) * response could name the same port as the "real" port we sent it. * * !!! This is only used for testing. - */ + */ static u_int fake_port(env, port) ENV *env; @@ -1807,7 +1968,7 @@ fake_port(env, port) s = INVALID_SOCKET; for (ai = ai0; ai != NULL; ai = ai->ai_next) { if ((s = socket(ai->ai_family, - ai->ai_socktype, ai->ai_protocol)) == SOCKET_ERROR) { + ai->ai_socktype, ai->ai_protocol)) == SOCKET_ERROR) { ret = net_errno; s = INVALID_SOCKET; __db_err(env, ret, "fake_port:socket"); @@ -1818,7 +1979,7 @@ fake_port(env, port) * tests. When there is no "port arbiter" running, it's not an * error; it just means we should use the normal configured port * as is. - */ + */ if (connect(s, ai->ai_addr, (socklen_t)ai->ai_addrlen) != 0) { ret = net_errno; (void)closesocket(s); @@ -1873,7 +2034,7 @@ err: * Note that we always return some port value, even if an error happens. * Since this is just test code: if an error prevented proper fake port * substitution, it should result in a test failure. - */ + */ if (s != INVALID_SOCKET) (void)closesocket(s); __os_freeaddrinfo(env, ai0); diff --git a/src/repmgr/repmgr_posix.c b/src/repmgr/repmgr_posix.c index 70df3fff..0687681a 100644 --- a/src/repmgr/repmgr_posix.c +++ b/src/repmgr/repmgr_posix.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -159,7 +159,7 @@ __repmgr_await_cond(env, pred, ctx, timeout, wait_condition) db_rep->mutex, &deadline); else ret = pthread_cond_wait(wait_condition, db_rep->mutex); - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) return (DB_REP_UNAVAIL); if (ret == ETIMEDOUT) return (DB_TIMEOUT); @@ -265,7 +265,7 @@ __repmgr_await_drain(env, conn, timeout) db_rep->mutex, &deadline); switch (ret) { case 0: - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) goto out; /* #4. */ /* * Another thread could have stumbled into an error on @@ -692,7 +692,7 @@ __repmgr_select_loop(env) } } LOCK_MUTEX(db_rep->mutex); - if (db_rep->finished) { + if (db_rep->repmgr_status == stopped) { ret = 0; goto out; } @@ -728,6 +728,11 @@ __repmgr_select_loop(env) goto out; } out: + UNLOCK_MUTEX(db_rep->mutex); + if (ret == DB_DELETED) + ret = __repmgr_bow_out(env); + LOCK_MUTEX(db_rep->mutex); + (void)__repmgr_net_close(env); UNLOCK_MUTEX(db_rep->mutex); return (ret); } diff --git a/src/repmgr/repmgr_queue.c b/src/repmgr/repmgr_queue.c index de13e725..6a381acf 100644 --- a/src/repmgr/repmgr_queue.c +++ b/src/repmgr/repmgr_queue.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -70,7 +70,7 @@ __repmgr_queue_get(env, msgp, th) db_rep = env->rep_handle; while ((m = available_work(env)) == NULL && - !db_rep->finished && !th->quit_requested) { + db_rep->repmgr_status == running && !th->quit_requested) { #ifdef DB_WIN32 /* * On Windows, msg_avail means either there's something in the @@ -78,7 +78,7 @@ __repmgr_queue_get(env, msgp, th) * not true. */ if (STAILQ_EMPTY(&db_rep->input_queue.header) && - !db_rep->finished && + db_rep->repmgr_status == running && !ResetEvent(db_rep->msg_avail)) { ret = GetLastError(); goto err; @@ -99,7 +99,7 @@ __repmgr_queue_get(env, msgp, th) goto err; #endif } - if (db_rep->finished || th->quit_requested) + if (db_rep->repmgr_status == stopped || th->quit_requested) ret = DB_REP_UNAVAIL; else { STAILQ_REMOVE(&db_rep->input_queue.header, @@ -119,7 +119,7 @@ err: * is. But otherwise skip over any message type that may possibly turn out to * be "long-running", so that we avoid starving out the important rep message * processing. - */ + */ static REPMGR_MESSAGE * available_work(env) ENV *env; @@ -135,7 +135,7 @@ available_work(env) * currently processing non-replication messages (a.k.a. possibly * long-running messages, a.k.a. "deferrable"). We always ensure that * db_rep->nthreads > reserved. - */ + */ if (db_rep->nthreads > db_rep->non_rep_th + RESERVED_MSG_TH(env)) return (STAILQ_FIRST(&db_rep->input_queue.header)); STAILQ_FOREACH(m, &db_rep->input_queue.header, entries) { diff --git a/src/repmgr/repmgr_sel.c b/src/repmgr/repmgr_sel.c index 18741fca..ba14368f 100644 --- a/src/repmgr/repmgr_sel.c +++ b/src/repmgr/repmgr_sel.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -14,22 +14,24 @@ typedef int (*HEARTBEAT_ACTION) __P((ENV *)); static int accept_handshake __P((ENV *, REPMGR_CONNECTION *, char *)); static int accept_v1_handshake __P((ENV *, REPMGR_CONNECTION *, char *)); -static int __repmgr_call_election __P((ENV *)); -static int __repmgr_connector_main __P((ENV *, REPMGR_RUNNABLE *)); -static void *__repmgr_connector_thread __P((void *)); +static void check_min_log_file __P((ENV *)); static int dispatch_msgin __P((ENV *, REPMGR_CONNECTION *)); -static int __repmgr_next_timeout __P((ENV *, - db_timespec *, HEARTBEAT_ACTION *)); static int prepare_input __P((ENV *, REPMGR_CONNECTION *)); static int process_own_msg __P((ENV *, REPMGR_CONNECTION *)); static int process_parameters __P((ENV *, REPMGR_CONNECTION *, char *, u_int, u_int32_t, int, u_int32_t)); static int read_version_response __P((ENV *, REPMGR_CONNECTION *)); static int record_permlsn __P((ENV *, REPMGR_CONNECTION *)); +static int __repmgr_call_election __P((ENV *)); +static int __repmgr_connector_main __P((ENV *, REPMGR_RUNNABLE *)); +static void *__repmgr_connector_thread __P((void *)); +static int __repmgr_next_timeout __P((ENV *, + db_timespec *, HEARTBEAT_ACTION *)); static int __repmgr_retry_connections __P((ENV *)); static int __repmgr_send_heartbeat __P((ENV *)); +static int __repmgr_try_one __P((ENV *, int)); +static int resolve_collision __P((ENV *, REPMGR_SITE *, REPMGR_CONNECTION *)); static int send_version_response __P((ENV *, REPMGR_CONNECTION *)); -static int __repmgr_try_one __P((ENV *, u_int)); #define ONLY_HANDSHAKE(env, conn) do { \ if (conn->msg_type != REPMGR_HANDSHAKE) { \ @@ -54,9 +56,7 @@ __repmgr_select_thread(argsp) args = argsp; env = args->env; - if ((ret = __repmgr_select_loop(env)) == DB_DELETED) - ret = __repmgr_bow_out(env); - if (ret != 0) { + if ((ret = __repmgr_select_loop(env)) != 0) { __db_err(env, ret, DB_STR("3614", "select loop failed")); (void)__repmgr_thread_failure(env, ret); } @@ -73,7 +73,6 @@ __repmgr_bow_out(env) DB_REP *db_rep; int ret; - RPRINT(env, (env, DB_VERB_REPMGR_MISC, "Stopping repmgr threads")); db_rep = env->rep_handle; LOCK_MUTEX(db_rep->mutex); ret = __repmgr_stop_threads(env); @@ -142,6 +141,10 @@ __repmgr_accept(env) (void)closesocket(s); return (ret); } + if ((ret = __repmgr_set_keepalive(env, conn)) != 0) { + (void)__repmgr_destroy_conn(env, conn); + return (ret); + } if ((ret = __repmgr_set_nonblock_conn(conn)) != 0) { __db_err(env, ret, DB_STR("3616", "can't set nonblock after accept")); @@ -149,8 +152,6 @@ __repmgr_accept(env) return (ret); } - F_SET(conn, CONN_INCOMING); - /* * We don't yet know which site this connection is coming from. So for * now, put it on the "orphans" list; we'll move it to the appropriate @@ -232,8 +233,9 @@ __repmgr_next_timeout(env, deadline, action) REP *rep; HEARTBEAT_ACTION my_action; REPMGR_CONNECTION *conn; - REPMGR_SITE *site; + REPMGR_SITE *master; db_timespec t; + u_int32_t version; db_rep = env->rep_handle; rep = db_rep->region; @@ -243,19 +245,29 @@ __repmgr_next_timeout(env, deadline, action) t = db_rep->last_bcast; TIMESPEC_ADD_DB_TIMEOUT(&t, rep->heartbeat_frequency); my_action = __repmgr_send_heartbeat; - } else if ((conn = __repmgr_master_connection(env)) != NULL && + } else if ((master = __repmgr_connected_master(env)) != NULL && !IS_SUBORDINATE(db_rep) && - rep->heartbeat_monitor_timeout > 0 && - conn->version >= HEARTBEAT_MIN_VERSION) { - /* - * If we have a working connection to a heartbeat-aware master, - * let's monitor it. Otherwise there's really nothing we can - * do. - */ - site = SITE_FROM_EID(rep->master_id); - t = site->last_rcvd_timestamp; - TIMESPEC_ADD_DB_TIMEOUT(&t, rep->heartbeat_monitor_timeout); - my_action = __repmgr_call_election; + rep->heartbeat_monitor_timeout > 0) { + version = 0; + if ((conn = master->ref.conn.in) != NULL && + IS_READY_STATE(conn->state)) + version = conn->version; + if ((conn = master->ref.conn.out) != NULL && + IS_READY_STATE(conn->state) && + conn->version > version) + version = conn->version; + if (version >= HEARTBEAT_MIN_VERSION) { + /* + * If we have a working connection to a heartbeat-aware + * master, let's monitor it. Otherwise there's really + * nothing we can do. + */ + t = master->last_rcvd_timestamp; + TIMESPEC_ADD_DB_TIMEOUT(&t, + rep->heartbeat_monitor_timeout); + my_action = __repmgr_call_election; + } else + return (FALSE); } else return (FALSE); @@ -285,7 +297,7 @@ __repmgr_send_heartbeat(env) __repmgr_permlsn_args permlsn; u_int8_t buf[__REPMGR_PERMLSN_SIZE]; u_int unused1, unused2; - int ret; + int ret, unused3; db_rep = env->rep_handle; rep = db_rep->region; @@ -299,31 +311,28 @@ __repmgr_send_heartbeat(env) DB_INIT_DBT(rec, NULL, 0); return (__repmgr_send_broadcast(env, - REPMGR_HEARTBEAT, &control, &rec, &unused1, &unused2)); + REPMGR_HEARTBEAT, &control, &rec, &unused1, &unused2, &unused3)); } /* - * PUBLIC: REPMGR_CONNECTION *__repmgr_master_connection __P((ENV *)); - + * PUBLIC: REPMGR_SITE *__repmgr_connected_master __P((ENV *)); */ -REPMGR_CONNECTION * -__repmgr_master_connection(env) +REPMGR_SITE * +__repmgr_connected_master(env) ENV *env; { DB_REP *db_rep; - REP *rep; REPMGR_SITE *master; int master_id; db_rep = env->rep_handle; - rep = db_rep->region; - master_id = rep->master_id; + master_id = db_rep->region->master_id; if (!IS_KNOWN_REMOTE_SITE(master_id)) return (NULL); master = SITE_FROM_EID(master_id); - if (IS_SITE_HANDSHAKEN(master)) - return master->ref.conn; + if (master->state == SITE_CONNECTED) + return (master); return (NULL); } @@ -332,13 +341,22 @@ __repmgr_call_election(env) ENV *env; { REPMGR_CONNECTION *conn; + REPMGR_SITE *master; + int ret; - conn = __repmgr_master_connection(env); - DB_ASSERT(env, conn != NULL); + master = __repmgr_connected_master(env); + if (master == NULL) + return (0); RPRINT(env, (env, DB_VERB_REPMGR_MISC, "heartbeat monitor timeout expired")); STAT(env->rep_handle->region->mstat.st_connection_drop++); - return (__repmgr_bust_connection(env, conn)); + if ((conn = master->ref.conn.in) != NULL && + (ret = __repmgr_bust_connection(env, conn)) != 0) + return (ret); + if ((conn = master->ref.conn.out) != NULL && + (ret = __repmgr_bust_connection(env, conn)) != 0) + return (ret); + return (0); } /* @@ -381,8 +399,7 @@ __repmgr_retry_connections(env) REPMGR_SITE *site; REPMGR_RETRY *retry; db_timespec now; - u_int eid; - int ret; + int eid, ret; db_rep = env->rep_handle; __os_gettime(env, &now, 1); @@ -396,6 +413,7 @@ __repmgr_retry_connections(env) eid = retry->eid; __os_free(env, retry); + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); DB_ASSERT(env, site->state == SITE_PAUSING); @@ -420,8 +438,7 @@ __repmgr_first_try_connections(env) { DB_REP *db_rep; REPMGR_SITE *site; - u_int eid; - int ret; + int eid, ret; db_rep = env->rep_handle; FOR_EACH_REMOTE_SITE_INDEX(eid) { @@ -448,7 +465,7 @@ __repmgr_first_try_connections(env) static int __repmgr_try_one(env, eid) ENV *env; - u_int eid; + int eid; { DB_REP *db_rep; REPMGR_SITE *site; @@ -456,6 +473,7 @@ __repmgr_try_one(env, eid) int ret; db_rep = env->rep_handle; + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); th = site->connector; if (th == NULL) { @@ -476,7 +494,7 @@ __repmgr_try_one(env, eid) site->state = SITE_CONNECTING; th->run = __repmgr_connector_thread; - th->args.eid = (int)eid; + th->args.eid = eid; if ((ret = __repmgr_thread_start(env, th)) != 0) { __os_free(env, th); site->connector = NULL; @@ -524,8 +542,9 @@ __repmgr_connector_main(env, th) ret = 0; LOCK_MUTEX(db_rep->mutex); + DB_ASSERT(env, IS_VALID_EID(th->args.eid)); site = SITE_FROM_EID(th->args.eid); - if (site->state != SITE_CONNECTING && db_rep->finished) + if (site->state != SITE_CONNECTING && db_rep->repmgr_status == stopped) goto unlock; /* @@ -553,12 +572,13 @@ __repmgr_connector_main(env, th) } conn->type = REP_CONNECTION; site = SITE_FROM_EID(th->args.eid); - if (site->state != SITE_CONNECTING || db_rep->finished) + if (site->state != SITE_CONNECTING || + db_rep->repmgr_status == stopped) goto cleanup; - conn->eid = (int)th->args.eid; + conn->eid = th->args.eid; site = SITE_FROM_EID(th->args.eid); - site->ref.conn = conn; + site->ref.conn.out = conn; site->state = SITE_CONNECTED; __os_gettime(env, &site->last_rcvd_timestamp, 1); ret = __repmgr_wake_main_thread(env); @@ -571,12 +591,13 @@ __repmgr_connector_main(env, th) LOCK_MUTEX(db_rep->mutex); site = SITE_FROM_EID(th->args.eid); - if (site->state != SITE_CONNECTING || db_rep->finished) { + if (site->state != SITE_CONNECTING || + db_rep->repmgr_status == stopped) { ret = 0; goto unlock; } ret = __repmgr_schedule_connection_attempt(env, - (u_int)th->args.eid, FALSE); + th->args.eid, FALSE); } else goto out; @@ -881,7 +902,12 @@ prepare_input(env, conn) * final handshake, implying that this connection is to be used * for a one-shot GMDB request. */ - DB_ASSERT(env, REPMGR_OWN_BUF_SIZE(msg_hdr) > 0); + if (REPMGR_OWN_BUF_SIZE(msg_hdr) == 0) { + __db_errx(env, DB_STR_A("3680", + "invalid own buf size %lu in prepare_input", "%lu"), + (u_long)REPMGR_OWN_BUF_SIZE(msg_hdr)); + return (DB_REP_UNAVAIL); + } DB_INIT_DBT(conn->input.rep_message->v.gmdb_msg.request, (u_int8_t*)membase + sizeof(REPMGR_MESSAGE), REPMGR_OWN_BUF_SIZE(msg_hdr)); @@ -892,7 +918,12 @@ prepare_input(env, conn) case REPMGR_APP_RESPONSE: size = APP_RESP_BUFFER_SIZE(msg_hdr); conn->cur_resp = APP_RESP_TAG(msg_hdr); - DB_ASSERT(env, conn->cur_resp < conn->aresp); + if (conn->cur_resp >= conn->aresp) { + __db_errx(env, DB_STR_A("3681", + "invalid cur resp %lu in prepare_input", "%lu"), + (u_long)conn->cur_resp); + return (DB_REP_UNAVAIL); + } resp = &conn->responses[conn->cur_resp]; DB_ASSERT(env, F_ISSET(resp, RESP_IN_USE)); @@ -967,7 +998,10 @@ prepare_input(env, conn) break; default: - return (__db_unknown_path(env, "prepare_input")); + __db_errx(env, DB_STR_A("3676", + "unexpected msg type %lu in prepare_input", "%lu"), + (u_long)conn->msg_type); + return (DB_REP_UNAVAIL); } if (skip) { @@ -1317,7 +1351,10 @@ process_own_msg(env, conn) case REPMGR_REMOVE_REQUEST: case REPMGR_RESOLVE_LIMBO: default: - return (__db_unknown_path(env, "process_own_msg")); + __db_errx(env, DB_STR_A("3677", + "unexpected msg type %lu in process_own_msg", "%lu"), + (u_long)REPMGR_OWN_MSG_TYPE(msg->msg_hdr)); + return (DB_REP_UNAVAIL); } /* * If we haven't given ownership of the msg buffer to another thread, @@ -1448,7 +1485,10 @@ __repmgr_send_handshake(env, conn, opt, optlen, flags) cntrl_len = __REPMGR_HANDSHAKE_SIZE; break; default: - return (__db_unknown_path(env, "__repmgr_send_handshake")); + __db_errx(env, DB_STR_A("3678", + "unexpected conn version %lu in send_handshake", "%lu"), + (u_long)conn->version); + return (DB_REP_UNAVAIL); } hostname_len = strlen(my_addr->host); rec_len = hostname_len + 1 + @@ -1644,7 +1684,10 @@ accept_handshake(env, conn, hostname) ack = hs.ack_policy; break; default: - return (__db_unknown_path(env, "accept_handshake")); + __db_errx(env, DB_STR_A("3679", + "unexpected conn version %lu in accept_handshake", "%lu"), + (u_long)conn->version); + return (DB_REP_UNAVAIL); } return (process_parameters(env, @@ -1690,7 +1733,7 @@ process_parameters(env, conn, host, port, ack, electable, flags) REPMGR_SITE *site; __repmgr_connect_reject_args reject; u_int8_t reject_buf[__REPMGR_CONNECT_REJECT_SIZE]; - int eid, ret, sockopt; + int eid, ret; db_rep = env->rep_handle; @@ -1742,18 +1785,6 @@ process_parameters(env, conn, host, port, ack, electable, flags) TAILQ_INSERT_TAIL(&site->sub_conns, conn, entries); conn->eid = eid; - -#ifdef SO_KEEPALIVE - sockopt = 1; - if (setsockopt(conn->fd, SOL_SOCKET, - SO_KEEPALIVE, (sockopt_t)&sockopt, - sizeof(sockopt)) != 0) { - ret = net_errno; - __db_err(env, ret, DB_STR("3626", - "can't set KEEPALIVE socket option")); - return (ret); - } -#endif } else { DB_EVENT(env, DB_EVENT_REP_CONNECT_ESTD, &eid); @@ -1774,17 +1805,10 @@ process_parameters(env, conn, host, port, ack, electable, flags) * least we thought we were. */ RPRINT(env, (env, DB_VERB_REPMGR_MISC, - "connection from %s:%u EID %u supersedes existing", + "connection from %s:%u EID %u while already connected", host, port, eid)); - - /* - * No need for site-oriented recovery, - * since we now have a replacement - * connection; so skip bust_connection() - * and call disable_conn() directly. - */ - if ((ret = __repmgr_disable_connection( - env, site->ref.conn)) != 0) + if ((ret = resolve_collision(env, + site, conn)) != 0) return (ret); break; case SITE_CONNECTING: @@ -1802,7 +1826,7 @@ process_parameters(env, conn, host, port, ack, electable, flags) } conn->eid = eid; site->state = SITE_CONNECTED; - site->ref.conn = conn; + site->ref.conn.in = conn; __os_gettime(env, &site->last_rcvd_timestamp, 1); } @@ -1854,6 +1878,43 @@ process_parameters(env, conn, host, port, ack, electable, flags) return (0); } +static int +resolve_collision(env, site, conn) + ENV *env; + REPMGR_SITE *site; + REPMGR_CONNECTION *conn; +{ + int ret; + + /* + * No need for site-oriented recovery, since we now have a replacement + * connection; so skip bust_connection() and call disable_conn() + * directly. + * + * If we already had an incoming connection, this new one always + * replaces it. Whether it also/alternatively replaces an outgoing + * connection depends on whether we're client or server (so as to avoid + * connection collisions resulting in no remaining connections). (If + * it's an older version that doesn't know about our collision + * resolution protocol, it will behave like a client.) + */ + if (site->ref.conn.in != NULL) { + ret = __repmgr_disable_connection(env, site->ref.conn.in); + site->ref.conn.in = NULL; + if (ret != 0) + return (ret); + } + if (site->ref.conn.out != NULL && + conn->version >= CONN_COLLISION_VERSION && + __repmgr_is_server(env, site)) { + ret = __repmgr_disable_connection(env, site->ref.conn.out); + site->ref.conn.out = NULL; + if (ret != 0) + return (ret); + } + return (0); +} + static int record_permlsn(env, conn) ENV *env; @@ -1865,11 +1926,17 @@ record_permlsn(env, conn) SITE_STRING_BUFFER location; u_int32_t gen; int ret; + u_int do_log_check; db_rep = env->rep_handle; + do_log_check = 0; - DB_ASSERT(env, conn->version > 0 && - IS_READY_STATE(conn->state) && IS_VALID_EID(conn->eid)); + if (conn->version == 0 || + !IS_READY_STATE(conn->state) || !IS_VALID_EID(conn->eid)) { + __db_errx(env, DB_STR("3682", + "unexpected connection info in record_permlsn")); + return (DB_REP_UNAVAIL); + } site = SITE_FROM_EID(conn->eid); /* @@ -1907,7 +1974,15 @@ record_permlsn(env, conn) if (ackp->generation == gen && LOG_COMPARE(&ackp->lsn, &site->max_ack) == 1) { + /* + * If file number for this site changed, check lowest log + * file needed after recording new permlsn for this site. + */ + if (ackp->lsn.file > site->max_ack.file) + do_log_check = 1; memcpy(&site->max_ack, &ackp->lsn, sizeof(DB_LSN)); + if (do_log_check) + check_min_log_file(env); if ((ret = __repmgr_wake_waiters(env, &db_rep->ack_waiters)) != 0) return (ret); @@ -1915,6 +1990,56 @@ record_permlsn(env, conn) return (0); } +/* + * Maintains lowest log file still needed by the repgroup. This is stored + * in shared rep region so that it is accessible to repmgr subordinate + * processes that may not themselves have connections to other sites + * (e.g. a separate db_archive process.) + */ +static void +check_min_log_file(env) + ENV *env; +{ + DB_REP *db_rep; + REP *rep; + REPMGR_CONNECTION *conn; + REPMGR_SITE *site; + u_int32_t min_log; + int eid; + + db_rep = env->rep_handle; + rep = db_rep->region; + min_log = 0; + + /* + * Record the lowest log file number from all connected sites. If this + * is a client, ignore the master because the master does not maintain + * nor send out its repmgr perm LSN in this way. Consider connections + * so that we don't allow a site that has been down a long time to + * indefinitely prevent log archiving. + */ + FOR_EACH_REMOTE_SITE_INDEX(eid) { + if (eid == rep->master_id) + continue; + site = SITE_FROM_EID(eid); + if (site->state == SITE_CONNECTED && + (((conn = site->ref.conn.in) != NULL && + conn->state == CONN_READY) || + ((conn = site->ref.conn.out) != NULL && + conn->state == CONN_READY)) && + !IS_ZERO_LSN(site->max_ack) && + (min_log == 0 || site->max_ack.file < min_log)) + min_log = site->max_ack.file; + } + /* + * During normal operation min_log should increase over time, but it + * is possible if a site returns after being disconnected for a while + * that min_log could decrease. + */ + if (min_log != 0 && min_log != rep->min_log_file) + rep->min_log_file = min_log; +} + /* * PUBLIC: int __repmgr_write_some __P((ENV *, REPMGR_CONNECTION *)); */ diff --git a/src/repmgr/repmgr_stat.c b/src/repmgr/repmgr_stat.c index 8bcc85fa..fd6dabd3 100644 --- a/src/repmgr/repmgr_stat.c +++ b/src/repmgr/repmgr_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -339,10 +339,18 @@ __repmgr_site_list(dbenv, countp, listp) * does indeed have a connection established (db_stat can't know * that). */ - status[i].status = db_rep->selector == NULL ? 0 : - (site->state == SITE_CONNECTED && - IS_READY_STATE(site->ref.conn->state) ? - DB_REPMGR_CONNECTED : DB_REPMGR_DISCONNECTED); + if (db_rep->selector == NULL) + status[i].status = 0; + else if (site->state != SITE_CONNECTED) + status[i].status = DB_REPMGR_DISCONNECTED; + else if ((site->ref.conn.in != NULL && + IS_READY_STATE(site->ref.conn.in->state)) || + (site->ref.conn.out != NULL && + IS_READY_STATE(site->ref.conn.out->state))) + status[i].status = DB_REPMGR_CONNECTED; + else + status[i].status = DB_REPMGR_DISCONNECTED; + i++; } diff --git a/src/repmgr/repmgr_stub.c b/src/repmgr/repmgr_stub.c index ab5fc66d..734c2240 100644 --- a/src/repmgr/repmgr_stub.c +++ b/src/repmgr/repmgr_stub.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/repmgr/repmgr_util.c b/src/repmgr/repmgr_util.c index b67e993d..c2439436 100644 --- a/src/repmgr/repmgr_util.c +++ b/src/repmgr/repmgr_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -14,7 +14,6 @@ #include "dbinc/txn.h" #define INITIAL_SITES_ALLOCATION 3 /* Arbitrary guess. */ -#define RETRY_TIME_ADJUST 200000 /* Arbitrary estimate. */ static int get_eid __P((ENV *, const char *, u_int, int *)); static int __repmgr_addrcmp __P((repmgr_netaddr_t *, repmgr_netaddr_t *)); @@ -26,7 +25,7 @@ static int read_gmdb __P((ENV *, DB_THREAD_INFO *, u_int8_t **, size_t *)); * parameter is given as TRUE, we'll make the wait time 0, and put the request * at the _beginning_ of the retry queue. * - * PUBLIC: int __repmgr_schedule_connection_attempt __P((ENV *, u_int, int)); + * PUBLIC: int __repmgr_schedule_connection_attempt __P((ENV *, int, int)); * * !!! * Caller should hold mutex. @@ -37,7 +36,7 @@ static int read_gmdb __P((ENV *, DB_THREAD_INFO *, u_int8_t **, size_t *)); int __repmgr_schedule_connection_attempt(env, eid, immediate) ENV *env; - u_int eid; + int eid; int immediate; { DB_REP *db_rep; @@ -45,39 +44,20 @@ __repmgr_schedule_connection_attempt(env, eid, immediate) REPMGR_RETRY *retry, *target; REPMGR_SITE *site; db_timespec t; - int cmp, ret; + int ret; db_rep = env->rep_handle; rep = db_rep->region; if ((ret = __os_malloc(env, sizeof(*retry), &retry)) != 0) return (ret); + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); __os_gettime(env, &t, 1); if (immediate) TAILQ_INSERT_HEAD(&db_rep->retries, retry, entries); else { TIMESPEC_ADD_DB_TIMEOUT(&t, rep->connection_retry_wait); - - /* - * Although it's extremely rare, two sites could be trying to - * connect to each other simultaneously, and each could kill its - * own connection when it received the other's. And this could - * continue, in sync, since configured retry times are usually - * the same. So, perturb one site's retry time by a small - * amount to break the cycle. Since each site has its own - * address, it's always possible to decide which is "greater - * than". - * (The mnemonic is that a server conventionally has a - * small well-known port number. And clients have the right to - * connect to servers, not the other way around.) - */ - cmp = __repmgr_addrcmp(&site->net_addr, - &SITE_FROM_EID(db_rep->self_eid)->net_addr); - DB_ASSERT(env, cmp != 0); - if (cmp == 1) - TIMESPEC_ADD_DB_TIMEOUT(&t, RETRY_TIME_ADJUST); - /* * Insert the new "retry" on the (time-ordered) list in its * proper position. To do so, find the list entry ("target") @@ -102,6 +82,37 @@ __repmgr_schedule_connection_attempt(env, eid, immediate) return (__repmgr_wake_main_thread(env)); } +/* + * Determines whether a remote site should be considered a "server" to us as a + * "client" (in typical client/server terminology, not to be confused with our + * usual use of the term "client" as in the master/client replication role), or + * vice versa. + * + * PUBLIC: int __repmgr_is_server __P((ENV *, REPMGR_SITE *)); + */ +int +__repmgr_is_server(env, site) + ENV *env; + REPMGR_SITE *site; +{ + DB_REP *db_rep; + int cmp; + + db_rep = env->rep_handle; + cmp = __repmgr_addrcmp(&site->net_addr, + &SITE_FROM_EID(db_rep->self_eid)->net_addr); + DB_ASSERT(env, cmp != 0); + + /* + * The mnemonic here is that a server conventionally has a + * small well-known port number, while clients typically use a port + * number from the higher ephemeral range. So, for the remote site to + * be considered a server, its address should have compared as lower + * than ours. + */ + return (cmp == -1); +} + /* * Compare two network addresses (lexicographically), and return -1, 0, or 1, as * the first is less than, equal to, or greater than the second. @@ -183,6 +194,30 @@ __repmgr_new_connection(env, connp, s, state) return (0); } +/* + * PUBLIC: int __repmgr_set_keepalive __P((ENV *, REPMGR_CONNECTION *)); + */ +int +__repmgr_set_keepalive(env, conn) + ENV *env; + REPMGR_CONNECTION *conn; +{ + int ret, sockopt; + + ret = 0; +#ifdef SO_KEEPALIVE + sockopt = 1; + if (setsockopt(conn->fd, SOL_SOCKET, + SO_KEEPALIVE, (sockopt_t)&sockopt, sizeof(sockopt)) != 0) { + ret = net_errno; + __db_err(env, ret, DB_STR("3626", + "can't set KEEPALIVE socket option")); + (void)__repmgr_destroy_conn(env, conn); + } +#endif + return (ret); +} + /* * PUBLIC: int __repmgr_new_site __P((ENV *, REPMGR_SITE**, * PUBLIC: const char *, u_int)); @@ -256,6 +291,7 @@ __repmgr_new_site(env, sitep, host, port) timespecclear(&site->last_rcvd_timestamp); TAILQ_INIT(&site->sub_conns); site->connector = NULL; + site->ref.conn.in = site->ref.conn.out = NULL; site->state = SITE_IDLE; site->membership = 0; @@ -715,8 +751,7 @@ __repmgr_each_connection(env, callback, info, err_quit) DB_REP *db_rep; REPMGR_CONNECTION *conn, *next; REPMGR_SITE *site; - u_int eid; - int ret, t_ret; + int eid, ret, t_ret; #define HANDLE_ERROR \ do { \ @@ -746,8 +781,11 @@ __repmgr_each_connection(env, callback, info, err_quit) site = SITE_FROM_EID(eid); if (site->state == SITE_CONNECTED) { - conn = site->ref.conn; - if ((t_ret = (*callback)(env, conn, info)) != 0) + if ((conn = site->ref.conn.in) != NULL && + (t_ret = (*callback)(env, conn, info)) != 0) + HANDLE_ERROR; + if ((conn = site->ref.conn.out) != NULL && + (t_ret = (*callback)(env, conn, info)) != 0) HANDLE_ERROR; } @@ -932,10 +970,30 @@ int __repmgr_env_refresh(env) ENV *env; { + DB_REP *db_rep; + REP *rep; + REGINFO *infop; + SITEINFO *shared_array; + u_int i; int ret; - ret = F_ISSET(env, ENV_PRIVATE) ? - __mutex_free(env, &env->rep_handle->region->mtx_repmgr) : 0; + db_rep = env->rep_handle; + rep = db_rep->region; + infop = env->reginfo; + ret = 0; + COMPQUIET(i, 0); + + if (F_ISSET(env, ENV_PRIVATE)) { + ret = __mutex_free(env, &rep->mtx_repmgr); + if (rep->siteinfo_off != INVALID_ROFF) { + shared_array = R_ADDR(infop, rep->siteinfo_off); + for (i = 0; i < db_rep->site_cnt; i++) + __env_alloc_free(infop, R_ADDR(infop, + shared_array[i].addr.host)); + __env_alloc_free(infop, shared_array); + rep->siteinfo_off = INVALID_ROFF; + } + } return (ret); } @@ -1095,27 +1153,28 @@ out: * array entry in the range from <= x < limit. Passing from >= limit is * allowed, and is effectively a no-op. * - * PUBLIC: int __repmgr_init_new_sites __P((ENV *, u_int, u_int)); + * PUBLIC: int __repmgr_init_new_sites __P((ENV *, int, int)); * * !!! Assumes caller holds db_rep->mutex. */ int __repmgr_init_new_sites(env, from, limit) ENV *env; - u_int from, limit; + int from, limit; { DB_REP *db_rep; REPMGR_SITE *site; - u_int i; - int ret; + int i, ret; db_rep = env->rep_handle; if (db_rep->selector == NULL) return (0); + + DB_ASSERT(env, IS_VALID_EID(from) && IS_VALID_EID(limit) && + from <= limit); for (i = from; i < limit; i++) { site = SITE_FROM_EID(i); - if (site->membership == SITE_PRESENT && (ret = __repmgr_schedule_connection_attempt(env, i, TRUE)) != 0) @@ -1141,7 +1200,7 @@ __repmgr_failchk(env) db_rep = env->rep_handle; rep = db_rep->region; - COMPQUIET(unused, 0); + DB_THREADID_INIT(unused); MUTEX_LOCK(env, rep->mtx_repmgr); /* @@ -1166,19 +1225,26 @@ __repmgr_master_is_known(env) ENV *env; { DB_REP *db_rep; - REP *rep; - int master; + REPMGR_CONNECTION *conn; + REPMGR_SITE *master; db_rep = env->rep_handle; - rep = db_rep->region; - master = rep->master_id; /* * We are the master, or we know of a master and have a healthy * connection to it. */ - return (master == db_rep->self_eid || - __repmgr_master_connection(env) != NULL); + if (db_rep->region->master_id == db_rep->self_eid) + return (TRUE); + if ((master = __repmgr_connected_master(env)) == NULL) + return (FALSE); + if ((conn = master->ref.conn.in) != NULL && + IS_READY_STATE(conn->state)) + return (TRUE); + if ((conn = master->ref.conn.out) != NULL && + IS_READY_STATE(conn->state)) + return (TRUE); + return (FALSE); } /* @@ -1194,36 +1260,21 @@ __repmgr_stable_lsn(env, stable_lsn) ENV *env; DB_LSN *stable_lsn; { - DB_LSN min_lsn; DB_REP *db_rep; REP *rep; - REPMGR_SITE *site; - u_int eid; db_rep = env->rep_handle; rep = db_rep->region; - ZERO_LSN(min_lsn); - LOCK_MUTEX(db_rep->mutex); - FOR_EACH_REMOTE_SITE_INDEX(eid) { - site = SITE_FROM_EID(eid); + if (rep->min_log_file != 0 && rep->min_log_file < stable_lsn->file) { /* - * Record the smallest ack'ed LSN from all connected sites. - * If we're a client, ignore the master because the master - * does not maintain nor send out its repmgr perm LSN in - * this way. + * Returning an LSN to be consistent with the rest of the + * log archiving processing. Construct LSN of format + * [filenum][0]. */ - if ((int)eid == rep->master_id) - continue; - if (IS_SITE_AVAILABLE(site) && - !IS_ZERO_LSN(site->max_ack) && - (IS_ZERO_LSN(min_lsn) || - LOG_COMPARE(&site->max_ack, &min_lsn) < 0)) - min_lsn = site->max_ack; + stable_lsn->file = rep->min_log_file; + stable_lsn->offset = 0; } - UNLOCK_MUTEX(db_rep->mutex); - if (!IS_ZERO_LSN(min_lsn) && LOG_COMPARE(&min_lsn, stable_lsn) < 0) - *stable_lsn = min_lsn; RPRINT(env, (env, DB_VERB_REPMGR_MISC, "Repmgr_stable_lsn: Returning stable_lsn[%lu][%lu]", (u_long)stable_lsn->file, (u_long)stable_lsn->offset)); @@ -1303,7 +1354,8 @@ __repmgr_marshal_member_list(env, bufp, lenp) continue; site_info.host.data = site->net_addr.host; - site_info.host.size = (u_int32_t)strlen(site->net_addr.host) + 1; + site_info.host.size = + (u_int32_t)strlen(site->net_addr.host) + 1; site_info.port = site->net_addr.port; site_info.flags = site->membership; @@ -1479,7 +1531,7 @@ __repmgr_refresh_membership(env, buf, len) ret = __repmgr_membr_vers_unmarshal(env, &membr_vers, buf, len, &p); DB_ASSERT(env, ret == 0); - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) return (0); /* Ignore obsolete versions. */ if (__repmgr_gmdb_version_cmp(env, @@ -1511,6 +1563,7 @@ __repmgr_refresh_membership(env, buf, len) if ((ret = __repmgr_find_site(env, host, port, &eid)) != 0) goto err; + DB_ASSERT(env, IS_VALID_EID(eid)); F_SET(SITE_FROM_EID(eid), SITE_TOUCHED); } ret = __rep_set_nsites_int(env, n); @@ -1873,13 +1926,14 @@ __repmgr_set_membership(env, host, port, status) MUTEX_LOCK(env, rep->mtx_repmgr); if ((ret = get_eid(env, host, port, &eid)) == 0) { + DB_ASSERT(env, IS_VALID_EID(eid)); site = SITE_FROM_EID(eid); orig = site->membership; sites = R_ADDR(infop, rep->siteinfo_off); RPRINT(env, (env, DB_VERB_REPMGR_MISC, "set membership for %s:%lu %lu (was %lu)", - host, (u_long)port, (u_long)status, (u_long)orig )); + host, (u_long)port, (u_long)status, (u_long)orig)); if (status != sites[eid].status) { /* * Show that a change is occurring. @@ -1907,7 +1961,8 @@ __repmgr_set_membership(env, host, port, status) * If our notion of the site's membership changed, we may need to create * or kill a connection. */ - if (ret == 0 && !db_rep->finished && SELECTOR_RUNNING(db_rep)) { + if (ret == 0 && db_rep->repmgr_status == running && + SELECTOR_RUNNING(db_rep)) { if (eid == db_rep->self_eid && status != SITE_PRESENT) ret = DB_DELETED; @@ -1927,7 +1982,7 @@ __repmgr_set_membership(env, host, port, status) * naturally try again later. */ ret = __repmgr_schedule_connection_attempt(env, - (u_int)eid, TRUE); + eid, TRUE); if (eid != db_rep->self_eid) DB_EVENT(env, DB_EVENT_REP_SITE_ADDED, &eid); } else if (orig != 0 && status == 0) @@ -2014,10 +2069,15 @@ __repmgr_bcast_own_msg(env, type, buf, len) site = SITE_FROM_EID(i); if (site->state != SITE_CONNECTED) continue; - conn = site->ref.conn; - if (conn->state != CONN_READY) - continue; - if ((ret = __repmgr_send_own_msg(env, + if ((conn = site->ref.conn.in) != NULL && + conn->state == CONN_READY && + (ret = __repmgr_send_own_msg(env, + conn, type, buf, (u_int32_t)len)) != 0 && + (ret = __repmgr_bust_connection(env, conn)) != 0) + return (ret); + if ((conn = site->ref.conn.out) != NULL && + conn->state == CONN_READY && + (ret = __repmgr_send_own_msg(env, conn, type, buf, (u_int32_t)len)) != 0 && (ret = __repmgr_bust_connection(env, conn)) != 0) return (ret); diff --git a/src/repmgr/repmgr_windows.c b/src/repmgr/repmgr_windows.c index 625ba6de..d9c2a03d 100644 --- a/src/repmgr/repmgr_windows.c +++ b/src/repmgr/repmgr_windows.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -143,12 +143,13 @@ __repmgr_wake_waiters(env, w) db_rep = env->rep_handle; waiters = *w; for (i = 0; i < waiters->next_avail; i++) { - slot = &waiters->array[i]; - if (!WAITER_SLOT_IN_USE(slot)) - continue; - if ((*slot->pred)(env, slot->ctx) || db_rep->finished) - if (!SetEvent(slot->event) && ret == 0) - ret = GetLastError(); + slot = &waiters->array[i]; + if (!WAITER_SLOT_IN_USE(slot)) + continue; + if ((*slot->pred)(env, slot->ctx) || + db_rep->repmgr_status == stopped) + if (!SetEvent(slot->event) && ret == 0) + ret = GetLastError(); } return (ret); } @@ -194,7 +195,7 @@ __repmgr_await_cond(env, pred, ctx, timeout, waiters_p) LOCK_MUTEX(db_rep->mutex); free_wait_slot(env, i, waiters); - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) ret = DB_REP_UNAVAIL; err: @@ -245,6 +246,14 @@ allocate_wait_slot(env, resultp, table) w = &table->array[i]; table->first_free = w->next_free; } + /* + * Make sure this event state is nonsignaled. It is possible that + * late processing could have signaled this event after the end of + * the previous wait but before reacquiring the mutex, and this + * extra signal would incorrectly cause the next wait to return + * immediately. + */ + (void)WaitForSingleObject(w->event, 0); *resultp = i; return (0); } @@ -332,7 +341,7 @@ __repmgr_await_drain(env, conn, timeout) } else DB_ASSERT(env, ret == WAIT_OBJECT_0); - if (db_rep->finished) + if (db_rep->repmgr_status == stopped) return (0); if (conn->state == CONN_DEFUNCT) return (DB_REP_UNAVAIL); @@ -682,7 +691,7 @@ __repmgr_select_loop(env) UNLOCK_MUTEX(db_rep->mutex); ret = WSAWaitForMultipleEvents( io_info.nevents, events, FALSE, select_timeout, FALSE); - if (db_rep->finished) { + if (db_rep->repmgr_status == stopped) { ret = 0; goto out; } @@ -732,6 +741,11 @@ unlock: out: if (!CloseHandle(listen_event) && ret == 0) ret = GetLastError(); + if (ret == DB_DELETED) + ret = __repmgr_bow_out(env); + LOCK_MUTEX(db_rep->mutex); + (void)__repmgr_net_close(env); + UNLOCK_MUTEX(db_rep->mutex); return (ret); } diff --git a/src/sequence/seq_stat.c b/src/sequence/seq_stat.c index a26b15a4..d5b9a401 100644 --- a/src/sequence/seq_stat.c +++ b/src/sequence/seq_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/sequence/sequence.c b/src/sequence/sequence.c index c73b6535..1c19f838 100644 --- a/src/sequence/sequence.c +++ b/src/sequence/sequence.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn.c b/src/txn/txn.c index 4139c167..81225e5c 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 @@ -686,9 +686,13 @@ __txn_commit(txn, flags) * should always be a perm record in the log because the master updates * the LSN history system database in rep_start() (with IGNORE_LEASE * set). + * + * Only check leases if this txn writes to the log file + * (i.e. td->last_lsn). */ if (txn->parent == NULL && IS_REP_MASTER(env) && IS_USING_LEASES(env) && !F_ISSET(txn, TXN_IGNORE_LEASE) && + !IS_ZERO_LSN(td->last_lsn) && (ret = __rep_lease_check(env, 1)) != 0) { DB_ASSERT(env, ret != DB_NOTFOUND); goto err; @@ -841,9 +845,13 @@ __txn_commit(txn, flags) * If we're a child, that is not a perm record. If we are a * master and cannot get valid leases now, something happened * during the commit. The only thing to do is panic. + * + * Only check leases if this txn writes to the log file + * (i.e. td->last_lsn). */ if (txn->parent == NULL && IS_REP_MASTER(env) && IS_USING_LEASES(env) && !F_ISSET(txn, TXN_IGNORE_LEASE) && + !IS_ZERO_LSN(td->last_lsn) && (ret = __rep_lease_check(env, 1)) != 0) return (__env_panic(env, ret)); diff --git a/src/txn/txn.src b/src/txn/txn.src index 526ab260..7e82dc82 100644 --- a/src/txn/txn.src +++ b/src/txn/txn.src @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_chkpt.c b/src/txn/txn_chkpt.c index bffc1801..73715b10 100644 --- a/src/txn/txn_chkpt.c +++ b/src/txn/txn_chkpt.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1995, 1996 @@ -97,7 +97,7 @@ __txn_checkpoint(env, kbytes, minutes, flags) u_int32_t kbytes, minutes, flags; { DB_LOG *dblp; - DB_LSN ckp_lsn, last_ckp; + DB_LSN ckp_lsn, last_ckp, msg_lsn; DB_TXNMGR *mgr; DB_TXNREGION *region; LOG *lp; @@ -146,6 +146,10 @@ __txn_checkpoint(env, kbytes, minutes, flags) if ((ret = __log_current_lsn_int(env, &ckp_lsn, &mbytes, &bytes)) != 0) goto err; + /* + * Save for possible use in START_SYNC message. + */ + msg_lsn = ckp_lsn; if (!LF_ISSET(DB_FORCE)) { /* Don't checkpoint a quiescent database. */ if (bytes == 0 && mbytes == 0) @@ -224,9 +228,14 @@ do_ckp: (ret = __repmgr_autostart(env)) != 0) goto err; #endif + /* + * Send the LSN (saved in msg_lsn) where the sync starts + * on the master. Clients must have this LSN to assure that + * they have applied all txns up to this point. + */ if (env->rep_handle->send != NULL) (void)__rep_send_message(env, DB_EID_BROADCAST, - REP_START_SYNC, &ckp_lsn, NULL, 0, 0); + REP_START_SYNC, &msg_lsn, NULL, 0, 0); } /* Flush the cache. */ @@ -318,7 +327,7 @@ err: MUTEX_UNLOCK(env, region->mtx_ckp); * We check both the file and offset for 0 since the lsn may be in * transition. If it is then we don't care about this txn because it * must be starting after we set the initial value of lsnp in the caller. - * All txns must initalize their begin_lsn before writing to the log. + * All txns must initialize their begin_lsn before writing to the log. * * PUBLIC: int __txn_getactive __P((ENV *, DB_LSN *)); */ diff --git a/src/txn/txn_failchk.c b/src/txn/txn_failchk.c index 3f7e98fa..b2007ad6 100644 --- a/src/txn/txn_failchk.c +++ b/src/txn/txn_failchk.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_method.c b/src/txn/txn_method.c index 531dd78d..629eac04 100644 --- a/src/txn/txn_method.c +++ b/src/txn/txn_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_rec.c b/src/txn/txn_rec.c index 4658645c..b39d56d1 100644 --- a/src/txn/txn_rec.c +++ b/src/txn/txn_rec.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 1996 diff --git a/src/txn/txn_recover.c b/src/txn/txn_recover.c index b1e5c8fa..67f24439 100644 --- a/src/txn/txn_recover.c +++ b/src/txn/txn_recover.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_region.c b/src/txn/txn_region.c index b52de86e..6f43d45f 100644 --- a/src/txn/txn_region.c +++ b/src/txn/txn_region.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_stat.c b/src/txn/txn_stat.c index 4d006c9c..62fe622d 100644 --- a/src/txn/txn_stat.c +++ b/src/txn/txn_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/src/txn/txn_util.c b/src/txn/txn_util.c index 119e8502..0ecd7f6c 100644 --- a/src/txn/txn_util.c +++ b/src/txn/txn_util.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -180,7 +180,10 @@ __txn_lockevent(env, txn, dbp, lock, locker) e->u.t.locker = locker; e->u.t.lock = *lock; e->u.t.dbp = dbp; - e->op = TXN_TRADE; + if (F2_ISSET(dbp, DB2_AM_EXCL)) + e->op = TXN_XTRADE; + else + e->op = TXN_TRADE; /* This event goes on the current transaction, not its parent. */ TAILQ_INSERT_TAIL(&txn->events, e, links); dbp->cur_txn = txn; @@ -206,7 +209,8 @@ __txn_remlock(env, txn, lock, locker) for (e = TAILQ_FIRST(&txn->events); e != NULL; e = next_e) { next_e = TAILQ_NEXT(e, links); - if ((e->op != TXN_TRADE && e->op != TXN_TRADED) || + if ((e->op != TXN_TRADE && e->op != TXN_TRADED && + e->op != TXN_XTRADE) || (e->u.t.lock.off != lock->off && e->u.t.locker != locker)) continue; TAILQ_REMOVE(&txn->events, e, links); @@ -275,8 +279,13 @@ __txn_doevents(env, txn, opcode, preprocess) for (e = TAILQ_FIRST(&txn->events); e != NULL; e = enext) { enext = TAILQ_NEXT(e, links); - if (e->op != TXN_TRADE || - IS_WRITELOCK(e->u.t.lock.mode)) + /* + * Move all exclusive handle locks and + * read handle locks to the handle locker. + */ + if (!(opcode == TXN_COMMIT && e->op == TXN_XTRADE) && + (e->op != TXN_TRADE || + IS_WRITELOCK(e->u.t.lock.mode))) continue; DO_TRADE; if (txn->parent != NULL) { @@ -297,12 +306,13 @@ __txn_doevents(env, txn, opcode, preprocess) TAILQ_REMOVE(&txn->events, e, links); /* * Most deferred events should only happen on - * commits, not aborts or prepares. The one exception - * is a close which gets done on commit and abort, but + * commits, not aborts or prepares. The two exceptions are + * close and xtrade which gets done on commit and abort, but * not prepare. If we're not doing operations, then we * can just go free resources. */ - if (opcode == TXN_ABORT && e->op != TXN_CLOSE) + if (opcode == TXN_ABORT && (e->op != TXN_CLOSE && + e->op != TXN_XTRADE)) goto dofree; switch (e->op) { case TXN_CLOSE: @@ -324,6 +334,7 @@ __txn_doevents(env, txn, opcode, preprocess) ret = t_ret; break; case TXN_TRADE: + case TXN_XTRADE: DO_TRADE; if (txn->parent != NULL) { TAILQ_INSERT_HEAD( @@ -332,10 +343,25 @@ __txn_doevents(env, txn, opcode, preprocess) } /* Fall through */ case TXN_TRADED: - /* Downgrade the lock. */ - if ((t_ret = __lock_downgrade(env, - &e->u.t.lock, DB_LOCK_READ, 0)) != 0 && ret == 0) - ret = t_ret; + /* + * Downgrade the lock if it is not an exclusive + * database handle lock. An exclusive database + * should not have any locks other than the + * handle lock. + */ + if (ret == 0 && !F2_ISSET(e->u.t.dbp, DB2_AM_EXCL)) { + if ((t_ret = __lock_downgrade(env, + &e->u.t.lock, DB_LOCK_READ, 0)) != 0 && + ret == 0) + ret = t_ret; + /* Update the handle lock mode. */ + if (ret == 0 && e->u.t.lock.off == + e->u.t.dbp->handle_lock.off && + e->u.t.lock.ndx == + e->u.t.dbp->handle_lock.ndx) + e->u.t.dbp->handle_lock.mode = + DB_LOCK_READ; + } break; default: /* This had better never happen. */ @@ -352,6 +378,7 @@ dofree: __os_free(env, e->u.r.name); break; case TXN_TRADE: + case TXN_XTRADE: if (opcode == TXN_ABORT) e->u.t.dbp->cur_txn = NULL; break; @@ -452,25 +479,40 @@ __txn_dref_fname(env, txn) ptd = txn->parent != NULL ? txn->parent->td : NULL; np = R_ADDR(&mgr->reginfo, td->log_dbs); - np += td->nlog_dbs - 1; - for (i = 0; i < td->nlog_dbs; i++, np--) { - fname = R_ADDR(&dblp->reginfo, *np); - MUTEX_LOCK(env, fname->mutex); - if (ptd != NULL) { + /* + * The order in which FNAMEs are cleaned up matters. Cleaning up + * in the wrong order can result in database handles leaking. If + * we are passing the FNAMEs to the parent transaction make sure + * they are passed in order. If we are cleaning up the FNAMEs, + * make sure that is done in reverse order. + */ + if (ptd != NULL) { + for (i = 0; i < td->nlog_dbs; i++, np++) { + fname = R_ADDR(&dblp->reginfo, *np); + MUTEX_LOCK(env, fname->mutex); ret = __txn_record_fname(env, txn->parent, fname); fname->txn_ref--; MUTEX_UNLOCK(env, fname->mutex); - } else if (fname->txn_ref == 1) { - MUTEX_UNLOCK(env, fname->mutex); - DB_ASSERT(env, fname->txn_ref != 0); - ret = __dbreg_close_id_int( - env, fname, DBREG_CLOSE, 0); - } else { - fname->txn_ref--; - MUTEX_UNLOCK(env, fname->mutex); + if (ret != 0) + break; + } + } else { + np += td->nlog_dbs - 1; + for (i = 0; i < td->nlog_dbs; i++, np--) { + fname = R_ADDR(&dblp->reginfo, *np); + MUTEX_LOCK(env, fname->mutex); + if (fname->txn_ref == 1) { + MUTEX_UNLOCK(env, fname->mutex); + DB_ASSERT(env, fname->txn_ref != 0); + ret = __dbreg_close_id_int( + env, fname, DBREG_CLOSE, 0); + } else { + fname->txn_ref--; + MUTEX_UNLOCK(env, fname->mutex); + } + if (ret != 0 && ret != EIO) + break; } - if (ret != 0 && ret != EIO) - break; } return (ret); diff --git a/src/xa/xa.c b/src/xa/xa.c index 083325ba..ee75e792 100644 --- a/src/xa/xa.c +++ b/src/xa/xa.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -116,8 +116,13 @@ __xa_get_txn(env, xid, td, txnp, flags, ending) DB_ASSERT(env, ending == 0); if (LF_ISSET(TMJOIN | TMRESUME)) ret = XAER_NOTA; + /* + * The snapshot flag is ignored if the database is not + * enabled for MVCC. This allows MVCC to be used + * with XA transactions. + */ else if ((ret = __txn_begin(env, - ip, NULL, txnp, DB_TXN_NOWAIT)) != 0) { + ip, NULL, txnp, DB_TXN_NOWAIT|DB_TXN_SNAPSHOT)) != 0) { dbenv->err(dbenv, ret, DB_STR("4540", "xa_get_txn: transaction begin failed")); ret = XAER_RMERR; @@ -137,7 +142,7 @@ __xa_get_txn(env, xid, td, txnp, flags, ending) td->xa_br_status = TXN_XA_ACTIVE; } } else { - /* If we get here, the tranaction exists. */ + /* If we get here, the transaction exists. */ if (ending == 0 && !LF_ISSET(TMRESUME) && !LF_ISSET(TMJOIN)) { ret = XAER_DUPID; goto out; @@ -847,7 +852,7 @@ __db_xa_commit(xid, rmid, arg_flags) return (ret); /* - * Because this transaction is curently associated, commit will not free + * Because this transaction is currently associated, commit will not free * the transaction structure, which is good, because we need to do that * in xa_put_txn below. */ diff --git a/src/xa/xa_map.c b/src/xa/xa_map.c index 4917bf61..4dcf4d75 100644 --- a/src/xa/xa_map.c +++ b/src/xa/xa_map.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/common/test_util.h b/test/c/common/test_util.h index b501dc70..74be1bb8 100644 --- a/test/c/common/test_util.h +++ b/test/c/common/test_util.h @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -44,7 +44,7 @@ static int teardown_envdir(const char *dir) return (0); /* Get a list of the directory contents. */ - if ((ret = __os_dirlist(NULL, dir, 0, &names, &cnt)) != 0) + if ((ret = __os_dirlist(NULL, dir, 1, &names, &cnt)) != 0) return (ret); /* Go through the file name list, remove each file in the list */ diff --git a/test/c/cutest/CuTest.c b/test/c/cutest/CuTest.c index dfaae913..d7da5b22 100644 --- a/test/c/cutest/CuTest.c +++ b/test/c/cutest/CuTest.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/cutest/CuTest.h b/test/c/cutest/CuTest.h index 7fcab4ad..76cbceb4 100644 --- a/test/c/cutest/CuTest.h +++ b/test/c/cutest/CuTest.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/cutest/CuTests.c b/test/c/cutest/CuTests.c index 0c6d59fa..430aa7fa 100644 --- a/test/c/cutest/CuTests.c +++ b/test/c/cutest/CuTests.c @@ -11,6 +11,15 @@ extern int TestChannelSuiteTeardown(CuSuite *suite); extern int TestChannelTestSetup(CuTest *test); extern int TestChannelTestTeardown(CuTest *test); extern int TestChannelFeature(CuTest *ct); +extern int TestDbHotBackupSuiteSetup(CuSuite *suite); +extern int TestDbHotBackupSuiteTeardown(CuSuite *suite); +extern int TestDbHotBackupTestSetup(CuTest *ct); +extern int TestDbHotBackupTestTeardown(CuTest *ct); +extern int TestDbHotBackupSimpleEnv(CuTest *ct); +extern int TestDbHotBackupPartitionDB(CuTest *ct); +extern int TestDbHotBackupMultiDataDir(CuTest *ct); +extern int TestDbHotBackupSetLogDir(CuTest *ct); +extern int TestDbHotBackupQueueDB(CuTest *ct); extern int TestDbTuner(CuTest *ct); extern int TestNoEncryptedDb(CuTest *ct); extern int TestEncryptedDbFlag(CuTest *ct); @@ -69,6 +78,31 @@ int RunChannelTests(CuString *output) return (count); } +int RunDbHotBackupTests(CuString *output) +{ + CuSuite *suite = CuSuiteNew("TestDbHotBackup", + TestDbHotBackupSuiteSetup, TestDbHotBackupSuiteTeardown); + int count; + + SUITE_ADD_TEST(suite, TestDbHotBackupSimpleEnv, + TestDbHotBackupTestSetup, TestDbHotBackupTestTeardown); + SUITE_ADD_TEST(suite, TestDbHotBackupPartitionDB, + TestDbHotBackupTestSetup, TestDbHotBackupTestTeardown); + SUITE_ADD_TEST(suite, TestDbHotBackupMultiDataDir, + TestDbHotBackupTestSetup, TestDbHotBackupTestTeardown); + SUITE_ADD_TEST(suite, TestDbHotBackupSetLogDir, + TestDbHotBackupTestSetup, TestDbHotBackupTestTeardown); + SUITE_ADD_TEST(suite, TestDbHotBackupQueueDB, + TestDbHotBackupTestSetup, TestDbHotBackupTestTeardown); + + CuSuiteRun(suite); + CuSuiteSummary(suite, output); + CuSuiteDetails(suite, output); + count = suite->failCount; + CuSuiteDelete(suite); + return (count); +} + int RunDbTunerTests(CuString *output) { CuSuite *suite = CuSuiteNew("TestDbTuner", @@ -240,6 +274,7 @@ int RunQueueTests(CuString *output) TestSuite g_suites[] = { { "TestChannel", RunChannelTests }, + { "TestDbHotBackup", RunDbHotBackupTests }, { "TestDbTuner", RunDbTunerTests }, { "TestEncryption", RunEncryptionTests }, { "TestEnvConfig", RunEnvConfigTests }, diff --git a/test/c/cutest/Runner.c b/test/c/cutest/Runner.c index 16fa358c..c8812afe 100644 --- a/test/c/cutest/Runner.c +++ b/test/c/cutest/Runner.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/suites/TestChannel.c b/test/c/suites/TestChannel.c index 59a37747..dfbf4e8d 100644 --- a/test/c/suites/TestChannel.c +++ b/test/c/suites/TestChannel.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. */ #include @@ -19,8 +19,8 @@ #include #endif -#include "../cutest/CuTest.h" -#include "../common/test_util.h" +#include "CuTest.h" +#include "test_util.h" #define MAX_SEGS 10 #define MAX_MSGS 10 @@ -59,6 +59,8 @@ struct channel_test_globals { CuTest *test; mutex_t mtx; cond_t cond; + u_int *ports; + int ports_cnt; }; struct report { @@ -98,6 +100,7 @@ static void clear_rpt_int __P((struct report *)); static int env_done __P((void *)); static struct report *get_rpt __P((const DB_ENV *)); static int fortify __P((DB_ENV *, struct channel_test_globals *)); +static int get_avail_ports __P((u_int *, int)); static int has_msgs __P((void *)); static void msg_disp __P((DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t)); static void msg_disp2 __P((DB_ENV *, DB_CHANNEL *, DBT *, u_int32_t, u_int32_t)); @@ -203,6 +206,7 @@ setup(envp1, envp2, envp3, g) DB_SITE *dbsite; u_int32_t flags; int ret; + u_int *ports; #define CHECK(call) \ do { \ @@ -212,6 +216,8 @@ setup(envp1, envp2, envp3, g) } \ } while (0); + ports = g->ports; + dbenv1 = dbenv2 = dbenv3 = NULL; CHECK(db_env_create(&dbenv1, 0)); CHECK(fortify(dbenv1, g)); @@ -223,13 +229,11 @@ setup(envp1, envp2, envp3, g) CHECK(dbenv1->open(dbenv1, "DIR1", flags, 0)); CHECK(dbenv1->rep_set_config(dbenv1, DB_REPMGR_CONF_ELECTIONS, 0)); - CHECK(dbenv1->repmgr_site(dbenv1, "localhost", 6000, &dbsite, 0)); + CHECK(dbenv1->repmgr_site(dbenv1, "localhost", ports[0], &dbsite, 0)); CHECK(dbsite->set_config(dbsite, DB_LOCAL_SITE, 1)); CHECK(dbsite->close(dbsite)); CHECK(dbenv1->set_event_notify(dbenv1, notify)); CHECK(dbenv1->repmgr_msg_dispatch(dbenv1, msg_disp, 0)); - CHECK(dbenv1->rep_set_timeout(dbenv1, - DB_REP_CONNECTION_RETRY, 3000000)); CHECK(dbenv1->repmgr_start(dbenv1, 2, DB_REP_MASTER)); CHECK(db_env_create(&dbenv2, 0)); @@ -240,15 +244,13 @@ setup(envp1, envp2, envp3, g) CHECK(dbenv2->open(dbenv2, "DIR2", flags, 0)); CHECK(dbenv2->rep_set_config(dbenv2, DB_REPMGR_CONF_ELECTIONS, 0)); - CHECK(dbenv2->repmgr_site(dbenv2, "localhost", 6001, &dbsite, 0)); + CHECK(dbenv2->repmgr_site(dbenv2, "localhost", ports[1], &dbsite, 0)); CHECK(dbsite->set_config(dbsite, DB_LOCAL_SITE, 1)); CHECK(dbsite->close(dbsite)); - CHECK(dbenv2->repmgr_site(dbenv2, "localhost", 6000, &dbsite, 0)); + CHECK(dbenv2->repmgr_site(dbenv2, "localhost", ports[0], &dbsite, 0)); CHECK(dbsite->set_config(dbsite, DB_BOOTSTRAP_HELPER, 1)); CHECK(dbsite->close(dbsite)); CHECK(dbenv2->set_event_notify(dbenv2, notify)); - CHECK(dbenv2->rep_set_timeout(dbenv2, - DB_REP_CONNECTION_RETRY, 3000000)); CHECK(dbenv2->repmgr_start(dbenv2, 2, DB_REP_CLIENT)); await_condition(is_started, dbenv2, 60); @@ -267,15 +269,13 @@ setup(envp1, envp2, envp3, g) CHECK(dbenv3->open(dbenv3, "DIR3", flags, 0)); CHECK(dbenv3->rep_set_config(dbenv3, DB_REPMGR_CONF_ELECTIONS, 0)); - CHECK(dbenv3->repmgr_site(dbenv3, "localhost", 6002, &dbsite, 0)); + CHECK(dbenv3->repmgr_site(dbenv3, "localhost", ports[2], &dbsite, 0)); CHECK(dbsite->set_config(dbsite, DB_LOCAL_SITE, 1)); CHECK(dbsite->close(dbsite)); - CHECK(dbenv3->repmgr_site(dbenv3, "localhost", 6000, &dbsite, 0)); + CHECK(dbenv3->repmgr_site(dbenv3, "localhost", ports[0], &dbsite, 0)); CHECK(dbsite->set_config(dbsite, DB_BOOTSTRAP_HELPER, 1)); CHECK(dbsite->close(dbsite)); CHECK(dbenv3->set_event_notify(dbenv3, notify)); - CHECK(dbenv3->rep_set_timeout(dbenv3, - DB_REP_CONNECTION_RETRY, 3000000)); CHECK(dbenv3->repmgr_start(dbenv3, 2, DB_REP_CLIENT)); await_condition(is_started, dbenv3, 60); @@ -388,6 +388,8 @@ get_rpt(dbenv) } int TestChannelFeature(CuTest *ct) { +/* Run this test only when replication is supported. */ +#ifdef HAVE_REPLICATION DB_ENV *dbenv1, *dbenv2, *dbenv3; DB_CHANNEL *ch; DB_REP_STAT *stats; @@ -402,6 +404,7 @@ int TestChannelFeature(CuTest *ct) { u_int8_t short_buf[4]; size_t sz; int done, eid, ret; + u_int ports[3]; #ifdef _WIN32 setvbuf(stdout, NULL, _IONBF, 0); @@ -409,15 +412,26 @@ int TestChannelFeature(CuTest *ct) { printf("this is a test for repmgr channels feature\n"); g = ct->context; + ret = get_avail_ports(ports, 3); + CuAssertTrue(ct, (ret == 0)); + + g->ports = ports; + g->ports_cnt = 3; + + printf("use ports: {%u, %u, %u}\n", ports[0], ports[1], ports[2]); + + /* + * The ports[0] will be the local port for dbenv1, ports[1] for dbenv2, + * and ports[2] for dbenv3. + */ CuAssertTrue(ct, (ret = setup(&dbenv1, &dbenv2, &dbenv3, g) == 0)); /* - * For this first section, we're sending to ENV2. TODO: make that more - * clear, without duplicating the hard-coding of the port. + * For this first section, we're sending to ENV2. */ CuAssertTrue(ct, (ret = dbenv1->repmgr_site(dbenv1, - "localhost", 6001, &dbsite, 0)) == 0); + "localhost", ports[1], &dbsite, 0)) == 0); CuAssertTrue(ct, (ret = dbsite->get_eid(dbsite, &eid)) == 0); CuAssertTrue(ct, (ret = dbsite->close(dbsite)) == 0); CuAssertTrue(ct, (ret = dbenv1->repmgr_channel(dbenv1, eid, &ch, 0)) == 0); @@ -666,13 +680,12 @@ int TestChannelFeature(CuTest *ct) { /* ---------------------------------------- */ - // If you go from env2 to env, we know that it's port 6000. TODO: make this - // more robust by storing it some more structured form. + // If you go from env2 to env, we know that it's ports[0] // CuAssertTrue(ct, (ret = dbenv1->repmgr_msg_dispatch(dbenv1, msg_disp3, 0)) == 0); CuAssertTrue(ct, (ret = dbenv2->repmgr_site(dbenv2, - "localhost", 6000, &dbsite, 0)) == 0); + "localhost", ports[0], &dbsite, 0)) == 0); CuAssertTrue(ct, (ret = dbsite->get_eid(dbsite, &eid)) == 0); CuAssertTrue(ct, (ret = dbsite->close(dbsite)) == 0); CuAssertTrue(ct, (ret = dbenv2->repmgr_channel(dbenv2, eid, &ch, 0)) == 0); @@ -725,7 +738,7 @@ int TestChannelFeature(CuTest *ct) { CuAssertTrue(ct, (ret = dbenv2->repmgr_msg_dispatch(dbenv2, msg_disp4, 0)) == 0); CuAssertTrue(ct, (ret = dbenv2->repmgr_site(dbenv2, - "localhost", 6002, &dbsite, 0)) == 0); + "localhost", ports[2], &dbsite, 0)) == 0); CuAssertTrue(ct, (ret = dbsite->get_eid(dbsite, &eid)) == 0); CuAssertTrue(ct, (ret = dbsite->close(dbsite)) == 0); CuAssertTrue(ct, (ret = dbenv2->repmgr_channel(dbenv2, eid, &ch, 0)) == 0); @@ -775,6 +788,9 @@ int TestChannelFeature(CuTest *ct) { td(dbenv2); td(dbenv3); +#else + printf("TestChannelFeature is not supported by the build.\n"); +#endif /* HAVE_REPLICATION */ return (0); } @@ -1263,3 +1279,114 @@ mystrcmp(actual, expected) ; return (strcmp(p, expected)); } + +static int get_avail_ports(ports, count) + u_int *ports; + int count; +{ +/* This function is used only when replication is supported. */ +#ifdef HAVE_REPLICATION + u_int base, port, upper, curport; + int ret, t_ret, incr, i; + char buf[20], *rbuf, *str; + socket_t s; + ADDRINFO *orig_ai, *ai; +#ifdef _WIN32 +#define in_port_t u_short +#ifndef EADDRINUSE +#define EADDRINUSE WSAEADDRINUSE +#endif + WSADATA wsaData; + if ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) { + printf("WSAStartup failed with error: %d\n", ret); + return (ret); + } +#endif + base = 30100; + upper = 65535; + + /* + * It is very convenient to have a very simple mapping between port + * numbers and sites. So usually, we search a sequence of ports + * starting from (10 * N + 1). To avoid redundant check on a port, + * we set the incr to be times of 10 and just bigger or equal to count. + */ + incr = 10 * ((count + 9) / 10); + + /* + * The format for BDBPORTRANGE should be base:upper, + * either of base or upper can be empty, and if empty, + * we will use the default value for it. + * If no colon, the whole is considered to be base. + */ + rbuf = buf; + if ((ret = __os_getenv(NULL, "BDBPORTRANGE", &rbuf, sizeof(buf))) != 0) + goto end; + if (rbuf != NULL && rbuf[0] != '\0') { + if ((str = strsep(&rbuf, ":")) != NULL && str[0] != '\0') + base = (u_int)atoi(str); + if (rbuf != NULL && rbuf[0] != '\0') + upper = (u_int)atoi(rbuf); + } + + for (port = base + 1; (port + incr) <= upper; port += incr) { + curport = port; + i = incr; + + while (i-- > 0) { + if (ret = __repmgr_getaddr(NULL, "localhost", curport, + AI_PASSIVE, &orig_ai) != 0) + goto end; + + for (ai = orig_ai; ai != NULL; ai = ai->ai_next) { + if ((s = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol)) == INVALID_SOCKET) + continue; + + if (bind(s, ai->ai_addr, + (socklen_t)ai->ai_addrlen) != 0) { + ret = net_errno; + (void)closesocket(s); + s = INVALID_SOCKET; + continue; + } + + ret = 0; + goto clean; + } + if (ret == 0) + ret = net_errno; +clean: + if (s != INVALID_SOCKET) + (void)closesocket(s); + __os_freeaddrinfo(NULL, orig_ai); + if (ret != 0 && ret != EADDRINUSE) + goto end; + else if (ret != 0) + break; + curport++; + } + + /* We've found the port sequence now */ + if (ret == 0) { + for (i = 0; i < count; i++) + ports[i] = port + i; + break; + } + } +end: +#ifdef _WIN32 + if (WSACleanup() == SOCKET_ERROR) { + t_ret = net_errno; + printf("WSACleanup failed with error: %d\n", t_ret); + if (ret == 0) + ret = t_ret; + } +#endif + + return (ret); +#else + return (0); +#endif /* HAVE_REPLICATION */ +} + diff --git a/test/c/suites/TestDbHotBackup.c b/test/c/suites/TestDbHotBackup.c new file mode 100644 index 00000000..b330e734 --- /dev/null +++ b/test/c/suites/TestDbHotBackup.c @@ -0,0 +1,945 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + * + * $Id$ + */ + +/* + * A C Unit test for db_hotbackup APIs [#20451] + * + * Different testing environments: + * without any configuration, + * have partitioned databases, + * have multiple add_data_dir configured, + * have set_lg_dir configured, + * with queue extent files. + * + */ + +#include +#include +#include +#include + +#include "db.h" +#include "CuTest.h" +#include "test_util.h" + +struct handlers { + DB_ENV *dbenvp; + DB *dbp; +}; + +typedef enum { + SIMPLE_ENV = 1, + PARTITION_DB = 2, + MULTI_DATA_DIR = 3, + SET_LOG_DIR = 4, + QUEUE_DB = 5 +} ENV_CONF_T; + +static int setup_test(ENV_CONF_T); +static int open_dbp(DB_ENV **, DB **, ENV_CONF_T); +static int store_records(DB *, ENV_CONF_T); +static int cleanup_test(DB_ENV *, DB *); +static int backup_db(CuTest *, DB_ENV *, const char *, u_int32_t, int); +static int backup_env(CuTest *, DB_ENV *, u_int32_t, int); +static int make_dbconfig(ENV_CONF_T); +static int verify_db(ENV_CONF_T); +static int verify_log(ENV_CONF_T); +static int verify_dbconfig(ENV_CONF_T); +static int cmp_files(const char *, const char *); +int backup_open(DB_ENV *, const char *, const char *, void **); +int backup_write(DB_ENV *, u_int32_t, u_int32_t, u_int32_t, u_int8_t *, void *); +int backup_close(DB_ENV *, const char *, void *); + +#define BACKUP_DIR "BACKUP" +#define BACKUP_DB "backup.db" +#define LOG_DIR "LOG" +#define NPARTS 3 + +char *data_dirs[3] = {"DATA1", "DATA2", NULL}; + +int TestDbHotBackupSuiteSetup(CuSuite *suite) { + return (0); +} + +int TestDbHotBackupSuiteTeardown(CuSuite *suite) { + return (0); +} + +int TestDbHotBackupTestSetup(CuTest *ct) { + struct handlers *info; + + if ((info = calloc(1, sizeof(*info))) == NULL) + return (ENOMEM); + ct->context = info; + setup_envdir(TEST_ENV, 1); + setup_envdir(BACKUP_DIR, 1); + return (0); +} + +int TestDbHotBackupTestTeardown(CuTest *ct) { + struct handlers *info; + DB_ENV *dbenv; + DB *dbp; + + if (ct->context == NULL) + return (EINVAL); + info = ct->context; + dbenv = info->dbenvp; + dbp = info->dbp; + /* Close all handles and clean the directories. */ + CuAssert(ct, "cleanup_test", cleanup_test(dbenv, dbp) == 0); + free(info); + ct->context = NULL; + return (0); +} + +int TestDbHotBackupSimpleEnv(CuTest *ct) { + DB_ENV *dbenv; + DB *dbp; + ENV_CONF_T envconf; + struct handlers *info; + char **names; + int cnt, has_callback; + u_int32_t flag; + + envconf = SIMPLE_ENV; + info = ct->context; + has_callback = 0; + flag = DB_EXCL; + + /* Step 1: set up test by making relative directories. */ + CuAssert(ct, "setup_test", setup_test(envconf) == 0); + + /* Step 2: open db handle. */ + CuAssert(ct,"open_dbp", open_dbp(&dbenv, &dbp, envconf) == 0); + info->dbenvp = dbenv; + info->dbp = dbp; + + /* Step 3: store records into db. */ + CuAssert(ct,"store_records", store_records(dbp, envconf) == 0); + CuAssert(ct, "DB->sync", dbp->sync(dbp, 0) == 0); + + /* Step 4: backup only the db file without callbacks. */ + CuAssert(ct, "backup_env", + backup_db(ct, dbenv, BACKUP_DB, flag, has_callback) == 0); + + /* Step 5: check backup result. */ + /* 5a: dump the db and verify the content is same. */ + CuAssert(ct, "verify_db", verify_db(envconf) == 0); + + /* 5b: no other files are in backupdir. */ + CuAssert(ct, "__os_dirlist", + __os_dirlist(NULL, BACKUP_DIR, 0, &names, &cnt) == 0); + CuAssert(ct, "too many files in backupdir", cnt == 1); + + return (0); +} + +int TestDbHotBackupPartitionDB(CuTest *ct) { + DB_ENV *dbenv; + DB *dbp; + ENV_CONF_T envconf; + struct handlers *info; + int has_callback; + u_int32_t flag; + + envconf = PARTITION_DB; + info = ct->context; + has_callback = 0; + flag = DB_BACKUP_CLEAN | DB_CREATE | DB_BACKUP_SINGLE_DIR; + + /* Step 1: set up test by making relative directories. */ + CuAssert(ct, "setup_test", setup_test(envconf) == 0); + + /* Step 2: open db handle. */ + CuAssert(ct,"open_dbp", open_dbp(&dbenv, &dbp, envconf) == 0); + info->dbenvp = dbenv; + info->dbp = dbp; + + /* Step 3: store records into db. */ + CuAssert(ct,"store_records", store_records(dbp, envconf) == 0); + CuAssert(ct, "DB->sync", dbp->sync(dbp, 0) == 0); + + /* Step 4: backup the whole environment into a single directory. */ + CuAssert(ct, "backup_env", + backup_env(ct, dbenv, flag, has_callback) == 0); + + /* Step 5: check backup result. */ + /* 5a: dump the db and verify the content is same. */ + CuAssert(ct, "verify_db", verify_db(envconf) == 0); + + /* 5b: verify that creation directory is not in backupdir. */ + CuAssert(ct, "__os_exist", __os_exists(NULL, "BACKUP/DATA1", 0) != 0); + + /* 5c: verify that log files are in backupdir. */ + CuAssert(ct, "verify_log", verify_log(envconf) == 0); + + /* 5d: verify that DB_CONFIG is not in backupdir*/ + CuAssert(ct, "verify_dbconfig", verify_dbconfig(envconf) == 0); + + return (0); +} + +int TestDbHotBackupMultiDataDir(CuTest *ct) { + DB_ENV *dbenv; + DB *dbp; + ENV_CONF_T envconf; + struct handlers *info; + int has_callback; + u_int32_t flag; + + envconf = MULTI_DATA_DIR; + info = ct->context; + has_callback = 0; + flag = DB_BACKUP_CLEAN | DB_CREATE | DB_BACKUP_FILES; + + /* Step 1: set up test by making relative directories. */ + CuAssert(ct, "setup_test", setup_test(envconf) == 0); + + /* Step 2: open db handle. */ + CuAssert(ct,"open_dbp", open_dbp(&dbenv, &dbp, envconf) == 0); + info->dbenvp = dbenv; + info->dbp = dbp; + + /* Step 3: store records into db. */ + CuAssert(ct,"store_records", store_records(dbp, envconf) == 0); + CuAssert(ct, "DB->sync", dbp->sync(dbp, 0) == 0); + + /* Step 4: backup the whole environment without callbacks. */ + CuAssert(ct, "backup_env", + backup_env(ct, dbenv, flag, has_callback) == 0); + + /* Step 5: check backup result. */ + /* 5a: dump the db and verify the content is same. */ + CuAssert(ct, "verify_db", verify_db(envconf) == 0); + + /* 5b: verify that data_dirs are in backupdir. */ + CuAssert(ct, "__os_exist", __os_exists(NULL, "BACKUP/DATA1", 0) == 0); + CuAssert(ct, "__os_exist", __os_exists(NULL, "BACKUP/DATA2", 0) == 0); + + /* 5c: verify that log files are in backupdir. */ + CuAssert(ct, "verify_log", verify_log(envconf) == 0); + + /* 5d: verify that DB_CONFIG is in backupdir. */ + CuAssert(ct, "verify_dbconfig", verify_dbconfig(envconf) == 0); + + return (0); +} + +int TestDbHotBackupSetLogDir(CuTest *ct) { + DB_ENV *dbenv; + DB *dbp; + ENV_CONF_T envconf; + struct handlers *info; + int has_callback = 1; + u_int32_t flag; + + envconf = SET_LOG_DIR; + info = ct->context; + has_callback = 1; + flag = DB_BACKUP_CLEAN | DB_CREATE | DB_BACKUP_FILES; + + /* Step 1: set up test by making relative directories. */ + CuAssert(ct, "setup_test", setup_test(envconf) == 0); + + /* Step 2: open db handle. */ + CuAssert(ct,"open_dbp", open_dbp(&dbenv, &dbp, envconf) == 0); + info->dbenvp = dbenv; + info->dbp = dbp; + + /* Step 3: store records into db. */ + CuAssert(ct,"store_records", store_records(dbp, envconf) == 0); + CuAssert(ct, "DB->sync", dbp->sync(dbp, 0) == 0); + + /* Step 4: backup a whole environment with callbacks. */ + CuAssert(ct, "backup_env", + backup_env(ct, dbenv, flag, has_callback) == 0); + + /* Step 5: check backup result. */ + /* 5a: dump the db and verify the content is same. */ + CuAssert(ct, "verify_db", verify_db(envconf) == 0); + + /* 5b: verify that log files are in backupdir/log_dir. */ + CuAssert(ct, "verify_log", verify_log(envconf) == 0); + + /* 5c: verify that DB_CONFIG is in backupdir*/ + CuAssert(ct, "verify_dbconfig", verify_dbconfig(envconf) == 0); + + return (0); +} + +int TestDbHotBackupQueueDB(CuTest *ct) { + DB_ENV *dbenv; + DB *dbp; + ENV_CONF_T envconf; + struct handlers *info; + int has_callback; + u_int32_t flag; + + envconf = QUEUE_DB; + info = ct->context; + has_callback = 0; + flag = DB_BACKUP_CLEAN | DB_CREATE; + + /* Step 1: set up test by making relative directories. */ + CuAssert(ct, "setup_test", setup_test(envconf) == 0); + + /* Step 2: open db handle. */ + CuAssert(ct,"open_dbp", open_dbp(&dbenv, &dbp, envconf) == 0); + info->dbenvp = dbenv; + info->dbp = dbp; + + /* Step 3: store records into db. */ + CuAssert(ct,"store_records", store_records(dbp, envconf) == 0); + CuAssert(ct, "DB->sync", dbp->sync(dbp, 0) == 0); + + /* Step 4: backup the whole environment without callbacks. */ + CuAssert(ct, "backup_env", + backup_env(ct, dbenv, flag, has_callback) == 0); + + /* Step 5: check backup result. */ + /* 5a: dump the db and verify the content is same. */ + CuAssert(ct, "verify_db", verify_db(envconf) == 0); + + /* 5b: verify that log files are in backupdir. */ + CuAssert(ct, "verify_log", verify_log(envconf) == 0); + + /* 5c: vertify that DB_CONFIG is not in backupdir. */ + CuAssert(ct, "verify_dbconfig", verify_dbconfig(envconf) == 0); + + return (0); +} + +static int +setup_test(envconf) + ENV_CONF_T envconf; +{ + char path[1024]; + int i, ret; + + /* Make directories based on config. */ + switch (envconf) { + case SIMPLE_ENV: + break; + case PARTITION_DB: + snprintf(path, sizeof(path),"%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], data_dirs[0]); + if ((ret = setup_envdir(path, 1)) != 0) + return (ret); + break; + case MULTI_DATA_DIR: + for (i = 0; i < 2; i++) { + snprintf(path, sizeof(path),"%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], data_dirs[i]); + if ((ret = setup_envdir(path, 1)) != 0) + return (ret); + } + break; + case SET_LOG_DIR: + snprintf(path, sizeof(path),"%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], LOG_DIR); + if ((ret = setup_envdir(path, 1)) != 0) + return (ret); + break; + case QUEUE_DB: + break; + default: + return (EINVAL); + } + + /* Make DB_CONFIG for PARTITION_DB, MULT_DATA_DIR and SET_LOG_DIR. */ + if(envconf >= 2 && envconf <= 4) + make_dbconfig(envconf); + + return (0); +} + +static int +open_dbp(dbenvp, dbpp, envconf) + DB_ENV **dbenvp; + DB **dbpp; + ENV_CONF_T envconf; +{ + DB_ENV *dbenv; + DB *dbp; + DBT key1, key2, keys[2]; + DBTYPE dtype; + int i, ret, value1, value2; + + dbenv = NULL; + dbp = NULL; + dtype = DB_BTREE; + ret = 0; + + if ((ret = db_env_create(&dbenv, 0)) != 0) { + fprintf(stderr, "db_env_create: %s\n", db_strerror(ret)); + return (ret); + } + + *dbenvp = dbenv; + + dbenv->set_errfile(dbenv, stderr); + dbenv->set_errpfx(dbenv, "TestDbHotBackup"); + + /* Configure the environment. */ + switch (envconf) { + case SIMPLE_ENV: + case PARTITION_DB: + break; + /* Add data directories. */ + case MULTI_DATA_DIR: + for (i = 0; i < 2; i++) { + if ((ret = dbenv->add_data_dir(dbenv, + data_dirs[i])) != 0) { + fprintf(stderr, "DB_ENV->add_data_dir: %s\n", + db_strerror(ret)); + return (ret); + } + } + break; + /* Set log directory. */ + case SET_LOG_DIR: + if ((ret = dbenv->set_lg_dir(dbenv, LOG_DIR)) != 0) { + fprintf(stderr, "DB_ENV->set_lg_dir: %s\n", + db_strerror(ret)); + return (ret); + } + break; + case QUEUE_DB: + dtype = DB_QUEUE; + break; + default: + return (EINVAL); + } + + /* Open the environment. */ + if ((ret = dbenv->open(dbenv, TEST_ENV, DB_CREATE | DB_INIT_LOCK | + DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0) { + fprintf(stderr, "DB_ENV->open: %s\n", db_strerror(ret)); + return (ret); + } + + /* Configure the db handle. */ + if ((ret = db_create(&dbp, dbenv, 0)) != 0) { + fprintf(stderr, "db_create: %s\n", db_strerror(ret)); + return (ret); + } + + *dbpp = dbp; + + dbp->set_errfile(dbp, stderr); + dbp->set_errpfx(dbp, "TestDbHotBackup"); + + /* Set db creation directory for PARTTION_DB and MULTI_DATA_DRI. */ + if (envconf == PARTITION_DB || envconf == MULTI_DATA_DIR) { + if ((ret = dbp->set_create_dir(dbp, data_dirs[0])) != 0) { + fprintf(stderr, "DB_ENV->add_data_dir: %s\n", + db_strerror(ret)); + return (ret); + } + } + + /* Set partition. */ + if (envconf == PARTITION_DB) { + value1 = 8; + key1.data = &value1; + key1.size = sizeof(value1); + value2 = 16; + key2.data = &value2; + key2.size = sizeof(value2); + keys[0] = key1; + keys[1] = key2; + if ((ret = dbp->set_partition(dbp, NPARTS, keys, NULL)) != 0) { + dbp->err(dbp, ret, "DB->set_partition"); + return (ret); + } + } + + /* Set queue record length and extent size. */ + if (envconf == QUEUE_DB) { + if ((ret = dbp->set_re_len(dbp, 50)) != 0) { + dbp->err(dbp, ret, "DB->set_re_len"); + return (ret); + } + if ((ret = dbp->set_q_extentsize(dbp, 1)) != 0) { + dbp->err(dbp, ret, "DB->set_q_extentsize"); + return (ret); + } + } + /* Set flag for Btree. */ + else { + if ((ret = dbp->set_flags(dbp, DB_DUPSORT)) != 0) { + dbp->err(dbp, ret, "DB->set_flags"); + return (ret); + } + } + + if ((ret = dbp->set_pagesize(dbp, 512)) != 0) { + dbp->err(dbp, ret, "DB->set_pagesize"); + return (ret); + } + + /*Open the db handle. */ + if ((ret = dbp->open(dbp, NULL, BACKUP_DB, + NULL, dtype, DB_CREATE, 0644)) != 0) { + dbp->err(dbp, ret, "%s: DB->open", BACKUP_DB); + return (ret); + } + + return (0); +} + +static int +store_records(dbp, envconf) + DB *dbp; + ENV_CONF_T envconf; +{ + DBT key, data; + int i, ret; + size_t num; + u_int32_t flag; + + char *buf = "abcdefghijefghijklmnopqrstuvwxyz"; + num = strlen(buf); + flag = envconf == QUEUE_DB ? DB_APPEND : 0; + + memset(&key, 0, sizeof(DBT)); + memset(&data, 0, sizeof(DBT)); + + for (i = 0; i < num; i++) { + key.data = &i; + key.size = sizeof(i); + + data.data = &buf[i]; + data.size = sizeof(char); + + if ((ret = dbp->put(dbp, NULL, &key, &data, flag)) != 0) { + dbp->err(dbp, ret, "DB->put"); + return (ret); + } + } + return (ret); +} + +static int +cleanup_test(dbenv, dbp) + DB_ENV *dbenv; + DB *dbp; +{ + int ret, t_ret; + + ret = 0;; + if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) + fprintf(stderr, "DB->close: %s\n", db_strerror(ret)); + + if (dbenv != NULL && (t_ret = dbenv->close(dbenv, 0)) != 0) { + fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(t_ret)); + ret = t_ret; + } + + teardown_envdir(TEST_ENV); + teardown_envdir(BACKUP_DIR); + + return (ret); +} + +/* + * backup_env: + * CuTest *ct + * DB_ENV *dbenv: the environment to backup + * u_int32_t flags: hotbackup flags + * int has_callback: 0 if not use callback, 1 otherwise +*/ +static int +backup_env(ct, dbenv, flags, has_callback) + CuTest *ct; + DB_ENV *dbenv; + u_int32_t flags; + int has_callback; +{ + if (has_callback != 0) { + CuAssert(ct, "DB_ENV->set_backup_callbacks", + dbenv->set_backup_callbacks(dbenv, backup_open, + backup_write, backup_close) == 0); + } + CuAssert(ct, "DB_ENV->backup", + dbenv->backup(dbenv, BACKUP_DIR, flags) == 0); + return (0); +} + +/* + * backup_db: + * CuTest *ct + * DB_ENV *dbenv: the environment to backup + * const char *dname: the name of db file to backup + * u_int32_t flags: hot_backup flags + * int has_callback: 0 if not use callback, 1 otherwise +*/ + +static int +backup_db(ct, dbenv, dname, flags, has_callback) + CuTest *ct; + DB_ENV *dbenv; + const char *dname; + u_int32_t flags; + int has_callback; +{ + if (has_callback != 0) { + CuAssert(ct, "DB_ENV->set_backup_callbacks", + dbenv->set_backup_callbacks(dbenv, backup_open, + backup_write, backup_close) == 0); + } + CuAssert(ct, "DB_ENV->dbbackup", + dbenv->dbbackup(dbenv, dname, BACKUP_DIR, flags) == 0); + return (0); +} + +static int +verify_db(envconf) + ENV_CONF_T envconf; +{ + char buf1[100], buf2[100], path1[100], path2[100], pfx[10]; + char **names1, **names2; + int cnt1, cnt2, i, m_cnt, ret, t_cnt1, t_cnt2; + + names1 = names2 = NULL; + cnt1 = cnt2 = i = m_cnt = ret = t_cnt1 = t_cnt2 = 0; + + /* Get the data directory paths. */ + if (envconf == PARTITION_DB) { + snprintf(path1, sizeof(path1), "%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], data_dirs[0]); + snprintf(path2, sizeof(path2), "%s", BACKUP_DIR); + } else if (envconf == MULTI_DATA_DIR) { + snprintf(path1, sizeof(path1), "%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], data_dirs[0]); + snprintf(path2, sizeof(path2), "%s%c%s", + BACKUP_DIR, PATH_SEPARATOR[0], data_dirs[0]); + } else { + snprintf(path1, sizeof(path1), "%s", TEST_ENV); + snprintf(path2, sizeof(path2), "%s", BACKUP_DIR); + } + + /* Define the prefix of partition db and queue extent files. */ + if (envconf == PARTITION_DB) + snprintf(pfx, sizeof(pfx), "%s", "__dbp."); + else if (envconf == QUEUE_DB) + snprintf(pfx, sizeof(pfx), "%s", "__dbq."); + else + pfx[0] = '\0'; + + /* Get the lists of db file, partition db files and queue extent. */ + if ((ret = __os_dirlist(NULL, path1, 0, &names1, &cnt1)) != 0) + return (ret); + if ((ret = __os_dirlist(NULL, path2, 0, &names2, &cnt2)) != 0) + return (ret); + + /* Get the numbers of db files. */ + m_cnt = cnt1 > cnt2 ? cnt1 : cnt2; + t_cnt1 = cnt1; + t_cnt2 = cnt2; + for (i = 0; i < m_cnt; i++) { + if (i < cnt1 && + strncmp(names1[i], BACKUP_DB, strlen(BACKUP_DB)) != 0 && + (strlen(pfx) > 0 ? + strncmp(names1[i], pfx, strlen(pfx)) != 0 : 1)) { + t_cnt1--; + names1[i] = NULL; + } + if (i < cnt2 && + strncmp(names2[i], BACKUP_DB, strlen(BACKUP_DB)) != 0 && + (strlen(pfx) > 0 ? + strncmp(names2[i], pfx, strlen(pfx)) != 0 : 1)) { + t_cnt2--; + names2[i] = NULL; + } + } + if ((ret = t_cnt1 == t_cnt2 ? 0 : EINVAL) != 0) + return (ret); + + /* Compare each db file. */ + for (i = 0; i < cnt1; i++) { + if (names1[i] == NULL) + continue; + snprintf(buf1, sizeof(buf1), "%s%c%s", + path1, PATH_SEPARATOR[0], names1[i]); + snprintf(buf2, sizeof(buf2), "%s%c%s", + path2, PATH_SEPARATOR[0], names1[i]); + if ((ret = cmp_files(buf1, buf2)) != 0) + break; + } + + return (ret); +} + +static int +verify_log(envconf) + ENV_CONF_T envconf; +{ + char buf1[100], buf2[100], lg1[100], lg2[100], pfx[10]; + char **names1, **names2; + int cnt1, cnt2, i, m_cnt, ret, t_cnt1, t_cnt2; + + cnt1 = cnt2 = i = m_cnt = ret = t_cnt1 = t_cnt2 = 0; + + /* Get the log paths. */ + if (envconf == SET_LOG_DIR) { + snprintf(lg1, sizeof(lg1), + "%s%c%s", TEST_ENV, PATH_SEPARATOR[0], LOG_DIR); + snprintf(lg2, sizeof(lg2), + "%s%c%s", BACKUP_DIR, PATH_SEPARATOR[0], LOG_DIR); + } + else { + snprintf(lg1, sizeof(lg1), "%s", TEST_ENV); + snprintf(lg2, sizeof(lg2), "%s", BACKUP_DIR); + } + + /* Define the prefix of log file. */ + snprintf(pfx, sizeof(pfx), "%s", "log."); + + /* Get the lists of log files. */ + if ((ret = __os_dirlist(NULL, lg1, 0, &names1, &cnt1)) != 0) + return (ret); + if ((ret = __os_dirlist(NULL, lg2, 0, &names2, &cnt2)) != 0) + return (ret); + + /* Get the numbers of log files. */ + m_cnt = cnt1 > cnt2 ? cnt1 : cnt2; + t_cnt1 = cnt1; + t_cnt2 = cnt2; + for (i = 0; i < m_cnt; i++) { + if (i < cnt1 && + strncmp(names1[i], pfx, strlen(pfx)) != 0) { + t_cnt1--; + names1[i] = NULL; + } + if (i < cnt2 && + strncmp(names2[i], pfx, strlen(pfx)) != 0) { + t_cnt2--; + names2[i] = NULL; + } + } + if ((ret = t_cnt1 == t_cnt2 ? 0 : EINVAL) != 0) + return (ret); + + /* Compare each log file. */ + for (i = 0; i < cnt1; i++) { + if (names1[i] == NULL) + continue; + snprintf(buf1, sizeof(buf1), "%s%c%s", + lg1, PATH_SEPARATOR[0], names1[i]); + snprintf(buf2, sizeof(buf2), "%s%c%s", + lg2, PATH_SEPARATOR[0], names1[i]); + if ((ret = cmp_files(buf1, buf2)) != 0) + break; + } + + return (ret); +} + +static int +verify_dbconfig(envconf) + ENV_CONF_T envconf; +{ + char *path1, *path2; + int ret; + + path1 = path2 = NULL; + ret = 0; + + if ((ret = __os_calloc(NULL, 1024, 1, &path1)) != 0) + goto err; + if ((ret = __os_calloc(NULL, 1024, 1, &path2)) != 0) + goto err; + + switch(envconf) { + /* DB_CONFIG is not in backupdir for this test cases. */ + case SIMPLE_ENV: + case PARTITION_DB: + case QUEUE_DB: + if((ret = __os_exists(NULL, "BACKUP/DB_CONFIG", 0)) != 0) + return (0); + break; + /* DB_CONFIG is in backupdir for MULTI_DATA_DIR and SET_LOG_DIR. */ + case MULTI_DATA_DIR: + case SET_LOG_DIR: + snprintf(path1, 1024, "%s%c%s", + TEST_ENV, PATH_SEPARATOR[0], "DB_CONFIG"); + snprintf(path2, 1024, "%s%c%s", + BACKUP_DIR, PATH_SEPARATOR[0], "DB_CONFIG"); + if ((ret = cmp_files(path1, path2)) != 0) + goto err; + break; + default: + return (EINVAL); + } + +err: + if (path1 != NULL) + __os_free(NULL, path1); + if (path2 != NULL) + __os_free(NULL, path2); + return (ret); +} + +int backup_open(dbenv, dbname, target, handle) + DB_ENV *dbenv; + const char *dbname; + const char *target; + void **handle; +{ + DB_FH *fp; + const char *t_target; + char str[1024]; + u_int32_t flags; + int ret; + + fp = NULL; + flags = DB_OSO_CREATE; + ret = 0; + + if (target == NULL) + t_target = BACKUP_DIR; + else + t_target = target; + sprintf(str, "%s%s%s", t_target, "/", dbname); + + if ((ret = __os_open(NULL, str, 0, flags, DB_MODE_600, &fp)) != 0) + return (ret); + + *handle = fp; + + return (ret); +} + +int backup_write(dbenv, gigs, offset, size, buf, handle) + DB_ENV *dbenv; + u_int32_t gigs, offset, size; + u_int8_t *buf; + void *handle; +{ + DB_FH *fp; + size_t nw; + int ret; + + ret = 0; + fp = (DB_FH *)handle; + + if (size <= 0) + return (EINVAL); + + if ((ret = __os_write(NULL, fp, buf, size, &nw)) != 0) + return (ret); + if (nw != size) + ret = EIO; + + return (ret); +} + +int backup_close(dbenv, dbname, handle) + DB_ENV *dbenv; + const char *dbname; + void *handle; +{ + DB_FH *fp; + int ret; + + fp = (DB_FH *)handle; + ret = 0; + + ret = __os_closehandle(NULL, fp); + + return (ret); + +} + +static int +make_dbconfig(envconf) + ENV_CONF_T envconf; +{ + const char *path = "TESTDIR/DB_CONFIG"; + char str[1024]; + FILE *fp; + + if (envconf >= PARTITION_DB && envconf <= SET_LOG_DIR) + fp = fopen(path, "w"); + else + return (0); + + switch(envconf) { + case PARTITION_DB: + case MULTI_DATA_DIR: + snprintf(str, 1024, "%s", "set_data_dir DATA1"); + break; + case SET_LOG_DIR: + snprintf(str, 1024, "%s", "set_lg_dir LOG"); + break; + default: + return (EINVAL); + } + + fputs(str, fp); + fclose(fp); + + return (0); +} + +static int +cmp_files(name1, name2) + const char *name1; + const char *name2; +{ + DB_FH *fhp1, *fhp2; + void *buf1, *buf2; + size_t nr1, nr2; + int ret, t_ret; + + fhp1 = fhp2 = NULL; + buf1 = buf2 = NULL; + nr1 = nr2 = 0; + ret = t_ret = 0; + + /* Allocate memory for buffers. */ + if ((ret = __os_calloc(NULL, MEGABYTE, 1, &buf1)) != 0) + goto err; + if ((ret = __os_calloc(NULL, MEGABYTE, 1, &buf2)) != 0) + goto err; + + /* Open the input files. */ + if ( (ret = __os_open(NULL, name1, 0, DB_OSO_RDONLY, 0, &fhp1)) != 0 || + (t_ret = __os_open(NULL, name2, 0, DB_OSO_RDONLY, 0, &fhp2)) != 0) { + if (ret == 0) + ret = t_ret; + goto err; + } + + /* Read and compare the file content. */ + while ((ret = __os_read(NULL, fhp1, buf1, MEGABYTE, &nr1)) == 0 && + nr1 > 0 && (ret = __os_read(NULL, fhp2, + buf2, MEGABYTE, &nr2)) == 0 && nr2 > 0) { + if (nr1 != nr2) { + ret = EINVAL; + break; + } + if ((ret = memcmp(buf1, buf2, nr1)) != 0) + break; + } + if(ret == 0 && nr1 > 0 && nr2 > 0 && nr1 != nr2) + ret = EINVAL; + +err: + if (buf1 != NULL) + __os_free(NULL, buf1); + if (buf2 != NULL) + __os_free(NULL, buf2); + if (fhp1 != NULL && (t_ret = __os_closehandle(NULL, fhp1)) != 0) + ret = t_ret; + if (fhp2 != NULL && (t_ret = __os_closehandle(NULL, fhp2)) != 0) + ret = t_ret; + return (ret); +} diff --git a/test/c/suites/TestDbTuner.c b/test/c/suites/TestDbTuner.c index 56810ca7..08a16bb3 100644 --- a/test/c/suites/TestDbTuner.c +++ b/test/c/suites/TestDbTuner.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/suites/TestEncryption.c b/test/c/suites/TestEncryption.c index 2045d690..d0176306 100644 --- a/test/c/suites/TestEncryption.c +++ b/test/c/suites/TestEncryption.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ * @@ -27,6 +27,7 @@ #include "db.h" #include "CuTest.h" +#include "test_util.h" const char *progname_crypt = "encryption"; #define DATABASE "encryption.db" @@ -59,7 +60,12 @@ int TestEncryptedDbFlag(CuTest *ct) { } int TestEncryptedDb(CuTest *ct) { +/* Run this test only when cryptography is supported. */ +#ifdef HAVE_CRYPTO CuAssert(ct, "TestEncryptedDb", encryptTestCase(ct, 0, 0, 1, 0) == 0); +#else + printf("TestEncryptedDb is not supported by the build.\n"); +#endif /* HAVE_CRYPTO */ return (0); } @@ -94,25 +100,48 @@ int TestEnvWithEncryptedDbFlagAndDb(CuTest *ct) { } int TestEncyptedEnv(CuTest *ct) { +/* Run this test only when cryptography is supported. */ +#ifdef HAVE_CRYPTO CuAssert(ct, "TestEncyptedEnv", encryptTestCase(ct, 1, 1, 0, 0) == 0); +#else + printf("TestEyptedEnv is not supported by the build.\n"); +#endif /* HAVE_CRYPTO */ return (0); } int TestEncyptedEnvWithEncyptedDbFlag(CuTest *ct) { +/* Run this test only when cryptography is supported. */ +#ifdef HAVE_CRYPTO CuAssert(ct, "TestEncyptedEnvWithEncyptedDbFlag", encryptTestCase(ct, 1, 1, 0, 1) == 0); +#else + printf("TestEncyptedEnvWithEncyptedDbFlag " + "is not supported by the build.\n"); +#endif /* HAVE_CRYPTO */ return (0); } int TestEncyptedEnvWithEncyptedDb(CuTest *ct) { +/* Run this test only when cryptography is supported. */ +#ifdef HAVE_CRYPTO CuAssert(ct, "TestEncyptedEnvWithEncyptedDb", encryptTestCase(ct, 1, 1, 1, 0) == 0); +#else + printf("TestEncyptedEnvWithEncyptedDb " + "is not supported by the build.\n"); +#endif /* HAVE_CRYPTO */ return (0); } int TestEncyptedEnvWithEncryptedDbFlagAndDb(CuTest *ct) { +/* Run this test only when cryptography is supported. */ +#ifdef HAVE_CRYPTO CuAssert(ct, "TestEncyptedEnvWithEncryptedDbFlagAndDb", encryptTestCase(ct, 1, 1, 1, 1) == 0); +#else + printf("TestEncyptedEnvWithEncyptedDbFlagAndDb " + "is not supported by the build.\n"); +#endif /* HAVE_CRYPTO */ return (0); } @@ -307,8 +336,7 @@ int dbPutGet(CuTest *ct, DB *dbp) DBT key, data; char buf[1024]; const char *str = "abcdefghijklmnopqrst"; - int cnt, ret; - size_t len; + int cnt, ret, len; ret = 0; diff --git a/test/c/suites/TestEnvConfig.c b/test/c/suites/TestEnvConfig.c index 2bbf4833..f19b7b48 100644 --- a/test/c/suites/TestEnvConfig.c +++ b/test/c/suites/TestEnvConfig.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. */ #include diff --git a/test/c/suites/TestEnvMethod.c b/test/c/suites/TestEnvMethod.c index adf1c653..7da0f785 100644 --- a/test/c/suites/TestEnvMethod.c +++ b/test/c/suites/TestEnvMethod.c @@ -1,16 +1,18 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ #include "db.h" #include "CuTest.h" +#include "test_util.h" int TestSetThreadCount(CuTest *ct) { /* SKIP */ - +/* Run this test only when hash is supported. */ +#ifdef HAVE_HASH DB_ENV *dbenv; DB *db; @@ -28,6 +30,8 @@ int TestSetThreadCount(CuTest *ct) { /* SKIP */ db->close(db, 0); dbenv->close(dbenv, 0); - +#else + printf("TestSetThreadCount is not supported by the build.\n"); +#endif /* HAVE_HASH */ return (0); } diff --git a/test/c/suites/TestKeyExistErrorReturn.c b/test/c/suites/TestKeyExistErrorReturn.c index 4b6aa47e..75078bc2 100644 --- a/test/c/suites/TestKeyExistErrorReturn.c +++ b/test/c/suites/TestKeyExistErrorReturn.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/c/suites/TestPartial.c b/test/c/suites/TestPartial.c index 8cd16d93..cacc6d51 100644 --- a/test/c/suites/TestPartial.c +++ b/test/c/suites/TestPartial.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -56,6 +56,8 @@ int TestPartialTestTeardown(CuTest *ct) { /* Test cases */ int TestDbPartialGet(CuTest *ct) { +/* Run this test only when queue is supported. */ +#ifdef HAVE_QUEUE DB *pdb; OpenDb(ct, NULL, &pdb, dbName, DB_BTREE, 0); @@ -77,6 +79,9 @@ int TestDbPartialGet(CuTest *ct) { CheckDbPartial(ct, pdb, 0, DB_CONSUME_WAIT, 0); CuAssert(ct, "DB->close", CloseDb(pdb) == 0); CuAssert(ct, "remove()", remove(dbName) == 0); +#else + printf("TestDbPartialGet is not supported by the build.\n"); +#endif /* HAVE_QUEUE */ return (0); } diff --git a/test/c/suites/TestQueue.c b/test/c/suites/TestQueue.c index c6f48331..70f0209b 100644 --- a/test/c/suites/TestQueue.c +++ b/test/c/suites/TestQueue.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. * * A C test for the queue access method. * TODO: Make this more consistent with the CuTest harness. diff --git a/test/c/test_api_methods.c b/test/c/test_api_methods.c index fe39bfc8..5998f556 100644 --- a/test/c/test_api_methods.c +++ b/test/c/test_api_methods.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. */ #include diff --git a/test/c/test_log_verify.c b/test/c/test_log_verify.c index 1088f233..2fac4ee5 100644 --- a/test/c/test_log_verify.c +++ b/test/c/test_log_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestConstruct01.cpp b/test/cxx/TestConstruct01.cpp index a21f6483..7d7eb6d0 100644 --- a/test/cxx/TestConstruct01.cpp +++ b/test/cxx/TestConstruct01.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestGetSetMethods.cpp b/test/cxx/TestGetSetMethods.cpp index 5e42a4a6..d45c827d 100644 --- a/test/cxx/TestGetSetMethods.cpp +++ b/test/cxx/TestGetSetMethods.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestKeyRange.cpp b/test/cxx/TestKeyRange.cpp index c64ff43c..e399751a 100644 --- a/test/cxx/TestKeyRange.cpp +++ b/test/cxx/TestKeyRange.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1997, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestLogc.cpp b/test/cxx/TestLogc.cpp index bd9712c6..e8ec695b 100644 --- a/test/cxx/TestLogc.cpp +++ b/test/cxx/TestLogc.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestMulti.cpp b/test/cxx/TestMulti.cpp index 5b37d1b7..cc82f1f3 100644 --- a/test/cxx/TestMulti.cpp +++ b/test/cxx/TestMulti.cpp @@ -1,11 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. */ #include "db_cxx.h" #include +#ifdef HAVE_STRING_H +#include +#endif using namespace std; void test1() @@ -45,8 +48,10 @@ void test1() DbMultipleKeyDataIterator i(multidata); while(err==0 && i.next(key,data)) { - int actualKey= *((int*)key.get_data()); - int actualData= *((int*)data.get_data()); + int actualKey; + int actualData; + memmove(&actualKey, key.get_data(), sizeof(actualKey)); + memmove(&actualData, data.get_data(), sizeof(actualData)); if(actualKey!=actualData) { std::cout << "Error: key/data mismatch. " << actualKey << "!=" << actualData << std::endl; @@ -118,7 +123,8 @@ void test2() DbMultipleDataIterator i(multidata); while(err==0 && i.next(data)) { - int actualData= *((int*)data.get_data()); + int actualData; + memmove(&actualData, data.get_data(), sizeof(actualData)); if(numberOfKeysRead!=actualData) { std::cout << "Error: key/data mismatch. " << numberOfKeysRead << "!=" << actualData << std::endl; @@ -176,7 +182,8 @@ void test3() DbMultipleRecnoDataIterator i(multidata); while(err==0 && i.next(recno,data)) { - int actualData= *((int*)data.get_data()); + u_int32_t actualData; + memmove(&actualData, data.get_data(), sizeof(actualData)); if(recno!=actualData+1) { std::cout << "Error: recno/data mismatch. " << recno << "!=" << actualData << "+1" << std::endl; diff --git a/test/cxx/TestSimpleAccess.cpp b/test/cxx/TestSimpleAccess.cpp index 2f49ead8..efa93779 100644 --- a/test/cxx/TestSimpleAccess.cpp +++ b/test/cxx/TestSimpleAccess.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/cxx/TestTruncate.cpp b/test/cxx/TestTruncate.cpp index 7639f01a..d86910ca 100644 --- a/test/cxx/TestTruncate.cpp +++ b/test/cxx/TestTruncate.cpp @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_curalloc.c b/test/micro/source/b_curalloc.c index e454818d..215abdb0 100644 --- a/test/micro/source/b_curalloc.c +++ b/test/micro/source/b_curalloc.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_curwalk.c b/test/micro/source/b_curwalk.c index f74d6d6e..2c7134af 100644 --- a/test/micro/source/b_curwalk.c +++ b/test/micro/source/b_curwalk.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_del.c b/test/micro/source/b_del.c index b526e631..0acd9e48 100644 --- a/test/micro/source/b_del.c +++ b/test/micro/source/b_del.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_get.c b/test/micro/source/b_get.c index 30bea8d8..6699823e 100644 --- a/test/micro/source/b_get.c +++ b/test/micro/source/b_get.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_inmem.c b/test/micro/source/b_inmem.c index 31665298..d1018ce9 100644 --- a/test/micro/source/b_inmem.c +++ b/test/micro/source/b_inmem.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_latch.c b/test/micro/source/b_latch.c index b9dd27d9..bb4fb979 100644 --- a/test/micro/source/b_latch.c +++ b/test/micro/source/b_latch.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_load.c b/test/micro/source/b_load.c index 0f920a5b..c738660f 100644 --- a/test/micro/source/b_load.c +++ b/test/micro/source/b_load.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_open.c b/test/micro/source/b_open.c index c8af0718..cebd25da 100644 --- a/test/micro/source/b_open.c +++ b/test/micro/source/b_open.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_put.c b/test/micro/source/b_put.c index 596bba42..ad48f0e3 100644 --- a/test/micro/source/b_put.c +++ b/test/micro/source/b_put.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_recover.c b/test/micro/source/b_recover.c index ca061d98..cf6b1904 100644 --- a/test/micro/source/b_recover.c +++ b/test/micro/source/b_recover.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_txn.c b/test/micro/source/b_txn.c index 7a4c2914..0f04a343 100644 --- a/test/micro/source/b_txn.c +++ b/test/micro/source/b_txn.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_txn_write.c b/test/micro/source/b_txn_write.c index eac3851e..f1c42f53 100644 --- a/test/micro/source/b_txn_write.c +++ b/test/micro/source/b_txn_write.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_uname.c b/test/micro/source/b_uname.c index 9ed3aa3d..b178e223 100644 --- a/test/micro/source/b_uname.c +++ b/test/micro/source/b_uname.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_util.c b/test/micro/source/b_util.c index 6c952bde..5b3ed2d4 100644 --- a/test/micro/source/b_util.c +++ b/test/micro/source/b_util.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_workload.c b/test/micro/source/b_workload.c index dc407f78..54a9f111 100644 --- a/test/micro/source/b_workload.c +++ b/test/micro/source/b_workload.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/b_workload.h b/test/micro/source/b_workload.h index c1c5c8c0..4ffa7711 100644 --- a/test/micro/source/b_workload.h +++ b/test/micro/source/b_workload.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/bench.h b/test/micro/source/bench.h index 4faa860d..7e8c4f45 100644 --- a/test/micro/source/bench.h +++ b/test/micro/source/bench.h @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/micro/source/test_micro.c b/test/micro/source/test_micro.c index 272cf398..fc3e5e07 100644 --- a/test/micro/source/test_micro.c +++ b/test/micro/source/test_micro.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ diff --git a/test/tcl/README b/test/tcl/README index fbcddc09..c10c1d8a 100644 --- a/test/tcl/README +++ b/test/tcl/README @@ -28,7 +28,7 @@ Each test starts with a section like the following: # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2010 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/TESTS b/test/tcl/TESTS index 350ad620..606dc731 100644 --- a/test/tcl/TESTS +++ b/test/tcl/TESTS @@ -1,6 +1,13 @@ # Automatically built by dist/s_test; may require local editing. +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +Cold-boot a 4-site group. The first two sites start quickly and + initiate an election. The other two sites don't join the election until + the middle of the long full election timeout period. It's important that + the number of sites that start immediately be a sub-majority, because + that's the case that used to have a bug in it [#18456]. + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= backup Test of hotbackup functionality. @@ -14,11 +21,11 @@ backup (2) Test with -data_dir (-d). (3) Test updating an existing hot backup (-u). (4) Test with absolute path. - (5) Test with DB_CONFIG (-D), setting log_dir (-l) + (5) Test with DB_CONFIG, setting log_dir (-l) and data_dir (-d). (6) DB_CONFIG and update. - (7) Repeat hot backup (non-update) with DB_CONFIG and - existing directories. + (7) Repeat hot backup (non-update) with DB_CONFIG, + DB_CONFIG (-D) and existing directories. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= bigfile001 @@ -34,11 +41,8 @@ bigfile002 with 1K pages. Dirty page 6000000. Sync. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -Cold-boot a 4-site group. The first two sites start quickly and - initiate an election. The other two sites don't join the election until - the middle of the long full election timeout period. It's important that - the number of sites that start immediately be a sub-majority, because - that's the case that used to have a bug in it [#18456]. +db_reptest + Wrapper to configure and run the db_reptest program. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= dbm @@ -48,10 +52,6 @@ dbm Then reopen the file, re-retrieve everything. Finally, delete everything. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -db_reptest - Wrapper to configure and run the db_reptest program. - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= dead001 Use two different configurations to test deadlock detection among a @@ -1639,6 +1639,38 @@ rep098 After client gets UPDATE file information, delete entries to remove pages in the database. +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +rep099 + Test of multiple data dirs and databases, both active replication + and internal init. + + One master, two clients using several data_dirs. + Create databases in different data_dirs. Replicate to client. + Add 2nd client later to require it to catch up via internal init. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +rep100 + Checkpoints and unresolved txns + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +rep101 + Test of exclusive access to databases and HA. + Confirm basic functionality with master and client. + Confirm excl access after checkpoint and archive. + Confirm internal init with open excl databases. + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +rep102 + Test of exclusive access to databases and HA. + Master creates a database, writes some txns, and closes the db. + Client opens the database (in child process). + Master opens database exclusively. + Client tries to read database and gets HANDLE_DEAD. Closes db. + Client tries to reopen database and is blocked. + + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= repmgr001 Basic repmgr test. @@ -1826,6 +1858,24 @@ repmgr030 repmgr032 The (undocumented) AUTOROLLBACK config feature. +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +repmgr033 + Under quorum policy, if the number of peers in the group is less than a + majority, that's still OK. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +repmgr034 + Repmgr site removal and restart. + + Start two repmgr sites, master and client1. The client1 removes + itself and restarts, sometimes more than once. Start a third + repmgr site client2 and make sure it can remove client1 from + the group. + + This test must use heartbeats to ensure that a client that has + been removed and restarted without recovery can sync up. + + =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= repmgr100 Basic test of repmgr's multi-process master support. @@ -2108,7 +2158,8 @@ sdb019 sdb020 Tests in-memory subdatabases. Create an in-memory subdb with one page size. Close, and - open with a different page size: should fail. + open with a different page size: should succeed, but the underlying + page size is not changed. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= sdbtest001 @@ -3278,15 +3329,22 @@ test127 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= test128 - Test database bulk update for sub database and duplicate database. + Test database bulk update for non-duplicate databases, with different + configurations. - This is essentially test126 with sub database and secondary database. + This is essentially test126 with the following configurations: + * sub database. + * secondary database. + * bulk buffer pre-sort. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= test129 - Test database bulk update for duplicate sub database. + Test database bulk update for duplicate database, with different + configurations. - This is essentially test127 with sub database. + This is essentially test127 with the following configurations: + * sub database. + * bulk buffer pre-sort. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= test130 @@ -3330,8 +3388,90 @@ test133 Finally, move the 3rd cursor once. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -test134 - Test cursor cleanup for sub databases. +test134 + Test cursor cleanup for sub databases. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test135 + Test operations on similar overflow records. [#20329] + Open 3 kinds of databases: one is not dup, and one is dup-unsorted + while another one is dup-sorted. + Then we put some similar but not identical overflow records into + these databases. + Also, we try to remove some records from these databases. + We'll verify the records after put and after deletion. + Here is how we define the 'similar overflow' in this test: + * Both the key.size and data.size are not small than DB's pagesize: + The key.size is around 2*pagesize and data.size equals to pagesize. + * The keys are of same length, and they only differ in a small piece. + The location of difference could be in the start/middle/end. + * For dup databases, the dup datas have same rule as the key rule + mentioned above. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test136 + Test operations on similar overflow records. [#20329] + Here, we use subdatabases. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test137 + Test Automatic Resource Management. [#16188][#20281] + Open an environment, and open a database in it. + Do some operations in the database, including: + insert, dump, delete + Close the environment without closing the database. + Re-open the database and verify the records are the ones we expected. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test138 + Test Automatic Resource Management. [#16188][#20281] + Here, we test the following cases: + Non-encrypt for cds + Non-encrypt for tds + Encrypt for ds + Encrypt for cds + Encrypt for tds + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test139 + + Verify an open database. + Create and populate a database, leave open, and run + db->verify. + Delete half the data, verify, compact, verify again. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test140 + Test expansion and contraction of hash chains with + deletion, compaction, and recovery. + + On each cycle, populate a database to create reasonably + long hash chains, say 8 - 10 entries. Delete some + entries, check for consistency, compact, and check + for consistency again. We both commit and abort the + compact, and in the case of the abort, compare + the recovered database to the pre-compact database. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test141 + Test moving a large part of a hash table to a continguous + block of free pages. + + Create a database with a btree and a hash subdb. Remove + all the data from the first (btree) db and then compact + to cause the hash db to get moved. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +test142 + Tests exclusive database handles. + 1. Test that exclusive database handles return an error in incompatible + environments. + 2. Test that an exclusive subdatabase handle does not block opening a + handle on another database in the same file. + 3. Run script tests on a subdatabase with both wait and no wait + configuration. + 4. Run script tests on a database with both wait and no wait + configuration. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= txn001 diff --git a/test/tcl/archive.tcl b/test/tcl/archive.tcl index 48310101..53200889 100644 --- a/test/tcl/archive.tcl +++ b/test/tcl/archive.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/backup.tcl b/test/tcl/backup.tcl index b6f6ab61..741b8362 100644 --- a/test/tcl/backup.tcl +++ b/test/tcl/backup.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -16,11 +16,11 @@ # TEST (2) Test with -data_dir (-d). # TEST (3) Test updating an existing hot backup (-u). # TEST (4) Test with absolute path. -# TEST (5) Test with DB_CONFIG (-D), setting log_dir (-l) +# TEST (5) Test with DB_CONFIG, setting log_dir (-l) # TEST and data_dir (-d). # TEST (6) DB_CONFIG and update. -# TEST (7) Repeat hot backup (non-update) with DB_CONFIG and -# TEST existing directories. +# TEST (7) Repeat hot backup (non-update) with DB_CONFIG, +# TEST DB_CONFIG (-D) and existing directories. proc backup { {nentries 1000} } { source ./include.tcl @@ -98,6 +98,7 @@ proc backup { {nentries 1000} } { error_check_good db_close [$db close] 0 error_check_good env_close [$env close] 0 env_cleanup $testdir + env_cleanup $backupdir puts "\tBackuptest.b: Hot backup with data_dir." file mkdir $testdir/data1 @@ -261,6 +262,19 @@ proc backup { {nentries 1000} } { -${c}vh $testdir -b $backupdir -D } res] } { error "FAIL: $res" } + # Check that DB_CONFIG file is in backupdir. + error_check_good found_db_config\ + [file exists $backupdir/DB_CONFIG] 1 + # Check that db is in backupdir/data1 and not in backupdir. + error_check_good found_db\ + [file exists $backupdir/data1/$testfile] 1 + error_check_bad found_db\ + [file exists $backupdir/$testfile] 1 + # Check that logs are in backupdir/logs and not in backupdir. + set logfiles [glob $backupdir/logs/log*] + error_check_bad found_logs [llength $logfiles] 0 + set logfiles [glob $backupdir/log*] + error_check_good found_logs [llength $logfiles] 1 # We are not doing an update this time. puts "\tBackuptest.g:\ @@ -269,6 +283,15 @@ proc backup { {nentries 1000} } { -${c}vh $testdir -b $backupdir } res] } { error "FAIL: $res" } + # Check that no DB_CONFIG file is in backupdir. + error_check_bad found_db_config\ + [file exists $backupdir/DB_CONFIG] 1 + # Check that db is in backupdir. + error_check_good found_db\ + [file exists $backupdir/$testfile] 1 + # Check that logs are in backupdir. + set logfiles [glob $backupdir/log*] + error_check_good found_logs [expr [llength $logfiles] > 1] 1 error_check_good db_close [$db close] 0 error_check_good env_close [$env close] 0 diff --git a/test/tcl/bigfile001.tcl b/test/tcl/bigfile001.tcl index c65499db..0abfbb95 100644 --- a/test/tcl/bigfile001.tcl +++ b/test/tcl/bigfile001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/bigfile002.tcl b/test/tcl/bigfile002.tcl index 46293162..c101359a 100644 --- a/test/tcl/bigfile002.tcl +++ b/test/tcl/bigfile002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/byteorder.tcl b/test/tcl/byteorder.tcl index e9419540..4129e0cf 100644 --- a/test/tcl/byteorder.tcl +++ b/test/tcl/byteorder.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/conscript.tcl b/test/tcl/conscript.tcl index 85c81206..04dc1baa 100644 --- a/test/tcl/conscript.tcl +++ b/test/tcl/conscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/db_reptest.tcl b/test/tcl/db_reptest.tcl index 9bbcd7ca..185dd966 100644 --- a/test/tcl/db_reptest.tcl +++ b/test/tcl/db_reptest.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -98,17 +98,17 @@ proc db_reptest_prof { } { } proc generate_profiles {} { - global envdirs - global num_sites + global dirs + global use global util_path # # Once it is complete, generate profile information. # - for { set i 1 } { $i <= $num_sites } { incr i } { + for { set i 1 } { $i <= $use(nsites) } { incr i } { set gmon NULL set known_gmons \ - { $envdirs($i)/db_reptest.gmon $envdirs($i)/gmon.out } + { $dirs(env.$i)/db_reptest.gmon $dirs(env.$i)/gmon.out } foreach gfile $known_gmons { if { [file exists $gfile] } { set gmon $gfile @@ -185,13 +185,21 @@ proc db_reptest_loop { cmd stopstr count } { # proc db_reptest_int { cfgtype { restoredir NULL } } { source ./include.tcl - global envdirs - global num_sites + global dirs + global use env_cleanup $testdir - set savedir TESTDIR/SAVE_RUN - reptest_cleanup $savedir + set dirs(save) TESTDIR/SAVE_RUN + set dirs(restore) $restoredir + reptest_cleanup $dirs(save) + + # + # Set up the array to indicate if we are going to use + # a metadata dir or database data dir. If we are using + # datadirs, decide which one gets the created database. + # + get_datadirs $cfgtype use dirs # # Get all the default or random values needed for the test @@ -202,59 +210,79 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { # Get number of sites first because pretty much everything else # after here depends on how many sites there are. # - set num_sites [get_nsites $cfgtype $restoredir] - set use_lease [get_lease $cfgtype $restoredir] - set use_peers [get_peers $cfgtype] + set use(nsites) [get_nsites $cfgtype $dirs(restore)] + set use(lease) [get_lease $cfgtype $dirs(restore)] + set use(peers) [get_peers $cfgtype] + # + # Get port information in case it needs to be converted for this + # run. A conversion will happen for a restored run if the current + # baseport is different than the one used in restoredir. + # + set portlist [available_ports $use(nsites)] + set baseport(curr) [expr [lindex $portlist 0] - 1] + set baseport(orig) [get_orig_baseport $cfgtype $dirs(restore)] # # Only use kill if we have > 2 sites. # Returns a list. An empty list means this will not be a kill test. # Otherwise the list has 3 values, the kill type and 2 kill sites. # See the 'get_kill' proc for a description of kill types. # - set kill_type 0 + set use(kill) "" + set kill_type "NONE" set kill_site 0 - set kill_remove 0 + set kill_remover 0 set site_remove 0 - if { $num_sites > 2 } { - set kill [get_kill $cfgtype $restoredir $num_sites] - if { [llength $kill] > 0 } { - set kill_type [lindex $kill 0] - set kill_site [lindex $kill 1] - set kill_remove [lindex $kill 2] + if { $use(nsites) > 2 } { + set use(kill) [get_kill $cfgtype \ + $dirs(restore) $use(nsites) baseport] + if { [llength $use(kill)] > 0 } { + set kill_type [lindex $use(kill) 0] + set kill_site [lindex $use(kill) 1] + set kill_remover [lindex $use(kill) 2] } else { # If we are not doing a kill test, determine if # we are doing a remove test. - set site_remove [get_remove $cfgtype $num_sites] + set site_remove [get_remove $cfgtype $dirs(restore) \ + $use(nsites)] } } if { $cfgtype != "restore" } { - if { $use_lease } { - set use_master 0 + if { $use(lease) } { + set use(master) 0 } else { - set use_master [get_usemaster $cfgtype] - if { $site_remove == $use_master } { + set use(master) [get_usemaster $cfgtype] + if { $site_remove == $use(master) } { set site_remove 0 } } - set master_site [get_mastersite $cfgtype $use_master $num_sites] - set noelect [get_noelect $use_master] + set master_site [get_mastersite $cfgtype $use(master) $use(nsites)] + set noelect [get_noelect $use(master)] set master2_site [get_secondary_master \ - $noelect $master_site $kill_site $num_sites] - set workers [get_workers $cfgtype $use_lease] + $noelect $master_site $kill_site $use(nsites)] + set workers [get_workers $cfgtype $use(lease)] set dbtype [get_dbtype $cfgtype] set runtime [get_runtime $cfgtype] - puts -nonewline "Running: $num_sites sites, $runtime seconds " - if { $kill_site } { - puts -nonewline "kill site $kill_site " - if { $kill_remove } { - puts -nonewline "removed by site $kill_remove " - } - } elseif { $site_remove } { - puts -nonewline "remove site $site_remove " + puts "Running: $use(nsites) sites, $runtime seconds." + puts -nonewline "Running: " + if { $use(createdir) } { + puts -nonewline \ + "$use(datadir) datadirs, createdir DATA.$use(createdir), " } - if { $use_lease } { - puts "with leases" - } elseif { $use_master } { + if { $use(metadir) } { + puts -nonewline "METADIR, " + } + if { $kill_type == "DIE" || $kill_type == "REMOVE" } { + puts -nonewline "kill site $kill_site, " + } + if { $kill_type == "LIVE_REM" } { + puts -nonewline \ + "live removal of site $kill_site by $kill_remover, " + } elseif { $site_remove } { + puts -nonewline "remove site $site_remove, " + } + if { $use(lease) } { + puts "with leases." + } elseif { $use(master) } { set master_text "master site $master_site" if { $noelect } { set master_text [concat $master_text \ @@ -264,41 +292,56 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { set master_text [concat $master_text \ "secondary master site $master2_site"] } - puts "$master_text" + puts "$master_text." } else { - puts "no master" + puts "no master." } } # # This loop sets up the args to the invocation of db_reptest # for each site. # - set portlist [available_ports $num_sites] - for { set i 1 } {$i <= $num_sites } { incr i } { - set envdirs($i) TESTDIR/ENV$i - set homedirs($i) ../ENV$i - reptest_cleanup $envdirs($i) + for { set i 1 } {$i <= $use(nsites) } { incr i } { + set dirs(env.$i) TESTDIR/ENV$i + set dirs(home.$i) ../ENV$i + reptest_cleanup $dirs(env.$i) # # If we are restoring the args, just read them from the # saved location for this sites. Otherwise build up # the args for each piece we need. # if { $cfgtype == "restore" } { - set cid [open $restoredir/DB_REPTEST_ARGS.$i r] + set cid [open $dirs(restore)/DB_REPTEST_ARGS.$i r] set prog_args($i) [read $cid] close $cid + # + # Convert -K port number arguments to current + # baseport if needed. regsub -all substitutes + # all occurrences of pattern, which is "-K " + # and a number. The result of regsub contains a tcl + # expression with the number (\2, the second part of + # the pattern), operators and variable names, e.g.: + # -K [expr 30104 - $baseport(orig) + $baseport(curr)] + # and then subst evalutes the tcl expression. + # + if { $baseport(curr) != $baseport(orig) } { + regsub -all {(-K )([0-9]+)} $prog_args($i) \ + {-K [expr \2 - $baseport(orig) + \ + $baseport(curr)]} prog_args($i) + set prog_args($i) [subst $prog_args($i)] + } if { $runtime == 0 } { set runtime [parse_runtime $prog_args($i)] puts "Runtime: $runtime" } } else { - set nmsg [berkdb random_int 1 [expr $num_sites * 2]] + set nmsg [berkdb random_int 1 [expr $use(nsites) * 2]] set prog_args($i) \ "-v -c $workers -t $dbtype -T $runtime -m $nmsg " set prog_args($i) \ - [concat $prog_args($i) "-h $homedirs($i)"] + [concat $prog_args($i) "-h $dirs(home.$i)"] set prog_args($i) \ - [concat $prog_args($i) "-o $num_sites"] + [concat $prog_args($i) "-o $use(nsites)"] # # Add in if this site should remove itself. # @@ -308,13 +351,14 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { # # Add in if this site should kill itself. # - if { $kill_site == $i } { + if { ($kill_type == "DIE" || $kill_type == "REMOVE") && \ + $kill_site == $i} { set prog_args($i) [concat $prog_args($i) "-k"] } # # Add in if this site should remove a killed site. # - if { $kill_remove == $i } { + if { $kill_remover == $i } { set kport [lindex $portlist \ [expr $kill_site - 1]] set prog_args($i) [concat $prog_args($i) \ @@ -333,7 +377,7 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { # start as a client. Otherwise start with # elections. # - if { $use_master } { + if { $use(master) } { set prog_args($i) \ [concat $prog_args($i) "-C"] } else { @@ -353,19 +397,18 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { } } } - save_db_reptest $savedir ARGS $i $prog_args($i) + save_db_reptest $dirs(save) ARGS $i $prog_args($i) } # Now make the DB_CONFIG file for each site. - reptest_make_config $savedir $num_sites envdirs state \ - $use_lease $use_peers $kill_site $portlist $cfgtype $restoredir + reptest_make_config $cfgtype dirs state use $portlist baseport # Run the test - run_db_reptest $savedir envdirs $num_sites $runtime $use_lease + run_db_reptest dirs $use(nsites) $runtime $use(lease) puts "Test run complete. Verify." # Verify the test run. - verify_db_reptest $num_sites envdirs $kill_site + verify_db_reptest $use(nsites) dirs use $kill_site $site_remove # Show the summary files print_summary @@ -375,10 +418,11 @@ proc db_reptest_int { cfgtype { restoredir NULL } } { # # Make a DB_CONFIG file for all sites in the group # -proc reptest_make_config { savedir nsites edirs st lease peers kill \ - portlist cfgtype restoredir } { - upvar $edirs envdirs - upvar $st state +proc reptest_make_config { cfgtype dirsarr starr usearr portlist baseptarr } { + upvar $dirsarr dirs + upvar $starr state + upvar $baseptarr baseport + upvar $usearr use global rporttype # @@ -408,12 +452,12 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # 2site strict and ack policy must be the same on all sites. # if { $cfgtype == "random" } { - if { $nsites == 2 } { + if { $use(nsites) == 2 } { set strict [berkdb random_int 0 1] } else { set strict 0 } - if { $lease } { + if { $use(lease) } { # # 2site strict with leases must have ack policy of # one because quorum acks are ignored in this case, @@ -436,7 +480,7 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # it is a rarely used option. # if { $ackpolicy == "db_repmgr_acks_none" && \ - $nsites > 2 } { + $use(nsites) > 2 } { continue } # @@ -446,7 +490,7 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # to ignore acks and blast the clients with # log records. # - if { $kill && \ + if { [llength $use(kill)] > 0 && \ ($ackpolicy == "db_repmgr_acks_all" || \ $ackpolicy == "db_repmgr_acks_all_peers") } { @@ -464,24 +508,44 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # set known_master 0 if { $cfgtype != "restore" } { - for { set i 1 } { $i <= $nsites } { incr i } { + for { set i 1 } { $i <= $use(nsites) } { incr i } { if { $state($i) == "MASTER" } { set known_master $i } } if { $known_master == 0 } { - set known_master [berkdb random_int 1 $nsites] + set known_master [berkdb random_int 1 $use(nsites)] } } - for { set i 1 } { $i <= $nsites } { incr i } { + for { set i 1 } { $i <= $use(nsites) } { incr i } { # # If we're restoring we just need to copy it. # if { $cfgtype == "restore" } { - file copy $restoredir/DB_CONFIG.$i \ - $envdirs($i)/DB_CONFIG - file copy $restoredir/DB_CONFIG.$i \ - $savedir/DB_CONFIG.$i + # + # Convert DB_CONFIG port numbers to current baseport + # if needed. + # + set restore_cfile $dirs(restore)/DB_CONFIG.$i + set new_cfile $dirs(env.$i)/DB_CONFIG + set new_save_cfile $dirs(save)/DB_CONFIG.$i + if { $baseport(curr) != $baseport(orig) } { + convert_config_ports $restore_cfile \ + $new_cfile baseport + file copy $new_cfile $new_save_cfile + } else { + file copy $restore_cfile $new_cfile + file copy $restore_cfile $new_save_cfile + } + if { $use(metadir) } { + file mkdir $dirs(env.$i)/METADIR + } + if { $use(datadir) } { + for { set diri 1 } { $diri <= $use(datadir) } \ + { incr diri } { + file mkdir $dirs(env.$i)/DATA.$diri + } + } continue } # @@ -493,8 +557,8 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # Add lease configuration if needed. We're running all # locally, so there is no clock skew. # - set allist [get_ack_lease_timeouts $lease] - if { $lease } { + set allist [get_ack_lease_timeouts $use(lease)] + if { $use(lease) } { # # We need to have an ack timeout > lease timeout. # Otherwise txns can get committed without waiting @@ -510,6 +574,30 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ "db_rep_ack_timeout [lindex $allist 0]" } } + # + # Add datadirs and the metadir, if needed. If we are using + # datadirs, then set which one is the create dir. + # + if { $use(metadir) } { + file mkdir $dirs(env.$i)/METADIR + lappend cfglist { "set_metadata_dir" "METADIR" } + } + if { $use(datadir) } { + for { set diri 1 } { $diri <= $use(datadir) } \ + { incr diri } { + file mkdir $dirs(env.$i)/DATA.$diri + # + # Need to add to list in 2 steps otherwise + # $diri in the list will not get evaluated + # until later. + # + set litem [list add_data_dir DATA.$diri] + lappend cfglist $litem + } + lappend cfglist { "set_create_dir" \ + "DATA.$use(createdir)" } + } + # # Priority # @@ -554,27 +642,37 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # known_master (either master or group creator) set the # group creator flag on. # + # Must use explicit 127.0.0.1 rather than localhost because + # localhost can be configured differently on different + # machines or platforms. Use of localhost can cause + # available_ports to return ports that are actually in use. + # set lport($i) [lindex $portlist [expr $i - 1]] if { $i == $known_master } { + # + # Any change to this generated syntax will probably + # require a change to get_orig_baseport, which relies + # on this ordering and these embedded spaces. + # set litem [list repmgr_site \ - "localhost $lport($i) db_local_site on \ + "127.0.0.1 $lport($i) db_local_site on \ db_group_creator on"] } else { set litem [list repmgr_site \ - "localhost $lport($i) db_local_site on"] + "127.0.0.1 $lport($i) db_local_site on"] } lappend cfglist $litem - set rport($i) [get_rport $portlist $i $nsites \ + set rport($i) [get_rport $portlist $i $use(nsites) \ $known_master $cfgtype] # # Declare all sites bootstrap helpers. # foreach p $rport($i) { - if { $peers } { - set litem [list repmgr_site "localhost $p \ + if { $use(peers) } { + set litem [list repmgr_site "127.0.0.1 $p \ db_bootstrap_helper on db_repmgr_peer on"] } else { - set litem [list repmgr_site "localhost $p \ + set litem [list repmgr_site "127.0.0.1 $p \ db_bootstrap_helper on"] } # @@ -588,18 +686,18 @@ proc reptest_make_config { savedir nsites edirs st lease peers kill \ # # Now write out the DB_CONFIG file. # - set cid [open $envdirs($i)/DB_CONFIG a] + set cid [open $dirs(env.$i)/DB_CONFIG a] foreach c $cfglist { set carg [subst [lindex $c 0]] set cval [subst [lindex $c 1]] puts $cid "$carg $cval" } close $cid - set cid [open $envdirs($i)/DB_CONFIG r] + set cid [open $dirs(env.$i)/DB_CONFIG r] set cfg [read $cid] close $cid - save_db_reptest $savedir CONFIG $i $cfg + save_db_reptest $dirs(save) CONFIG $i $cfg } } @@ -629,9 +727,9 @@ proc save_db_reptest { savedir op site savelist } { close $cid } -proc run_db_reptest { savedir edirs numsites runtime use_lease } { +proc run_db_reptest { dirsarr numsites runtime use_lease } { source ./include.tcl - upvar $edirs envdirs + upvar $dirsarr dirs global killed_procs set pids {} @@ -645,8 +743,8 @@ proc run_db_reptest { savedir edirs numsites runtime use_lease } { [expr $ack_timeout / 1000000] * $numsites] for {set i 1} {$i <= $numsites} {incr i} { lappend pids [exec $tclsh_path $test_path/wrap_reptest.tcl \ - $savedir/DB_REPTEST_ARGS.$i $envdirs($i) \ - $savedir/site$i.log &] + $dirs(save)/DB_REPTEST_ARGS.$i $dirs(env.$i) \ + $dirs(save)/site$i.log &] tclsleep 1 } watch_procs $pids 15 $watch_time @@ -656,22 +754,27 @@ proc run_db_reptest { savedir edirs numsites runtime use_lease } { } } -proc verify_db_reptest { num_sites edirs kill } { - upvar $edirs envdirs +proc verify_db_reptest { num_sites dirsarr usearr kill site_rem } { + upvar $dirsarr dirs + upvar $usearr use set startenv 1 set cmpeid 2 - if { $kill == 1 } { + if { $kill == 1 || $site_rem == 1 } { set startenv 2 set cmpeid 3 } - set envbase [berkdb_env_noerr -home $envdirs($startenv)] + set envbase [berkdb_env_noerr -home $dirs(env.$startenv)] + set datadir "" + if { $use(createdir) } { + set datadir DATA.$use(createdir) + } for { set i $cmpeid } { $i <= $num_sites } { incr i } { - if { $i == $kill } { + if { $i == $kill || $i == $site_rem } { continue } - set cmpenv [berkdb_env_noerr -home $envdirs($i)] - puts "Compare $envdirs($startenv) with $envdirs($i)" + set cmpenv [berkdb_env_noerr -home $dirs(env.$i)] + puts "Compare $dirs(env.$startenv) with $dirs(env.$i)" # # Compare 2 envs. We assume the name of the database that # db_reptest creates and know it is 'am1.db'. @@ -679,8 +782,8 @@ proc verify_db_reptest { num_sites edirs kill } { # 0 - compare_shared_portion # 1 - match databases # 0 - don't compare logs (for now) - rep_verify $envdirs($startenv) $envbase $envdirs($i) $cmpenv \ - 0 1 0 am1.db + rep_verify $dirs(env.$startenv) $envbase $dirs(env.$i) $cmpenv \ + 0 1 0 am1.db $datadir $cmpenv close } $envbase close @@ -746,7 +849,7 @@ proc get_lease { cfgtype restoredir } { # we only know we have at least 1 site. # if { $cfgtype == "restore" } { - set use_lease 0 + set uselease 0 set cid [open $restoredir/DB_CONFIG.1 r] while { [gets $cid cfglist] } { # puts "Read in: $cfglist" @@ -757,13 +860,13 @@ proc get_lease { cfgtype restoredir } { if { $cfg == "rep_set_config" } { set lease [lindex $cfglist 1] if { $lease == "db_rep_conf_lease" } { - set use_lease 1 + set uselease 1 break; } } } close $cid - return $use_lease + return $uselease } if { $cfgtype == "random" } { set leases { 1 0 0 0 } @@ -786,20 +889,29 @@ proc get_lease { cfgtype restoredir } { # a site to do the removal. # # We return a list with the kill type and the sites. Return -# an empty list if we don't kill any site. There are 2 variants: +# an empty list if we don't kill any site. There are a few variants: # # 1: Die - A site just kills itself but remains part of the group. -# Return a list {1 deadsite# 0}. +# Return a list {DIE deadsite# 0}. # 2: Removal - A site kills itself, and some site will also remove -# the dead site from the group. (Could be the same site that is dying). -# {2 deadsite# removalsite#}. +# the dead site from the group. (Could be the same site that is dying, +# in which case the removal is done right before it exits.) +# {REMOVE deadsite# removalsite#}. +# 3. Live removal - Some site removes another live site from the group. +# (Could be itself.) +# {LIVE_REM killsite# removalsite#}. # -proc get_kill { cfgtype restoredir num_sites } { +proc get_kill { cfgtype restoredir num_sites basept } { + upvar $basept baseport + set nokill "" if { $cfgtype == "restore" } { set ksite 0 - set ktype 0 + set localkill 0 + set rkill 0 set rsite 0 + set kport 0 + set ktype NONE for { set i 1 } { $i <= $num_sites } { incr i } { set cid [open $restoredir/DB_REPTEST_ARGS.$i r] # !!! @@ -811,14 +923,15 @@ proc get_kill { cfgtype restoredir num_sites } { set dokill [lsearch $arglist "-k"] set dorem [lsearch $arglist "-K"] # - # Only 1 of those 3 should ever be set. If we - # find -K, we have all the information we need - # and can break the loop. If we find a -k we might - # find a later -K so we keep looking. + # Only 1 of those args should ever be set for a given + # input line. We need to look at all sites in order + # to determine the kill type. If we find both -k and + # -K, the site will be the same, so overwriting it + # no matter what order the sites, is okay. # - if { $dokill != -1 } { + if { $dokill >= 0 } { set ksite $i - set ktype 1 + set localkill 1 } # # If it is a remote removal kill type, we are @@ -828,42 +941,72 @@ proc get_kill { cfgtype restoredir num_sites } { # The site in the arg is the port number so grab # the site number out of it. # - if { $dorem != -1 } { - set ktype 2 + if { $dorem >= 0 } { + set rkill 1 set kport [lindex $arglist [expr $dorem + 1]] - set ksite [site_from_port $kport $num_sites] + set ksite [expr $kport - $baseport(orig)] + # Convert kport to current baseport if needed. + if { $baseport(curr) != $baseport(orig) } { + set kport [expr $kport - \ + $baseport(orig) + $baseport(curr)] + } set rsite $i - break } } - if { $ktype == 0 } { + # + # If we have a remote kill, then we decide the kill type + # based on whether the killed site will be dead or alive. + # If we found no site to kill/remove, we know it is not + # a kill test. + # + if { $ksite == 0 } { return $nokill } else { + # + # See proc comment for a definition of each kill type. + # + if { $localkill == 1 && $rkill == 0 } { + set ktype DIE + } + if { $localkill == 1 && $rkill == 1 } { + set ktype REMOVE + } + if { $localkill == 0 && $rkill == 2 } { + set ktype LIVE_REM + } return [list $ktype $ksite $rsite] } } if { $cfgtype == "random" } { - # Do a kill test half the time. + # Do a kill and/or removal test half the time. set k { 0 0 0 1 1 1 0 1 1 0 } set len [expr [llength $k] - 1] set i [berkdb random_int 0 $len] - if { [lindex $k $i] == 1 } { - set ktype 1 - set ksite [berkdb random_int 1 $num_sites] - set rsite 0 - # Do a removal half the time we do a kill. - set k { 0 0 0 1 1 1 0 1 1 0 } - set len [expr [llength $k] - 1] - set i [berkdb random_int 0 $len] - if { [lindex $k $i] == 1 } { - set ktype 2 - set rsite [berkdb random_int 1 $num_sites] - } - set klist [list $ktype $ksite $rsite] - } else { - set klist $nokill + set dokill [lindex $k $i] + set i [berkdb random_int 0 $len] + set dorem [lindex $k $i] + # + # Set up for the possibilities listed above. + # + if { $dokill == 0 && $dorem == 0 } { + return $nokill } - return $klist + # + # Choose which sites to kill and do removal. + # + set ksite [berkdb random_int 1 $num_sites] + set rsite [berkdb random_int 1 $num_sites] + if { $dokill == 1 && $dorem == 0 } { + set ktype DIE + set rsite 0 + } + if { $dokill == 1 && $dorem == 1 } { + set ktype REMOVE + } + if { $dokill == 0 && $dorem == 1 } { + set ktype LIVE_REM + } + return [list $ktype $ksite $rsite] } if { $cfgtype == "basic0" || $cfgtype == "basic1" } { return $nokill @@ -878,13 +1021,8 @@ proc get_kill { cfgtype restoredir num_sites } { # it will return 0 if no removal test. Sites are numbered # starting at 1. # -proc get_remove { cfgtype nsites } { -# -# For now, until the "restart a dead carcass" work is done -# post-5.2, we don't use this option. 5.2 requires a site -# to shutdown if it gets removed while it is alive. -# -return 0 +proc get_remove { cfgtype restoredir nsites } { + set rsite 0 if { $cfgtype == "random" } { # Do a remove test half the time we're called. set k { 0 0 0 1 1 1 0 1 1 0 } @@ -892,13 +1030,33 @@ return 0 set i [berkdb random_int 0 $len] if { [lindex $k $i] == 1 } { set rsite [berkdb random_int 1 $nsites] - } else { - set rsite 0 } - return $rsite - } else { - return 0 + } elseif { $cfgtype == "restore" } { + # + # If we're restoring we still need to know if a site is + # running its own removal test so we know to skip it for verify. + # + for { set i 1 } { $i <= $nsites } { incr i } { + set cid [open $restoredir/DB_REPTEST_ARGS.$i r] + # !!! + # We currently assume the args file is 1 line. + # This code also assumes only 1 site ever does removal. + # + gets $cid arglist + close $cid +# puts "Read in: $arglist" + set dorem [lsearch $arglist "-r"] + if { $dorem >= 0 } { + set rsite $i + # + # If we find one, we know no other site will + # be doing removal. So stop now. + # + break + } + } } + return $rsite } # @@ -1117,6 +1275,103 @@ proc get_ack_lease_timeouts { useleases } { } } +# +# Use datadir half the time. Then pick how many and which datadir +# the database should reside in. Use a metadata dir 25% of the time. +# +proc get_datadirs { cfgtype usearr dirarr } { + upvar $usearr use + upvar $dirarr dir + + set use(datadir) 0 + set use(createdir) 0 + set use(metadir) 0 + if { $cfgtype == "random" } { + set meta { 0 0 0 1 } + # + # Randomly pick if we use datadirs, and if so, how many, up to 4. + # Although we may create several datadirs, we only choose one + # of them in which to create the database. + # + set data { 0 0 0 0 1 2 3 4 } + set mlen [expr [llength $meta] - 1] + set dlen [expr [llength $data] - 1] + set im [berkdb random_int 0 $mlen] + set id [berkdb random_int 0 $dlen] + set use(datadir) [lindex $data $id] + set use(metadir) [lindex $meta $im] + # + # If we're using datadirs, then randomly pick the creation dir. + # + if { $use(datadir) != 0 } { + set use(createdir) [berkdb random_int 1 $use(datadir)] + } + } elseif { $cfgtype == "restore" } { + set cid [open $dir(restore)/DB_CONFIG.1 r] + set cfg [read $cid] + # Look for metadata_dir, add_data_dir and set_create_dir. + set use(metadir) [regexp -all {(set_metadata_dir)} $cfg] + set use(datadir) [regexp -all {(add_data_dir)} $cfg] + if { $use(datadir) } { + set c [regexp {(set_create_dir )(DATA.[0-9])} $cfg m cr] + # + # We need to extract the directory number from the + # createdir directory name. I.e., DATA.2 needs '2'. + # + regexp {(DATA.)([0-9])} $m match d use(createdir) + } + close $cid + } + return 0 +} + +# +# Get the original baseport for a configuration to be restored by using +# the local site port number for its first site because every configuration +# will have a first site. +# +proc get_orig_baseport { cfgtype { restoredir NULL } } { + if { $cfgtype != "restore" } { + return 0 + } else { + set cid [open $restoredir/DB_CONFIG.1 r] + set cfg [read $cid] + # Look for a number between "127.0.0.1" and "db_local_site on". + # The spaces after 127.0.0.1 and before db_local_site are + # significant in the pattern match. + regexp {(127.0.0.1 )([0-9]+)( db_local_site on)} $cfg \ + match p1 pnum + close $cid + return [expr $pnum - 1] + } +} + +# +# Convert DB_CONFIG file port numbers following "127.0.0.1 " to use a +# different baseport. regsub -all substitutes all occurrences of pattern, +# which is "127.0.0.1 " and a number. The result of regsub contains a tcl +# expression with the number (\2, the second part of the pattern), operators +# and variable names, e.g.: +# -K [expr 30104 - $baseport(orig) + $baseport(curr)] +# and then subst evalutes the tcl expression. +# +# Writes a converted copy of orig_file to new_file. +# +proc convert_config_ports { orig_file new_file basept } { + upvar $basept baseport + + set cid [open $orig_file r] + set cfg [read $cid] + regsub -all {(127.0.0.1 )([0-9]+)} $cfg \ + {127.0.0.1 [expr \2 - $baseport(orig) + $baseport(curr)]} cfg + set cfg [subst $cfg] + close $cid + set cid [open $new_file a] + puts -nonewline $cid $cfg + close $cid + return 0 +} + proc parse_runtime { progargs } { set i [lsearch $progargs "-T"] set val [lindex $progargs [expr $i + 1]] @@ -1125,7 +1380,6 @@ proc parse_runtime { progargs } { proc print_summary { } { source ./include.tcl - global envdirs set ret [catch {glob $testdir/summary.*} result] if { $ret == 0 } { diff --git a/test/tcl/dbm.tcl b/test/tcl/dbm.tcl index 83558abb..b1176aa1 100644 --- a/test/tcl/dbm.tcl +++ b/test/tcl/dbm.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dbscript.tcl b/test/tcl/dbscript.tcl index 0a9bf9a2..59cecf6e 100644 --- a/test/tcl/dbscript.tcl +++ b/test/tcl/dbscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/ddoyscript.tcl b/test/tcl/ddoyscript.tcl index 983806c3..51c43ef6 100644 --- a/test/tcl/ddoyscript.tcl +++ b/test/tcl/ddoyscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/ddscript.tcl b/test/tcl/ddscript.tcl index 07879d70..a12d0796 100644 --- a/test/tcl/ddscript.tcl +++ b/test/tcl/ddscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead001.tcl b/test/tcl/dead001.tcl index cfeb52ff..15710893 100644 --- a/test/tcl/dead001.tcl +++ b/test/tcl/dead001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead002.tcl b/test/tcl/dead002.tcl index 3d83374a..bdfd4e29 100644 --- a/test/tcl/dead002.tcl +++ b/test/tcl/dead002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead003.tcl b/test/tcl/dead003.tcl index f3a7635c..a4035606 100644 --- a/test/tcl/dead003.tcl +++ b/test/tcl/dead003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead004.tcl b/test/tcl/dead004.tcl index b4d83d09..6eba4f03 100644 --- a/test/tcl/dead004.tcl +++ b/test/tcl/dead004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead005.tcl b/test/tcl/dead005.tcl index 73a13f27..3fc080f9 100644 --- a/test/tcl/dead005.tcl +++ b/test/tcl/dead005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead006.tcl b/test/tcl/dead006.tcl index 89151ea5..5d677661 100644 --- a/test/tcl/dead006.tcl +++ b/test/tcl/dead006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead007.tcl b/test/tcl/dead007.tcl index 7d836443..54695dd1 100644 --- a/test/tcl/dead007.tcl +++ b/test/tcl/dead007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead008.tcl b/test/tcl/dead008.tcl index 8a25375d..2b800a83 100644 --- a/test/tcl/dead008.tcl +++ b/test/tcl/dead008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead009.tcl b/test/tcl/dead009.tcl index 1e71f8ff..717d3a2b 100644 --- a/test/tcl/dead009.tcl +++ b/test/tcl/dead009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead010.tcl b/test/tcl/dead010.tcl index 198384f8..9f6a1a7f 100644 --- a/test/tcl/dead010.tcl +++ b/test/tcl/dead010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/dead011.tcl b/test/tcl/dead011.tcl index 0f8dc3c7..dacf592a 100644 --- a/test/tcl/dead011.tcl +++ b/test/tcl/dead011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env001.tcl b/test/tcl/env001.tcl index 2cc581af..6eeb55be 100644 --- a/test/tcl/env001.tcl +++ b/test/tcl/env001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env002.tcl b/test/tcl/env002.tcl index 829de457..ba7330b0 100644 --- a/test/tcl/env002.tcl +++ b/test/tcl/env002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env003.tcl b/test/tcl/env003.tcl index 66893404..eaa09e0e 100644 --- a/test/tcl/env003.tcl +++ b/test/tcl/env003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env004.tcl b/test/tcl/env004.tcl index ed29aabc..890e2145 100644 --- a/test/tcl/env004.tcl +++ b/test/tcl/env004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env005.tcl b/test/tcl/env005.tcl index 04a51aa3..d65bfe60 100644 --- a/test/tcl/env005.tcl +++ b/test/tcl/env005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env006.tcl b/test/tcl/env006.tcl index 103c6716..fad13516 100644 --- a/test/tcl/env006.tcl +++ b/test/tcl/env006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env007.tcl b/test/tcl/env007.tcl index 11c26953..c19709f5 100644 --- a/test/tcl/env007.tcl +++ b/test/tcl/env007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -212,6 +212,7 @@ proc env007 { } { set cfglist { { "set_data_dir" "." "get_data_dirs" "." } { "add_data_dir" "." "get_data_dirs" "." } + { "set_metadata_dir" "." "get_metadata_dir" "."} { "set_create_dir" "." "get_create_dir" "."} { "set_flags" "db_auto_commit" "get_flags" "-auto_commit" } { "set_flags" "db_cdb_alldb" "get_flags" "-cdb_alldb" } @@ -620,9 +621,6 @@ proc env007 { } { puts "\tEnv007.f: Test that bad config values are rejected." set cfglist { { "set_cache_max" "1" } - { "set_data_dir" "dir1 dir2" } - { "add_data_dir" "dir1 dir2" } - { "set_create_dir" "dir1 dir2" } { "set_intermediate_dir_mode" "0644 0666" } { "set_cachesize" "1048576" } { "set_flags" "db_xxx" } @@ -634,7 +632,6 @@ proc env007 { } { { "log_set_config" "db_log_auto_remove x x1" } { "set_lg_bsize" "db_xxx" } { "set_lg_max" "db_xxx" } - { "set_lg_dir" "dir1 dir2" } { "set_lg_regionmax" "db_xxx" } { "set_lock_timeout" "lock 500"} { "set_lk_detect" "db_xxx" } @@ -657,7 +654,6 @@ proc env007 { } { { "set_shm_key" ""} { "set_shm_key" "11 12 13"} { "set_tas_spins" "db_xxx" } - { "set_tmp_dir" "dir1 dir2" } { "set_tx_max" "db_xxx" } { "set_txn_timeout" "txn 5000" } { "set_verbose" "db_xxx" } @@ -728,6 +724,7 @@ proc env007 { } { { "-len" "20" "-recno" "get_re_len" } { "-pad" "0" "-recno" "get_re_pad" } { "-source" "include.tcl" "-recno" "get_re_source" } + { "-heap_regionsize" "1000" "-heap" "get_heap_regionsize" } } set o "berkdb_open_noerr -create -mode 0644" diff --git a/test/tcl/env007script.tcl b/test/tcl/env007script.tcl index 9f4aa4c4..1466dcc0 100644 --- a/test/tcl/env007script.tcl +++ b/test/tcl/env007script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # env007script - for use with env007. # Usage: configarg configval getter getval diff --git a/test/tcl/env008.tcl b/test/tcl/env008.tcl index c84e7dc5..5829f0c3 100644 --- a/test/tcl/env008.tcl +++ b/test/tcl/env008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env009.tcl b/test/tcl/env009.tcl index 6fd4e6c4..f166ea9a 100644 --- a/test/tcl/env009.tcl +++ b/test/tcl/env009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env010.tcl b/test/tcl/env010.tcl index a779ff96..869f17bf 100644 --- a/test/tcl/env010.tcl +++ b/test/tcl/env010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env011.tcl b/test/tcl/env011.tcl index fc8266c8..44fbc817 100644 --- a/test/tcl/env011.tcl +++ b/test/tcl/env011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env012.tcl b/test/tcl/env012.tcl index 9ef24257..0099ea81 100644 --- a/test/tcl/env012.tcl +++ b/test/tcl/env012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env013.tcl b/test/tcl/env013.tcl index 985b5731..1d9cd710 100644 --- a/test/tcl/env013.tcl +++ b/test/tcl/env013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env014.tcl b/test/tcl/env014.tcl index 7ef06658..f09917c7 100644 --- a/test/tcl/env014.tcl +++ b/test/tcl/env014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env015.tcl b/test/tcl/env015.tcl index 237184fd..34cdc2f8 100644 --- a/test/tcl/env015.tcl +++ b/test/tcl/env015.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env016.tcl b/test/tcl/env016.tcl index efed1b75..1f49b865 100644 --- a/test/tcl/env016.tcl +++ b/test/tcl/env016.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env017.tcl b/test/tcl/env017.tcl index 9f54c169..c7a8b101 100644 --- a/test/tcl/env017.tcl +++ b/test/tcl/env017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -281,7 +281,7 @@ proc env017_rep_stat { } { { "Elections won" st_elections_won } { "Election phase" st_election_status } { "Election winner" st_election_cur_winner } - { "Election generation number" st_election_gen } + { "Election winner generation number" st_election_gen } { "Election data generation number" st_election_datagen } { "Election max LSN" st_election_lsn } { "Election sites" st_election_nsites } diff --git a/test/tcl/env018.tcl b/test/tcl/env018.tcl index 5f8db49d..78c2a182 100644 --- a/test/tcl/env018.tcl +++ b/test/tcl/env018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env019.tcl b/test/tcl/env019.tcl index 590ee5cd..f2a709c4 100644 --- a/test/tcl/env019.tcl +++ b/test/tcl/env019.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env019script.tcl b/test/tcl/env019script.tcl index c2cb7f4e..4c7c46b7 100644 --- a/test/tcl/env019script.tcl +++ b/test/tcl/env019script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/env020.tcl b/test/tcl/env020.tcl index 0950ff71..58ae1773 100644 --- a/test/tcl/env020.tcl +++ b/test/tcl/env020.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -408,6 +408,8 @@ proc env020_init { } { "Mutex" "Revision count" "Reference count" + "Sync open count" + "Sync/read only open count" "Block count" "Last page number" "Original last page number" @@ -732,6 +734,7 @@ proc env020_init { } { "ThreadId" "ThreadIdString" "Log dir" + "Metadata dir" "Tmp dir" "Data dir" "Intermediate directory mode" diff --git a/test/tcl/env021.tcl b/test/tcl/env021.tcl index c8e9ebb5..ab28de32 100644 --- a/test/tcl/env021.tcl +++ b/test/tcl/env021.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/envscript.tcl b/test/tcl/envscript.tcl index 069ce6ab..386f3a60 100644 --- a/test/tcl/envscript.tcl +++ b/test/tcl/envscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop001.tcl b/test/tcl/fop001.tcl index 19121db7..6819e8f8 100644 --- a/test/tcl/fop001.tcl +++ b/test/tcl/fop001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop002.tcl b/test/tcl/fop002.tcl index 32bd6f45..a25749f5 100644 --- a/test/tcl/fop002.tcl +++ b/test/tcl/fop002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop003.tcl b/test/tcl/fop003.tcl index b11e257f..c8b895a9 100644 --- a/test/tcl/fop003.tcl +++ b/test/tcl/fop003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop004.tcl b/test/tcl/fop004.tcl index 3b7a8104..5afecced 100644 --- a/test/tcl/fop004.tcl +++ b/test/tcl/fop004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop005.tcl b/test/tcl/fop005.tcl index fe89e3d8..0323571f 100644 --- a/test/tcl/fop005.tcl +++ b/test/tcl/fop005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop006.tcl b/test/tcl/fop006.tcl index 5fb93901..8a373826 100644 --- a/test/tcl/fop006.tcl +++ b/test/tcl/fop006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop007.tcl b/test/tcl/fop007.tcl index 611fcfdb..c262a534 100644 --- a/test/tcl/fop007.tcl +++ b/test/tcl/fop007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop008.tcl b/test/tcl/fop008.tcl index cee20a63..b5ff5fe7 100644 --- a/test/tcl/fop008.tcl +++ b/test/tcl/fop008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop009.tcl b/test/tcl/fop009.tcl index cdc5cc5d..8bcd5a0d 100644 --- a/test/tcl/fop009.tcl +++ b/test/tcl/fop009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop010.tcl b/test/tcl/fop010.tcl index 4580e9a9..7c50d632 100644 --- a/test/tcl/fop010.tcl +++ b/test/tcl/fop010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop011.tcl b/test/tcl/fop011.tcl index 0f5d68f6..853916c9 100644 --- a/test/tcl/fop011.tcl +++ b/test/tcl/fop011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fop012.tcl b/test/tcl/fop012.tcl index f343d1fd..2c11ebda 100644 --- a/test/tcl/fop012.tcl +++ b/test/tcl/fop012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/fopscript.tcl b/test/tcl/fopscript.tcl index 5e54ccdb..e0187d83 100644 --- a/test/tcl/fopscript.tcl +++ b/test/tcl/fopscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/foputils.tcl b/test/tcl/foputils.tcl index aebf8a3f..1e6ff1bf 100644 --- a/test/tcl/foputils.tcl +++ b/test/tcl/foputils.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/hsearch.tcl b/test/tcl/hsearch.tcl index 47dfea8c..cc0b70e5 100644 --- a/test/tcl/hsearch.tcl +++ b/test/tcl/hsearch.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/include.tcl b/test/tcl/include.tcl index 03b8a37e..605112ae 100644 --- a/test/tcl/include.tcl +++ b/test/tcl/include.tcl @@ -6,6 +6,7 @@ set tcllib .libs/libdb_tcl-@DB_VERSION_MAJOR@.@DB_VERSION_MINOR@@LIBTSO_MODSUFFI set src_root @srcdir@/.. set test_path @srcdir@/../test/tcl set je_root @srcdir@/../../je +set tcl_utils @srcdir@/../test/tcl_utils global testdir set testdir ./TESTDIR diff --git a/test/tcl/join.tcl b/test/tcl/join.tcl index a8e6c5a3..20cf6669 100644 --- a/test/tcl/join.tcl +++ b/test/tcl/join.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock001.tcl b/test/tcl/lock001.tcl index 6186c482..71f54fd2 100644 --- a/test/tcl/lock001.tcl +++ b/test/tcl/lock001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock002.tcl b/test/tcl/lock002.tcl index 0480e54b..aec34d43 100644 --- a/test/tcl/lock002.tcl +++ b/test/tcl/lock002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock003.tcl b/test/tcl/lock003.tcl index 2bc4df13..e7b47e21 100644 --- a/test/tcl/lock003.tcl +++ b/test/tcl/lock003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock004.tcl b/test/tcl/lock004.tcl index 6e832bab..0f1fda78 100644 --- a/test/tcl/lock004.tcl +++ b/test/tcl/lock004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock005.tcl b/test/tcl/lock005.tcl index 247e6228..9b39318d 100644 --- a/test/tcl/lock005.tcl +++ b/test/tcl/lock005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lock006.tcl b/test/tcl/lock006.tcl index 0bf70a3b..0657d5c9 100644 --- a/test/tcl/lock006.tcl +++ b/test/tcl/lock006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/lockscript.tcl b/test/tcl/lockscript.tcl index c68da1fa..7346a8a9 100644 --- a/test/tcl/lockscript.tcl +++ b/test/tcl/lockscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log001.tcl b/test/tcl/log001.tcl index 35bf9c83..63d998d2 100644 --- a/test/tcl/log001.tcl +++ b/test/tcl/log001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log002.tcl b/test/tcl/log002.tcl index 54f3e012..40143628 100644 --- a/test/tcl/log002.tcl +++ b/test/tcl/log002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log003.tcl b/test/tcl/log003.tcl index aca0c881..bc399e44 100644 --- a/test/tcl/log003.tcl +++ b/test/tcl/log003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log004.tcl b/test/tcl/log004.tcl index e083ad99..348012e8 100644 --- a/test/tcl/log004.tcl +++ b/test/tcl/log004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log005.tcl b/test/tcl/log005.tcl index dedc39e2..2a7f8d6f 100644 --- a/test/tcl/log005.tcl +++ b/test/tcl/log005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log006.tcl b/test/tcl/log006.tcl index bc8d4155..cd41b91d 100644 --- a/test/tcl/log006.tcl +++ b/test/tcl/log006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log007.tcl b/test/tcl/log007.tcl index 6468b67f..3f859fae 100644 --- a/test/tcl/log007.tcl +++ b/test/tcl/log007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log008.tcl b/test/tcl/log008.tcl index ccce4b81..d15fd124 100644 --- a/test/tcl/log008.tcl +++ b/test/tcl/log008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log008script.tcl b/test/tcl/log008script.tcl index ab77f70b..26d97a9e 100644 --- a/test/tcl/log008script.tcl +++ b/test/tcl/log008script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/log009.tcl b/test/tcl/log009.tcl index 2da13c47..161a7296 100644 --- a/test/tcl/log009.tcl +++ b/test/tcl/log009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/logtrack.tcl b/test/tcl/logtrack.tcl index df10709e..be813a99 100644 --- a/test/tcl/logtrack.tcl +++ b/test/tcl/logtrack.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mdbscript.tcl b/test/tcl/mdbscript.tcl index e7e2019f..cc57eab3 100644 --- a/test/tcl/mdbscript.tcl +++ b/test/tcl/mdbscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/memp001.tcl b/test/tcl/memp001.tcl index a3336afd..4ba8bd79 100644 --- a/test/tcl/memp001.tcl +++ b/test/tcl/memp001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/memp002.tcl b/test/tcl/memp002.tcl index fb5fc2c0..51052a63 100644 --- a/test/tcl/memp002.tcl +++ b/test/tcl/memp002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/memp003.tcl b/test/tcl/memp003.tcl index a9b3bff2..0b13d884 100644 --- a/test/tcl/memp003.tcl +++ b/test/tcl/memp003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/memp004.tcl b/test/tcl/memp004.tcl index a1a8c99b..012bf305 100644 --- a/test/tcl/memp004.tcl +++ b/test/tcl/memp004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/memp005.tcl b/test/tcl/memp005.tcl index a019dca9..fc2e2cfb 100644 --- a/test/tcl/memp005.tcl +++ b/test/tcl/memp005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mpoolscript.tcl b/test/tcl/mpoolscript.tcl index 5b0414ee..9f7b30f2 100644 --- a/test/tcl/mpoolscript.tcl +++ b/test/tcl/mpoolscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mut001.tcl b/test/tcl/mut001.tcl index 9e8696fe..565394cf 100644 --- a/test/tcl/mut001.tcl +++ b/test/tcl/mut001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mut002.tcl b/test/tcl/mut002.tcl index da566460..66a5bc83 100644 --- a/test/tcl/mut002.tcl +++ b/test/tcl/mut002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mut002script.tcl b/test/tcl/mut002script.tcl index b9390168..4d183031 100644 --- a/test/tcl/mut002script.tcl +++ b/test/tcl/mut002script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/mut003.tcl b/test/tcl/mut003.tcl index 7014f80e..51690d45 100644 --- a/test/tcl/mut003.tcl +++ b/test/tcl/mut003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/ndbm.tcl b/test/tcl/ndbm.tcl index 4b1e8c7b..76e64b3c 100644 --- a/test/tcl/ndbm.tcl +++ b/test/tcl/ndbm.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/parallel.tcl b/test/tcl/parallel.tcl index 50734d0b..acf9299c 100644 --- a/test/tcl/parallel.tcl +++ b/test/tcl/parallel.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # Code to load up the tests in to the Queue database # $Id$ @@ -309,6 +309,7 @@ proc mkparalleldirs { nprocs basename queuedir } { regsub {test_path } $d {test_path ../} d regsub {src_root } $d {src_root ../} d + regsub {tcl_utils } $d {tcl_utils ../} d set tdir "TESTDIR.$i" regsub -all {TESTDIR} $d $tdir d set outfile [open $destdir/include.tcl w] diff --git a/test/tcl/plat001.tcl b/test/tcl/plat001.tcl index 8c4c19c0..8aad00d9 100644 --- a/test/tcl/plat001.tcl +++ b/test/tcl/plat001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -17,6 +17,12 @@ proc plat001 { method {tnum "001"} args } { global fixed_len global util_path + # Heap doesn't support sequences. + if { [is_heap $method] } { + puts "Plat001 skipping for method $method." + return + } + # Fixed_len must be increased from the default to # accommodate fixed-record length methods. set orig_fixed_len $fixed_len diff --git a/test/tcl/portable.tcl b/test/tcl/portable.tcl index 8de17b9f..aea8e635 100644 --- a/test/tcl/portable.tcl +++ b/test/tcl/portable.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ @@ -49,12 +49,10 @@ proc test_portable_logs { { archived_test_loc } } { puts -nonewline $o "Log portability test started at: " puts $o [clock format [clock seconds] -format "%H:%M %D"] puts $o [berkdb version -string] - puts $o "Testing $e files" puts -nonewline "Log portability test started at: " puts [clock format [clock seconds] -format "%H:%M %D"] puts [berkdb version -string] - puts "Testing $e files" set portable_dir $archived_test_loc puts $o "Using archived databases in $portable_dir." @@ -62,8 +60,8 @@ proc test_portable_logs { { archived_test_loc } } { close $o foreach version [glob $portable_dir/*] { - if { [string first CVS $version] != -1 } { continue } regexp \[^\/\]*$ $version version + if { [string equal $version "logversion"] == 1 } { continue } # Test only files where the endianness of the db does # not match the endianness of the test platform. @@ -74,9 +72,11 @@ foreach version [glob $portable_dir/*] { on $myendianness platform." } else { set o [open PORTABLE.OUT a] - puts $o "Testing $dbendianness files" + puts $o "Testing $dbendianness files\ + on $myendianness platform." close $o - puts "Testing $dbendianness files" + puts "Testing $dbendianness files\ + on $myendianness platform." foreach method [glob -nocomplain $portable_dir/$version/*] { regexp \[^\/\]*$ $method method @@ -158,6 +158,13 @@ proc _recover_test { dir version method name dbendianness } { # the recovered database. catch { file rename -force $testdir/$name.db \ $testdir/$name.db.init } res + if { [is_heap $method] == 1 } { + file rename -force $testdir/$name.db1 \ + $testdir/$name.db.init1 + file rename -force $testdir/$name.db2 \ + $testdir/$name.db.init2 + } + # Recover. set ret [catch {eval {exec} $util_path/db_recover -h $testdir} res] @@ -321,7 +328,12 @@ proc save_portable_files { dir } { if { [llength $dbfiles] > 0 } { set logfiles [glob -nocomplain $dir/log.*] set dbfile [lindex $dbfiles 0] - + + if { $portable_method == "heap" } { + append dbfile1 $dbfile "1" + append dbfile2 $dbfile "2" + } + # We arbitrarily name the tar file where we save # everything after the first database file we # find. This works because the database files @@ -336,8 +348,8 @@ proc save_portable_files { dir } { cd $dir if { [catch { eval exec tar -cvf $dest/$basename.tar \ - [glob -nocomplain *.db log.* \ - __dbq.$basename-$en.db.*] + [glob -nocomplain *.db *.db1 *.db2 \ + log.* __dbq.$basename-$en.db.*] exec gzip --best $dest/$basename.tar } res ] } { puts "FAIL: tar/gzip of $basename failed\ diff --git a/test/tcl/recd001.tcl b/test/tcl/recd001.tcl index 6dbc5801..dd935962 100644 --- a/test/tcl/recd001.tcl +++ b/test/tcl/recd001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd002.tcl b/test/tcl/recd002.tcl index 09658242..5b094cbc 100644 --- a/test/tcl/recd002.tcl +++ b/test/tcl/recd002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd003.tcl b/test/tcl/recd003.tcl index 1ca4f314..51ca5837 100644 --- a/test/tcl/recd003.tcl +++ b/test/tcl/recd003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd004.tcl b/test/tcl/recd004.tcl index 06844f60..21a444ac 100644 --- a/test/tcl/recd004.tcl +++ b/test/tcl/recd004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd005.tcl b/test/tcl/recd005.tcl index 3bed7707..4a6caafe 100644 --- a/test/tcl/recd005.tcl +++ b/test/tcl/recd005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd006.tcl b/test/tcl/recd006.tcl index d781ef84..affd1057 100644 --- a/test/tcl/recd006.tcl +++ b/test/tcl/recd006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd007.tcl b/test/tcl/recd007.tcl index 0ae70ced..89b2b5e8 100644 --- a/test/tcl/recd007.tcl +++ b/test/tcl/recd007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd008.tcl b/test/tcl/recd008.tcl index 5c112c15..4b1e95f3 100644 --- a/test/tcl/recd008.tcl +++ b/test/tcl/recd008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd009.tcl b/test/tcl/recd009.tcl index 3a34c736..c99c59f6 100644 --- a/test/tcl/recd009.tcl +++ b/test/tcl/recd009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd010.tcl b/test/tcl/recd010.tcl index a06e7756..c919b896 100644 --- a/test/tcl/recd010.tcl +++ b/test/tcl/recd010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd011.tcl b/test/tcl/recd011.tcl index 41377821..60fb042b 100644 --- a/test/tcl/recd011.tcl +++ b/test/tcl/recd011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd012.tcl b/test/tcl/recd012.tcl index 41d46110..a24e4938 100644 --- a/test/tcl/recd012.tcl +++ b/test/tcl/recd012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd013.tcl b/test/tcl/recd013.tcl index 71268a82..2a3dfdf8 100644 --- a/test/tcl/recd013.tcl +++ b/test/tcl/recd013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd014.tcl b/test/tcl/recd014.tcl index ad7de693..92e94078 100644 --- a/test/tcl/recd014.tcl +++ b/test/tcl/recd014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd015.tcl b/test/tcl/recd015.tcl index 2110bb8e..8a9920f7 100644 --- a/test/tcl/recd015.tcl +++ b/test/tcl/recd015.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd016.tcl b/test/tcl/recd016.tcl index 983acc63..dede49c9 100644 --- a/test/tcl/recd016.tcl +++ b/test/tcl/recd016.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd017.tcl b/test/tcl/recd017.tcl index bc76e625..d190a8a9 100644 --- a/test/tcl/recd017.tcl +++ b/test/tcl/recd017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd018.tcl b/test/tcl/recd018.tcl index d3d86326..2c0aec23 100644 --- a/test/tcl/recd018.tcl +++ b/test/tcl/recd018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd019.tcl b/test/tcl/recd019.tcl index 2d3c3f05..5e3a1aaa 100644 --- a/test/tcl/recd019.tcl +++ b/test/tcl/recd019.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd020.tcl b/test/tcl/recd020.tcl index 3d56488b..442a0b69 100644 --- a/test/tcl/recd020.tcl +++ b/test/tcl/recd020.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd021.tcl b/test/tcl/recd021.tcl index 33267f4f..89891b86 100644 --- a/test/tcl/recd021.tcl +++ b/test/tcl/recd021.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd022.tcl b/test/tcl/recd022.tcl index eeda6b79..ed84c828 100644 --- a/test/tcl/recd022.tcl +++ b/test/tcl/recd022.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd023.tcl b/test/tcl/recd023.tcl index f8b7beba..a9f9f07f 100644 --- a/test/tcl/recd023.tcl +++ b/test/tcl/recd023.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd024.tcl b/test/tcl/recd024.tcl index b4b4e270..49c66106 100644 --- a/test/tcl/recd024.tcl +++ b/test/tcl/recd024.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd025.tcl b/test/tcl/recd025.tcl index 1a04d2c2..1f2c05e1 100644 --- a/test/tcl/recd025.tcl +++ b/test/tcl/recd025.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recd15scr.tcl b/test/tcl/recd15scr.tcl index 28e27238..5ad45228 100644 --- a/test/tcl/recd15scr.tcl +++ b/test/tcl/recd15scr.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/recdscript.tcl b/test/tcl/recdscript.tcl index da05da28..a931fdae 100644 --- a/test/tcl/recdscript.tcl +++ b/test/tcl/recdscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep001.tcl b/test/tcl/rep001.tcl index 01b29fd5..63661cb9 100644 --- a/test/tcl/rep001.tcl +++ b/test/tcl/rep001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep002.tcl b/test/tcl/rep002.tcl index 0321ba7a..694314c1 100644 --- a/test/tcl/rep002.tcl +++ b/test/tcl/rep002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep003.tcl b/test/tcl/rep003.tcl index 55c4a051..f70d4aec 100644 --- a/test/tcl/rep003.tcl +++ b/test/tcl/rep003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep005.tcl b/test/tcl/rep005.tcl index fcb5eb4c..fa3431e1 100644 --- a/test/tcl/rep005.tcl +++ b/test/tcl/rep005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep006.tcl b/test/tcl/rep006.tcl index 65bd5f63..609f69dd 100644 --- a/test/tcl/rep006.tcl +++ b/test/tcl/rep006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep007.tcl b/test/tcl/rep007.tcl index cfd0918f..6e18ab64 100644 --- a/test/tcl/rep007.tcl +++ b/test/tcl/rep007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep008.tcl b/test/tcl/rep008.tcl index 93d961a5..c6be6b60 100644 --- a/test/tcl/rep008.tcl +++ b/test/tcl/rep008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep009.tcl b/test/tcl/rep009.tcl index 24a56075..f6732876 100644 --- a/test/tcl/rep009.tcl +++ b/test/tcl/rep009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep010.tcl b/test/tcl/rep010.tcl index c9182472..67ef5726 100644 --- a/test/tcl/rep010.tcl +++ b/test/tcl/rep010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep011.tcl b/test/tcl/rep011.tcl index 06f7d9d7..23ad1b12 100644 --- a/test/tcl/rep011.tcl +++ b/test/tcl/rep011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep012.tcl b/test/tcl/rep012.tcl index 065a5053..84bf0837 100644 --- a/test/tcl/rep012.tcl +++ b/test/tcl/rep012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep013.tcl b/test/tcl/rep013.tcl index bdc5d968..d4ba7259 100644 --- a/test/tcl/rep013.tcl +++ b/test/tcl/rep013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep014.tcl b/test/tcl/rep014.tcl index f7a5ef7f..e60bc459 100644 --- a/test/tcl/rep014.tcl +++ b/test/tcl/rep014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep015.tcl b/test/tcl/rep015.tcl index 3a2d998d..18c4bdf5 100644 --- a/test/tcl/rep015.tcl +++ b/test/tcl/rep015.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep016.tcl b/test/tcl/rep016.tcl index 55e82fcc..5bce3670 100644 --- a/test/tcl/rep016.tcl +++ b/test/tcl/rep016.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep017.tcl b/test/tcl/rep017.tcl index 26c9924a..080d1f74 100644 --- a/test/tcl/rep017.tcl +++ b/test/tcl/rep017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep017script.tcl b/test/tcl/rep017script.tcl index d165b13c..492ed4e7 100644 --- a/test/tcl/rep017script.tcl +++ b/test/tcl/rep017script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep018.tcl b/test/tcl/rep018.tcl index 24279841..8a1c5caf 100644 --- a/test/tcl/rep018.tcl +++ b/test/tcl/rep018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep018script.tcl b/test/tcl/rep018script.tcl index d69a414c..82074582 100644 --- a/test/tcl/rep018script.tcl +++ b/test/tcl/rep018script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep019.tcl b/test/tcl/rep019.tcl index e908eb53..1ade455d 100644 --- a/test/tcl/rep019.tcl +++ b/test/tcl/rep019.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep020.tcl b/test/tcl/rep020.tcl index 5e510b67..d45b48f1 100644 --- a/test/tcl/rep020.tcl +++ b/test/tcl/rep020.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep021.tcl b/test/tcl/rep021.tcl index 7145f738..47d955af 100644 --- a/test/tcl/rep021.tcl +++ b/test/tcl/rep021.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep022.tcl b/test/tcl/rep022.tcl index 43da6d4f..6fb2dc5a 100644 --- a/test/tcl/rep022.tcl +++ b/test/tcl/rep022.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep023.tcl b/test/tcl/rep023.tcl index 66c057aa..5dee27e7 100644 --- a/test/tcl/rep023.tcl +++ b/test/tcl/rep023.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep024.tcl b/test/tcl/rep024.tcl index 2b3a7304..1559edfa 100644 --- a/test/tcl/rep024.tcl +++ b/test/tcl/rep024.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep025.tcl b/test/tcl/rep025.tcl index eb995148..40043704 100644 --- a/test/tcl/rep025.tcl +++ b/test/tcl/rep025.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep026.tcl b/test/tcl/rep026.tcl index bdf65f73..8bd6790b 100644 --- a/test/tcl/rep026.tcl +++ b/test/tcl/rep026.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep027.tcl b/test/tcl/rep027.tcl index a4f33ebc..b05aa07d 100644 --- a/test/tcl/rep027.tcl +++ b/test/tcl/rep027.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep028.tcl b/test/tcl/rep028.tcl index 8fdebc7c..7a6617f5 100644 --- a/test/tcl/rep028.tcl +++ b/test/tcl/rep028.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep029.tcl b/test/tcl/rep029.tcl index 954a498f..707d04c0 100644 --- a/test/tcl/rep029.tcl +++ b/test/tcl/rep029.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep030.tcl b/test/tcl/rep030.tcl index 4bdb68fb..a55f0b01 100644 --- a/test/tcl/rep030.tcl +++ b/test/tcl/rep030.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -121,6 +121,9 @@ proc rep030_sub { method niter tnum logset recargs opts largs } { set maxpg 16384 set log_max [expr $maxpg * 8] set cache [expr $maxpg * 32 ] + if { $databases_in_memory } { + set cache [expr $maxpg * 64] + } set m_logtype [lindex $logset 0] set c_logtype [lindex $logset 1] @@ -132,7 +135,6 @@ proc rep030_sub { method niter tnum logset recargs opts largs } { set c_txnargs [adjust_txnargs $c_logtype] # Run internal init using a data directory - # file mkdir $masterdir/data file mkdir $masterdir/data2 file mkdir $clientdir/data @@ -321,11 +323,11 @@ proc rep030_sub { method niter tnum logset recargs opts largs } { } rep_verify $masterdir $masterenv $clientdir $clientenv\ - 1 1 1 test.db $masterdir/data + 1 1 1 test.db data for { set i 0 } { $i < $nfiles } { incr i } { set dbname "test.$i.db" rep_verify $masterdir $masterenv $clientdir $clientenv \ - 1 1 0 $dbname $masterdir/data + 1 1 0 $dbname data } # Close the database held open on master for initialization. @@ -350,11 +352,11 @@ proc rep030_sub { method niter tnum logset recargs opts largs } { process_msgs $envlist 0 NONE err rep_verify $masterdir $masterenv $clientdir $clientenv \ - 1 1 0 test.db $masterdir/data + 1 1 0 test.db data for { set i 0 } { $i < $nfiles } { incr i } { set dbname "test.$i.db" rep_verify $masterdir $masterenv $clientdir $clientenv \ - 1 1 0 $dbname $masterdir/data + 1 1 0 $dbname data } set bulkxfer [stat_field $masterenv rep_stat "Bulk buffer transfers"] if { $opts == "bulk" } { diff --git a/test/tcl/rep031.tcl b/test/tcl/rep031.tcl index 3aacb40a..f0245cc4 100644 --- a/test/tcl/rep031.tcl +++ b/test/tcl/rep031.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep032.tcl b/test/tcl/rep032.tcl index 815bc616..5f37247c 100644 --- a/test/tcl/rep032.tcl +++ b/test/tcl/rep032.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep033.tcl b/test/tcl/rep033.tcl index 99af8d40..41b36848 100644 --- a/test/tcl/rep033.tcl +++ b/test/tcl/rep033.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -103,11 +103,17 @@ proc rep033_sub { method niter tnum envargs recargs clean when largs } { set log_buf [expr $pagesize * 2] set log_max [expr $log_buf * 4] + set cacheargs "" + if { $databases_in_memory } { + set cachesize [expr 1024 * 1024] + set cacheargs "-cachesize { 0 $cachesize 1 }" + } + # Open a master. repladd 1 set ma_envcmd "berkdb_env_noerr -create -txn nosync \ -log_buffer $log_buf -log_max $log_max $envargs \ - -errpfx MASTER $verbargs $repmemargs \ + -errpfx MASTER $verbargs $repmemargs $cacheargs \ -home $masterdir -rep_transport \[list 1 replsend\]" set masterenv [eval $ma_envcmd $recargs -rep_master] @@ -115,7 +121,7 @@ proc rep033_sub { method niter tnum envargs recargs clean when largs } { repladd 2 set cl_envcmd "berkdb_env_noerr -create -txn nosync \ -log_buffer $log_buf -log_max $log_max $envargs \ - -errpfx CLIENT $verbargs $repmemargs \ + -errpfx CLIENT $verbargs $repmemargs $cacheargs \ -home $clientdir -rep_transport \[list 2 replsend\]" set clientenv [eval $cl_envcmd $recargs -rep_client] diff --git a/test/tcl/rep034.tcl b/test/tcl/rep034.tcl index 9e6dbcbc..d28382e4 100644 --- a/test/tcl/rep034.tcl +++ b/test/tcl/rep034.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep035.tcl b/test/tcl/rep035.tcl index 3ab482f9..cdd0eae7 100644 --- a/test/tcl/rep035.tcl +++ b/test/tcl/rep035.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep035script.tcl b/test/tcl/rep035script.tcl index e0180aba..fb4dd94e 100644 --- a/test/tcl/rep035script.tcl +++ b/test/tcl/rep035script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep036.tcl b/test/tcl/rep036.tcl index 0d532141..16ec6e5d 100644 --- a/test/tcl/rep036.tcl +++ b/test/tcl/rep036.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep036script.tcl b/test/tcl/rep036script.tcl index d11873d7..84975c5e 100644 --- a/test/tcl/rep036script.tcl +++ b/test/tcl/rep036script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep037.tcl b/test/tcl/rep037.tcl index fa5875a9..10dea8a9 100644 --- a/test/tcl/rep037.tcl +++ b/test/tcl/rep037.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep038.tcl b/test/tcl/rep038.tcl index cb621dd7..5c523847 100644 --- a/test/tcl/rep038.tcl +++ b/test/tcl/rep038.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep039.tcl b/test/tcl/rep039.tcl index 3ece0597..4a51b0b3 100644 --- a/test/tcl/rep039.tcl +++ b/test/tcl/rep039.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep040.tcl b/test/tcl/rep040.tcl index 185bd555..6008ef48 100644 --- a/test/tcl/rep040.tcl +++ b/test/tcl/rep040.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep040script.tcl b/test/tcl/rep040script.tcl index d4fedc82..cc57db4e 100644 --- a/test/tcl/rep040script.tcl +++ b/test/tcl/rep040script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep041.tcl b/test/tcl/rep041.tcl index 371cd77f..d6cf08ae 100644 --- a/test/tcl/rep041.tcl +++ b/test/tcl/rep041.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep042.tcl b/test/tcl/rep042.tcl index c334c526..eac7decf 100644 --- a/test/tcl/rep042.tcl +++ b/test/tcl/rep042.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep042script.tcl b/test/tcl/rep042script.tcl index d18f56da..b21bec01 100644 --- a/test/tcl/rep042script.tcl +++ b/test/tcl/rep042script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep043.tcl b/test/tcl/rep043.tcl index a6ba74da..ba9f731a 100644 --- a/test/tcl/rep043.tcl +++ b/test/tcl/rep043.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep043script.tcl b/test/tcl/rep043script.tcl index 6a1a4a44..646fbe5b 100644 --- a/test/tcl/rep043script.tcl +++ b/test/tcl/rep043script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep044.tcl b/test/tcl/rep044.tcl index 2bbf7aff..3793c7a2 100644 --- a/test/tcl/rep044.tcl +++ b/test/tcl/rep044.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep045.tcl b/test/tcl/rep045.tcl index 78b81da4..34d6d81c 100644 --- a/test/tcl/rep045.tcl +++ b/test/tcl/rep045.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -104,12 +104,20 @@ proc rep045_sub { method tnum logset largs } { set c_txnargs [adjust_txnargs $c_logtype] set c2_txnargs [adjust_txnargs $c2_logtype] + # Increase cache size for in-memory databases. + set cacheargs "" + if { $databases_in_memory } { + set cachesize [expr 2 * (1024 * 1024)] + set cacheargs "-cachesize { 0 $cachesize 1 }" + } + set omethod [convert_method $method] # Open a master. repladd 1 set envcmd(M0) "berkdb_env_noerr -create $m_txnargs \ $m_logargs -errpfx ENV.M0 $verbargs $repmemargs \ + $cacheargs \ -errfile /dev/stderr -lock_detect default \ -home $masterdir -rep_transport \[list 1 replsend\]" set menv [eval $envcmd(M0) -rep_master] @@ -118,6 +126,7 @@ proc rep045_sub { method tnum logset largs } { repladd 2 set envcmd(C0) "berkdb_env_noerr -create $c_txnargs \ $c_logargs -errpfx ENV.C0 $verbargs $repmemargs \ + $cacheargs \ -errfile /dev/stderr -lock_detect default \ -home $clientdir0 -rep_transport \[list 2 replsend\]" set cenv0 [eval $envcmd(C0) -rep_client] @@ -126,6 +135,7 @@ proc rep045_sub { method tnum logset largs } { repladd 3 set envcmd(C1) "berkdb_env_noerr -create $c2_txnargs \ $c2_logargs -errpfx ENV.C1 $verbargs $repmemargs \ + $cacheargs \ -errfile /dev/stderr -lock_detect default \ -home $clientdir1 -rep_transport \[list 3 replsend\]" set cenv1 [eval $envcmd(C1) -rep_client] diff --git a/test/tcl/rep045script.tcl b/test/tcl/rep045script.tcl index 4d31d37e..82864b0c 100644 --- a/test/tcl/rep045script.tcl +++ b/test/tcl/rep045script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep046.tcl b/test/tcl/rep046.tcl index 5b150378..b5d6ea76 100644 --- a/test/tcl/rep046.tcl +++ b/test/tcl/rep046.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep047.tcl b/test/tcl/rep047.tcl index 2c683eaf..ca791aeb 100644 --- a/test/tcl/rep047.tcl +++ b/test/tcl/rep047.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep048.tcl b/test/tcl/rep048.tcl index 0e748a22..aaeeefb8 100644 --- a/test/tcl/rep048.tcl +++ b/test/tcl/rep048.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep048script.tcl b/test/tcl/rep048script.tcl index e724d9f0..60753997 100644 --- a/test/tcl/rep048script.tcl +++ b/test/tcl/rep048script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep049.tcl b/test/tcl/rep049.tcl index 8ee34fad..5b6a5577 100644 --- a/test/tcl/rep049.tcl +++ b/test/tcl/rep049.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep050.tcl b/test/tcl/rep050.tcl index 77f9a2be..390d8b88 100644 --- a/test/tcl/rep050.tcl +++ b/test/tcl/rep050.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep051.tcl b/test/tcl/rep051.tcl index b3bd2fca..505feeff 100644 --- a/test/tcl/rep051.tcl +++ b/test/tcl/rep051.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep052.tcl b/test/tcl/rep052.tcl index e8184585..353d2eb3 100644 --- a/test/tcl/rep052.tcl +++ b/test/tcl/rep052.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep053.tcl b/test/tcl/rep053.tcl index ef8047cc..ea217a13 100644 --- a/test/tcl/rep053.tcl +++ b/test/tcl/rep053.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -187,9 +187,13 @@ proc rep053_sub { method niter tnum logset recargs throttle largs } { # set expected_msgs 3 - if { [is_queue $method] } { - # Queue database require an extra request - # to retrieve the meta page. + if { [is_queue $method] || [is_heap $method] } { + # Queue databases require an extra request + # to retrieve the meta page; heap databases + # need extra messages to process the "shadow" + # databases we use for the heap Tcl implementation. + # Allowing one extra message here automatically + # allows two extra messages when throttling. incr expected_msgs } diff --git a/test/tcl/rep054.tcl b/test/tcl/rep054.tcl index 36beb0f7..ca3799d1 100644 --- a/test/tcl/rep054.tcl +++ b/test/tcl/rep054.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -116,9 +116,9 @@ proc rep054_sub { method nentries tnum logset recargs largs } { set c2_logtype [lindex $logset 2] # In-memory logs cannot be used with -txn nosync. - set m_logargs [adjust_logargs $m_logtype] - set c_logargs [adjust_logargs $c_logtype] - set c2_logargs [adjust_logargs $c2_logtype] + set m_logargs [adjust_logargs $m_logtype 1048576] + set c_logargs [adjust_logargs $c_logtype 1048576] + set c2_logargs [adjust_logargs $c2_logtype 1048576] set m_txnargs [adjust_txnargs $m_logtype] set c_txnargs [adjust_txnargs $c_logtype] set c2_txnargs [adjust_txnargs $c2_logtype] diff --git a/test/tcl/rep055.tcl b/test/tcl/rep055.tcl index b7dd1225..3aead361 100644 --- a/test/tcl/rep055.tcl +++ b/test/tcl/rep055.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep058.tcl b/test/tcl/rep058.tcl index d096658c..cfdbca88 100644 --- a/test/tcl/rep058.tcl +++ b/test/tcl/rep058.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep060.tcl b/test/tcl/rep060.tcl index 168fa708..d1eee952 100644 --- a/test/tcl/rep060.tcl +++ b/test/tcl/rep060.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep061.tcl b/test/tcl/rep061.tcl index bb067526..cfaf9992 100644 --- a/test/tcl/rep061.tcl +++ b/test/tcl/rep061.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep062.tcl b/test/tcl/rep062.tcl index 18e45ea7..5e681d4c 100644 --- a/test/tcl/rep062.tcl +++ b/test/tcl/rep062.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -244,6 +244,9 @@ proc rep062_sub { method tnum logset recargs largs } { puts "\tRep$tnum.c: Add a few records to test db." set nentries 10 set start 0 + if { $encryptenv == 1 } { + set encrypt 1 + } eval rep_test $method1 \ $masterenv $db1 $nentries $start $start 0 $args1 incr start $nentries diff --git a/test/tcl/rep063.tcl b/test/tcl/rep063.tcl index 38ec6837..b64fd38a 100644 --- a/test/tcl/rep063.tcl +++ b/test/tcl/rep063.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep064.tcl b/test/tcl/rep064.tcl index 7ed7667a..78804c88 100644 --- a/test/tcl/rep064.tcl +++ b/test/tcl/rep064.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep065.tcl b/test/tcl/rep065.tcl index f5800187..54dd2045 100644 --- a/test/tcl/rep065.tcl +++ b/test/tcl/rep065.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -119,7 +119,9 @@ proc rep065_sub { iter mv nsites slist } { set histdirs($sid) $histtestdir/SITE.$i set upgdir($sid) $controldir/$testdir/SITE.$i file mkdir $histdirs($sid) + file mkdir $histdirs($sid)/DATADIR file mkdir $upgdir($sid) + file mkdir $upgdir($sid)/DATADIR } # Open master env running 4.4. @@ -378,20 +380,34 @@ proc get_master { nsites verslist } { } proc method_version { } { - global valid_methods - set methods $valid_methods + set mv {} + + # Set up version 5.2, which adds the method 'heap'. Since + # heap is new, we'd like to test it heavily. Always test a + # 5.2/heap pair, plus one other 5.2 with a random non-heap + # version. Here's the hard-coded one: + set db52 "db-5.2.36" + lappend mv [list heap $db52] + + set methods {btree rbtree recno frecno rrecno queue queueext hash} + set methods_len [expr [llength $methods] - 1] + set midx [berkdb random_int 0 $methods_len] + set method [lindex $methods $midx] + lappend mv [list $method $db52] + + # Now take care of versions 4.4 though 5.1, which share + # the same list of eight valid methods. set remaining_methods $methods set methods_len [expr [llength $remaining_methods] - 1] - set versions {db-5.1.25 db-5.0.26 \ + set versions {db-5.1.25 db-5.0.32 \ db-4.8.30 db-4.7.25 db-4.6.21 db-4.5.20 db-4.4.20} set remaining_versions $versions set versions_len [expr [llength $remaining_versions] - 1] # Walk through the list of methods and the list of versions and # pair them at random. Stop when either list is empty. - set mv {} while { $versions_len >= 0 && $methods_len >= 0 } { set vidx [berkdb random_int 0 $versions_len] set midx [berkdb random_int 0 $methods_len] @@ -405,20 +421,18 @@ proc method_version { } { incr versions_len -1 incr methods_len -1 - if { $method != "heap" } { - lappend mv [list $method $version] - } + lappend mv [list $method $version] } - + # If there are remaining versions, randomly assign any of # the original methods to each one. while { $versions_len >= 0 } { - set methods_len [expr [llength $valid_methods] - 1] + set methods_len [expr [llength $methods] - 1] set midx [berkdb random_int 0 $methods_len] set version [lindex $remaining_versions 0] - set method [lindex $valid_methods $midx] + set method [lindex $methods $midx] set remaining_versions [lreplace $remaining_versions 0 0] incr versions_len -1 diff --git a/test/tcl/rep065script.tcl b/test/tcl/rep065script.tcl index 539de61d..47a165be 100644 --- a/test/tcl/rep065script.tcl +++ b/test/tcl/rep065script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -52,16 +52,16 @@ proc rep065scr_reptest { repenv oplist markerdb } { } proc rep065scr_repget { repenv oplist mydir markerfile } { - set dbname "$mydir/test.db" + set dbname "$mydir/DATADIR/test.db" set i 0 while { [file exists $dbname] == 0 } { tclsleep 2 incr i if { $i >= 15 && $i % 5 == 0 } { - puts "After $i seconds, no database exists." + puts "After $i seconds, no database $dbname exists." } if { $i > 180 } { - error "Database never created." + error "Database $dbname never created." } } set loop 1 @@ -113,33 +113,19 @@ proc rep065scr_starttest { role oplist envid msgdir mydir allids markerfile } { set logbuf [expr 16 * 1024] set logmax [expr $logbuf * 4] if { $role == "MASTER" } { - set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ - -log_max $logmax -log_buffer $logbuf $repmemargs \ - -lock_max_objects $lockmax -lock_max_locks $lockmax \ - -errpfx MASTER -txn -rep_master \ - -rep_transport \[list $envid replsend_noenv\]" - set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ - -log_max $logmax -log_buffer $logbuf $repmemargs \ - -lock_max_objects $lockmax -lock_max_locks $lockmax \ - -errpfx MASTER -txn -rep_master \ - -verbose {rep on} -errfile /dev/stderr \ - -rep_transport \[list $envid replsend_noenv\]" + set rolearg "-rep_master" } elseif { $role == "CLIENT" } { - set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ - -log_max $logmax -log_buffer $logbuf $repmemargs \ - -lock_max_objects $lockmax -lock_max_locks $lockmax \ - -errpfx CLIENT -txn -rep_client \ - -rep_transport \[list $envid replsend_noenv\]" - set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ - -log_max $logmax -log_buffer $logbuf $repmemargs \ - -lock_max_objects $lockmax -lock_max_locks $lockmax \ - -errpfx CLIENT -txn -rep_client \ - -verbose {rep on} -errfile /dev/stderr \ - -rep_transport \[list $envid replsend_noenv\]" + set rolearg "-rep_client" } else { puts "FAIL: unrecognized replication role $role" return } + set rep_env_cmd "berkdb_env_noerr -create -home $mydir \ + -log_max $logmax -log_buffer $logbuf $repmemargs \ + -lock_max_objects $lockmax -lock_max_locks $lockmax \ + -errpfx $role -txn $rolearg -data_dir DATADIR \ + -verbose {rep on} -errfile /dev/stderr \ + -rep_transport \[list $envid replsend_noenv\]" # Change directories to where this will run. # !!! @@ -231,25 +217,18 @@ proc rep065scr_msgs { role envid msgdir mydir allids markerfile } { puts "set up env cmd" if { $role == "MASTER" } { - set rep_env_cmd "berkdb_env_noerr -home $mydir \ - -errpfx MASTER -txn -rep_master $repmemargs \ - -rep_transport \[list $envid replsend_noenv\]" - set rep_env_cmd "berkdb_env_noerr -home $mydir \ - -errpfx MASTER -txn -rep_master $repmemargs \ - -verbose {rep on} -errfile /dev/stderr \ - -rep_transport \[list $envid replsend_noenv\]" + set rolearg "-rep_master" } elseif { $role == "CLIENT" } { - set rep_env_cmd "berkdb_env_noerr -home $mydir \ - -errpfx CLIENT -txn -rep_client $repmemargs \ - -rep_transport \[list $envid replsend_noenv\]" - set rep_env_cmd "berkdb_env_noerr -home $mydir \ - -errpfx CLIENT -txn -rep_client $repmemargs \ - -verbose {rep on} -errfile /dev/stderr \ - -rep_transport \[list $envid replsend_noenv\]" + set rolearg "-rep_client" } else { puts "FAIL: unrecognized replication role $role" return } + set rep_env_cmd "berkdb_env_noerr -home $mydir \ + -errpfx $role -txn $rolearg $repmemargs \ + -verbose {rep on} -errfile /dev/stderr \ + -data_dir DATADIR \ + -rep_transport \[list $envid replsend_noenv\]" # Change directories to where this will run. cd $mydir @@ -296,6 +275,7 @@ proc rep065scr_verify { oplist mydir id } { global util_path set rep_env_cmd "berkdb_env_noerr -home $mydir -txn \ + -data_dir DATADIR \ -rep_transport \[list $id replnoop\]" # Change directories to where this will run. @@ -311,18 +291,21 @@ proc rep065scr_verify { oplist mydir id } { set repenv [eval $rep_env_cmd] error_check_good env_open [is_valid_env $repenv] TRUE if { $op == "DB" } { - set dbname "$mydir/test.db" + set dbname "$mydir/DATADIR/test.db" + puts "Open db: $dbname" set db [berkdb_open -env $repenv -rdonly $dbname] error_check_good dbopen [is_valid_db $db] TRUE set txn "" set method [$db get_type] + set dumpfile "$mydir/VERIFY/dbdump" if { [is_record_based $method] == 1 } { - dump_file $db $txn $mydir/VERIFY/dbdump \ + dump_file $db $txn $dumpfile \ rep_test_upg.recno.check } else { - dump_file $db $txn $mydir/VERIFY/dbdump \ + dump_file $db $txn $dumpfile \ rep_test_upg.check } + puts "Done dumping $dbname to $dumpfile" error_check_good dbclose [$db close] 0 } if { $op == "LOG" } { diff --git a/test/tcl/rep066.tcl b/test/tcl/rep066.tcl index 3dcf34f4..ba0c9dd8 100644 --- a/test/tcl/rep066.tcl +++ b/test/tcl/rep066.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep067.tcl b/test/tcl/rep067.tcl index 81f5e4f1..d2c78d8f 100644 --- a/test/tcl/rep067.tcl +++ b/test/tcl/rep067.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep067 # TEST Full election timeout test. diff --git a/test/tcl/rep068.tcl b/test/tcl/rep068.tcl index 3e934eb0..adfe6dd8 100644 --- a/test/tcl/rep068.tcl +++ b/test/tcl/rep068.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep069.tcl b/test/tcl/rep069.tcl index 859e1a7e..b24a23c0 100644 --- a/test/tcl/rep069.tcl +++ b/test/tcl/rep069.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep070.tcl b/test/tcl/rep070.tcl index 7c137c76..c7c359e3 100644 --- a/test/tcl/rep070.tcl +++ b/test/tcl/rep070.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep071.tcl b/test/tcl/rep071.tcl index 915b50e8..95cbf37c 100644 --- a/test/tcl/rep071.tcl +++ b/test/tcl/rep071.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep072.tcl b/test/tcl/rep072.tcl index 1799a19d..fa091657 100644 --- a/test/tcl/rep072.tcl +++ b/test/tcl/rep072.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -95,8 +95,8 @@ proc rep072_sub {method {niter 200} {tnum 072} logset \ # In-memory logs require a large log buffer, and cannot # be used with -txn nosync. Adjust the args for master # and client. - set m_logargs [adjust_logargs $m_logtype] - set c_logargs [adjust_logargs $c_logtype] + set m_logargs [adjust_logargs $m_logtype 1048576] + set c_logargs [adjust_logargs $c_logtype 1048576] set m_txnargs [adjust_txnargs $m_logtype] set c_txnargs [adjust_txnargs $c_logtype] diff --git a/test/tcl/rep073.tcl b/test/tcl/rep073.tcl index 73da6b6f..115595f5 100644 --- a/test/tcl/rep073.tcl +++ b/test/tcl/rep073.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep074.tcl b/test/tcl/rep074.tcl index 3bb652fa..4d0c312f 100644 --- a/test/tcl/rep074.tcl +++ b/test/tcl/rep074.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep075.tcl b/test/tcl/rep075.tcl index 0ed24781..99f4d68c 100644 --- a/test/tcl/rep075.tcl +++ b/test/tcl/rep075.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep076.tcl b/test/tcl/rep076.tcl index 22d55b7d..9d24cebf 100644 --- a/test/tcl/rep076.tcl +++ b/test/tcl/rep076.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep077.tcl b/test/tcl/rep077.tcl index 35534b8a..fceb8166 100644 --- a/test/tcl/rep077.tcl +++ b/test/tcl/rep077.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep078.tcl b/test/tcl/rep078.tcl index 55def654..1c398fed 100644 --- a/test/tcl/rep078.tcl +++ b/test/tcl/rep078.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep078script.tcl b/test/tcl/rep078script.tcl index 796b0b6b..1d036d9b 100644 --- a/test/tcl/rep078script.tcl +++ b/test/tcl/rep078script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep079.tcl b/test/tcl/rep079.tcl index 8831ce63..d5a4f875 100644 --- a/test/tcl/rep079.tcl +++ b/test/tcl/rep079.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -317,8 +317,14 @@ proc rep079_sub { method tnum logset largs } { # (And this will be the 'before we commit' check that returns # an error, not the 'after' check that panics). # + # We need to create a txn that actually generates log records. + # + set omethod [convert_method $method] set txn [$masterenv txn] + set db [berkdb_open_noerr -create $omethod -env $masterenv -txn $txn \ + -mode 0644 lease.db] set stat [catch {$txn commit} ret] + error_check_good close [$db close] 0 error_check_good stat $stat 1 error_check_good exp [is_substr $ret REP_LEASE_EXPIRED] 1 diff --git a/test/tcl/rep080.tcl b/test/tcl/rep080.tcl index 6e65dc2a..bd9ddea0 100644 --- a/test/tcl/rep080.tcl +++ b/test/tcl/rep080.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep081.tcl b/test/tcl/rep081.tcl index dbed4076..79e9ffa7 100644 --- a/test/tcl/rep081.tcl +++ b/test/tcl/rep081.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -66,18 +66,22 @@ proc rep081 { method { niter 200 } { tnum "081" } args } { # Run with options to remove or replace the master database file. set testopts { removefile replacefile } + set metaopts { nometadir metadir } foreach t $testopts { - foreach l $logsets { - puts "Rep$tnum ($method $t $args): Test of\ - internal init with missing db file $msg $msg2." - puts "Rep$tnum: Master logs are [lindex $l 0]" - puts "Rep$tnum: Client logs are [lindex $l 1]" - rep081_sub $method $niter $tnum $l $t $args + foreach m $metaopts { + foreach l $logsets { + puts "Rep$tnum ($method $t $m $args): Test of\ + internal init with missing db file $msg\ + $msg2." + puts "Rep$tnum: Master logs are [lindex $l 0]" + puts "Rep$tnum: Client logs are [lindex $l 1]" + rep081_sub $method $niter $tnum $l $t $m $args + } } } } -proc rep081_sub { method niter tnum logset testopt largs } { +proc rep081_sub { method niter tnum logset testopt metaopt largs } { global testdir global util_path global databases_in_memory @@ -105,6 +109,15 @@ proc rep081_sub { method niter tnum logset testopt largs } { file mkdir $masterdir file mkdir $clientdir + set meta_diropts "" + set meta_dir "" + if { $metaopt == "metadir" } { + set meta_dir "meta" + file mkdir $masterdir/$meta_dir + file mkdir $clientdir/$meta_dir + set meta_diropts "-metadata_dir $meta_dir" + } + # Log size is small so we quickly create more than one. # The documentation says that the log file must be at least # four times the size of the in-memory log buffer. @@ -125,7 +138,7 @@ proc rep081_sub { method niter tnum logset testopt largs } { repladd 1 set ma_envcmd "berkdb_env_noerr -create $m_txnargs $repmemargs \ $m_logargs -log_max $log_max -errpfx MASTER $verbargs \ - -home $masterdir -rep_transport \[list 1 replsend\]" + $meta_diropts -home $masterdir -rep_transport \[list 1 replsend\]" set masterenv [eval $ma_envcmd -rep_master] $masterenv rep_limit 0 0 @@ -177,7 +190,7 @@ proc rep081_sub { method niter tnum logset testopt largs } { repladd 2 set cl_envcmd "berkdb_env_noerr -create $c_txnargs $repmemargs \ $c_logargs -log_max $log_max -errpfx CLIENT $verbargs \ - -home $clientdir -rep_transport \[list 2 replsend\]" + $meta_diropts -home $clientdir -rep_transport \[list 2 replsend\]" set clientenv [eval $cl_envcmd -rep_client] $clientenv rep_limit 0 0 set envlist "{$masterenv 1} {$clientenv 2}" @@ -220,10 +233,22 @@ proc rep081_sub { method niter tnum logset testopt largs } { # Internal init file is very transient, but exists in # the rep files on-disk case during the second iteration # of this loop. Take this chance to make sure the internal - # init file doesn't exist when rep files are in-memory. - if { $i == 1 && $repfiles_in_memory == 1 } { - error_check_good noinit \ - [file exists "$clientdir/__db.rep.init"] 0 + # init file doesn't exist when rep files are in-memory, or + # that it exists in the correct location when rep files are + # on-disk. + if { $i == 1 } { + if { $repfiles_in_memory == 1 } { + error_check_good noinit \ + [file exists "$clientdir/__db.rep.init"] 0 + } else { + if { $meta_dir == "" } { + set chkdir "$clientdir" + } else { + set chkdir "$clientdir/$meta_dir" + } + error_check_good initfile \ + [file exists "$chkdir/__db.rep.init"] 1 + } } # # When we are in internal init, remove the mdb database file. diff --git a/test/tcl/rep082.tcl b/test/tcl/rep082.tcl index ab6eabf4..d33cb5e2 100644 --- a/test/tcl/rep082.tcl +++ b/test/tcl/rep082.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep082 # TEST Sending replication requests to correct master site. diff --git a/test/tcl/rep083.tcl b/test/tcl/rep083.tcl index db90cb05..d762aa8a 100644 --- a/test/tcl/rep083.tcl +++ b/test/tcl/rep083.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep083 # TEST Replication clients must never send VERIFY_FAIL to a c2c request. diff --git a/test/tcl/rep084.tcl b/test/tcl/rep084.tcl index aa2158f3..6b6c0a7e 100644 --- a/test/tcl/rep084.tcl +++ b/test/tcl/rep084.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep084 # TEST Abbreviated internal init for named in-memory databases (NIMDBs). diff --git a/test/tcl/rep085.tcl b/test/tcl/rep085.tcl index 1c8628a5..aae94675 100644 --- a/test/tcl/rep085.tcl +++ b/test/tcl/rep085.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep085 # TEST Skipping unnecessary abbreviated internal init. diff --git a/test/tcl/rep086.tcl b/test/tcl/rep086.tcl index ace91a13..04207db5 100644 --- a/test/tcl/rep086.tcl +++ b/test/tcl/rep086.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep086 # TEST Interrupted abbreviated internal init. diff --git a/test/tcl/rep087.tcl b/test/tcl/rep087.tcl index 09ea3daf..653e29c8 100644 --- a/test/tcl/rep087.tcl +++ b/test/tcl/rep087.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep087 # TEST Abbreviated internal init with open file handles. diff --git a/test/tcl/rep088.tcl b/test/tcl/rep088.tcl index 0f99cce6..ebaa554c 100644 --- a/test/tcl/rep088.tcl +++ b/test/tcl/rep088.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep088 # TEST Replication roll-back preserves checkpoint. diff --git a/test/tcl/rep089.tcl b/test/tcl/rep089.tcl index 8ad4214c..825d69c6 100644 --- a/test/tcl/rep089.tcl +++ b/test/tcl/rep089.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep089 # TEST Test of proper clean-up of mpool during interrupted internal init. diff --git a/test/tcl/rep090.tcl b/test/tcl/rep090.tcl index 98f83585..36b42043 100644 --- a/test/tcl/rep090.tcl +++ b/test/tcl/rep090.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep091.tcl b/test/tcl/rep091.tcl index 247fe4dc..36fa18ca 100644 --- a/test/tcl/rep091.tcl +++ b/test/tcl/rep091.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep091 # TEST Read-your-writes consistency. diff --git a/test/tcl/rep092.tcl b/test/tcl/rep092.tcl index 6eda2bd1..e8d59ed2 100644 --- a/test/tcl/rep092.tcl +++ b/test/tcl/rep092.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep092 # TEST Read-your-writes consistency. diff --git a/test/tcl/rep092script.tcl b/test/tcl/rep092script.tcl index f1dbc64a..73d19c25 100644 --- a/test/tcl/rep092script.tcl +++ b/test/tcl/rep092script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # Rep092 script - multi-thread wake-ups in checking read-your-writes # consistency. diff --git a/test/tcl/rep093.tcl b/test/tcl/rep093.tcl index 46f339f7..9855ee45 100644 --- a/test/tcl/rep093.tcl +++ b/test/tcl/rep093.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep093 # TEST Egen changes during election. diff --git a/test/tcl/rep094.tcl b/test/tcl/rep094.tcl index dd59c608..4bfcfe65 100644 --- a/test/tcl/rep094.tcl +++ b/test/tcl/rep094.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST rep094 # TEST Full election with less than majority initially connected. diff --git a/test/tcl/rep095.tcl b/test/tcl/rep095.tcl index 9cc3414f..1e4e67e2 100644 --- a/test/tcl/rep095.tcl +++ b/test/tcl/rep095.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep095script.tcl b/test/tcl/rep095script.tcl index 1d7269a1..8db8f72f 100644 --- a/test/tcl/rep095script.tcl +++ b/test/tcl/rep095script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep096.tcl b/test/tcl/rep096.tcl index 0df6cda0..b9ce9db1 100644 --- a/test/tcl/rep096.tcl +++ b/test/tcl/rep096.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep097.tcl b/test/tcl/rep097.tcl index 13b3189d..3af95d9d 100644 --- a/test/tcl/rep097.tcl +++ b/test/tcl/rep097.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep097script.tcl b/test/tcl/rep097script.tcl index 7073619f..7e6b84d1 100644 --- a/test/tcl/rep097script.tcl +++ b/test/tcl/rep097script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rep098.tcl b/test/tcl/rep098.tcl index b1474246..7fcfbbd7 100644 --- a/test/tcl/rep098.tcl +++ b/test/tcl/rep098.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -121,8 +121,8 @@ proc rep098_sub { method niter tnum logset recargs largs } { set c_logtype [lindex $logset 1] # In-memory logs cannot be used with -txn nosync. - set m_logargs [adjust_logargs $m_logtype] - set c_logargs [adjust_logargs $c_logtype] + set m_logargs [adjust_logargs $m_logtype 1048576] + set c_logargs [adjust_logargs $c_logtype 1048576] set m_txnargs [adjust_txnargs $m_logtype] set c_txnargs [adjust_txnargs $c_logtype] diff --git a/test/tcl/rep099.tcl b/test/tcl/rep099.tcl new file mode 100644 index 00000000..939c5b6e --- /dev/null +++ b/test/tcl/rep099.tcl @@ -0,0 +1,375 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST rep099 +# TEST Test of multiple data dirs and databases, both active replication +# TEST and internal init. +# TEST +# TEST One master, two clients using several data_dirs. +# TEST Create databases in different data_dirs. Replicate to client. +# TEST Add 2nd client later to require it to catch up via internal init. +# +proc rep099 { method { niter 500 } { tnum "099" } args } { + source ./include.tcl + global databases_in_memory + global repfiles_in_memory + global env_private + + # Valid for all access methods. + if { $checking_valid_methods } { + return "ALL" + } + + set args [convert_args $method $args] + set logsets [create_logsets 3] + + # This test needs to set its own pagesize. + set pgindex [lsearch -exact $args "-pagesize"] + if { $pgindex != -1 } { + puts "Rep$tnum: skipping for specific pagesizes" + return + } + + # This test needs on-disk databases. + if { $databases_in_memory } { + puts "Rep$tnum: skipping for in-memory databases" + return + } + set msg "using on-disk databases" + + set msg2 "and on-disk replication files" + if { $repfiles_in_memory } { + set msg2 "and in-memory replication files" + } + + set msg3 "" + if { $env_private } { + set msg3 "with private env" + } + + # + # Run the body of the test with and without recovery, + # and with varying directory configurations: + # datadir: rep files in db_home, databases in data0/data1/data2 + # repdir: rep files in meta, databases in db_home + # both: rep files in meta, databases in data0/data1/data2 + # overlap0: rep files in data0, databases in data0/data1/data2 + # overlap1: rep files in data1, databases in data0/data1/data2 + # overlap2: rep files in data2, databases in data0/data1/data2 + # + set opts { datadir repdir both overlap0 overlap1 overlap2 } + foreach r $test_recopts { + foreach c $opts { + foreach l $logsets { + set logindex [lsearch -exact $l "in-memory"] + if { $r == "-recover" && $logindex != -1 } { + puts "Skipping rep$tnum for -recover\ + with in-memory logs." + continue + } + puts "Rep$tnum ($method $r $c):\ + Multiple databases in multiple data_dirs \ + $msg $msg2 $msg3." + puts "Rep$tnum: Master logs are [lindex $l 0]" + puts "Rep$tnum: Client logs are [lindex $l 1]" + puts "Rep$tnum: Client2 logs are [lindex $l 2]" + rep099_sub $method $niter $tnum $l $r $c $args + } + } + } +} + +proc rep099_sub { method niter tnum logset recargs opts largs } { + global testdir + global util_path + global repfiles_in_memory + global env_private + global rep_verbose + global verbose_type + + set verbargs "" + if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " + } + + set repmemargs "" + if { $repfiles_in_memory } { + set repmemargs "-rep_inmem_files " + } + + set privargs "" + if { $env_private == 1 } { + set privargs " -private " + } + + env_cleanup $testdir + + replsetup $testdir/MSGQUEUEDIR + + set masterdir $testdir/MASTERDIR + set clientdir $testdir/CLIENTDIR + set clientdir2 $testdir/CLIENTDIR2 + set newdir $testdir/NEWDIR + + file mkdir $masterdir + file mkdir $newdir + file mkdir $clientdir + file mkdir $clientdir2 + + # Log size is small so we quickly create more than one. + # The documentation says that the log file must be at least + # four times the size of the in-memory log buffer. + set pagesize 4096 + append largs " -pagesize $pagesize " + set log_max [expr $pagesize * 8] + set omethod [convert_method $method] + + set m_logtype [lindex $logset 0] + set c_logtype [lindex $logset 1] + set c2_logtype [lindex $logset 2] + + # In-memory logs cannot be used with -txn nosync. + set m_logargs [adjust_logargs $m_logtype] + set c_logargs [adjust_logargs $c_logtype] + set c2_logargs [adjust_logargs $c2_logtype] + set m_txnargs [adjust_txnargs $m_logtype] + set c_txnargs [adjust_txnargs $c_logtype] + set c2_txnargs [adjust_txnargs $c2_logtype] + + # Set up data directories for the various configurations. + set create_dirs {} + set nfiles 0 + set data_diropts "" + if { $opts == "repdir" } { + set nfiles 1 + } else { + set create_dirs {data0 data1 data2} + foreach d $create_dirs { + incr nfiles + file mkdir $masterdir/$d + file mkdir $clientdir/$d + file mkdir $clientdir2/$d + file mkdir $newdir/$d + lappend data_diropts -data_dir + lappend data_diropts $d + } + } + + # Set up metadata directory for all configurations except "datadir", + # which doesn't have one. + set meta_diropts "" + set meta_dir "" + switch $opts { + "repdir" - + "both" { + set meta_dir "meta" + file mkdir $masterdir/$meta_dir + file mkdir $clientdir/$meta_dir + file mkdir $clientdir2/$meta_dir + file mkdir $newdir/$meta_dir + } + "overlap0" { set meta_dir "data0" } + "overlap1" { set meta_dir "data1" } + "overlap2" { set meta_dir "data2" } + } + if { $opts != "datadir" } { + set meta_diropts "-metadata_dir $meta_dir" + } + + # Open a master. + repladd 1 + set ma_envcmd "berkdb_env_noerr -create $m_txnargs \ + $repmemargs $privargs $meta_diropts \ + $m_logargs -log_max $log_max -errpfx MASTER \ + $data_diropts $verbargs \ + -home $masterdir -rep_transport \[list 1 replsend\]" + set masterenv [eval $ma_envcmd $recargs -rep_master] + + # Open a client + repladd 2 + set cl_envcmd "berkdb_env_noerr -create $c_txnargs \ + $repmemargs $privargs $meta_diropts \ + $c_logargs -log_max $log_max -errpfx CLIENT \ + $data_diropts $verbargs \ + -home $clientdir -rep_transport \[list 2 replsend\]" + set clientenv [eval $cl_envcmd $recargs -rep_client] + + # Bring the client online by processing the startup messages. + set envlist "{$masterenv 1} {$clientenv 2}" + process_msgs $envlist + + # Clobber replication's 30-second anti-archive timer, which will have + # been started by client sync-up internal init, so that we can do a + # log_archive in a moment. + # + $masterenv test force noarchive_timeout + + # + # Create a database in each data_dir and add some data to it. + # Run rep_test in the master (and update client). + # This is broken up into two loops because we want all of the + # file creations done first so that they're all in the first + # log file. Later archiving will then remove all creation records. + # + puts "\tRep$tnum.a.0: Running rep_test $nfiles times in replicated env." + set dbopen "" + if { $opts == "repdir" } { + set dbname "dbdata.db" + set db(0) [eval {berkdb_open_noerr -env $masterenv \ + -auto_commit -create -mode 0644} $largs $omethod $dbname] + } else { + for { set i 0 } { $i < $nfiles } { incr i } { + set crdir [lindex $create_dirs $i] + set dbname "db$crdir.db" + set db($i) [eval {berkdb_open_noerr -env $masterenv \ + -auto_commit -create -create_dir $crdir \ + -mode 0644} $largs $omethod $dbname] + } + } + for { set i 0 } { $i < $nfiles } { incr i } { + set mult [expr $i * 10] + set nentries [expr $niter + $mult] + eval rep_test $method $masterenv $db($i) $nentries $mult $mult \ + 0 $largs + process_msgs $envlist + } + + # + # Check that the database creation replicated to the correct data_dir. + # + puts "\tRep$tnum.b: Check create_dirs properly replicated." + rep099_dir_verify $nfiles $clientdir $create_dirs $opts + + # + # Check that running recovery from full log files recreates + # correctly. This can only be done from on-disk log files. + # NOTE: This part of the test has nothing to do with replication + # but is a good thing to test and is easy to do here. + # + if { $m_logtype == "on-disk" } { + puts "\tRep$tnum.c: Check create_dirs properly recovered." + set lfiles [glob -nocomplain $masterdir/log.*] + foreach lf $lfiles { + set fname [file tail $lf] + file copy $lf $newdir/$fname + } + set stat [catch {exec $util_path/db_recover -c -h $newdir} result] + rep099_dir_verify $nfiles $newdir $create_dirs $opts + } + + # + # Now check that a client that is initialized via internal init + # correctly recreates the data_dir structure. + # + puts "\tRep$tnum.d: Initialize client2 via internal init." + # + # First make sure the master moves beyond log file 1. + # + set firstlf [get_logfile $masterenv first] + $masterenv log_archive -arch_remove + while { [get_logfile $masterenv first] <= $firstlf } { + eval rep_test $method $masterenv $db(0) $nentries $mult $mult \ + 0 $largs + process_msgs $envlist + incr mult $nentries + $masterenv log_archive -arch_remove + } + + # + # Now that we've archived, start up the 2nd client. + # + repladd 3 + set cl2_envcmd "berkdb_env_noerr -create $c2_txnargs \ + $repmemargs $privargs $meta_diropts \ + $c2_logargs -log_max $log_max -errpfx CLIENT2 \ + $data_diropts $verbargs \ + -home $clientdir2 -rep_transport \[list 3 replsend\]" + set client2env [eval $cl2_envcmd $recargs -rep_client] + + # Bring the client online by processing the startup messages. + set envlist "{$masterenv 1} {$clientenv 2} {$client2env 3}" + process_msgs $envlist + + # Now that internal init is complete, check the file locations. + rep099_dir_verify $nfiles $clientdir2 $create_dirs $opts + + for { set i 0 } { $i < $nfiles } { incr i } { + error_check_good db_close [$db($i) close] 0 + } + + puts "\tRep$tnum.e: Location check for all envs." + check_log_location $masterenv + check_log_location $clientenv + check_log_location $client2env + + puts "\tRep$tnum.f: Check location of persistent rep files." + if { !$repfiles_in_memory } { + check_persistent_rep_files $masterdir $meta_dir + check_persistent_rep_files $clientdir $meta_dir + check_persistent_rep_files $clientdir2 $meta_dir + } + if { $opts != "datadir" } { + error_check_good getmdd [$masterenv get_metadata_dir] $meta_dir + } + + # Make sure there are no rep files in the data + # directories. Even when rep files are on disk, + # they should be in the env's home directory. + foreach d $create_dirs { + # Check that databases are in-memory or on-disk as expected. + check_db_location $masterenv $d + check_db_location $clientenv $d + check_db_location $client2env $d + + # Check no rep files in data dirs in non-overlapping configs. + if { $opts == "datadir" || $opts == "both" } { + no_rep_files_on_disk $masterdir/$d + no_rep_files_on_disk $clientdir/$d + no_rep_files_on_disk $clientdir2/$d + } + } + # create_dirs is empty for repdir, so check repdir separately. Can't + # perform no_rep_files_on_disk because database location (db_home) + # also contains non-persistent metadata files. + if { $opts == "repdir" } { + check_db_location $masterenv "" + check_db_location $clientenv "" + check_db_location $client2env "" + } + error_check_good masterenv_close [$masterenv close] 0 + error_check_good clientenv_close [$clientenv close] 0 + error_check_good clientenv2_close [$client2env close] 0 + replclose $testdir/MSGQUEUEDIR +} + +proc rep099_dir_verify { nfiles checkdir create_dirs opts } { + if { $opts == "repdir" } { + set dbname "dbdata.db" + error_check_good db_0 [file exists $checkdir/$dbname] 1 + } else { + for { set i 0 } { $i < $nfiles } { incr i } { + set crdir [lindex $create_dirs $i] + set dbname "db$crdir.db" + error_check_good db_$crdir \ + [file exists $checkdir/$crdir/$dbname] 1 + } + } +} + +proc check_persistent_rep_files { dir metadir } { + if { $metadir == "" } { + set checkdir "$dir" + } else { + set checkdir "$dir/$metadir" + } + # + # Cannot check for persistent file __db.rep.init because it is not + # there most of the time. + # + error_check_good gen [file exists "$checkdir/__db.rep.gen"] 1 + error_check_good egen [file exists "$checkdir/__db.rep.egen"] 1 + error_check_good sysdb [file exists "$checkdir/__db.rep.system"] 1 +} diff --git a/test/tcl/rep100.tcl b/test/tcl/rep100.tcl new file mode 100644 index 00000000..5076f0d7 --- /dev/null +++ b/test/tcl/rep100.tcl @@ -0,0 +1,203 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST rep100 +# TEST Checkpoints and unresolved txns +# TEST +proc rep100 { method { niter 10 } { tnum "100" } args } { + source ./include.tcl + global repfiles_in_memory + + # Run for all access methods. + if { $checking_valid_methods } { + return "ALL" + } + + set args [convert_args $method $args] + set logsets [create_logsets 2] + + set msg2 "and on-disk replication files" + if { $repfiles_in_memory } { + set msg2 "and in-memory replication files" + } + + # Run the body of the test with and without recovery. + foreach r $test_recopts { + foreach l $logsets { + set logindex [lsearch -exact $l "in-memory"] + if { $logindex != -1 } { + puts "Rep$tnum: Skipping for in-memory logs." + continue + } + + puts "Rep$tnum ($method $r):\ + Checkpoints and unresolved txns $msg2." + puts "Rep$tnum: Master logs are [lindex $l 0]" + puts "Rep$tnum: Client logs are [lindex $l 1]" + rep100_sub $method $niter $tnum $l $r $args + } + } +} + +proc rep100_sub { method niter tnum logset recargs largs } { + source ./include.tcl + global perm_response_list + global repfiles_in_memory + global rep_verbose + global verbose_type + + set verbargs "" + if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " + } + + set repmemargs "" + if { $repfiles_in_memory } { + set repmemargs "-rep_inmem_files " + } + + env_cleanup $testdir + set omethod [convert_method $method] + + replsetup $testdir/MSGQUEUEDIR + + set masterdir $testdir/MASTERDIR + set clientdir $testdir/CLIENTDIR + + file mkdir $masterdir + file mkdir $clientdir + set m_logtype [lindex $logset 0] + set c_logtype [lindex $logset 1] + + # Since we're sure to be using on-disk logs, txnargs will be -txn nosync. + set m_logargs [adjust_logargs $m_logtype] + set c_logargs [adjust_logargs $c_logtype] + set m_txnargs [adjust_txnargs $m_logtype] + set c_txnargs [adjust_txnargs $c_logtype] + + # Open a master. + repladd 1 + set ma_cmd "berkdb_env_noerr -create $verbargs \ + -log_max 1000000 $m_txnargs $m_logargs $repmemargs \ + -home $masterdir -rep_master -errpfx MASTER \ + -rep_transport \[list 1 replsend\]" + set masterenv [eval $ma_cmd $recargs] + + # Open a client + repladd 2 + set cl_cmd "berkdb_env_noerr -create -home $clientdir $verbargs \ + $c_txnargs $c_logargs -rep_client -errpfx CLIENT $repmemargs \ + -rep_transport \[list 2 replsend\]" + set clientenv [eval $cl_cmd $recargs] + + # Bring the client online. + process_msgs "{$masterenv 1} {$clientenv 2}" + + # Open database in master, make lots of changes so checkpoint + # will take a while, and propagate to client. + puts "\tRep$tnum.a: Create and populate database." + set dbname rep100.db + set dbname1 rep100_1.db + set db [eval "berkdb_open_noerr -create $omethod -auto_commit \ + -env $masterenv $largs $dbname"] + set db1 [eval "berkdb_open_noerr -create $omethod -auto_commit \ + -env $masterenv $largs $dbname1"] + for { set i 1 } { $i <= $niter } { incr i } { + set t [$masterenv txn] + error_check_good db_put \ + [eval $db put -txn $t $i [chop_data $method data$i]] 0 + error_check_good db1_put \ + [eval $db1 put -txn $t $i [chop_data $method data$i]] 0 + error_check_good txn_commit [$t commit] 0 + } + process_msgs "{$masterenv 1} {$clientenv 2}" 1 + + # Get the master's last LSN before the checkpoint + set pre_ckp_offset \ + [stat_field $masterenv log_stat "Current log file offset"] + + puts "\tRep$tnum.b: Checkpoint on master." + error_check_good checkpoint [$masterenv txn_checkpoint] 0 + process_msgs "{$masterenv 1} {$clientenv 2}" + + # + # We want to generate a checkpoint that is mid-txn on the master, + # but is mid-txn on a different txn on the client because the + # client is behind the master. We want to make sure we don't + # get a Log sequence error on recovery. The sequence of steps is: + # + # Open a txn T1 on the master. Made a modification. + # Open a 2nd txn T2 on the master and make a modification for that txn. + # Replicate all of the above to the client. + # Make another modification to T1. + # Commit T1 but do not replicate to the client (i.e. lose those records). + # Checkpoint on the master and replicate to client. + # This should cause the client to sync pages but not the pages that + # modify T1 because its commit hasn't appeared yet, even though it + # has committed on the master. + # Commit T2 + # Crash client and run recovery. + # + set start $niter + set end [expr $niter * 2] + + # Open txn T1 and make a modification. + puts "\tRep$tnum.c: Open txn t1 and do an update." + set i $start + set t1 [$masterenv txn] + error_check_good db_put \ + [eval $db1 put -txn $t1 $i [chop_data $method data$i]] 0 + + # Open a 2nd txn T2 on the master and make a modification in that txn. + # Replicate all to the client. + puts "\tRep$tnum.d: Open txn T2." + set t2 [$masterenv txn] + + error_check_good db_put \ + [eval $db put -txn $t2 $end [chop_data $method data$end]] 0 + process_msgs "{$masterenv 1} {$clientenv 2}" + + # Make another modification to T1. + # Commit T1 but do not replicate to the client (i.e. lose that record). + puts "\tRep$tnum.e: Update and commit T1, clear msgs for client." + error_check_good db_put \ + [eval $db1 put -txn $t1 $i [chop_data $method data$end]] 0 + error_check_good txn_commit [$t1 commit] 0 + replclear 2 + + # Checkpoint on the master and replicate to client. + puts "\tRep$tnum.f: Checkpoint and replicate messages." + error_check_good checkpoint [$masterenv txn_checkpoint] 0 + process_msgs "{$masterenv 1} {$clientenv 2}" + + # + # Commit T2. We have to sleep enough time so that the client + # will rerequest and catch up when it receives these records. + # + puts "\tRep$tnum.g: Sleep, commit T2 and catch client up." + tclsleep 2 + error_check_good txn_commit [$t2 commit] 0 + process_msgs "{$masterenv 1} {$clientenv 2}" + + # + # At this point the client has all outstanding log records that + # have been written by the master. So everything should be okay. + # + puts "\tRep$tnum.h: Abandon clientenv and reopen with recovery." + # "Crash" client (by abandoning its env) and run recovery. + set clientenv_new [eval $cl_cmd -recover] + + # Clean up. + puts "\tRep$tnum.i: Clean up." + error_check_good db_close [$db close] 0 + error_check_good db_close [$db1 close] 0 + error_check_good masterenv_close [$masterenv close] 0 + error_check_good clientenv_close [$clientenv_new close] 0 + # Clean up abandoned handle. + catch {$clientenv close} + + replclose $testdir/MSGQUEUEDIR +} diff --git a/test/tcl/rep101.tcl b/test/tcl/rep101.tcl new file mode 100644 index 00000000..24c28804 --- /dev/null +++ b/test/tcl/rep101.tcl @@ -0,0 +1,303 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST rep101 +# TEST Test of exclusive access to databases and HA. +# TEST Confirm basic functionality with master and client. +# TEST Confirm excl access after checkpoint and archive. +# TEST Confirm internal init with open excl databases. +# TEST +proc rep101 { method { niter 100 } { tnum "101" } args } { + source ./include.tcl + global repfiles_in_memory + + # Run for just btree. + if { $checking_valid_methods } { + return "btree" + } + + if { [is_btree $method] == 0 } { + puts "Rep$tnum: skipping for non-btree method $method." + return + } + + set args [convert_args $method $args] + set logsets [create_logsets 4] + + set msg2 "and on-disk replication files" + if { $repfiles_in_memory } { + set msg2 "and in-memory replication files" + } + + # Run the body of the test with and without recovery. + foreach r $test_recopts { + foreach l $logsets { + set logindex [lsearch -exact $l "in-memory"] + if { $logindex != -1 } { + puts "Rep$tnum: Skipping for in-memory logs." + continue + } + + puts "Rep$tnum ($method $r): Exclusive databases and HA." + puts "Rep$tnum: Master logs are [lindex $l 0]" + puts "Rep$tnum: Client logs are [lindex $l 1]" + puts "Rep$tnum: Client2 logs are [lindex $l 2]" + puts "Rep$tnum: Client3 logs are [lindex $l 3]" + rep101_sub $method $niter $tnum $l $r $args + } + } +} + +proc rep101_sub { method niter tnum logset recargs largs } { + source ./include.tcl + global databases_in_memory + global repfiles_in_memory + global rep_verbose + global verbose_type + + set verbargs "" + if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " + } + + set repmemargs "" + if { $repfiles_in_memory } { + set repmemargs "-rep_inmem_files " + } + + env_cleanup $testdir + set omethod [convert_method $method] + + replsetup $testdir/MSGQUEUEDIR + + set masterdir $testdir/MASTERDIR + set clientdir $testdir/CLIENTDIR + set clientdir2 $testdir/CLIENTDIR2 + set clientdir3 $testdir/CLIENTDIR3 + + file mkdir $masterdir + file mkdir $clientdir + file mkdir $clientdir2 + file mkdir $clientdir3 + + # Log size is small so we quickly create more than one. + # The documentation says that the log file must be at least + # four times the size of the in-memory log buffer. + set pagesize 4096 + append largs " -pagesize $pagesize " + set log_max [expr $pagesize * 8] + + set m_logtype [lindex $logset 0] + set c_logtype [lindex $logset 1] + set c2_logtype [lindex $logset 2] + set c3_logtype [lindex $logset 3] + + # Since we're sure to be using on-disk logs, txnargs will be -txn nosync. + set m_logargs [adjust_logargs $m_logtype] + set c_logargs [adjust_logargs $c_logtype] + set c2_logargs [adjust_logargs $c2_logtype] + set c3_logargs [adjust_logargs $c3_logtype] + set m_txnargs [adjust_txnargs $m_logtype] + set c_txnargs [adjust_txnargs $c_logtype] + set c2_txnargs [adjust_txnargs $c2_logtype] + set c3_txnargs [adjust_txnargs $c3_logtype] + + # Open a master. + repladd 1 + set ma_cmd "berkdb_env_noerr -create $verbargs \ + -log_max $log_max $m_txnargs $m_logargs $repmemargs \ + -home $masterdir -rep_master -errpfx MASTER \ + -rep_transport \[list 1 replsend\]" + set masterenv [eval $ma_cmd $recargs] + + # Open some clients + repladd 2 + set cl_cmd "berkdb_env_noerr -create -home $clientdir $verbargs \ + $c_txnargs $c_logargs -rep_client -errpfx CLIENT $repmemargs \ + -log_max $log_max -rep_transport \[list 2 replsend\]" + set clientenv [eval $cl_cmd $recargs] + + repladd 3 + set cl2_cmd "berkdb_env_noerr -create -home $clientdir2 $verbargs \ + $c2_txnargs $c2_logargs -rep_client -errpfx CLIENT2 $repmemargs \ + -log_max $log_max -rep_transport \[list 3 replsend\]" + set clientenv2 [eval $cl2_cmd $recargs] + + # + # Set up the command but don't do the repladd nor open the + # environment until we need it. + # + set cl3_cmd "berkdb_env_noerr -create -home $clientdir3 $verbargs \ + $c3_txnargs $c3_logargs -rep_client -errpfx CLIENT3 $repmemargs \ + -log_max $log_max -rep_transport \[list 4 replsend\]" + + # + # Need this so that clientenv2 does not later need an internal + # init because we must match while having a checkpoint in the log. + # + $masterenv txn_checkpoint -force + + # Bring the clients online. + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + # Close client2. We want it later to synchronize with the + # master, but not doing an internal init. That is, we want + # to test that running sync-up recovery does the right thing + # regarding exclusive databases. + $clientenv2 log_flush + error_check_good env_close [$clientenv2 close] 0 + + # Open exclusive database in master. Process messages to client1. + # Confirm client cannot open the database. + puts "\tRep$tnum.a: Running rep_test to exclusive db." + set start 0 + if { $databases_in_memory } { + set testfile { "" "test.db" } + } else { + set testfile "test.db" + } + set omethod [convert_method $method] + set dbargs [convert_args $method $largs] + set mdb [eval {berkdb_open} -env $masterenv -auto_commit -create $omethod \ + -lk_exclusive 0 -mode 0644 $dbargs $testfile ] + error_check_good reptest_db [is_valid_db $mdb] TRUE + + eval rep_test\ + $method $masterenv $mdb $niter $start $start 0 $largs + incr start $niter + process_msgs "{$masterenv 1} {$clientenv 2}" + + puts "\tRep$tnum.a.1: Confirm client cannot access excl db." + rep_client_access $clientenv $testfile FAIL + + # Open client2 with recovery. + replclear 3 + puts "\tRep$tnum.a.2: Confirm client2 cannot access excl db after start." + set clientenv2 [eval $cl2_cmd -recover] + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + rep_client_access $clientenv2 $testfile FAIL + + puts "\tRep$tnum.a.3: Close excl database and confirm client access." + error_check_good dbclose [$mdb close] 0 + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + # Only need to check on one client. + rep_client_access $clientenv $testfile SUCCESS + + puts "\tRep$tnum.b: Confirm checkpoints and archiving." + puts "\tRep$tnum.b.1: Reopen excl db and move log forward." + set mdb [eval {berkdb_open} -env $masterenv -auto_commit $omethod \ + -lk_exclusive 0 -mode 0644 $dbargs $testfile ] + error_check_good reptest_db [is_valid_db $mdb] TRUE + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + # + # Test here that processing the open log records from the master + # (as opposed to the create-then-open log records the master + # originally wrote for exclusive access) also works to + # provide exclusive access. Testing one client is sufficient. + # + rep_client_access $clientenv2 $testfile FAIL + + # + # Clobber replication's 30 second anti-archive timer. + $masterenv test force noarchive_timeout + + # + # We want to move all sites forward, beyond log file 1, and + # then archive the logs to remove the exclusive creation and + # open records from the log. This entire test section tests + # the ability to restore the exclusive property from just + # running recovery with checkpoint records in the log. + # + set stop 0 + set orig_master_last [get_logfile $masterenv last] + while { $stop == 0 } { + # Run rep_test in the master beyond the first log file. + eval rep_test\ + $method $masterenv $mdb $niter $start $start 0 $largs + incr start $niter + + puts "\tRep$tnum.b.2: Run db_archive on master." + if { $m_logtype == "on-disk" } { + $masterenv log_flush + $masterenv log_archive -arch_remove + } + # + # Make sure we have moved beyond the master's original logs. + # + set curr_master_first [get_logfile $masterenv first] + if { $curr_master_first > $orig_master_last } { + set stop 1 + } + } + puts "\tRep$tnum.b.3: Run db_archive on clients." + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + eval exec $util_path/db_archive -d -h $clientdir + eval exec $util_path/db_archive -d -h $clientdir2 + + # + # Client2 is now in a state where it no longer has the + # the original exclusive open of the database in the + # log. Open with recovery to force it to use checkpoint + # records and then run sync-up recovery. + puts "\tRep$tnum.b.4: Close client, do more txns, reopen client." + $clientenv2 log_flush + error_check_good env_close [$clientenv2 close] 0 + eval rep_test $method $masterenv $mdb $niter $start $start 0 $largs + incr start $niter + replclear 3 + process_msgs "{$masterenv 1} {$clientenv 2}" + set clientenv2 [eval $cl2_cmd -recover] + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + puts "\tRep$tnum.b.5: Confirm client cannot access excl db." + rep_client_access $clientenv2 $testfile FAIL + + # Close the client and then close the exclusive db. + # Confirm that when the client runs recovery it is able + # to access the database. + puts "\tRep$tnum.b.6: Confirm client recovery and closed excl db." + $clientenv2 log_flush + error_check_good env_close [$clientenv2 close] 0 + eval rep_test $method $masterenv $mdb $niter $start $start 0 $largs + incr start $niter + error_check_good dbclose [$mdb close] 0 + replclear 3 + process_msgs "{$masterenv 1} {$clientenv 2}" + set clientenv2 [eval $cl2_cmd -recover] + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3}" + + # + # Check both clients to make sure they can both now access the db. + # + rep_client_access $clientenv $testfile SUCCESS + rep_client_access $clientenv2 $testfile SUCCESS + + puts "\tRep$tnum.c: Add new client while excl db is open." + set mdb [eval {berkdb_open} -env $masterenv -auto_commit $omethod \ + -lk_exclusive 0 -mode 0644 $dbargs $testfile ] + error_check_good reptest_db [is_valid_db $mdb] TRUE + repladd 4 + set clientenv3 [eval $cl3_cmd $recargs] + eval rep_test $method $masterenv $mdb $niter $start $start 0 $largs + incr start $niter + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3} {$clientenv3 4}" + puts "\tRep$tnum.c.1: Confirm new client cannot access db." + rep_client_access $clientenv3 $testfile FAIL + puts "\tRep$tnum.c.2: Close db and confirm access." + error_check_good dbclose [$mdb close] 0 + process_msgs "{$masterenv 1} {$clientenv 2} {$clientenv2 3} {$clientenv3 4}" + rep_client_access $clientenv3 $testfile SUCCESS + + error_check_good masterenv_close [$masterenv close] 0 + error_check_good clientenv_close [$clientenv close] 0 + error_check_good clientenv_close [$clientenv2 close] 0 + error_check_good clientenv_close [$clientenv3 close] 0 + + replclose $testdir/MSGQUEUEDIR +} diff --git a/test/tcl/rep102.tcl b/test/tcl/rep102.tcl new file mode 100644 index 00000000..787c4896 --- /dev/null +++ b/test/tcl/rep102.tcl @@ -0,0 +1,186 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST rep102 +# TEST Test of exclusive access to databases and HA. +# TEST Master creates a database, writes some txns, and closes the db. +# TEST Client opens the database (in child process). +# TEST Master opens database exclusively. +# TEST Client tries to read database and gets HANDLE_DEAD. Closes db. +# TEST Client tries to reopen database and is blocked. +# TEST +proc rep102 { method { niter 10 } { tnum "102" } args } { + source ./include.tcl + global repfiles_in_memory + + # Run for just btree. + if { $checking_valid_methods } { + return "btree" + } + + if { [is_btree $method] == 0 } { + puts "Rep$tnum: skipping for non-btree method $method." + return + } + + set args [convert_args $method $args] + set logsets [create_logsets 2] + + set msg2 "and on-disk replication files" + if { $repfiles_in_memory } { + set msg2 "and in-memory replication files" + } + + # Run the body of the test with and without recovery. + foreach r $test_recopts { + foreach l $logsets { + set logindex [lsearch -exact $l "in-memory"] + if { $logindex != -1 } { + puts "Rep$tnum: Skipping for in-memory logs." + continue + } + + puts "Rep$tnum ($method $r): \ + Exclusive databases and HANDLE_DEAD." + puts "Rep$tnum: Master logs are [lindex $l 0]" + puts "Rep$tnum: Client logs are [lindex $l 1]" + rep102_sub $method $niter $tnum $l $r $args + } + } +} + +proc rep102_sub { method niter tnum logset recargs largs } { + source ./include.tcl + global databases_in_memory + global repfiles_in_memory + global rep_verbose + global verbose_type + + set verbargs "" + if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " + } + + set repmemargs "" + if { $repfiles_in_memory } { + set repmemargs "-rep_inmem_files " + } + + env_cleanup $testdir + set omethod [convert_method $method] + + replsetup $testdir/MSGQUEUEDIR + + set masterdir $testdir/MASTERDIR + set clientdir $testdir/CLIENTDIR + + file mkdir $masterdir + file mkdir $clientdir + + # Log size is small so we quickly create more than one. + # The documentation says that the log file must be at least + # four times the size of the in-memory log buffer. + set pagesize 4096 + append largs " -pagesize $pagesize " + set log_max [expr $pagesize * 8] + + set m_logtype [lindex $logset 0] + set c_logtype [lindex $logset 1] + + # Since we're sure to be using on-disk logs, txnargs will be -txn nosync. + set m_logargs [adjust_logargs $m_logtype] + set c_logargs [adjust_logargs $c_logtype] + set m_txnargs [adjust_txnargs $m_logtype] + set c_txnargs [adjust_txnargs $c_logtype] + + # Open a master. + repladd 1 + set ma_cmd "berkdb_env_noerr -create $verbargs \ + -log_max $log_max $m_txnargs $m_logargs $repmemargs \ + -home $masterdir -rep_master -errpfx MASTER \ + -rep_transport \[list 1 replsend\]" + set masterenv [eval $ma_cmd $recargs] + + # Open a client. + repladd 2 + set cl_cmd "berkdb_env_noerr -create -home $clientdir $verbargs \ + $c_txnargs $c_logargs -rep_client -errpfx CLIENT $repmemargs \ + -log_max $log_max -rep_transport \[list 2 replsend\]" + set clientenv [eval $cl_cmd $recargs] + + # Bring the client online. + process_msgs "{$masterenv 1} {$clientenv 2}" + + # Create database on master and process messages to client. + # Client (in script) will then open the database. + puts "\tRep$tnum.a: Running rep_test to non-exclusive db." + set start 0 + if { $databases_in_memory } { + set testfile { "" "test.db" } + } else { + set testfile "test.db" + } + set omethod [convert_method $method] + set dbargs [convert_args $method $largs] + set mdb [eval {berkdb_open} -env $masterenv -auto_commit -create $omethod \ + -mode 0644 $dbargs $testfile ] + error_check_good reptest_db [is_valid_db $mdb] TRUE + + eval rep_test\ + $method $masterenv $mdb $niter $start $start 0 $largs + error_check_good close [$mdb close] 0 + incr start $niter + process_msgs "{$masterenv 1} {$clientenv 2}" + + # Communicate with child process by creating a marker file. + set markerenv [berkdb_env_noerr -create -home $testdir -txn] + error_check_good markerenv_open [is_valid_env $markerenv] TRUE + set marker [eval "berkdb_open_noerr \ + -create -btree -auto_commit -env $markerenv marker.db"] + + # Fork child process. It should process whatever it finds in the + # message queue -- the remaining messages for the internal + # initialization. It is run in a separate process to test multiple + # processes using curinfo and originfo in the shared rep region. + # + puts "\tRep$tnum.b: Fork child process." + set pid [exec $tclsh_path $test_path/wrap.tcl \ + rep102script.tcl $testdir/repscript.log \ + $masterdir $clientdir $testfile $rep_verbose $verbose_type &] + + # Give child time to open environments to avoid lockout conflicts. + while { [llength [$marker get CHILDSETUP]] == 0 } { + tclsleep 1 + } + + puts "\tRep$tnum.c: Reopen database exclusively on master." + # + # Processing messages will hang until the client closes its handle. + # Signal the client the master is ready after we reopen. + # + set mdb [eval {berkdb_open} -env $masterenv -auto_commit $omethod \ + -lk_exclusive 0 -mode 0644 $dbargs $testfile ] + error_check_good reptest_db [is_valid_db $mdb] TRUE + error_check_good putpartinit [$marker put PARENTPARTINIT 1] 0 + process_msgs "{$masterenv 1} {$clientenv 2}" + + # Now wait for the child to finish. + puts "\tRep$tnum.d: Waiting for child to finish..." + # Watch until the script is done. + watch_procs $pid 10 + + puts "\tRep$tnum.e: Confirm client cannot access." + rep_client_access $clientenv $testfile FAIL + + error_check_good close [$mdb close] 0 + + error_check_good marker_close [$marker close] 0 + error_check_good markerenv_close [$markerenv close] 0 + error_check_good masterenv_close [$masterenv close] 0 + error_check_good clientenv_close [$clientenv close] 0 + replclose $testdir/MSGQUEUEDIR +} + diff --git a/test/tcl/rep102script.tcl b/test/tcl/rep102script.tcl new file mode 100644 index 00000000..cdf21737 --- /dev/null +++ b/test/tcl/rep102script.tcl @@ -0,0 +1,105 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# Rep102 script - HANDLE_DEAD and exclusive databases +# +# Repscript exists to open/close the exclusive database +# while a master is using it exclusively. This script +# requires a one-master and one-client setup. +# +# Usage: repscript masterdir clientdir rep_verbose verbose_type +# masterdir: master env directory +# clientdir: client env directory +# +source ./include.tcl +source $test_path/test.tcl +source $test_path/testutils.tcl +source $test_path/reputils.tcl + +set usage "repscript masterdir clientdir testfile rep_verbose verbose_type" + +# Verify usage +if { $argc != 5 } { + puts stderr "FAIL:[timestamp] Usage: $usage" + exit +} + +# Initialize arguments +set masterdir [ lindex $argv 0 ] +set clientdir [ lindex $argv 1 ] +set testfile [ lindex $argv 2 ] +set rep_verbose [ lindex $argv 3 ] +set verbose_type [ lindex $argv 4 ] +set verbargs "" +if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " +} + +# Join the queue env. We assume the rep test convention of +# placing the messages in $testdir/MSGQUEUEDIR. +set queueenv [eval berkdb_env -home $testdir/MSGQUEUEDIR] +error_check_good script_qenv_open [is_valid_env $queueenv] TRUE + +# We need to set up our own machids. +# Add 1 for master env id, and 2 for the clientenv id. +# +repladd 1 +repladd 2 + +# Join the master env. +set ma_cmd "berkdb_env_noerr -home $masterdir $verbargs \ + -txn -rep_master -rep_transport \[list 1 replsend\]" +set masterenv [eval $ma_cmd] +error_check_good script_menv_open [is_valid_env $masterenv] TRUE + +puts "Master open" + +# Join the client env. +set cl_cmd "berkdb_env_noerr -home $clientdir $verbargs \ + -txn -rep_client -rep_transport \[list 2 replsend\]" +set clientenv [eval $cl_cmd] +error_check_good script_cenv_open [is_valid_env $clientenv] TRUE + +puts "Everyone open. Now open $testfile" + +# Now open the database and hold the open database handle. +set t [$clientenv txn -nowait] +set cdb [eval {berkdb_open} -env $clientenv -txn $t $testfile] +error_check_good cdb_open [is_valid_db $db] TRUE +$t commit + +# Join the marker env/database and let parent know child is set up. +set markerenv [berkdb_env -home $testdir -txn] +error_check_good markerenv_open [is_valid_env $markerenv] TRUE +set marker [berkdb_open -unknown -env $markerenv -auto_commit marker.db] +error_check_good putchildsetup [$marker put CHILDSETUP 2] 0 + +# Give parent process time to start the internal init. +while { [llength [$marker get PARENTPARTINIT]] == 0 } { + tclsleep 1 +} + +# Sleep one more second to give parent process time to hang processing +# the messages. +tclsleep 1 + +# Try to access handle. Confirm it gets a dead handle. +puts "Client access gets DB_REP_HANDLE_DEAD." +set ret [catch {eval $cdb stat -faststat} res] +if { $ret == 0 } { + $cdb close + error "Looking for DB_REP_HANDLE_DEAD: got $res" +} +error_check_good cdb_stat $ret 1 +error_check_good cdb_stat_err [is_substr $res "DB_REP_HANDLE_DEAD"] 1 +error_check_good cdb_close [$cdb close] 0 + +# Close everything. +error_check_good marker_db_close [$marker close] 0 +error_check_good market_env_close [$markerenv close] 0 +error_check_good script_master_close [$masterenv close] 0 +error_check_good script_client_close [$clientenv close] 0 +puts "Repscript completed successfully" diff --git a/test/tcl/repmgr001.tcl b/test/tcl/repmgr001.tcl index 9059a0e5..ea82be42 100644 --- a/test/tcl/repmgr001.tcl +++ b/test/tcl/repmgr001.tcl @@ -1,7 +1,7 @@ # # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -102,10 +102,6 @@ proc basic_repmgr_test { niter inmemdb inmemlog \ print_repmgr_headers basic_repmgr_test $niter $inmemdb \ $inmemlog $inmemrep $envprivate $bulk - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tBasic repmgr test.a: Start an appointed master." set ma_envcmd "berkdb_env_noerr -create $logargs $verbargs \ @@ -114,8 +110,7 @@ proc basic_repmgr_test { niter inmemdb inmemlog \ -lock_max_locks 10000 -lock_max_objects 10000 $repmemarg" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open first client @@ -126,10 +121,9 @@ proc basic_repmgr_test { niter inmemdb inmemlog \ -lock_max_locks 10000 -lock_max_objects 10000 $repmemarg" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -141,10 +135,9 @@ proc basic_repmgr_test { niter inmemdb inmemlog \ -lock_max_locks 10000 -lock_max_objects 10000 $repmemarg" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv2 diff --git a/test/tcl/repmgr002.tcl b/test/tcl/repmgr002.tcl index a7bbac89..940c8fe8 100644 --- a/test/tcl/repmgr002.tcl +++ b/test/tcl/repmgr002.tcl @@ -1,7 +1,7 @@ # # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -107,10 +107,6 @@ proc basic_repmgr_election_test { niter inmemdb \ print_repmgr_headers basic_repmgr_election_test $niter $inmemdb\ $inmemlog $inmemrep $envprivate $bulk - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - puts "\tBasic repmgr election test.a: Start three clients." # Open first client @@ -119,11 +115,10 @@ proc basic_repmgr_election_test { niter inmemdb \ -errpfx CLIENT -home $clientdir -rep -thread $repmemarg" set clientenv [eval $cl_envcmd] set cl1_repmgr_conf "-ack all -pri 100 \ - -timeout {connection_retry 20000000} \ - -local { localhost [lindex $ports 0] \ + -local { 127.0.0.1 [lindex $ports 0] \ $creator_flag $legacy_flag } \ - -remote { localhost [lindex $ports 1] $legacy_flag } \ - -remote { localhost [lindex $ports 2] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 1] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 2] $legacy_flag } \ -start elect" eval $clientenv repmgr $cl1_repmgr_conf @@ -133,10 +128,9 @@ proc basic_repmgr_election_test { niter inmemdb \ -errpfx CLIENT2 -home $clientdir2 -rep -thread $repmemarg" set clientenv2 [eval $cl2_envcmd] set cl2_repmgr_conf "-ack all -pri 30 \ - -timeout {connection_retry 10000000} \ - -local { localhost [lindex $ports 1] $legacy_flag } \ - -remote { localhost [lindex $ports 0] $legacy_flag } \ - -remote { localhost [lindex $ports 2] $legacy_flag } \ + -local { 127.0.0.1 [lindex $ports 1] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 0] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 2] $legacy_flag } \ -start elect" eval $clientenv2 repmgr $cl2_repmgr_conf @@ -152,10 +146,9 @@ proc basic_repmgr_election_test { niter inmemdb \ -errpfx CLIENT3 -home $clientdir3 -rep -thread $repmemarg" set clientenv3 [eval $cl3_envcmd] set cl3_repmgr_conf "-ack all -pri 20 \ - -timeout {connection_retry 5000000} \ - -local { localhost [lindex $ports 2] $legacy_flag } \ - -remote { localhost [lindex $ports 0] $legacy_flag } \ - -remote { localhost [lindex $ports 1] $legacy_flag } \ + -local { 127.0.0.1 [lindex $ports 2] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 0] $legacy_flag } \ + -remote { 127.0.0.1 [lindex $ports 1] $legacy_flag } \ -start elect" eval $clientenv3 repmgr $cl3_repmgr_conf await_startup_done $clientenv3 diff --git a/test/tcl/repmgr003.tcl b/test/tcl/repmgr003.tcl index e1e7beaa..23ab318c 100644 --- a/test/tcl/repmgr003.tcl +++ b/test/tcl/repmgr003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -107,10 +107,6 @@ proc basic_repmgr_init_test { niter inmemdb inmemlog \ print_repmgr_headers basic_repmgr_init_test $niter $inmemdb\ $inmemlog $inmemrep $envprivate $bulk - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tBasic repmgr init test.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs $private \ @@ -118,8 +114,7 @@ proc basic_repmgr_init_test { niter inmemdb inmemlog \ -errpfx MASTER -home $masterdir -rep -thread $repmemarg" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master puts "\tBasic repmgr init test.b: Run some transactions at master." @@ -132,10 +127,9 @@ proc basic_repmgr_init_test { niter inmemdb inmemlog \ -errpfx CLIENT -home $clientdir -rep -thread $repmemarg" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -162,10 +156,9 @@ proc basic_repmgr_init_test { niter inmemdb inmemlog \ -errpfx CLIENT2 -home $clientdir2 -rep -thread $repmemarg" set clientenv2 [eval $cl_envcmd] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv2 diff --git a/test/tcl/repmgr007.tcl b/test/tcl/repmgr007.tcl index e9beaf2c..998caac3 100644 --- a/test/tcl/repmgr007.tcl +++ b/test/tcl/repmgr007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -51,18 +51,14 @@ proc repmgr007_sub { method niter tnum largs } { file mkdir $clientdir file mkdir $clientdir2 - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tRepmgr$tnum.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs \ - -errpfx MASTER -home $masterdir -txn -rep -thread" + -errpfx MASTER -errfile $testdir/rm7mas.err -home $masterdir \ + -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open first client @@ -71,10 +67,9 @@ proc repmgr007_sub { method niter tnum largs } { -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -84,10 +79,9 @@ proc repmgr007_sub { method niter tnum largs } { -errpfx CLIENT2 -home $clientdir2 -txn -rep -thread" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv2 @@ -106,10 +100,9 @@ proc repmgr007_sub { method niter tnum largs } { # Open -recover to clear env region, including startup_done value. set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -127,10 +120,9 @@ proc repmgr007_sub { method niter tnum largs } { # Open -recover to clear env region, including startup_done value. set clientenv2 [eval $cl2_envcmd -recover] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv2 @@ -141,6 +133,20 @@ proc repmgr007_sub { method niter tnum largs } { rep_verify $masterdir $masterenv $clientdir $clientenv 1 1 1 rep_verify $masterdir $masterenv $clientdir2 $clientenv2 1 1 1 + # + # Test that repmgr won't crash on a small amount of unexpected + # input over its port. + # + puts "\tRepmgr$tnum.k: Test that repmgr ignores unexpected input." + set msock [socket 127.0.0.1 [lindex $ports 0]] + set garbage "abcdefghijklmnopqrstuvwxyz" + puts $msock $garbage + close $msock + set maserrfile [open $testdir/rm7mas.err r] + set maserr [read $maserrfile] + close $maserrfile + error_check_good errchk [is_substr $maserr "unexpected msg type"] 1 + error_check_good client2_close [$clientenv2 close] 0 error_check_good client_close [$clientenv close] 0 error_check_good masterenv_close [$masterenv close] 0 diff --git a/test/tcl/repmgr009.tcl b/test/tcl/repmgr009.tcl index 8bb09013..126ac55a 100644 --- a/test/tcl/repmgr009.tcl +++ b/test/tcl/repmgr009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -55,10 +55,6 @@ proc repmgr009_sub { method niter tnum largs } { file mkdir $clientdir file mkdir $norepdir - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - puts "\tRepmgr$tnum.a: Set up environment without repmgr." set ma_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx MASTER -home $masterdir -txn -rep -thread" @@ -67,8 +63,7 @@ proc repmgr009_sub { method niter tnum largs } { puts "\tRepmgr$tnum.b: Call repmgr without open master (error)." catch {$masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master} res error_check_good errchk [is_substr $res "invalid command"] 1 @@ -80,8 +75,7 @@ proc repmgr009_sub { method niter tnum largs } { repladd 1 set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master puts "\tRepmgr$tnum.e: Start repmgr with no local sites (error)." @@ -89,8 +83,7 @@ proc repmgr009_sub { method niter tnum largs } { -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] catch {$clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -remote [list localhost [lindex $ports 7]] \ + -remote [list 127.0.0.1 [lindex $ports 7]] \ -start client} res error_check_good errchk [is_substr $res \ "local site must be named before calling repmgr_start"] 1 @@ -99,9 +92,8 @@ proc repmgr009_sub { method niter tnum largs } { puts "\tRepmgr$tnum.f: Start repmgr with two local sites (error)." set clientenv [eval $cl_envcmd] catch {$clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 8]] \ - -local [list localhost [lindex $ports 9]] \ + -local [list 127.0.0.1 [lindex $ports 8]] \ + -local [list 127.0.0.1 [lindex $ports 9]] \ -start client} res error_check_good errchk [string match "*already*set*" $res] 1 error_check_good client_close [$clientenv close] 0 @@ -110,17 +102,15 @@ proc repmgr009_sub { method niter tnum largs } { repladd 2 set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv puts "\tRepmgr$tnum.h: Start repmgr a second time (error)." catch {$clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client} res error_check_good errchk [is_substr $res "repmgr is already started"] 1 @@ -161,7 +151,7 @@ proc repmgr009_sub { method niter tnum largs } { puts "\tRepmgr$tnum.o: Call repmgr after rep_start (error)." catch {$masterenv2 repmgr -ack all \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master} res # Internal repmgr calls return EINVAL after hitting # base API application test. diff --git a/test/tcl/repmgr010.tcl b/test/tcl/repmgr010.tcl index d2df08e8..4223b8d8 100644 --- a/test/tcl/repmgr010.tcl +++ b/test/tcl/repmgr010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -53,19 +53,14 @@ proc repmgr010_sub { method niter tnum largs } { file mkdir $clientdir file mkdir $clientdir2 - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - puts "\tRepmgr$tnum.a: Start master, two clients, ack policy quorum." # Open a master. set ma_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx MASTER -home $masterdir -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack quorum \ - -timeout {connection_retry 20000000} \ -timeout {ack 5000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open first client @@ -73,10 +68,9 @@ proc repmgr010_sub { method niter tnum largs } { -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack quorum \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -85,10 +79,9 @@ proc repmgr010_sub { method niter tnum largs } { -errpfx CLIENT2 -home $clientdir2 -txn -rep -thread" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack quorum \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv2 @@ -133,10 +126,9 @@ proc repmgr010_sub { method niter tnum largs } { # Open -recover to clear env region, including startup_done value. set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv diff --git a/test/tcl/repmgr011.tcl b/test/tcl/repmgr011.tcl index 2570aea0..8bbd897e 100644 --- a/test/tcl/repmgr011.tcl +++ b/test/tcl/repmgr011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -50,18 +50,13 @@ proc repmgr011_sub { method niter tnum largs } { file mkdir $clientdir file mkdir $clientdir2 - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open first client as master and set 2site_strict. puts "\tRepmgr$tnum.a: Start first client as master." set cl_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master error_check_good c1strict [$clientenv rep_config {mgr2sitestrict on}] 0 @@ -71,9 +66,8 @@ proc repmgr011_sub { method niter tnum largs } { -errpfx CLIENT2 -home $clientdir2 -txn -rep -thread" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv2 error_check_good c2strict [$clientenv2 rep_config \ @@ -99,9 +93,8 @@ proc repmgr011_sub { method niter tnum largs } { puts "\tRepmgr$tnum.g: Restart first client as master" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ -start master await_expected_master $clientenv diff --git a/test/tcl/repmgr012.tcl b/test/tcl/repmgr012.tcl index 177b7f2f..6fc63346 100644 --- a/test/tcl/repmgr012.tcl +++ b/test/tcl/repmgr012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -50,18 +50,13 @@ proc repmgr012_sub { method niter tnum largs } { file mkdir $masterdir file mkdir $clientdir - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tRepmgr$tnum.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx MASTER -home $masterdir -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open a client. @@ -70,9 +65,8 @@ proc repmgr012_sub { method niter tnum largs } { -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv @@ -89,8 +83,8 @@ proc repmgr012_sub { method niter tnum largs } { # Timeouts are in microseconds, heartbeat monitor should be # longer than heartbeat_send. puts "\tRepmgr$tnum.e: Set heartbeat timeouts." - $masterenv repmgr -timeout {heartbeat_send 50000} - $clientenv repmgr -timeout {heartbeat_monitor 90000} + $masterenv repmgr -timeout {heartbeat_send 100000} + $clientenv repmgr -timeout {heartbeat_monitor 180000} puts "\tRepmgr$tnum.f: Run second set of transactions at master." eval rep_test $method $masterenv NULL $niter $niter 0 0 $largs diff --git a/test/tcl/repmgr013.tcl b/test/tcl/repmgr013.tcl index 821b8aff..5907bb97 100644 --- a/test/tcl/repmgr013.tcl +++ b/test/tcl/repmgr013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -52,17 +52,12 @@ proc repmgr013_sub { method niter tnum largs } { file mkdir $clientdir file mkdir $clientdir2 - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - puts "\tRepmgr$tnum.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx MASTER -home $masterdir -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master puts "\tRepmgr$tnum.b: Start first client." @@ -70,10 +65,9 @@ proc repmgr013_sub { method niter tnum largs } { -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ -start client await_startup_done $clientenv @@ -82,10 +76,9 @@ proc repmgr013_sub { method niter tnum largs } { -errpfx CLIENT2 -home $clientdir2 -txn -rep -thread" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1] peer] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1] peer] \ -start client await_startup_done $clientenv2 @@ -113,7 +106,7 @@ proc verify_sitelist { env numsites peervec } { foreach tuple $sitelist { error_check_good eidchk [string is integer -strict \ [lindex $tuple 0]] 1 - error_check_good hostchk [lindex $tuple 1] "localhost" + error_check_good hostchk [lindex $tuple 1] "127.0.0.1" set port [lindex $tuple 2] error_check_good portchk [string is integer -strict $port] 1 error_check_good statchk [lindex $tuple 3] connected diff --git a/test/tcl/repmgr017.tcl b/test/tcl/repmgr017.tcl index 789d3f7b..2b5799ca 100644 --- a/test/tcl/repmgr017.tcl +++ b/test/tcl/repmgr017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -57,10 +57,6 @@ proc repmgr017_sub { method niter tnum largs } { set logargs [adjust_logargs "in-memory"] set txnargs [adjust_txnargs "in-memory"] - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master with a very small cache. puts "\tRepmgr$tnum.a: Start a master with a very small cache." set cacheargs "-cachesize {0 32768 1}" @@ -68,8 +64,7 @@ proc repmgr017_sub { method niter tnum largs } { -errpfx MASTER -rep -thread -rep_inmem_files -private $cacheargs" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open a client @@ -78,9 +73,8 @@ proc repmgr017_sub { method niter tnum largs } { -errpfx CLIENT -rep -thread -rep_inmem_files -private" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv @@ -107,16 +101,14 @@ proc repmgr017_sub { method niter tnum largs } { set cacheargs "" set masterenv [eval $ma_envcmd -recover] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open -recover to clear env region, including startup_done value. set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv diff --git a/test/tcl/repmgr018.tcl b/test/tcl/repmgr018.tcl index d5ac4b74..32d5a080 100644 --- a/test/tcl/repmgr018.tcl +++ b/test/tcl/repmgr018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -51,18 +51,13 @@ proc repmgr018_sub { method niter tnum largs } { file mkdir $masterdir file mkdir $clientdir - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tRepmgr$tnum.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs -errpfx MASTER \ -home $masterdir -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open a client @@ -71,9 +66,8 @@ proc repmgr018_sub { method niter tnum largs } { -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv @@ -113,9 +107,8 @@ proc repmgr018_sub { method niter tnum largs } { # Open -recover to clear env region, including startup_done value. set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv $clientenv close @@ -128,9 +121,8 @@ proc repmgr018_sub { method niter tnum largs } { # Open -recover to clear env region, including startup_done value. set clientenv [eval $cl_envcmd -recover] $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ -start client await_startup_done $clientenv $clientenv close diff --git a/test/tcl/repmgr023.tcl b/test/tcl/repmgr023.tcl index 8fac705d..2ec3af45 100644 --- a/test/tcl/repmgr023.tcl +++ b/test/tcl/repmgr023.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr023 # TEST Test of JOIN_FAILURE event for repmgr applications. @@ -66,7 +66,7 @@ proc repmgr023_sub { method niter tnum largs } { -home $dira" set enva [eval $cmda] $enva repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $porta] -start master + -local [list 127.0.0.1 $porta] -start master set cmdb "berkdb_env_noerr -create -txn nosync \ $verbargs $repmemargs -rep -thread \ @@ -74,8 +74,8 @@ proc repmgr023_sub { method niter tnum largs } { -home $dirb" set envb [eval $cmdb] $envb repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $portb] -start client \ - -remote [list localhost $porta] + -local [list 127.0.0.1 $portb] -start client \ + -remote [list 127.0.0.1 $porta] puts "\tRepmgr$tnum.a: wait for client B to sync with master." await_startup_done $envb @@ -85,8 +85,8 @@ proc repmgr023_sub { method niter tnum largs } { -home $dirc" set envc [eval $cmdc] $envc repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $portc] -start client \ - -remote [list localhost $porta] + -local [list 127.0.0.1 $portc] -start client \ + -remote [list 127.0.0.1 $porta] puts "\tRepmgr$tnum.b: wait for client C to sync with master." await_startup_done $envc @@ -128,8 +128,8 @@ proc repmgr023_sub { method niter tnum largs } { set envc [eval $cmdc -recover -event] $envc rep_config {autoinit off} $envc repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $portc] -start client \ - -remote [list localhost $porta] + -local [list 127.0.0.1 $portc] -start client \ + -remote [list 127.0.0.1 $porta] # Since we've turned off auto-init, but are too far behind to sync, we # expect a join_failure event. diff --git a/test/tcl/repmgr024.tcl b/test/tcl/repmgr024.tcl index 75e45f70..e10885f3 100644 --- a/test/tcl/repmgr024.tcl +++ b/test/tcl/repmgr024.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr024 # TEST Test of group-wide log archiving awareness. @@ -69,7 +69,7 @@ proc repmgr024_sub { method niter tnum largs } { # the client is closed and we want to give it a chance to # wait later in the test. $enva repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $porta] -start master + -local [list 127.0.0.1 $porta] -start master set cmdb "berkdb_env_noerr -create -txn nosync \ $verbargs $repmemargs -rep -thread \ @@ -77,8 +77,8 @@ proc repmgr024_sub { method niter tnum largs } { -home $dirb" set envb [eval $cmdb] $envb repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $portb] -start client \ - -remote [list localhost $porta] + -local [list 127.0.0.1 $portb] -start client \ + -remote [list 127.0.0.1 $porta] puts "\tRepmgr$tnum.a: wait for client B to sync with master." await_startup_done $envb @@ -88,8 +88,8 @@ proc repmgr024_sub { method niter tnum largs } { -home $dirc" set envc [eval $cmdc] $envc repmgr -timeout {connection_retry 5000000} \ - -local [list localhost $portc] -start client \ - -remote [list localhost $porta] + -local [list 127.0.0.1 $portc] -start client \ + -remote [list 127.0.0.1 $porta] puts "\tRepmgr$tnum.b: wait for client C to sync with master." await_startup_done $envc @@ -195,6 +195,14 @@ proc repmgr024_sub { method niter tnum largs } { } } + # + # Make sure neither log_archive in same process nor db_archive + # in a different process show any files to archive. + # + error_check_good no_files_log_archive [llength [$enva log_archive]] 0 + set dbarchres [eval exec $util_path/db_archive -h $dira] + error_check_good no_files_db_archive [llength $dbarchres] 0 + puts "\tRepmgr$tnum.j: Try to archive. Verify it didn't." set res [$enva log_archive -arch_remove] set res [eval exec $util_path/db_archive -l -h $dira] diff --git a/test/tcl/repmgr025.tcl b/test/tcl/repmgr025.tcl index eb3c11a1..bf08f1f5 100644 --- a/test/tcl/repmgr025.tcl +++ b/test/tcl/repmgr025.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -80,31 +80,26 @@ proc repmgr025_sub { method niter tnum largs } { set cl_envcmd "$common -errpfx CLIENT -home $clientdir" set cl2_envcmd "$common -errpfx CLIENT2 -home $clientdir2" set masterenv [eval $ma_envcmd] - $masterenv repmgr -local [list localhost [lindex $ports 0]] \ + $masterenv repmgr -local [list 127.0.0.1 [lindex $ports 0]] \ -start master set clientenv [eval $cl_envcmd] - $clientenv repmgr -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] -start client + $clientenv repmgr -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] -start client await_startup_done $clientenv set clientenv2 [eval $cl2_envcmd] - $clientenv2 repmgr -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] -start client + $clientenv2 repmgr -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] -start client await_startup_done $clientenv2 $clientenv close $clientenv2 close $masterenv close - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tRepmgr$tnum.b: Start a master." set masterenv [eval $ma_envcmd] $masterenv repmgr -timeout {heartbeat_send 500000} $masterenv repmgr -ack all \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open first client @@ -112,8 +107,7 @@ proc repmgr025_sub { method niter tnum largs } { set clientenv [eval $cl_envcmd] $clientenv repmgr -timeout {heartbeat_monitor 1100000} $clientenv repmgr -ack all \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ -start client await_startup_done $clientenv @@ -149,8 +143,7 @@ proc repmgr025_sub { method niter tnum largs } { set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -timeout {heartbeat_monitor 1100000} $clientenv2 repmgr -ack all \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ -start client puts "\tRepmgr$tnum.g: Test for page requests from rerequest thread." diff --git a/test/tcl/repmgr026.tcl b/test/tcl/repmgr026.tcl index b836230b..9478af24 100644 --- a/test/tcl/repmgr026.tcl +++ b/test/tcl/repmgr026.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr026 # TEST Test of "full election" timeouts. @@ -72,26 +72,26 @@ proc repmgr026_sub { tnum client_down use_leases } { -timeout {election 5000000} -timeout {ack 3000000}" set enva [eval $cmda] eval $enva repmgr $common_mgr \ - -local {[list localhost $porta creator]} + -local {[list 127.0.0.1 $porta creator]} puts -nonewline "." ; flush stdout set envb [eval $cmdb] eval $envb repmgr $common_mgr \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envb puts -nonewline "." ; flush stdout set envc [eval $cmdc] eval $envc repmgr $common_mgr \ - -local {[list localhost $portc]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portc]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envc puts -nonewline "." ; flush stdout set envd [eval $cmdd] eval $envd repmgr $common_mgr \ - -local {[list localhost $portd]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portd]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envd puts -nonewline "." ; flush stdout set enve [eval $cmde] eval $enve repmgr $common_mgr \ - -local {[list localhost $porte]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $porte]} -remote {[list 127.0.0.1 $porta]} await_startup_done $enve puts "." $enve close @@ -116,16 +116,16 @@ proc repmgr026_sub { tnum client_down use_leases } { puts "\tRepmgr$tnum.a: Start first four sites." set enva [eval $cmda] - eval $enva repmgr $common_mgr -pri 200 -local {[list localhost $porta]} + eval $enva repmgr $common_mgr -pri 200 -local {[list 127.0.0.1 $porta]} set envb [eval $cmdb] - eval $envb repmgr $common_mgr -pri 100 -local {[list localhost $portb]} + eval $envb repmgr $common_mgr -pri 100 -local {[list 127.0.0.1 $portb]} set envc [eval $cmdc] - eval $envc repmgr $common_mgr -pri 90 -local {[list localhost $portc]} + eval $envc repmgr $common_mgr -pri 90 -local {[list 127.0.0.1 $portc]} set envd [eval $cmdd] - eval $envd repmgr $common_mgr -pri 80 -local {[list localhost $portd]} + eval $envd repmgr $common_mgr -pri 80 -local {[list 127.0.0.1 $portd]} if { $client_down } { set enve NONE @@ -133,7 +133,7 @@ proc repmgr026_sub { tnum client_down use_leases } { puts "\tRepmgr$tnum.b: Start fifth site." set enve [eval $cmde] eval $enve repmgr $common_mgr -pri 50 \ - -local {[list localhost $porte]} + -local {[list 127.0.0.1 $porte]} } # wait for results, and make sure they're correct diff --git a/test/tcl/repmgr027.tcl b/test/tcl/repmgr027.tcl index a9841bf6..ecc68273 100644 --- a/test/tcl/repmgr027.tcl +++ b/test/tcl/repmgr027.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr027 # TEST Test of "full election" timeouts, where a client starts up and joins the @@ -61,14 +61,14 @@ proc repmgr027_sub { tnum } { set cmdb "berkdb_env_noerr $common -errpfx SITE_B -home $dirb" set cmdc "berkdb_env_noerr $common -errpfx SITE_C -home $dirc" set enva [eval $cmda] - eval $enva repmgr $common_mgr -local {[list localhost $porta creator]} + eval $enva repmgr $common_mgr -local {[list 127.0.0.1 $porta creator]} set envb [eval $cmdb] eval $envb repmgr $common_mgr \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envb set envc [eval $cmdc] eval $envc repmgr $common_mgr \ - -local {[list localhost $portc]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portc]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envc $envc close $envb close @@ -78,10 +78,10 @@ proc repmgr027_sub { tnum } { # puts "\tRepmgr$tnum.a: Start first two sites." set enva [eval $cmda] - eval $enva repmgr $common_mgr -pri 200 -local {[list localhost $porta]} + eval $enva repmgr $common_mgr -pri 200 -local {[list 127.0.0.1 $porta]} set envb [eval $cmdb] - eval $envb repmgr $common_mgr -pri 100 -local {[list localhost $portb]} + eval $envb repmgr $common_mgr -pri 100 -local {[list 127.0.0.1 $portb]} # Wait until both sites recognize that they're in an election, plus a # few extra seconds just for good measure. @@ -100,7 +100,7 @@ proc repmgr027_sub { tnum } { puts "\tRepmgr$tnum.c: Start 3rd site." set envc [eval $cmdc] - eval $envc repmgr $common_mgr -pri 100 -local {[list localhost $portc]} + eval $envc repmgr $common_mgr -pri 100 -local {[list 127.0.0.1 $portc]} # Wait for results, and make sure they're correct. The election should # complete right away, once the third client has joined, regardless of diff --git a/test/tcl/repmgr028.tcl b/test/tcl/repmgr028.tcl index 97bb4fe7..fdb19f7d 100644 --- a/test/tcl/repmgr028.tcl +++ b/test/tcl/repmgr028.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr028 # TEST Repmgr allows applications to choose master explicitly, instead of @@ -53,10 +53,10 @@ proc repmgr028_sub { tnum } { set cmda "berkdb_env_noerr $common -errpfx SITE_A -home $dira" set cmdb "berkdb_env_noerr $common -errpfx SITE_B -home $dirb" set enva [eval $cmda] - eval $enva repmgr -local {[list localhost $porta]} -start master + eval $enva repmgr -local {[list 127.0.0.1 $porta]} -start master set envb [eval $cmdb] eval $envb repmgr -start client \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envb $envb close $enva close @@ -69,12 +69,12 @@ proc repmgr028_sub { tnum } { set enva [eval $cmda -recover] $enva rep_config {mgrelections off} eval $enva repmgr $common_mgr \ - -local {[list localhost $porta]} -start elect -pri 100 + -local {[list 127.0.0.1 $porta]} -start elect -pri 100 set envb [eval $cmdb -recover] $envb rep_config {mgrelections off} eval $envb repmgr $common_mgr -start elect -pri 99 \ - -local {[list localhost $portb]} + -local {[list 127.0.0.1 $portb]} await_startup_done $envb puts "\tRepmgr$tnum.b: Switch roles explicitly." @@ -124,7 +124,7 @@ proc repmgr028_sub { tnum } { set envb [eval $cmdb -recover] $envb rep_config {mgrelections off} eval $envb repmgr $common_mgr -start master \ - -local {[list localhost $portb]} + -local {[list 127.0.0.1 $portb]} # Force a checkpoint so that the client hears something from the master, # which should cause the client to notice the gen number change. Try a @@ -200,10 +200,10 @@ proc repmgr028_sub { tnum } { puts "\tRepmgr$tnum.h: Start up again, elections on by default." set enva [eval $cmda -recover] eval $enva repmgr $common_mgr \ - -local {[list localhost $porta]} -start master + -local {[list 127.0.0.1 $porta]} -start master set envb [eval $cmdb -recover] eval $envb repmgr $common_mgr -start client \ - -local {[list localhost $portb]} + -local {[list 127.0.0.1 $portb]} await_startup_done $envb puts "\tRepmgr$tnum.i: Check that dynamic role change attempt fails." @@ -236,10 +236,10 @@ proc repmgr028_sub { tnum } { # set enva [eval $cmda -recover] eval $enva repmgr $common_mgr \ - -local {[list localhost $porta]} -start client + -local {[list 127.0.0.1 $porta]} -start client set envb [eval $cmdb -recover] eval $envb repmgr $common_mgr -start client \ - -local {[list localhost $portb]} + -local {[list 127.0.0.1 $portb]} puts "\tRepmgr$tnum.j: Pause 10 seconds, check no election held." tclsleep 10 error_check_good no_election \ @@ -259,11 +259,11 @@ proc repmgr028_sub { tnum } { puts "\tRepmgr$tnum.k: Test election start policy on client startup." set enva [eval $cmda -recover] eval $enva repmgr $common_mgr \ - -local {[list localhost $porta]} -start master + -local {[list 127.0.0.1 $porta]} -start master $enva rep_config {mgr2sitestrict on} set envb [eval $cmdb -recover] eval $envb repmgr $common_mgr -start client \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envb $envb rep_config {mgr2sitestrict on} $envb close @@ -275,7 +275,7 @@ proc repmgr028_sub { tnum } { # set envb [eval $cmdb] eval $envb repmgr $common_mgr -start elect \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} puts "\tRepmgr$tnum.l: Pause 5 seconds, check election was attempted." tclsleep 5 error_check_good startup_election \ diff --git a/test/tcl/repmgr028script.tcl b/test/tcl/repmgr028script.tcl index 1cfb0503..ad492ad5 100644 --- a/test/tcl/repmgr028script.tcl +++ b/test/tcl/repmgr028script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # Repmgr028 script - subordinate repmgr processes and dynamic role changes diff --git a/test/tcl/repmgr029.tcl b/test/tcl/repmgr029.tcl index 241d81a6..bec3c56f 100644 --- a/test/tcl/repmgr029.tcl +++ b/test/tcl/repmgr029.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -66,7 +66,7 @@ proc z3 {} { puts "\tRepmgr029.z3.a: Primordial creation, Start Master site 0" set env1 [berkdb env -create -errpfx MASTER -home $masterdir -txn \ -rep -thread -recover -verbose [list rep $rv]] - $env1 repmgr -local [list localhost $port0] -start master + $env1 repmgr -local [list 127.0.0.1 $port0] -start master error_check_good nsites_A [$env1 rep_get_nsites] 1 puts "\tRepmgr029.z3.b: Simple join request, \ @@ -74,8 +74,8 @@ proc z3 {} { set env2 [berkdb env -create -errpfx CLIENT -home $clientdir -txn \ -rep -thread -recover -verbose [list rep $rv]] $env2 rep_config {mgr2sitestrict on} - $env2 repmgr -local [list localhost $port1] \ - -remote [list localhost $port0] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client await_startup_done $env2 error_check_good nsites_A2 [$env1 rep_get_nsites] 2 error_check_good nsites_B2 [$env2 rep_get_nsites] 2 @@ -84,8 +84,8 @@ proc z3 {} { set env3 [berkdb env -create -errpfx CLIENT2 -home $clientdir2 -txn \ -rep -thread -recover -verbose [list rep $rv]] $env3 rep_config {mgr2sitestrict on} - $env3 repmgr -local [list localhost $port2] \ - -remote [list localhost $port1] + $env3 repmgr -local [list 127.0.0.1 $port2] \ + -remote [list 127.0.0.1 $port1] set done no while {!$done} { if {[catch {$env3 repmgr -start client} msg]} { @@ -102,10 +102,10 @@ proc z3 {} { puts "\tRepmgr029.z3.d: Master cannot be removed \ (by itself, or as requested from a client)" - set ret [catch {$env1 repmgr -remove [list localhost $port0]} result] + set ret [catch {$env1 repmgr -remove [list 127.0.0.1 $port0]} result] error_check_bad no_failure $ret 0 error_check_match unavail $result "*DB_REP_UNAVAIL*" - set ret [catch {$env2 repmgr -remove [list localhost $port0]} result] + set ret [catch {$env2 repmgr -remove [list 127.0.0.1 $port0]} result] error_check_bad no_failure2 $ret 0 error_check_match unavail2 $result "*DB_REP_UNAVAIL*" @@ -119,8 +119,8 @@ proc z3 {} { puts "\t\tRepmgr029.z3.e.2: Start client 3." set env4 [berkdb env -create -errpfx CLIENT3 -home $clientdir3 \ -txn -rep -thread -recover -verbose [list rep $rv]] - set ret [catch {$env4 repmgr -local [list localhost $port3] \ - -remote [list localhost $port0] -start client} result] + set ret [catch {$env4 repmgr -local [list 127.0.0.1 $port3] \ + -remote [list 127.0.0.1 $port0] -start client} result] error_check_bad no_failure3 $ret 0 error_check_match unavail3 $result "*DB_REP_UNAVAIL*" @@ -128,14 +128,14 @@ proc z3 {} { puts "\t\tRepmgr029.z3.e.3: Check previous GMDB version $prev_vers" set SITE_ADDING 1 set SITE_PRESENT 4 - error_check_good site_3_adding [repmgr029_gmdb_status $db localhost $port3] \ + error_check_good site_3_adding [repmgr029_gmdb_status $db 127.0.0.1 $port3] \ $SITE_ADDING puts "\t\tRepmgr029.z3.e.4: limbo resolution, restart client 1." set env2 [berkdb env -create -errpfx CLIENT -home $clientdir -txn \ -rep -thread -recover -verbose [list rep $rv] -event] # no helper should be needed this time. - $env2 repmgr -local [list localhost $port1] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] -start client await_startup_done $env2 50 puts "\t\tRepmgr029.z3.e.5: normal txn at master" @@ -144,7 +144,7 @@ proc z3 {} { set new_vers [repmgr029_gmdb_version $db] puts "\t\tRepmgr029.z3.e.6: NEW GMDB version $new_vers" error_check_good version_incr $new_vers [expr $prev_vers + 1] - error_check_good site_3_added [repmgr029_gmdb_status $db localhost $port3] \ + error_check_good site_3_added [repmgr029_gmdb_status $db 127.0.0.1 $port3] \ $SITE_PRESENT puts "\t\tRepmgr029.z3.e.7: client 3 rejoins." @@ -173,35 +173,35 @@ proc z3 {} { puts "\t\tRepmgr029.z3.f.3: Start client 4." set env5 [berkdb env -create -errpfx CLIENT4 -home $clientdir4 \ -txn -rep -thread -recover -verbose [list rep $rv]] - set ret [catch {$env5 repmgr -local [list localhost $port4] \ - -remote [list localhost $port0] -start client} result] + set ret [catch {$env5 repmgr -local [list 127.0.0.1 $port4] \ + -remote [list 127.0.0.1 $port0] -start client} result] error_check_bad no_failure4 $ret 0 error_check_match unavail4 $result "*DB_REP_UNAVAIL*" set prev_vers [repmgr029_gmdb_version $db] puts "\t\tRepmgr029.z3.f.4: Check current GMDB version $prev_vers" - error_check_good site_4_adding [repmgr029_gmdb_status $db localhost $port4] \ + error_check_good site_4_adding [repmgr029_gmdb_status $db 127.0.0.1 $port4] \ $SITE_ADDING puts "\t\tRepmgr029.z3.f.5: Start client 5." set env6 [berkdb env -create -errpfx CLIENT5 -home $clientdir5 \ -txn -rep -thread -recover -verbose [list rep $rv]] - set ret [catch {$env6 repmgr -local [list localhost $port5] \ - -remote [list localhost $port0] -start client} result] + set ret [catch {$env6 repmgr -local [list 127.0.0.1 $port5] \ + -remote [list 127.0.0.1 $port0] -start client} result] error_check_bad no_failure5 $ret 0 error_check_match unavail5 $result "*DB_REP_UNAVAIL*" set prev_vers [repmgr029_gmdb_version $db] puts "\t\tRepmgr029.z3.f.6: Check current GMDB version $prev_vers" # [M]: There is no gm status for client 5 so far. Let alone the "ADDING". - #error_check_good site_5_adding [repmgr029_gmdb_status $db localhost $port5] \ + #error_check_good site_5_adding [repmgr029_gmdb_status $db 127.0.0.1 $port5] \ # $SITE_ADDING puts "\t\tRepmgr029.z3.f.7: limbo resolution, restart client 1." set env2 [berkdb env -create -errpfx CLIENT -home $clientdir -txn \ -rep -thread -recover -verbose [list rep $rv] -event] # no helper should be needed this time. - $env2 repmgr -local [list localhost $port1] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] -start client await_startup_done $env2 50 puts "\t\tRepmgr029.z3.f.8: normal txn at master" set niter 1 @@ -218,10 +218,10 @@ proc z3 {} { set new_vers [repmgr029_gmdb_version $db] puts "\t\tRepmgr029.z3.f.11: NEW GMDB version $new_vers" # Check for client 5, which has gm status as "ADDED" - error_check_good site_5_added [repmgr029_gmdb_status $db localhost $port5] \ + error_check_good site_5_added [repmgr029_gmdb_status $db 127.0.0.1 $port5] \ $SITE_PRESENT #[M]: So far gm status for client 4 is "ADDED" - error_check_good site_4_added [repmgr029_gmdb_status $db localhost $port4] \ + error_check_good site_4_added [repmgr029_gmdb_status $db 127.0.0.1 $port4] \ $SITE_PRESENT #[M]: We'd like to check the gm status on the client 4 sides. # No Way! as client 4 has not been start up and sync. @@ -237,8 +237,8 @@ proc z3 {} { puts "\t\tRepmgr029.z3.f.13: NEW GMDB version $new_vers" puts "\tRepmgr029.z3.h: Remove (downed) client 3, from master" - $env1 repmgr -remove [list localhost $port3] - error_check_good site_3_removed [repmgr029_gmdb_status $db localhost $port3] 0 + $env1 repmgr -remove [list 127.0.0.1 $port3] + error_check_good site_3_removed [repmgr029_gmdb_status $db 127.0.0.1 $port3] 0 error_check_good db_close [$db close] 0 error_check_good s_1_close [$env2 close] 0 error_check_good s_3_close [$env4 close] 0 @@ -272,22 +272,22 @@ proc z6 { } { puts -nonewline "\tRepmgr029.z6.a: Build basic 3-site group" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA creator] -start elect + $envA repmgr -local [list 127.0.0.1 $portA creator] -start elect error_check_good nsites_a [$envA rep_get_nsites] 1 puts -nonewline "."; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start elect + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start elect await_startup_done $envB error_check_good nsites_b [$envB rep_get_nsites] 2 puts -nonewline "."; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -verbose [list rep $rv] -event] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start elect + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start elect await_startup_done $envC error_check_good nsites_c [$envC rep_get_nsites] 3 puts "."; flush stdout @@ -296,9 +296,9 @@ proc z6 { } { set eid_C_at_B [repmgr029_get_eid $envB $portC] puts "\tRepmgr029.z6.b: Remove (live) site C from a request originating at B." - $envB repmgr -remove [list localhost $portC] + $envB repmgr -remove [list 127.0.0.1 $portC] set db [berkdb open -env $envA -thread __db.rep.system __db.membership] - error_check_good site_c_removed [repmgr029_gmdb_status $db localhost $portC] 0 + error_check_good site_c_removed [repmgr029_gmdb_status $db 127.0.0.1 $portC] 0 set master_ev [find_event [$envA event_info] site_removed] error_check_good site_a_event [llength $master_ev] 2 @@ -340,13 +340,13 @@ proc z8 { } { puts "\tRepmgr029.z8: Create primordial site" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA creator] -start elect + $envA repmgr -local [list 127.0.0.1 $portA creator] -start elect puts "\tRepmgr029.z8: Add client, check for event at master" set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start elect + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start elect set ev [find_event [$envA event_info] site_added] error_check_good ev_a [llength $ev] 2 set eid [lindex $ev 1] @@ -358,8 +358,9 @@ proc z8 { } { $envB event_info -clear set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -verbose [list rep $rv] -event] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start elect + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start elect + await_startup_done $envC set ev [find_event [$envA event_info] site_added] error_check_good ev_a2 [llength $ev] 2 @@ -403,13 +404,13 @@ proc z7 { } { puts -nonewline "\tRepmgr029.z7: Set up a group of 3, A (master), B, C" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout @@ -417,13 +418,13 @@ proc z7 { } { set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts "." puts "\tRepmgr029.z7: Remove site B itself" - $envB repmgr -remove [list localhost $portB] + $envB repmgr -remove [list 127.0.0.1 $portB] await_event $envB local_site_removed set master_ev [find_event [$envA event_info] site_removed] @@ -462,7 +463,7 @@ proc z4 {} { puts -nonewline "\tRepmgr029.z4.a: Start the master." set env1 [berkdb_env -create -errpfx MASTER -home $masterdir \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env1 repmgr -local [list localhost $port0] -start master + $env1 repmgr -local [list 127.0.0.1 $port0] -start master error_check_good nsites_1 [$env1 rep_get_nsites] 1 puts "."; flush stdout @@ -470,8 +471,8 @@ proc z4 {} { set env2 [berkdb_env -create -errpfx CLIENT -home $clientdir -txn \ -rep -thread -recover -verbose [list rep $rv]] $env2 rep_config {mgr2sitestrict on} - $env2 repmgr -local [list localhost $port1] \ - -remote [list localhost $port0] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client await_startup_done $env2 error_check_good nsites_2 [$env2 rep_get_nsites] 2 puts "."; flush stdout @@ -483,8 +484,8 @@ proc z4 {} { set env3 [berkdb_env -create -errpfx CLIENT2 -home $clientdir2 \ -txn -rep -thread -recover -verbose [list rep $rv]] $env3 rep_config {mgr2sitestrict on} - set ret [catch {$env3 repmgr -local [list localhost $port2] \ - -remote [list localhost $port0] -start client} result] + set ret [catch {$env3 repmgr -local [list 127.0.0.1 $port2] \ + -remote [list 127.0.0.1 $port0] -start client} result] error_check_bad no_failure $ret 0 error_check_match unavail $result "*DB_REP_UNAVAIL*" puts "\tRepmgr029.z4.e: The second join failed as expected, \ @@ -494,7 +495,7 @@ proc z4 {} { set env2 [berkdb_env -errpfx CLIENT -home $clientdir -txn -rep \ -thread -recover -create -verbose [list rep $rv]] $env2 rep_config {mgr2sitestrict on} - $env2 repmgr -local [list localhost $port1] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] -start client await_startup_done $env2 puts "."; flush stdout @@ -540,22 +541,22 @@ proc z5 {} { puts -nonewline "\tRepmgr029.z5.a: Set up a group of 3, one master and two clients." set env1 [berkdb env -create -errpfx MASTER -home $masterdir \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env1 repmgr -local [list localhost $port0] -start master + $env1 repmgr -local [list 127.0.0.1 $port0] -start master error_check_good nsites_1 [$env1 rep_get_nsites] 1 puts -nonewline "." ; flush stdout set env2 [berkdb env -create -errpfx CLIENT -home $clientdir \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env2 repmgr -local [list localhost $port1] \ - -remote [list localhost $port0] -start client + $env2 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client await_startup_done $env2 error_check_good nsites_2 [$env2 rep_get_nsites] 2 puts -nonewline "." ; flush stdout set env3 [berkdb env -create -errpfx CLIENT2 -home $clientdir2 \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env3 repmgr -local [list localhost $port2] \ - -remote [list localhost $port0] -start client + $env3 repmgr -local [list 127.0.0.1 $port2] \ + -remote [list 127.0.0.1 $port0] -start client await_startup_done $env3 error_check_good nsites_3 [$env1 rep_get_nsites] 3 puts "." ; flush stdout @@ -567,13 +568,13 @@ proc z5 {} { set env1 [berkdb env -create -errpfx A -home $masterdir \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env1 repmgr -local [list localhost $port0] -start elect -pri 100 + $env1 repmgr -local [list 127.0.0.1 $port0] -start elect -pri 100 set env2 [berkdb env -create -errpfx B -home $clientdir \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env2 repmgr -local [list localhost $port1] -start elect -pri 200 + $env2 repmgr -local [list 127.0.0.1 $port1] -start elect -pri 200 set env3 [berkdb env -create -errpfx C -home $clientdir2 \ -txn -rep -thread -recover -verbose [list rep $rv]] - $env3 repmgr -local [list localhost $port2] -start elect -pri 140 + $env3 repmgr -local [list 127.0.0.1 $port2] -start elect -pri 140 puts "\tRepmgr029.z5: Wait for election to choose a new master" await_condition {[repmgr029_known_master $env1 $env2 $env3]} @@ -615,22 +616,22 @@ proc z2 { } { puts -nonewline "\tRepmgr029.z2.a: Set up a group of 5: A, B, C, D, E" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master error_check_good nsites_a [$envA rep_get_nsites] 1 puts -nonewline "."; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB error_check_good nsites_b [$envB rep_get_nsites] 2 puts -nonewline "."; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC error_check_good nsites_c [$envC rep_get_nsites] 3 puts -nonewline "." ; flush stdout @@ -638,16 +639,16 @@ proc z2 { } { # It is ideal to increase the await time when the group size is large. set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envD repmgr -local [list localhost $portD] \ - -remote [list localhost $portA] -start client + $envD repmgr -local [list 127.0.0.1 $portD] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envD 100 error_check_good nsites_d [$envD rep_get_nsites] 4 puts -nonewline "." ; flush stdout set envE [berkdb env -create -errpfx E -home $dirE -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envE repmgr -local [list localhost $portE] \ - -remote [list localhost $portA] -start client + $envE repmgr -local [list 127.0.0.1 $portE] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envE 200 error_check_good nsites_e [$envE rep_get_nsites] 5 puts "." ; flush stdout @@ -657,7 +658,7 @@ proc z2 { } { error_check_good s_e_close [$envE close] 0 puts "\tRepmgr029.z2.c: remove site D from the group" - $envA repmgr -remove [list localhost $portD] + $envA repmgr -remove [list 127.0.0.1 $portD] error_check_good rm_at_a \ [string length [repmgr029_site_list_status $envA $portD]] 0 @@ -670,7 +671,7 @@ proc z2 { } { (neither of which know that D has been removed)" set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envD repmgr -local [list localhost $portD] -start elect\ + $envD repmgr -local [list 127.0.0.1 $portD] -start elect\ -timeout {connection_retry 2000000} # Should comments out the await here, otherwise, envD cannot join #await_startup_done $envD @@ -678,7 +679,7 @@ proc z2 { } { set envE [berkdb env -create -errpfx E -home $dirE -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envE repmgr -local [list localhost $portE] -start elect + $envE repmgr -local [list 127.0.0.1 $portE] -start elect await_condition {[expr [stat_field $envD \ rep_stat "Messages processed"] > 0]} puts "."; flush stdout @@ -686,17 +687,17 @@ proc z2 { } { puts -nonewline "\tRepmgr029.z2.f: Start sites A, B, and C" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start elect -pri 200 + $envA repmgr -local [list 127.0.0.1 $portA] -start elect -pri 200 puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] -start elect -pri 150 + $envB repmgr -local [list 127.0.0.1 $portB] -start elect -pri 150 puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] -start elect -pri 100 + $envC repmgr -local [list 127.0.0.1 $portC] -start elect -pri 100 await_startup_done $envC 1000 puts "." ; flush stdout @@ -738,22 +739,22 @@ proc z1 { } { puts -nonewline "\tRepmgr029.z1.a: Set up a group of 3: A, B, C" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master error_check_good nsitesA [$envA rep_get_nsites] 1 puts -nonewline "."; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB error_check_good nsitesB [$envB rep_get_nsites] 2 puts -nonewline "."; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC error_check_good nsitesC [$envC rep_get_nsites] 3 puts "."; flush stdout @@ -761,14 +762,14 @@ proc z1 { } { puts "\tRepmgr029.z1.b: Shut down site B, and remove it from the group." error_check_good s_b_close [$envB close] 0 - $envA repmgr -remove [list localhost $portB] + $envA repmgr -remove [list 127.0.0.1 $portB] error_check_good rm_at_a \ [string length [repmgr029_site_list_status $envA $portB]] 0 puts "\tRepmgr029.z1.c: restart B" set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ + $envB repmgr -local [list 127.0.0.1 $portB] \ -timeout {connection_retry 2000000} -start client await_startup_done $envB @@ -783,13 +784,13 @@ proc z1 { } { # event? puts "\tRepmgr029.z1.d: shut down and remove site B again" error_check_good s_b_close [$envB close] 0 - $envA repmgr -remove [list localhost $portB] + $envA repmgr -remove [list 127.0.0.1 $portB] puts "\tRepmgr029.z1.e: shut down site C, and then restart B" error_check_good s_c_close [$envC close] 0 set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ + $envB repmgr -local [list 127.0.0.1 $portB] \ -timeout {connection_retry 2000000} -start client await_event $envB local_site_removed @@ -833,36 +834,36 @@ proc z9 { } { puts -nonewline "\tRepmgr029.z9: Set up a group of 6" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx B -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts -nonewline "." ; flush stdout set envD [berkdb env -create -errpfx B -home $dirD -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envD repmgr -local [list localhost $portD] \ - -remote [list localhost $portA] -start client + $envD repmgr -local [list 127.0.0.1 $portD] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envD 30 puts -nonewline "." ; flush stdout set envE [berkdb env -create -errpfx B -home $dirE -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envE repmgr -local [list localhost $portE] \ - -remote [list localhost $portA] -start client + $envE repmgr -local [list 127.0.0.1 $portE] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envE 30 puts -nonewline "." ; flush stdout set envF [berkdb env -create -errpfx B -home $dirF -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envF repmgr -local [list localhost $portF] \ - -remote [list localhost $portA] -start client + $envF repmgr -local [list 127.0.0.1 $portF] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envF 40 puts "." @@ -871,11 +872,11 @@ proc z9 { } { puts "\tRepmgr029.z9: Remove site E" $envE close - $envA repmgr -remove [list localhost $portE] + $envA repmgr -remove [list 127.0.0.1 $portE] puts "\tRepmgr029.z9: Remove site D" $envD close - $envA repmgr -remove [list localhost $portD] + $envA repmgr -remove [list 127.0.0.1 $portD] puts "\tRepmgr029.z9: Shut down site C" $envC close @@ -884,7 +885,7 @@ proc z9 { } { $envA close set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start elect + $envA repmgr -local [list 127.0.0.1 $portA] -start elect # We now have a group of 4, with only A and B running. That's not # enough to elect a master. @@ -892,7 +893,7 @@ proc z9 { } { puts "\tRepmgr029.z9: Restart site F" set envF [berkdb env -create -errpfx F -home $dirF -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envF repmgr -local [list localhost $portF] -start elect + $envF repmgr -local [list 127.0.0.1 $portF] -start elect # There are now 3 sites running, in a 4-site group. That should be # enough to elect a master, if site F can be advised of the fact that @@ -935,18 +936,18 @@ proc z10 { } { puts "\tRepmgr029.z10: Set up a group of 3, A (master), B, C" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts "\tRepmgr029.z10: Shut down site C and generate enough churn to force internal init" @@ -976,12 +977,12 @@ proc z10 { } { puts "\tRepmgr029.z10: Restart site C alone" set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] -start elect + $envC repmgr -local [list 127.0.0.1 $portC] -start elect puts "\tRepmgr029.z10: Check list of known sites, A and B" set l [$envC repmgr_site_list] foreach p [list $portA $portB] { - set sought [list localhost $p] + set sought [list 127.0.0.1 $p] error_check_good port$p \ [expr [lsearch -glob $l [concat * $sought *]] >= 0] 1 } @@ -1019,20 +1020,20 @@ proc z11 { } { puts -nonewline "\tRepmgr029.z11: Set up a group initially of size 3" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts "." @@ -1042,8 +1043,8 @@ proc z11 { } { puts "\tRepmgr029.z11: Join new site D" set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ -recover -verbose [list rep $rv] -log_max $log_max] - $envD repmgr -local [list localhost $portD] \ - -remote [list localhost $portA] -start client + $envD repmgr -local [list 127.0.0.1 $portD] \ + -remote [list 127.0.0.1 $portA] -start client puts "\tRepmgr029.z11: Generate enough churn to force internal init at C later" set tail [get_logfile $envA last] @@ -1058,13 +1059,13 @@ proc z11 { } { puts "\tRepmgr029.z11: Restart site C" set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] -start elect + $envC repmgr -local [list 127.0.0.1 $portC] -start elect await_startup_done $envC puts "\tRepmgr029.z11: Check list of known sites" set l [$envC repmgr_site_list] foreach p [list $portA $portB $portD] { - set sought [list localhost $p] + set sought [list 127.0.0.1 $p] error_check_good port$p \ [expr [lsearch -glob $l [concat * $sought *]] >= 0] 1 } @@ -1096,14 +1097,14 @@ proc z12 { } { puts "\tRepmgr029.z12: Start primordial master site A" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA] -start master \ + $envA repmgr -local [list 127.0.0.1 $portA] -start master \ -timeout {connection_retry 2000000} puts "\tRepmgr029.z12: Add new client site B" set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -remote [list localhost $portA] \ - -local [list localhost $portB] -start client + $envB repmgr -remote [list 127.0.0.1 $portA] \ + -local [list 127.0.0.1 $portB] -start client await_startup_done $envB puts "\tRepmgr029.z12: Check connection events" @@ -1136,7 +1137,7 @@ proc z12 { } { $envA close set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] -start elect \ + $envB repmgr -local [list 127.0.0.1 $portB] -start elect \ -timeout {connection_retry 2000000} # new event instances should continue to be fired indefinitely. For # now, consider '3' to be close enough to infinity. @@ -1182,13 +1183,13 @@ proc z13 { } { puts -nonewline "\tRepmgr029.z13: Create first 2 sites" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts "." @@ -1197,8 +1198,8 @@ proc z13 { } { set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - set ret [catch {$envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client} result] + set ret [catch {$envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client} result] error_check_bad no_failure $ret 0 error_check_match unavail $result "*DB_REP_UNAVAIL*" @@ -1220,40 +1221,40 @@ proc z14 { } { set rv on } - env_cleanup $testdir foreach {portA portB portC} [available_ports 3] {} set dirA $testdir/A set dirB $testdir/B set dirC $testdir/C - file mkdir $dirA - file mkdir $dirB - file mkdir $dirC - foreach policy {all allpeers} { + env_cleanup $testdir + file mkdir $dirA + file mkdir $dirB + file mkdir $dirC + puts "\tRepmgr029.z14: Using \"$policy\" ack policy" puts "\tRepmgr029.z14: Create first site A" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -event] - $envA repmgr -local [list localhost $portA] -start master -ack $policy + $envA repmgr -local [list 127.0.0.1 $portA] -start master -ack $policy puts "\tRepmgr029.z14: Add 2nd site, B" set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client -ack $policy + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client -ack $policy await_startup_done $envB puts "\tRepmgr029.z14: Add 3rd site, C" set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client -ack $policy + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client -ack $policy await_startup_done $envC puts "\tRepmgr029.z14: Remove site B" - $envC repmgr -remove [list localhost $portB] + $envC repmgr -remove [list 127.0.0.1 $portB] error_check_good removed \ [string length [repmgr029_site_list_status $envA $portB]] 0 @@ -1291,27 +1292,27 @@ proc z15 { } { puts -nonewline "\tRepmgr029.z15: Create initial group of 4 sites" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts -nonewline "." ; flush stdout set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ -verbose [list rep $rv]] - $envD repmgr -local [list localhost $portD] \ - -remote [list localhost $portA] -start client + $envD repmgr -local [list 127.0.0.1 $portD] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envD puts "." @@ -1320,28 +1321,28 @@ proc z15 { } { $envD close set envE [berkdb env -create -errpfx E -home $dirE -txn -rep -thread \ -verbose [list rep $rv] -event] - set ret [catch {$envE repmgr -local [list localhost $portE] \ - -remote [list localhost $portA] -start client} result] + set ret [catch {$envE repmgr -local [list 127.0.0.1 $portE] \ + -remote [list 127.0.0.1 $portA] -start client} result] error_check_bad no_failure $ret 0 error_check_match unavail $result "*DB_REP_UNAVAIL*" error_check_good nsites [$envA rep_get_nsites] 5 await_condition {[expr [$envB rep_get_nsites] == 5]} puts "\tRepmgr029.z15: Rescind the addition of site E, by removing it" - $envA repmgr -remove [list localhost $portE] + $envA repmgr -remove [list 127.0.0.1 $portE] error_check_good nsites2 [$envA rep_get_nsites] 4 await_condition {[expr [$envB rep_get_nsites] == 4]} puts -nonewline "\tRepmgr029.z15: Restart sites C and D" set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] -start client + $envC repmgr -local [list 127.0.0.1 $portC] -start client await_startup_done $envC puts -nonewline "." ; flush stdout set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envD repmgr -local [list localhost $portD] -start client + $envD repmgr -local [list 127.0.0.1 $portD] -start client await_startup_done $envD puts "." @@ -1357,7 +1358,7 @@ proc z15 { } { and this time try removing site E" $envC close $envD close - set ret [catch {$envA repmgr -remove [list localhost $portE]} result] + set ret [catch {$envA repmgr -remove [list 127.0.0.1 $portE]} result] error_check_bad no_failure2 $ret 0 error_check_match unavail2 $result "*DB_REP_UNAVAIL*" error_check_good nsites2 [$envA rep_get_nsites] 5 @@ -1366,7 +1367,7 @@ proc z15 { } { set db [berkdb open -env $envA -thread __db.rep.system __db.membership] set SITE_DELETING 2 error_check_good deleting \ - [repmgr029_gmdb_status $db localhost $portE] $SITE_DELETING + [repmgr029_gmdb_status $db 127.0.0.1 $portE] $SITE_DELETING $db close puts "\tRepmgr029.z15: See that site E fired event for as little\ @@ -1380,7 +1381,7 @@ proc z15 { } { # zombie carcass in the same env handle. set envE [berkdb env -create -errpfx E -home $dirE -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envE repmgr -local [list localhost $portE] -start client + $envE repmgr -local [list 127.0.0.1 $portE] -start client error_check_good nsites4 [$envA rep_get_nsites] 5 error_check_good nsites5 [$envB rep_get_nsites] 5 @@ -1416,25 +1417,25 @@ proc z16 { } { puts -nonewline "\tRepmgr029.z16: Create a group of 3 sites" set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA] -start master + $envA repmgr -local [list 127.0.0.1 $portA] -start master puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -verbose [list rep $rv] -event] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC puts "." puts "\tRepmgr029.z16: Remove non-existent site" - $envB repmgr -remove [list localhost $portD] + $envB repmgr -remove [list 127.0.0.1 $portD] error_check_good nsites [$envA rep_get_nsites] 3 error_check_good nsites [$envB rep_get_nsites] 3 error_check_good nsites [$envC rep_get_nsites] 3 @@ -1442,7 +1443,7 @@ proc z16 { } { # While we're on the topic of removing sites, let's try having a site # remove itself. puts "\tRepmgr029.z16: Have site C remove itself" - $envC repmgr -remove [list localhost $portC] + $envC repmgr -remove [list 127.0.0.1 $portC] error_check_good nsites [$envA rep_get_nsites] 2 await_event $envC local_site_removed @@ -1478,30 +1479,30 @@ proc z17 { } { `$policy' ack policy" set envA [berkdb env -create -errpfx A -home $dirA -txn \ -rep -thread -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA creator] \ + $envA repmgr -local [list 127.0.0.1 $portA creator] \ -start elect -ack $policy puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn \ -rep -thread -verbose [list rep $rv] -event] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start elect -ack $policy + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start elect -ack $policy await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn \ -rep -thread -verbose [list rep $rv] -event] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start elect + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start elect await_startup_done $envC puts "." puts "\tRepmgr029.z17: Remove both clients." - $envA repmgr -remove [list localhost $portB] + $envA repmgr -remove [list 127.0.0.1 $portB] error_check_good nsites [$envA rep_get_nsites] 2 await_event $envB local_site_removed $envB close - $envA repmgr -remove [list localhost $portC] + $envA repmgr -remove [list 127.0.0.1 $portC] error_check_good nsites [$envA rep_get_nsites] 1 await_event $envC local_site_removed $envC close @@ -1542,7 +1543,7 @@ proc z18 { } { puts -nonewline "\tRepmgr029.z18.a: Start site A as master." set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA creator] \ + $envA repmgr -local [list 127.0.0.1 $portA creator] \ -start master error_check_good nsites_A [$envA rep_get_nsites] 1 puts "." ; flush stdout @@ -1550,8 +1551,8 @@ proc z18 { } { puts -nonewline "\tRepmgr029.z18.b. Start site B" set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -verbose [list rep $rv]] - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB error_check_good nsites_B [$envB rep_get_nsites] 2 puts "." ; flush stdout @@ -1566,8 +1567,8 @@ proc z18 { } { puts "\tRepmgr029.z18.c.2: Start up site C in $dirC." set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envC error_check_good nsites_C [$envC rep_get_nsites] 3 @@ -1614,7 +1615,7 @@ proc z19 {} { puts "\tRepmgr029.z19.a: Start up site A as master " set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv]] - $envA repmgr -local [list localhost $portA creator] -start master + $envA repmgr -local [list 127.0.0.1 $portA creator] -start master error_check_good nsites_A [$envA rep_get_nsites] 1 puts "\tRepmgr029.z19.b: Begin txn and open db on master." diff --git a/test/tcl/repmgr029script.tcl b/test/tcl/repmgr029script.tcl index 29595067..a1420d8a 100644 --- a/test/tcl/repmgr029script.tcl +++ b/test/tcl/repmgr029script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ @@ -25,7 +25,7 @@ proc in_sync_state { d } { puts "Start site C" set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv]] -$envC repmgr -local [list localhost $portC] -start elect +$envC repmgr -local [list 127.0.0.1 $portC] -start elect puts "Wait until it gets into SYNC_PAGES state" while {![in_sync_state $dirC]} { diff --git a/test/tcl/repmgr029script2.tcl b/test/tcl/repmgr029script2.tcl index 0c4ca275..e0288acf 100644 --- a/test/tcl/repmgr029script2.tcl +++ b/test/tcl/repmgr029script2.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ @@ -33,7 +33,7 @@ error_check_good a_txn_A_1 $active_txn_1 1 puts "Repmgr029script2: Start up B. It finishes when the txn has been aborted." set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread] -$envB repmgr -local [list localhost $portB] -remote [list localhost $portA] \ +$envB repmgr -local [list 127.0.0.1 $portB] -remote [list 127.0.0.1 $portA] \ -start client await_startup_done $envB error_check_good a_txn_A_0 [stat_field $envA txn_stat "Number active txns"] 0 @@ -41,4 +41,4 @@ error_check_good a_txn_A_0 [stat_field $envA txn_stat "Number active txns"] 0 puts "Repmgr029script2: Check gmdb at site B" error_check_good nsites_B [$envB rep_get_nsites] 2 -error_check_good client_close [$envB close] 0 \ No newline at end of file +error_check_good client_close [$envB close] 0 diff --git a/test/tcl/repmgr030.tcl b/test/tcl/repmgr030.tcl index 5c4ac3a5..1c9c645f 100644 --- a/test/tcl/repmgr030.tcl +++ b/test/tcl/repmgr030.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2007, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2007, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -57,18 +57,13 @@ proc repmgr030_sub { method niter tnum largs } { file mkdir $clientdir2 file mkdir $clientdir3 - # Use different connection retry timeout values to handle any - # collisions from starting sites at the same time by retrying - # at different times. - # Open a master. puts "\tRepmgr$tnum.a: Start a master." set ma_envcmd "berkdb_env_noerr -create $verbargs \ -errpfx MASTER -home $masterdir -txn -rep -thread" set masterenv [eval $ma_envcmd] $masterenv repmgr -ack all -pri 100 \ - -timeout {connection_retry 20000000} \ - -local [list localhost [lindex $ports 0]] \ + -local [list 127.0.0.1 [lindex $ports 0]] \ -start master # Open three clients, setting first two as peers of the third and @@ -78,11 +73,10 @@ proc repmgr030_sub { method niter tnum largs } { -errpfx CLIENT -home $clientdir -txn -rep -thread" set clientenv [eval $cl_envcmd] $clientenv repmgr -ack all -pri 80 \ - -timeout {connection_retry 10000000} \ - -local [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 3]] \ + -local [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 3]] \ -start client await_startup_done $clientenv @@ -90,11 +84,10 @@ proc repmgr030_sub { method niter tnum largs } { -errpfx CLIENT2 -home $clientdir2 -txn -rep -thread" set clientenv2 [eval $cl2_envcmd] $clientenv2 repmgr -ack all -pri 50 \ - -timeout {connection_retry 5000000} \ - -local [list localhost [lindex $ports 2]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1]] \ - -remote [list localhost [lindex $ports 3]] \ + -local [list 127.0.0.1 [lindex $ports 2]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1]] \ + -remote [list 127.0.0.1 [lindex $ports 3]] \ -start client await_startup_done $clientenv2 @@ -102,11 +95,10 @@ proc repmgr030_sub { method niter tnum largs } { -errpfx CLIENT3 -home $clientdir3 -txn -rep -thread" set clientenv3 [eval $cl3_envcmd] $clientenv3 repmgr -ack all -pri 50 \ - -timeout {connection_retry 75000000} \ - -local [list localhost [lindex $ports 3]] \ - -remote [list localhost [lindex $ports 0]] \ - -remote [list localhost [lindex $ports 1] peer] \ - -remote [list localhost [lindex $ports 2] peer] \ + -local [list 127.0.0.1 [lindex $ports 3]] \ + -remote [list 127.0.0.1 [lindex $ports 0]] \ + -remote [list 127.0.0.1 [lindex $ports 1] peer] \ + -remote [list 127.0.0.1 [lindex $ports 2] peer] \ -start client await_startup_done $clientenv3 diff --git a/test/tcl/repmgr031.tcl b/test/tcl/repmgr031.tcl index f0f7519a..98553607 100644 --- a/test/tcl/repmgr031.tcl +++ b/test/tcl/repmgr031.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # Test for ack policies that vary throughout the group, and that change @@ -32,22 +32,22 @@ proc repmgr031 { } { set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ -recover -verbose [list rep $rv] -event] $envA rep_config {mgrelections off} - $envA repmgr -local [list localhost $portA] -start master -ack none + $envA repmgr -local [list 127.0.0.1 $portA] -start master -ack none puts -nonewline "." ; flush stdout set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv]] $envB rep_config {mgrelections off} - $envB repmgr -local [list localhost $portB] \ - -remote [list localhost $portA] -start client + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client await_startup_done $envB puts -nonewline "." ; flush stdout set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ -recover -verbose [list rep $rv] -event] $envC rep_config {mgrelections off} - $envC repmgr -local [list localhost $portC] \ - -remote [list localhost $portA] -start client -ack none + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client -ack none await_startup_done $envC puts "." @@ -95,7 +95,7 @@ proc repmgr031 { } { set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ -recover -verbose [list rep $rv]] $envB rep_config {mgrelections off} - $envB repmgr -local [list localhost $portB] -start client + $envB repmgr -local [list 127.0.0.1 $portB] -start client await_startup_done $envB eval rep_test $method $envC NULL $niter 0 0 0 diff --git a/test/tcl/repmgr032.tcl b/test/tcl/repmgr032.tcl index 651008d6..462dfe82 100644 --- a/test/tcl/repmgr032.tcl +++ b/test/tcl/repmgr032.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr032 # TEST The (undocumented) AUTOROLLBACK config feature. @@ -76,7 +76,7 @@ proc repmgr032_sub { method tnum test_case largs } { set enva [eval $cmda] $enva rep_config {mgrelections off} eval $enva repmgr $common_mgr -ack allavailable \ - -local {[list localhost $porta]} -start master + -local {[list 127.0.0.1 $porta]} -start master if { $nimdbs } { set omethod [convert_method $method] @@ -91,7 +91,7 @@ proc repmgr032_sub { method tnum test_case largs } { set envb [eval $cmdb] $envb rep_config {mgrelections off} eval $envb repmgr $common_mgr -start client \ - -local {[list localhost $portb]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envb set cmdc "berkdb_env_noerr $common -errpfx SITE_C -home $dirc" @@ -99,7 +99,7 @@ proc repmgr032_sub { method tnum test_case largs } { $envc rep_config {mgrelections off} $envc rep_config {autorollback off} eval $envc repmgr $common_mgr -start client \ - -local {[list localhost $portc]} -remote {[list localhost $porta]} + -local {[list 127.0.0.1 $portc]} -remote {[list 127.0.0.1 $porta]} await_startup_done $envc puts "\tRepmgr$tnum.b: Run some transactions at master." @@ -130,14 +130,14 @@ proc repmgr032_sub { method tnum test_case largs } { set envb [eval $cmdb] $envb rep_config {mgrelections off} eval $envb repmgr $common_mgr -start master \ - -local {[list localhost $portb]} -remote {[list localhost $portc]} + -local {[list 127.0.0.1 $portb]} -remote {[list 127.0.0.1 $portc]} if { $do_close } { set envc [eval $cmdc -recover] $envc rep_config {autorollback off} eval $envc repmgr $common_mgr -start client \ - -local {[list localhost $portc]} \ - -remote {[list localhost $portb]} + -local {[list 127.0.0.1 $portc]} \ + -remote {[list 127.0.0.1 $portb]} } puts "\tRepmgr$tnum.e: Wait for WOULD_ROLLBACK event." await_condition {[is_event_present $envc would_rollback]} diff --git a/test/tcl/repmgr033.tcl b/test/tcl/repmgr033.tcl new file mode 100644 index 00000000..646c53da --- /dev/null +++ b/test/tcl/repmgr033.tcl @@ -0,0 +1,104 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# TEST repmgr033 +# TEST Under quorum policy, if the number of peers in the group is less than a +# TEST majority, that's still OK. + +proc repmgr033 { { tnum "033" } args } { + + source ./include.tcl + + if { $is_freebsd_test == 1 } { + puts "Skipping replication manager test on FreeBSD." + return + } + + set method "btree" + set args [convert_args $method $args] + + puts "Repmgr$tnum: Test quorum policy when the number of peers\ + is less than a majority." + repmgr033_sub $method $tnum $args +} + +proc repmgr033_sub { method tnum largs } { + global rep_verbose + global testdir + + set rv off + if { $rep_verbose == 1 } { + set rv on + } + + env_cleanup $testdir + foreach {portA portB portC portD portE} [available_ports 5] {} + + set dirA $testdir/A + set dirB $testdir/B + set dirC $testdir/C + set dirD $testdir/D + set dirE $testdir/E + + file mkdir $dirA + file mkdir $dirB + file mkdir $dirC + file mkdir $dirD + file mkdir $dirE + + puts -nonewline "\tRepmgr$tnum: Set up a group of 5" + set envA [berkdb env -create -errpfx A -home $dirA -txn -rep -thread \ + -verbose [list rep $rv] -event] + $envA repmgr -local [list 127.0.0.1 $portA] -start master + puts -nonewline "." ; flush stdout + + set envB [berkdb env -create -errpfx B -home $dirB -txn -rep -thread \ + -verbose [list rep $rv]] + $envB repmgr -local [list 127.0.0.1 $portB] \ + -remote [list 127.0.0.1 $portA] -start client + await_startup_done $envB + puts -nonewline "." ; flush stdout + + # These last three clients have priority 0, making them unelectable. + set envC [berkdb env -create -errpfx C -home $dirC -txn -rep -thread \ + -verbose [list rep $rv]] + $envC repmgr -local [list 127.0.0.1 $portC] \ + -remote [list 127.0.0.1 $portA] -start client -pri 0 + await_startup_done $envC + puts -nonewline "." ; flush stdout + + set envD [berkdb env -create -errpfx D -home $dirD -txn -rep -thread \ + -verbose [list rep $rv]] + $envD repmgr -local [list 127.0.0.1 $portD] \ + -remote [list 127.0.0.1 $portA] -start client -pri 0 + await_startup_done $envD + puts -nonewline "." ; flush stdout + + set envE [berkdb env -create -errpfx E -home $dirE -txn -rep -thread \ + -verbose [list rep $rv]] + $envE repmgr -local [list 127.0.0.1 $portE] \ + -remote [list 127.0.0.1 $portA] -pri 0 -start client + await_startup_done $envE + puts "." + + puts "\tRepmgr$tnum: Write updates and check perm_failed event" + $envA event_info -clear + set niter 1 + rep_test $method $envA NULL $niter 0 0 0 $largs + error_check_good nofailure \ + [string length [find_event [$envA event_info] perm_failed]] 0 + + # If site B, the only other electable site, is missing, then we should + # get a perm failure, because the other clients' acks are worthless. + $envB close + rep_test $method $envA NULL $niter 0 0 0 $largs + error_check_bad failure \ + [string length [find_event [$envA event_info] perm_failed]] 0 + + # Clean up. + $envE close + $envD close + $envC close + $envA close +} diff --git a/test/tcl/repmgr034.tcl b/test/tcl/repmgr034.tcl new file mode 100644 index 00000000..c212b990 --- /dev/null +++ b/test/tcl/repmgr034.tcl @@ -0,0 +1,228 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST repmgr034 +# TEST Repmgr site removal and restart. +# TEST +# TEST Start two repmgr sites, master and client1. The client1 removes +# TEST itself and restarts, sometimes more than once. Start a third +# TEST repmgr site client2 and make sure it can remove client1 from +# TEST the group. +# TEST +# TEST This test must use heartbeats to ensure that a client that has +# TEST been removed and restarted without recovery can sync up. +# TEST +proc repmgr034 { {niter 3} {tnum "034"} } { + source ./include.tcl + + if { $is_freebsd_test == 1 } { + puts "Skipping replication manager test on FreeBSD platform." + return + } + + set method "btree" + # The iter is the number of iteration on site removal and restart. + # When iter is 0, start master, client1, client2, and let client2 + # remove client1. When iter is non-0, client1 removes itself and + # restart iterately before being removed by client2. + foreach iter "0 $niter" { + # The nentries is the number of records being inserted + # to master when client1 is removed from the group. + # When nentries is 0, client1 does not need any sync up + # with master when restart its repmgr. When it is 100, + # client1 needs to sync up a bit. When it is 1000, + # it is simulated that client1 has been removed for a + # while in the group. + foreach nentries {0 100 1000} { + repmgr034_sub $method $tnum $iter $nentries + } + } +} + +proc repmgr034_sub { method tnum niter nentries} { + source ./include.tcl + global databases_in_memory + global env_private + global testdir + global repfiles_in_memory + global rep_verbose + global verbose_type + + if { $databases_in_memory } { + set dbmemmsg "using in-memory databases " + if { [is_queueext $method] } { + puts -nonewline "Skipping repmgr$tnum for method " + puts "$method with named in-memory databases." + return + } + set dbname { "" "test.db" } + } else { + set dbmemmsg "using on-disk databases " + set dbname "test.db" + } + + if { $env_private == 1 } { + set privargs " -private " + set primsg "in private env " + } else { + set privargs "" + set primsg "" + } + + if { $niter > 0 } { + set nitermsg "and restart for $niter time(s) " + } else { + set nitermsg "" + } + + if { $repfiles_in_memory } { + set repmemargs " -rep_inmem_files " + set repmemmsg "and in-memory replication files " + } else { + set repmemargs "" + set repmemmsg "and on-disk replication files " + } + + if { $rep_verbose == 1 } { + set verbargs " -verbose {$verbose_type on} " + } else { + set verbargs "" + } + + set omethod [convert_method $method] + + puts "Repmgr$tnum: Repmgr site removal, clean-up\ + $nitermsg$dbmemmsg$repmemmsg$primsg\ + with $nentries record(s)" + + foreach {port0 port1 port2} [available_ports 3] {} + env_cleanup $testdir + file mkdir [set masterdir $testdir/MASTERDIR] + file mkdir [set clientdir1 $testdir/CLIENTDIR1] + file mkdir [set clientdir2 $testdir/CLIENTDIR2] + + puts "\tRepmgr$tnum.a: Start master" + set env0 [eval "berkdb_env -create -errpfx MASTER -home $masterdir \ + -txn -rep -thread -recover $privargs $repmemargs $verbargs"] + $env0 repmgr -timeout {heartbeat_send 500000} + $env0 repmgr -local [list 127.0.0.1 $port0] -start master + error_check_good nsites_A0 [$env0 rep_get_nsites] 1 + set db [berkdb_open_noerr -create -auto_commit -env $env0 \ + $omethod $dbname] + error_check_good env0_opendb [is_valid_db $db] TRUE + + puts "\tRepmgr$tnum.b: Start client1" + set env1 [eval "berkdb_env_noerr -create -errpfx CLIENT1 \ + -home $clientdir1 -txn -rep -thread -recover -event \ + $privargs $repmemargs $verbargs"] + $env1 repmgr -timeout {heartbeat_monitor 1100000} + $env1 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client + await_startup_done $env1 + error_check_good nsites_B0 [$env0 rep_get_nsites] 2 + error_check_good nsites_A1 [$env1 rep_get_nsites] 2 + set db1 [berkdb_open_noerr -create -auto_commit -env $env1 \ + $omethod $dbname] + error_check_good env1_opendb [is_valid_db $db1] TRUE + + + if {$niter == 0} { + puts "\tRepmgr$tnum.c: Skip site self-removal and restart" + } else { + puts "\tRepmgr$tnum.c: Site removal and restart for\ + $niter time(s)" + } + for { set count 1 } { $count <= $niter } {incr count } { + $env1 event_info -clear + puts "\t\tRepmgr$tnum.c.$count.(a): Client1 removes itself from\ + the group: iter $count" + $env1 repmgr -remove [list 127.0.0.1 $port1] + await_event $env1 local_site_removed + error_check_good nsites_C0 [$env0 rep_get_nsites] 1 + + puts "\t\tRepmgr$tnum.c.$count.(b): The removed client1 is\ + still read only" + catch { [$db1 put "key" "data"] } ret + error_check_good readonly_failure \ + [is_substr $ret "permission denied"] 1 + error_check_good db1_notfound [llength [$db1 get "none"]] 0 + + if { $nentries > 0 } { + puts "\t\tRepmgr$tnum.c.$count.(b1): Write $nentries\ + record(s) on master, might/might not be synced\ + up to client1" + for { set i 0 } { $i < $nentries } { incr i } { + error_check_good db_put \ + [$db put "key_${count}_${i}]" "data"] 0 + } + error_check_good nkeys \ + [stat_field $db stat "Number of keys"] \ + [expr $nentries * $count ] + } + + puts "\t\tRepmgr$tnum.c.$count.(c): Restart client1" + $env1 repmgr -timeout {heartbeat_monitor 1100000} + # Allow a retry in case client1 didn't have time to fully + # shut down. + if {[catch {$env1 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client} result] && \ + [string match "*REP_UNAVAIL*" $result]} { + tclsleep 10 + $env1 repmgr -local [list 127.0.0.1 $port1] \ + -remote [list 127.0.0.1 $port0] -start client + } + await_event $env1 connection_established + error_check_good nsites_D0 [$env0 rep_get_nsites] 2 + error_check_good nsites_B1 [$env1 rep_get_nsites] 2 + + if { $nentries > 0 } { + puts "\t\tRepmgr$tnum.c.$count.(c1): Check client1 sync\ + up with master" + set max_retries [expr $nentries / 10 ] + for { set i 0 } { $i < $max_retries } { incr i } { + if { [stat_field $db1 stat "Number of keys"] \ + == [expr $nentries * $count ] } { + break + } else { + tclsleep 2 + } + } + if { $i == $max_retries } { + error "sync up duration is longer than expected" + } + } + } + + puts "\tRepmgr$tnum.d: Start client2" + set env2 [eval "berkdb_env -create -errpfx CLIENT2 -home $clientdir2 \ + -txn -rep -thread -recover -event $privargs $repmemargs $verbargs"] + # It is possible, especially when nentries=0, that we need a delay + # before the recently restarted client1 can ack a new site addition. + $env2 repmgr -timeout {heartbeat_monitor 1200000} + if {[catch {$env2 repmgr -local [list 127.0.0.1 $port2] \ + -remote [list 127.0.0.1 $port0] -start client} result] && \ + [string match "*REP_UNAVAIL*" $result]} { + tclsleep 3 + $env2 repmgr -local [list 127.0.0.1 $port2] \ + -remote [list 127.0.0.1 $port0] -start client + } + await_startup_done $env2 100 + + puts "\tRepmgr$tnum.e: Client2 removes client1 from the group" + $env2 repmgr -remove [list 127.0.0.1 $port1] + await_event $env1 local_site_removed + error_check_good nsites_F0 [$env0 rep_get_nsites] 2 + catch { [$db1 put "key" "data"] } ret + error_check_good readonly_failure \ + [is_substr $ret "permission denied"] 1 + + puts "\tRepmgr$tnum.f: Close all" + error_check_good db1_close [$db1 close] 0 + error_check_good db_close [$db close] 0 + error_check_good s_2_close [$env2 close] 0 + error_check_good s_1_close [$env1 close] 0 + error_check_good s_0_close [$env0 close] 0 +} diff --git a/test/tcl/repmgr100.tcl b/test/tcl/repmgr100.tcl index 0664c568..cfae3dea 100644 --- a/test/tcl/repmgr100.tcl +++ b/test/tcl/repmgr100.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr100 @@ -40,7 +40,7 @@ proc repmgr100 { } { fconfigure $master -buffering line puts $master "home $masterdir" make_dbconfig $masterdir \ - [list [list repmgr_site localhost $master_port db_local_site on] \ + [list [list repmgr_site 127.0.0.1 $master_port db_local_site on] \ "rep_set_config db_repmgr_conf_2site_strict off"] puts $master "output $testdir/m1output" puts $master "open_env" @@ -55,8 +55,8 @@ proc repmgr100 { } { puts $client "home $clientdir" puts $client "local $client_port" make_dbconfig $clientdir \ - [list [list repmgr_site localhost $client_port db_local_site on] \ - [list repmgr_site localhost $master_port db_bootstrap_helper on] \ + [list [list repmgr_site 127.0.0.1 $client_port db_local_site on] \ + [list repmgr_site 127.0.0.1 $master_port db_bootstrap_helper on] \ "rep_set_config db_repmgr_conf_2site_strict off"] puts $client "output $testdir/coutput" puts $client "open_env" diff --git a/test/tcl/repmgr101.tcl b/test/tcl/repmgr101.tcl index 7d0af34b..9d5b9625 100644 --- a/test/tcl/repmgr101.tcl +++ b/test/tcl/repmgr101.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr101 # TEST Repmgr support for multi-process master. @@ -34,7 +34,7 @@ proc repmgr101 { } { fconfigure $master -buffering line puts $master "home $masterdir" make_dbconfig $masterdir \ - [list [list repmgr_site localhost $master_port db_local_site on] \ + [list [list repmgr_site 127.0.0.1 $master_port db_local_site on] \ "rep_set_config db_repmgr_conf_2site_strict off"] puts $master "output $testdir/m1output" puts $master "open_env" @@ -65,8 +65,8 @@ proc repmgr101 { } { fconfigure $client -buffering line puts $client "home $clientdir" make_dbconfig $clientdir \ - [list [list repmgr_site localhost $client_port db_local_site on] \ - [list repmgr_site localhost $master_port db_bootstrap_helper on] \ + [list [list repmgr_site 127.0.0.1 $client_port db_local_site on] \ + [list repmgr_site 127.0.0.1 $master_port db_bootstrap_helper on] \ "rep_set_config db_repmgr_conf_2site_strict off"] puts $client "output $testdir/coutput" puts $client "open_env" diff --git a/test/tcl/repmgr102.tcl b/test/tcl/repmgr102.tcl index e55c16f5..d15a2cc6 100644 --- a/test/tcl/repmgr102.tcl +++ b/test/tcl/repmgr102.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr102 # TEST Ensuring exactly one listener process. @@ -38,7 +38,7 @@ proc repmgr102 { } { set master_port [lindex $ports 0] make_dbconfig $masterdir \ - [list [list repmgr_site localhost $master_port db_local_site on] \ + [list [list repmgr_site 127.0.0.1 $master_port db_local_site on] \ "rep_set_config db_repmgr_conf_2site_strict off"] set masterenv [berkdb_env -rep -txn -thread -home $masterdir \ -isalive my_isalive -create] diff --git a/test/tcl/repmgr105.tcl b/test/tcl/repmgr105.tcl index d486786e..957ffc82 100644 --- a/test/tcl/repmgr105.tcl +++ b/test/tcl/repmgr105.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr105 # TEST Repmgr recognition of peer setting, across processes. @@ -60,7 +60,7 @@ proc repmgr105_sub { config } { "home $testdir/A" \ "local $portA" \ "output $testdir/aoutput" \ - "remote localhost $mport" \ + "remote 127.0.0.1 $mport" \ "open_env" \ "start client"]] set env [berkdb_env -home $testdir/A] @@ -72,7 +72,7 @@ proc repmgr105_sub { config } { "home $testdir/B" \ "local $portB" \ "output $testdir/boutput" \ - "remote localhost $mport" \ + "remote 127.0.0.1 $mport" \ "open_env" \ "start client"]] set env [berkdb_env -home $testdir/B] @@ -145,17 +145,17 @@ proc repmgr105_sub { config } { # proc repmgr105_position_chg { c2 c } { set remote_config [uplevel 1 {list \ - "remote localhost $mport" \ - "remote localhost $portB" \ - "remote -p localhost $portA"}] + "remote 127.0.0.1 $mport" \ + "remote 127.0.0.1 $portB" \ + "remote -p 127.0.0.1 $portA"}] set i [lsearch -exact $c2 "open_env"] # It should be found, in the middle somewhere, or this will break. set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" set remote_config [uplevel 1 {list \ - "remote -p localhost $portA" \ - "remote localhost $mport"}] + "remote -p 127.0.0.1 $portA" \ + "remote 127.0.0.1 $mport"}] set i [lsearch -exact $c "open_env"] set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" @@ -166,17 +166,17 @@ proc repmgr105_position_chg { c2 c } { # proc repmgr105_chg_site { c2 c } { set remote_config [uplevel 1 {list \ - "remote localhost $mport" \ - "remote -p localhost $portB"}] + "remote 127.0.0.1 $mport" \ + "remote -p 127.0.0.1 $portB"}] set i [lsearch -exact $c2 "open_env"] # It should be found, in the middle somewhere, or this will break. set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" set remote_config [uplevel 1 {list \ - "remote localhost $portB" \ - "remote -p localhost $portA" \ - "remote localhost $mport"}] + "remote 127.0.0.1 $portB" \ + "remote -p 127.0.0.1 $portA" \ + "remote 127.0.0.1 $mport"}] set i [lsearch -exact $c "open_env"] set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" @@ -191,17 +191,17 @@ proc repmgr105_chg_site { c2 c } { # proc repmgr105_chg_after_open { c2 c } { set remote_config [uplevel 1 {list \ - "remote localhost $mport" \ - "remote localhost $portB" \ - "remote -p localhost $portA"}] + "remote 127.0.0.1 $mport" \ + "remote 127.0.0.1 $portB" \ + "remote -p 127.0.0.1 $portA"}] set i [lsearch -exact $c2 "open_env"] # It should be found, in the middle somewhere, or this will break. set c2 "[lrange $c2 0 [expr $i - 1]] $remote_config [lrange $c2 $i end]" set remote_config [uplevel 1 {list \ - "remote -p localhost $portB" \ - "remote localhost $mport"}] + "remote -p 127.0.0.1 $portB" \ + "remote 127.0.0.1 $mport"}] set i [lsearch -exact $c "open_env"] set c "[lrange $c 0 [expr $i - 1]] $remote_config [lrange $c $i end]" @@ -212,7 +212,7 @@ proc repmgr105_chg_after_open { c2 c } { # previously discovered a bug. # proc repmgr105_set_peer_after_open { c2 c } { - set remote_config [uplevel 1 {subst "remote -p localhost $portA"}] + set remote_config [uplevel 1 {subst "remote -p 127.0.0.1 $portA"}] lappend c $remote_config return [list $c2 $c] } diff --git a/test/tcl/repmgr106.tcl b/test/tcl/repmgr106.tcl index bdd60c24..32c502ce 100644 --- a/test/tcl/repmgr106.tcl +++ b/test/tcl/repmgr106.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr106 # TEST Simple smoke test for repmgr elections with multi-process envs. @@ -25,15 +25,15 @@ proc repmgr106 { } { # First just create the group. file mkdir $testdir/A make_dbconfig $testdir/A \ - [linsert $timeouts 0 [list repmgr_site localhost $portA db_local_site on]] + [linsert $timeouts 0 [list repmgr_site 127.0.0.1 $portA db_local_site on]] file mkdir $testdir/B make_dbconfig $testdir/B \ - [linsert $timeouts 0 [list repmgr_site localhost $portB db_local_site on] \ - [list repmgr_site localhost $portA db_bootstrap_helper on]] + [linsert $timeouts 0 [list repmgr_site 127.0.0.1 $portB db_local_site on] \ + [list repmgr_site 127.0.0.1 $portA db_bootstrap_helper on]] file mkdir $testdir/C make_dbconfig $testdir/C \ - [linsert $timeouts 0 [list repmgr_site localhost $portC db_local_site on] \ - [list repmgr_site localhost $portA db_bootstrap_helper on]] + [linsert $timeouts 0 [list repmgr_site 127.0.0.1 $portC db_local_site on] \ + [list repmgr_site 127.0.0.1 $portA db_bootstrap_helper on]] set cmds { {home $testdir/A} {open_env} diff --git a/test/tcl/repmgr107.tcl b/test/tcl/repmgr107.tcl index 5775ded3..999b63d5 100644 --- a/test/tcl/repmgr107.tcl +++ b/test/tcl/repmgr107.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr107 # TEST Repmgr combined with replication-unaware process at master. @@ -28,7 +28,7 @@ proc repmgr107 { } { {rep_set_timeout DB_REP_HEARTBEAT_MONITOR 1100000} } make_dbconfig $mdir \ - [linsert $dbconfig 0 [list repmgr_site localhost $mport db_local_site on]] + [linsert $dbconfig 0 [list repmgr_site 127.0.0.1 $mport db_local_site on]] set cmds { "home $mdir" "output $testdir/moutput" @@ -42,8 +42,8 @@ proc repmgr107 { } { make_dbconfig $cdir \ [linsert $dbconfig 0 \ - [list repmgr_site localhost $cport db_local_site on] \ - [list repmgr_site localhost $mport db_bootstrap_helper on]] + [list repmgr_site 127.0.0.1 $cport db_local_site on] \ + [list repmgr_site 127.0.0.1 $mport db_bootstrap_helper on]] set cmds { "home $cdir" "output $testdir/coutput" diff --git a/test/tcl/repmgr108.tcl b/test/tcl/repmgr108.tcl index 7ec7c839..1eb29c92 100644 --- a/test/tcl/repmgr108.tcl +++ b/test/tcl/repmgr108.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr108 # TEST Subordinate connections and processes should not trigger elections. @@ -19,10 +19,10 @@ proc repmgr108 { } { file mkdir [set cdir $testdir/CLIENT] make_dbconfig $mdir \ - [list [list repmgr_site localhost $mport db_local_site on]] + [list [list repmgr_site 127.0.0.1 $mport db_local_site on]] make_dbconfig $cdir \ - [list [list repmgr_site localhost $cport db_local_site on] \ - [list repmgr_site localhost $mport db_bootstrap_helper on]] + [list [list repmgr_site 127.0.0.1 $cport db_local_site on] \ + [list repmgr_site 127.0.0.1 $mport db_bootstrap_helper on]] puts "\tRepmgr$tnum.a: Set up a pair of sites, two processes each." set cmds { diff --git a/test/tcl/repmgr109.tcl b/test/tcl/repmgr109.tcl index cbb73567..f4b55057 100644 --- a/test/tcl/repmgr109.tcl +++ b/test/tcl/repmgr109.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr109 # TEST Test repmgr's internal juggling of peer EID's. @@ -68,7 +68,7 @@ proc repmgr109_sub { {a_too false} {while_active true} } { "home $dira" "local $aport" "output $testdir/aoutput" - "remote localhost $mport" + "remote 127.0.0.1 $mport" "open_env" "start client" } @@ -78,7 +78,7 @@ proc repmgr109_sub { {a_too false} {while_active true} } { "home $dirb" "local $bport" "output $testdir/boutput" - "remote localhost $mport" + "remote 127.0.0.1 $mport" "open_env" "start client" } @@ -100,8 +100,8 @@ proc repmgr109_sub { {a_too false} {while_active true} } { "home $dirc" "local $cport" "output $testdir/c1output" - "remote $peer_flag localhost $aport" - "remote localhost $mport" + "remote $peer_flag 127.0.0.1 $aport" + "remote 127.0.0.1 $mport" "open_env" } set c1 [open_site_prog [subst $cmds]] @@ -110,8 +110,8 @@ proc repmgr109_sub { {a_too false} {while_active true} } { "home $dirc" "local $cport" "output $testdir/c2output" - "remote -p localhost $bport" - "remote localhost $aport" + "remote -p 127.0.0.1 $bport" + "remote 127.0.0.1 $aport" "open_env" } set c2 [open_site_prog [subst $cmds]] @@ -159,16 +159,16 @@ proc repmgr109_sub { {a_too false} {while_active true} } { "home $dirc" "output $testdir/c1output2" "open_env" - "remote localhost $bport" - "remote -p localhost $aport" + "remote 127.0.0.1 $bport" + "remote -p 127.0.0.1 $aport" "start client" } } else { set cmds { "home $dirc" "output $testdir/c1output2" - "remote localhost $bport" - "remote -p localhost $aport" + "remote 127.0.0.1 $bport" + "remote -p 127.0.0.1 $aport" "open_env" "start client" } diff --git a/test/tcl/repmgr110.tcl b/test/tcl/repmgr110.tcl index 0912e44d..394dfdaf 100644 --- a/test/tcl/repmgr110.tcl +++ b/test/tcl/repmgr110.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr110 # TEST Multi-process repmgr start-up policies. @@ -40,7 +40,7 @@ proc repmgr110 { } { "home $dirb" "local $bport" "output $testdir/boutput1" - "remote localhost $aport" + "remote 127.0.0.1 $aport" "open_env" "start client" } @@ -70,7 +70,7 @@ proc repmgr110 { } { "home $dirb" "local $bport" "output $testdir/boutput1" - "remote localhost $aport" + "remote 127.0.0.1 $aport" "open_env" "start election" } @@ -134,7 +134,7 @@ proc repmgr110 { } { "home $dira" "local $aport" "output $testdir/a2output2" - "remote localhost $bport" + "remote 127.0.0.1 $bport" "open_env" "start master" } diff --git a/test/tcl/repmgr111.tcl b/test/tcl/repmgr111.tcl index d2a784f1..6e607533 100644 --- a/test/tcl/repmgr111.tcl +++ b/test/tcl/repmgr111.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr111 # TEST Multi-process repmgr with env open before set local site. @@ -43,7 +43,7 @@ proc repmgr111 { } { make_dbconfig $clientdir {{rep_set_config db_repmgr_conf_2site_strict off}} puts $client "output $testdir/coutput" puts $client "open_env" - puts $client "remote localhost $master_port" + puts $client "remote 127.0.0.1 $master_port" puts $client "start client" error_check_match start_client [gets $client] "*Successful*" diff --git a/test/tcl/repmgr112.tcl b/test/tcl/repmgr112.tcl index 43b0ee60..701ab3a1 100644 --- a/test/tcl/repmgr112.tcl +++ b/test/tcl/repmgr112.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # TEST repmgr112 # TEST Multi-process repmgr ack policies. @@ -55,7 +55,7 @@ proc repmgr112 { } { make_dbconfig $clientdir {} puts $client "output $testdir/coutput" puts $client "open_env" - puts $client "remote localhost $master_port" + puts $client "remote 127.0.0.1 $master_port" puts $client "start client" error_check_match start_client [gets $client] "*Successful*" @@ -74,7 +74,7 @@ proc repmgr112 { } { make_dbconfig $clientdir2 {} puts $client2 "output $testdir/c2output" puts $client2 "open_env" - puts $client2 "remote localhost $master_port" + puts $client2 "remote 127.0.0.1 $master_port" puts $client2 "start client" error_check_match start_client2 [gets $client2] "*Successful*" diff --git a/test/tcl/reputils.tcl b/test/tcl/reputils.tcl index 02963c33..0a656113 100644 --- a/test/tcl/reputils.tcl +++ b/test/tcl/reputils.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -355,7 +355,8 @@ proc repl_envsetup { envargs largs test {nclients 1} {droppct 0} { oob 0 } } { error_check_good env_close [$env close] 0 berkdb envremove -home $testdir - set small_pagesize_tests [list test035 test096 test112 test113 test114] + set small_pagesize_tests [list test035 test096 test112 test113 \ + test114 test135 test136] if { [lsearch -exact $small_pagesize_tests $test] != -1 } { set pagesize 512 } @@ -374,7 +375,7 @@ proc repl_envsetup { envargs largs test {nclients 1} {droppct 0} { oob 0 } } { set logregion 2097152 set ma_cmd "berkdb_env_noerr -create -log_max $logmax $envargs \ - -cachesize { 0 4194304 1 } -log_regionmax $logregion \ + -cachesize { 0 16777216 1 } -log_regionmax $logregion \ -lock_max_objects $lockmax -lock_max_locks $lockmax \ -errpfx $masterdir $verbargs -pagesize $pagesize \ -home $masterdir -txn nosync -rep_master -rep_transport \ @@ -388,7 +389,7 @@ proc repl_envsetup { envargs largs test {nclients 1} {droppct 0} { oob 0 } } { set envid [expr $i + 2] repladd $envid set cl_cmd "berkdb_env_noerr -create $envargs -txn nosync \ - -cachesize { 0 10000000 0 } -log_regionmax $logregion \ + -cachesize { 0 16777216 0 } -log_regionmax $logregion \ -lock_max_objects $lockmax -lock_max_locks $lockmax \ -errpfx $clientdir($i) $verbargs -pagesize $pagesize \ -home $clientdir($i) -rep_client -rep_transport \ @@ -1734,6 +1735,14 @@ proc rep_test { method env repdb {nentries 10000} \ incr count } close $did + set privateindx [lsearch [$env get_open_flags] "-private"] + if { $databases_in_memory == 1 && $privateindx == -1 } { + set inmemfile [lindex [$db get_dbname] 1] + set inmemdir [$env get_home] + # Don't dump/load, we don't have a replicated environment handle + error_check_good dbverify_inmem \ + [dbverify_inmem $inmemfile $inmemdir "" 0 1 0 1] 0 + } if { $repdb == "NULL" } { error_check_good rep_close [$db close] 0 } @@ -1858,6 +1867,14 @@ proc rep_test_bulk { method env repdb {nentries 10000} \ error_check_good txn [$t commit] 0 error_check_good txn_checkpoint [$env txn_checkpoint] 0 close $did + set privateindx [lsearch [$env get_open_flags] "-private"] + if { $databases_in_memory == 1 && $privateindx == -1 } { + set inmemfile [lindex [$db get_dbname] 1] + set inmemdir [$env get_home] + # Don't dump/load, we don't have a replicated environment handle + error_check_good dbverify_inmem \ + [dbverify_inmem $inmemfile $inmemdir "" 0 1 0 1] 0 + } if { $repdb == "NULL" } { error_check_good rep_close [$db close] 0 } @@ -2275,8 +2292,21 @@ proc rep_verify { masterdir masterenv clientdir clientenv \ # Check locations of dbs, repfiles, region files. if { $dbname != "NULL" } { - check_db_location $masterenv $dbname $datadir - check_db_location $clientenv $dbname $datadir + # + # check_db_location assumes the path through the env_home + # to the datadir, when one is given. Construct that here. + # + if { $datadir != "" } { + set mhome [get_home $masterenv] + set chome [get_home $clientenv] + set mdatadir $mhome/$datadir + set cdatadir $chome/$datadir + } else { + set mdatadir "" + set cdatadir "" + } + check_db_location $masterenv $dbname $mdatadir + check_db_location $clientenv $dbname $cdatadir } if { $repfiles_in_memory } { @@ -2379,65 +2409,6 @@ proc rep_verify_inmem { masterenv clientenv mdb cdb } { error_check_good recs $mrecs $crecs } -# NOTE: This routine has been copied to ../test/sql/bdb_util.tcl -# and changes to it should be made in both places because the SQL -# tests are currently independent of the core tests. -# -# Return a list of TCP port numbers that are not currently in use on -# the local system. Note that this doesn't actually reserve the -# ports, so it's possible that by the time the caller tries to use -# them, another process could have taken one of them. But for our -# purposes that's unlikely enough that this is still useful: it's -# still better than trying to find hard-coded port numbers that will -# always be available. -# -# Using a starting baseport value that falls in the non-ephemeral port -# range on most platforms. Can override starting baseport by setting -# environment variable BDBBASEPORT. -# -proc available_ports { n { rangeincr 10 } } { - global env - - if { [info exists env(BDBBASEPORT)] } { - set baseport $env(BDBBASEPORT) - } else { - set baseport 30100 - } - - # Try sets of contiguous ports ascending from baseport. - for { set i $baseport } { $i < $baseport + $rangeincr * 100 } \ - { incr i $rangeincr } { - set ports {} - set socks {} - set numports $n - set curport $i - - # Try one set of contiguous ports. - while { [incr numports -1] >= 0 } { - incr curport - if [catch { socket -server Unused \ - -myaddr localhost $curport } sock] { - # A port is unavailable, try another set. - break - } - lappend socks $sock - lappend ports $curport - } - foreach sock $socks { - close $sock - } - if { $numports == -1 } { - # We have all the ports we need. - break - } - } - if { $numports == -1 } { - return $ports - } else { - error "available_ports: could not get ports for $baseport" - } -} - # Return the corresponding site number for an individual port number # previously returned by available_ports. This procedure assumes that # the baseport number, n and rangeincr value are unchanged from the @@ -2922,3 +2893,21 @@ proc replicate_make_config { sitedir i pri } { } close $cid } + +# +# Proc for checking exclusive access to databases on clients. +# +proc rep_client_access { env testfile result } { + set t [$env txn -nowait] + set ret [catch {eval {berkdb_open} -env $env -txn $t $testfile} res] + $t abort + if { $result == "FAIL" } { + error_check_good clacc_fail $ret 1 + error_check_good clacc_fail_err \ + [is_substr $res "DB_LOCK_NOTGRANTED"] 1 + } else { + error_check_good clacc_good $ret 0 + error_check_good clacc_good1 [is_valid_db $res] TRUE + error_check_good clacc_close [$res close] 0 + } +} diff --git a/test/tcl/reputilsnoenv.tcl b/test/tcl/reputilsnoenv.tcl index 61409022..b8753de5 100644 --- a/test/tcl/reputilsnoenv.tcl +++ b/test/tcl/reputilsnoenv.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # The procs in this file are used for replication messaging # ONLY when the default mechanism of setting up a queue of diff --git a/test/tcl/rsrc001.tcl b/test/tcl/rsrc001.tcl index 7665b079..0867f7e3 100644 --- a/test/tcl/rsrc001.tcl +++ b/test/tcl/rsrc001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rsrc002.tcl b/test/tcl/rsrc002.tcl index 753c85c5..a230f292 100644 --- a/test/tcl/rsrc002.tcl +++ b/test/tcl/rsrc002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rsrc003.tcl b/test/tcl/rsrc003.tcl index fa414b54..e060dc12 100644 --- a/test/tcl/rsrc003.tcl +++ b/test/tcl/rsrc003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/rsrc004.tcl b/test/tcl/rsrc004.tcl index 3f5cb5f1..f2546254 100644 --- a/test/tcl/rsrc004.tcl +++ b/test/tcl/rsrc004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb001.tcl b/test/tcl/sdb001.tcl index 74ddb462..e9a04de9 100644 --- a/test/tcl/sdb001.tcl +++ b/test/tcl/sdb001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb002.tcl b/test/tcl/sdb002.tcl index b2b0b65c..be19c6d9 100644 --- a/test/tcl/sdb002.tcl +++ b/test/tcl/sdb002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb003.tcl b/test/tcl/sdb003.tcl index e598a689..f3117126 100644 --- a/test/tcl/sdb003.tcl +++ b/test/tcl/sdb003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb004.tcl b/test/tcl/sdb004.tcl index 9e043f4a..efd2ca15 100644 --- a/test/tcl/sdb004.tcl +++ b/test/tcl/sdb004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb005.tcl b/test/tcl/sdb005.tcl index 9edf6897..0db82101 100644 --- a/test/tcl/sdb005.tcl +++ b/test/tcl/sdb005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb006.tcl b/test/tcl/sdb006.tcl index 3b256f89..b8514df7 100644 --- a/test/tcl/sdb006.tcl +++ b/test/tcl/sdb006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb007.tcl b/test/tcl/sdb007.tcl index 23db4b04..46e0c8c5 100644 --- a/test/tcl/sdb007.tcl +++ b/test/tcl/sdb007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb008.tcl b/test/tcl/sdb008.tcl index 15fa2e5b..15a57e96 100644 --- a/test/tcl/sdb008.tcl +++ b/test/tcl/sdb008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb009.tcl b/test/tcl/sdb009.tcl index 628911f2..d3b36a57 100644 --- a/test/tcl/sdb009.tcl +++ b/test/tcl/sdb009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb010.tcl b/test/tcl/sdb010.tcl index bf192bc2..8cba398a 100644 --- a/test/tcl/sdb010.tcl +++ b/test/tcl/sdb010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb011.tcl b/test/tcl/sdb011.tcl index bba61aff..8ccdd6b9 100644 --- a/test/tcl/sdb011.tcl +++ b/test/tcl/sdb011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb012.tcl b/test/tcl/sdb012.tcl index b20f288d..b4e8e5f5 100644 --- a/test/tcl/sdb012.tcl +++ b/test/tcl/sdb012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb013.tcl b/test/tcl/sdb013.tcl index 508e2f48..8b9f3904 100644 --- a/test/tcl/sdb013.tcl +++ b/test/tcl/sdb013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -46,11 +46,19 @@ proc sdb013 { method { nentries 10 } args } { # the cache a little larger, but still on the small side. env_cleanup $testdir set csize {0 65536 1} + + # First check the native on-disk page size. + set native_pagesize [get_native_pagesize] + if { $native_pagesize > 8192 } { + set cache [expr 8 * $native_pagesize] + set csize "0 $cache 1" + } + # If we passed in a large pagesize in the args, adjust again. set pgindex [lsearch -exact $args "-pagesize"] if { $pgindex != -1 } { incr pgindex set pagesize [lindex $args $pgindex] - if { $pagesize > 8192 } { + if { $pagesize > $native_pagesize && $pagesize > 8192 } { set cache [expr 8 * $pagesize] set csize "0 $cache 1" } diff --git a/test/tcl/sdb014.tcl b/test/tcl/sdb014.tcl index 3e85af3a..45696f9b 100644 --- a/test/tcl/sdb014.tcl +++ b/test/tcl/sdb014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb015.tcl b/test/tcl/sdb015.tcl index 41372809..b0d631ef 100644 --- a/test/tcl/sdb015.tcl +++ b/test/tcl/sdb015.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb016.tcl b/test/tcl/sdb016.tcl index f2aec25b..0c5c4816 100644 --- a/test/tcl/sdb016.tcl +++ b/test/tcl/sdb016.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb017.tcl b/test/tcl/sdb017.tcl index 65ea0be5..c1c1b306 100644 --- a/test/tcl/sdb017.tcl +++ b/test/tcl/sdb017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb018.tcl b/test/tcl/sdb018.tcl index 95fe831c..206e9701 100644 --- a/test/tcl/sdb018.tcl +++ b/test/tcl/sdb018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb019.tcl b/test/tcl/sdb019.tcl index 481b0501..6414b36d 100644 --- a/test/tcl/sdb019.tcl +++ b/test/tcl/sdb019.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdb020.tcl b/test/tcl/sdb020.tcl index be2f1443..e4d9281d 100644 --- a/test/tcl/sdb020.tcl +++ b/test/tcl/sdb020.tcl @@ -1,13 +1,14 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # # TEST sdb020 # TEST Tests in-memory subdatabases. # TEST Create an in-memory subdb with one page size. Close, and -# TEST open with a different page size: should fail. +# TEST open with a different page size: should succeed, but the underlying +# TEST page size is not changed. proc sdb020 { method { nentries 10 } args } { source ./include.tcl @@ -74,14 +75,17 @@ proc sdb020 { method { nentries 10 } args } { error_check_good db_close [$db close] 0 - # Try to open again with a different page size (should fail). + # Try to open again with a different page size (should succeed). puts "\tSubdb$tnum.b: Try to reopen with different page size." - set errorCode NONE - catch {set db [eval {berkdb_open_noerr} $args -env $env \ - -pagesize $psize2 {$omethod $testfile $name}]} res - error_check_good expect_error [is_substr $errorCode EINVAL] 1 + set db [eval {berkdb_open_noerr} $args -env $env \ + -pagesize $psize2 {$omethod $testfile $name}] + error_check_good dbopen [is_valid_db $db] TRUE + error_check_good check_pagesize \ + [stat_field $db stat "Page size"] $psize + # Close DB + error_check_good db_close [$db close] 0 - # Try to open again with the correct pagesize (should succeed). + # Try to open again with original pagesize (should succeed). puts "\tSubdb$tnum.c: Reopen with original page size." set db [eval {berkdb_open_noerr} $args -env $env \ -pagesize $psize {$omethod $testfile $name}] @@ -95,15 +99,18 @@ proc sdb020 { method { nentries 10 } args } { error_check_good dbopen [is_valid_db $db] TRUE error_check_good db_close [$db close] 0 - # Try to open again with a different page size (should fail). + # Try to open again with a different page size (should succeed). set psize2 [expr $psize / 2] puts "\tSubdb$tnum.e: Try to reopen with different page size." - set errorCode NONE - catch {set db [eval {berkdb_open_noerr} $args -env $env \ - -pagesize $psize2 {$omethod $testfile $name}]} res - error_check_good expect_error [is_substr $errorCode EINVAL] 1 + set db [eval {berkdb_open_noerr} $args -env $env \ + -pagesize $psize2 {$omethod $testfile $name}] + error_check_good dbopen [is_valid_db $db] TRUE + error_check_good check_pagesize \ + [stat_field $db stat "Page size"] $psize + # Close DB + error_check_good db_close [$db close] 0 - # Try to open again with the correct pagesize (should succeed). + # Try to open again with original pagesize (should succeed). puts "\tSubdb$tnum.f: Reopen with original page size." set db [eval {berkdb_open} $args -env $env \ -pagesize $psize {$omethod $testfile $name}] diff --git a/test/tcl/sdbscript.tcl b/test/tcl/sdbscript.tcl index 1512286f..3ff1f69b 100644 --- a/test/tcl/sdbscript.tcl +++ b/test/tcl/sdbscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdbtest001.tcl b/test/tcl/sdbtest001.tcl index 5f5988f6..e6f01cb9 100644 --- a/test/tcl/sdbtest001.tcl +++ b/test/tcl/sdbtest001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdbtest002.tcl b/test/tcl/sdbtest002.tcl index 465e480e..547c014e 100644 --- a/test/tcl/sdbtest002.tcl +++ b/test/tcl/sdbtest002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sdbutils.tcl b/test/tcl/sdbutils.tcl index 48725d6e..cc1551fc 100644 --- a/test/tcl/sdbutils.tcl +++ b/test/tcl/sdbutils.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sec001.tcl b/test/tcl/sec001.tcl index 30ae7da6..31f04a1b 100644 --- a/test/tcl/sec001.tcl +++ b/test/tcl/sec001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sec002.tcl b/test/tcl/sec002.tcl index 396dd450..7b459a5b 100644 --- a/test/tcl/sec002.tcl +++ b/test/tcl/sec002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/shelltest.tcl b/test/tcl/shelltest.tcl index 4bd5f57f..66abb430 100644 --- a/test/tcl/shelltest.tcl +++ b/test/tcl/shelltest.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si001.tcl b/test/tcl/si001.tcl index fb1504f6..81c3f7a5 100644 --- a/test/tcl/si001.tcl +++ b/test/tcl/si001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si002.tcl b/test/tcl/si002.tcl index f1b1d6cb..e26c8914 100644 --- a/test/tcl/si002.tcl +++ b/test/tcl/si002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si003.tcl b/test/tcl/si003.tcl index 618f033c..fe73ce76 100644 --- a/test/tcl/si003.tcl +++ b/test/tcl/si003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si004.tcl b/test/tcl/si004.tcl index d65bd932..0952f4d8 100644 --- a/test/tcl/si004.tcl +++ b/test/tcl/si004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si005.tcl b/test/tcl/si005.tcl index 50b531ea..d66e6a9f 100644 --- a/test/tcl/si005.tcl +++ b/test/tcl/si005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si006.tcl b/test/tcl/si006.tcl index 92650b3e..4aa83342 100644 --- a/test/tcl/si006.tcl +++ b/test/tcl/si006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/si007.tcl b/test/tcl/si007.tcl index 2216471a..7590b30c 100644 --- a/test/tcl/si007.tcl +++ b/test/tcl/si007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -125,6 +125,7 @@ proc si007 { methods {nentries 10} {tnum "007"} args } { {$key [chop_data $pmethod $datum]}] error_check_good put($n) $ret 0 } + close $did # Open and associate the secondaries, with -create. puts "\tSi$tnum.b: Associate secondaries with -create." diff --git a/test/tcl/si008.tcl b/test/tcl/si008.tcl index be244782..f675dc30 100644 --- a/test/tcl/si008.tcl +++ b/test/tcl/si008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sijointest.tcl b/test/tcl/sijointest.tcl index 0a885d9a..fe1a9699 100644 --- a/test/tcl/sijointest.tcl +++ b/test/tcl/sijointest.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/siutils.tcl b/test/tcl/siutils.tcl index fd85d293..392ae5d5 100644 --- a/test/tcl/siutils.tcl +++ b/test/tcl/siutils.tcl @@ -1,6 +1,6 @@ #See the file LICENSE for redistribution information. # -# Copyright (c) 2001, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/sysscript.tcl b/test/tcl/sysscript.tcl index c17488bd..7b5667cb 100644 --- a/test/tcl/sysscript.tcl +++ b/test/tcl/sysscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/t106script.tcl b/test/tcl/t106script.tcl index 34485505..6be452fe 100644 --- a/test/tcl/t106script.tcl +++ b/test/tcl/t106script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test.tcl b/test/tcl/test.tcl index 2d698a92..8e2579c5 100644 --- a/test/tcl/test.tcl +++ b/test/tcl/test.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ @@ -642,15 +642,6 @@ proc r { args } { set tindex 0 } set clist [lrange $test_names(test) $tindex end] - set skip_list [list test126 test127 test128 \ - test129 test131 test132 test133 test134] - foreach stest $skip_list { - set sindx [lsearch -exact $clist $stest] - if {$sindx == -1} { - continue - } - set clist [lreplace $clist $sindx $sindx] - } foreach test $clist { eval run_compressed btree $test $display $run } @@ -1245,10 +1236,9 @@ proc run_replicate_test { method test {nsites 2} {largs "" } } { # Test124 can't be run under reptest because we delete all # the test files at the end of the test to avoid triggering - # verification failures (it uses a non-standard sort). - + # verification failures (it uses a non-standard sort). if { $test == "test124" } { - puts "Skipping test124 under run_replicate" + puts "Skipping $test under run_replicate" return } @@ -1469,9 +1459,8 @@ proc run_reptest { method test {droppct 0} {nclients 1} {do_del 0} \ # Test124 can't be run under reptest because we delete all # the test files at the end of the test to avoid triggering # verification failures (it uses a non-standard sort). - - if { $test == "test124" } { - puts "Skipping test124 under run_repmethod" + if { $test == "test124"} { + puts "Skipping $test under run_repmethod" return } diff --git a/test/tcl/test001.tcl b/test/tcl/test001.tcl index dd650c9c..83318d87 100644 --- a/test/tcl/test001.tcl +++ b/test/tcl/test001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test002.tcl b/test/tcl/test002.tcl index ac9e4584..72ee53f1 100644 --- a/test/tcl/test002.tcl +++ b/test/tcl/test002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test003.tcl b/test/tcl/test003.tcl index 948bac68..66c454f8 100644 --- a/test/tcl/test003.tcl +++ b/test/tcl/test003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -130,6 +130,7 @@ proc test003 { method args} { set txn "-txn $t" } dump_bin_file $db $txn $t1 $checkfunc + if { $txnenv == 1 } { error_check_good txn [$t commit] 0 } @@ -143,7 +144,12 @@ proc test003 { method args} { puts $oid $i } close $oid - file rename -force $t1 $t3 + if { [is_heap $method] == 1 } { + # There's no ordering in a heap database + filesort $t1 $t3 -n + } else { + file rename -force $t1 $t3 + } } else { set oid [open $t2.tmp w] foreach f $file_list { diff --git a/test/tcl/test004.tcl b/test/tcl/test004.tcl index 275df533..19d97a82 100644 --- a/test/tcl/test004.tcl +++ b/test/tcl/test004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test005.tcl b/test/tcl/test005.tcl index 744090e1..ebcf070b 100644 --- a/test/tcl/test005.tcl +++ b/test/tcl/test005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test006.tcl b/test/tcl/test006.tcl index 020a880b..f48a12fd 100644 --- a/test/tcl/test006.tcl +++ b/test/tcl/test006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test007.tcl b/test/tcl/test007.tcl index 881d5371..d2d7f7cb 100644 --- a/test/tcl/test007.tcl +++ b/test/tcl/test007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test008.tcl b/test/tcl/test008.tcl index 7edfbd4b..70791ae6 100644 --- a/test/tcl/test008.tcl +++ b/test/tcl/test008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test009.tcl b/test/tcl/test009.tcl index e9967e27..26582d3d 100644 --- a/test/tcl/test009.tcl +++ b/test/tcl/test009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test010.tcl b/test/tcl/test010.tcl index b66f9379..f7ba06a0 100644 --- a/test/tcl/test010.tcl +++ b/test/tcl/test010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test011.tcl b/test/tcl/test011.tcl index c938f81c..2756200d 100644 --- a/test/tcl/test011.tcl +++ b/test/tcl/test011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test012.tcl b/test/tcl/test012.tcl index cdc616e1..6d1d0bd5 100644 --- a/test/tcl/test012.tcl +++ b/test/tcl/test012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test013.tcl b/test/tcl/test013.tcl index 0b16a219..248a981d 100644 --- a/test/tcl/test013.tcl +++ b/test/tcl/test013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test014.tcl b/test/tcl/test014.tcl index 65f4adc9..bf23580a 100644 --- a/test/tcl/test014.tcl +++ b/test/tcl/test014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -203,7 +203,12 @@ proc test014_body { method flagp chars increase {nentries 10000} args } { puts $oid $i } close $oid - file rename -force $t1 $t3 + if { [is_heap $method] == 1 } { + # No ordering in heap + filesort $t1 $t3 -n + } else { + file rename -force $t1 $t3 + } } else { set q q filehead $nentries $dict $t3 diff --git a/test/tcl/test015.tcl b/test/tcl/test015.tcl index 0c649c08..c7e227af 100644 --- a/test/tcl/test015.tcl +++ b/test/tcl/test015.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test016.tcl b/test/tcl/test016.tcl index 96915f39..bd8581a0 100644 --- a/test/tcl/test016.tcl +++ b/test/tcl/test016.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test017.tcl b/test/tcl/test017.tcl index cfe2cb2f..cfd8ba7e 100644 --- a/test/tcl/test017.tcl +++ b/test/tcl/test017.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test018.tcl b/test/tcl/test018.tcl index fc59a1c4..62034815 100644 --- a/test/tcl/test018.tcl +++ b/test/tcl/test018.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test019.tcl b/test/tcl/test019.tcl index 2ec2d036..48b0dfd6 100644 --- a/test/tcl/test019.tcl +++ b/test/tcl/test019.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test020.tcl b/test/tcl/test020.tcl index 35a72374..4ffb57d3 100644 --- a/test/tcl/test020.tcl +++ b/test/tcl/test020.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test021.tcl b/test/tcl/test021.tcl index 51a3fe10..2c511660 100644 --- a/test/tcl/test021.tcl +++ b/test/tcl/test021.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test022.tcl b/test/tcl/test022.tcl index 4c9fb5e0..de5788ef 100644 --- a/test/tcl/test022.tcl +++ b/test/tcl/test022.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test023.tcl b/test/tcl/test023.tcl index 2b8ff35b..5596363e 100644 --- a/test/tcl/test023.tcl +++ b/test/tcl/test023.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test024.tcl b/test/tcl/test024.tcl index 83e4f91a..75448f83 100644 --- a/test/tcl/test024.tcl +++ b/test/tcl/test024.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test025.tcl b/test/tcl/test025.tcl index 8aa04afc..17681cc1 100644 --- a/test/tcl/test025.tcl +++ b/test/tcl/test025.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test026.tcl b/test/tcl/test026.tcl index f028eacf..c425f7f8 100644 --- a/test/tcl/test026.tcl +++ b/test/tcl/test026.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test027.tcl b/test/tcl/test027.tcl index 2e19eaa7..679900e6 100644 --- a/test/tcl/test027.tcl +++ b/test/tcl/test027.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test028.tcl b/test/tcl/test028.tcl index 1b6ff92c..b15748f9 100644 --- a/test/tcl/test028.tcl +++ b/test/tcl/test028.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test029.tcl b/test/tcl/test029.tcl index 13ddb435..7efcd4ad 100644 --- a/test/tcl/test029.tcl +++ b/test/tcl/test029.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test030.tcl b/test/tcl/test030.tcl index 183d02ab..b89543e4 100644 --- a/test/tcl/test030.tcl +++ b/test/tcl/test030.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test031.tcl b/test/tcl/test031.tcl index 1581267a..633a1200 100644 --- a/test/tcl/test031.tcl +++ b/test/tcl/test031.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test032.tcl b/test/tcl/test032.tcl index 1b99b1a3..634e17df 100644 --- a/test/tcl/test032.tcl +++ b/test/tcl/test032.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test033.tcl b/test/tcl/test033.tcl index f78dcb32..517b3a4c 100644 --- a/test/tcl/test033.tcl +++ b/test/tcl/test033.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test034.tcl b/test/tcl/test034.tcl index 64978aa5..5a1e1b6e 100644 --- a/test/tcl/test034.tcl +++ b/test/tcl/test034.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test035.tcl b/test/tcl/test035.tcl index 01f49403..b6dc8874 100644 --- a/test/tcl/test035.tcl +++ b/test/tcl/test035.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test036.tcl b/test/tcl/test036.tcl index 5983280c..bfe915bd 100644 --- a/test/tcl/test036.tcl +++ b/test/tcl/test036.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test037.tcl b/test/tcl/test037.tcl index 2b820e18..1e05cd96 100644 --- a/test/tcl/test037.tcl +++ b/test/tcl/test037.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test038.tcl b/test/tcl/test038.tcl index 98a4e9e1..86247a34 100644 --- a/test/tcl/test038.tcl +++ b/test/tcl/test038.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test039.tcl b/test/tcl/test039.tcl index e3fdc003..ded3f729 100644 --- a/test/tcl/test039.tcl +++ b/test/tcl/test039.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test040.tcl b/test/tcl/test040.tcl index b374ab1f..06072bf1 100644 --- a/test/tcl/test040.tcl +++ b/test/tcl/test040.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1998, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test041.tcl b/test/tcl/test041.tcl index e38c1c2a..298ef339 100644 --- a/test/tcl/test041.tcl +++ b/test/tcl/test041.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test042.tcl b/test/tcl/test042.tcl index 58bfdb8c..6b26e2dd 100644 --- a/test/tcl/test042.tcl +++ b/test/tcl/test042.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test043.tcl b/test/tcl/test043.tcl index af00364b..8b61dc37 100644 --- a/test/tcl/test043.tcl +++ b/test/tcl/test043.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test044.tcl b/test/tcl/test044.tcl index 57cb35a3..fbb47aec 100644 --- a/test/tcl/test044.tcl +++ b/test/tcl/test044.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test045.tcl b/test/tcl/test045.tcl index 598ab5f8..277ee05c 100644 --- a/test/tcl/test045.tcl +++ b/test/tcl/test045.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test046.tcl b/test/tcl/test046.tcl index cf4979ed..82216f98 100644 --- a/test/tcl/test046.tcl +++ b/test/tcl/test046.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test047.tcl b/test/tcl/test047.tcl index 460b64d8..5eb4ddca 100644 --- a/test/tcl/test047.tcl +++ b/test/tcl/test047.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test048.tcl b/test/tcl/test048.tcl index 32179a85..8ff08f29 100644 --- a/test/tcl/test048.tcl +++ b/test/tcl/test048.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test049.tcl b/test/tcl/test049.tcl index 73f75ef4..11d39188 100644 --- a/test/tcl/test049.tcl +++ b/test/tcl/test049.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test050.tcl b/test/tcl/test050.tcl index 31272a60..24d7c24e 100644 --- a/test/tcl/test050.tcl +++ b/test/tcl/test050.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test051.tcl b/test/tcl/test051.tcl index f75801a2..d24cd5ab 100644 --- a/test/tcl/test051.tcl +++ b/test/tcl/test051.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test052.tcl b/test/tcl/test052.tcl index 41c43b77..7de85c78 100644 --- a/test/tcl/test052.tcl +++ b/test/tcl/test052.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test053.tcl b/test/tcl/test053.tcl index 6b8eb392..6eb1785e 100644 --- a/test/tcl/test053.tcl +++ b/test/tcl/test053.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test054.tcl b/test/tcl/test054.tcl index e68a6323..531bb3a0 100644 --- a/test/tcl/test054.tcl +++ b/test/tcl/test054.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test055.tcl b/test/tcl/test055.tcl index c5a2238e..8e27f843 100644 --- a/test/tcl/test055.tcl +++ b/test/tcl/test055.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test056.tcl b/test/tcl/test056.tcl index d428f4ce..95d1b8ad 100644 --- a/test/tcl/test056.tcl +++ b/test/tcl/test056.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test057.tcl b/test/tcl/test057.tcl index 021fbd25..595944bc 100644 --- a/test/tcl/test057.tcl +++ b/test/tcl/test057.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test058.tcl b/test/tcl/test058.tcl index 7c34dce0..5fa938a1 100644 --- a/test/tcl/test058.tcl +++ b/test/tcl/test058.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test059.tcl b/test/tcl/test059.tcl index a804e174..ac01ebf5 100644 --- a/test/tcl/test059.tcl +++ b/test/tcl/test059.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test060.tcl b/test/tcl/test060.tcl index 6710bd94..f3864de0 100644 --- a/test/tcl/test060.tcl +++ b/test/tcl/test060.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test061.tcl b/test/tcl/test061.tcl index 9c811789..0283f93a 100644 --- a/test/tcl/test061.tcl +++ b/test/tcl/test061.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test062.tcl b/test/tcl/test062.tcl index a024916d..b46474b8 100644 --- a/test/tcl/test062.tcl +++ b/test/tcl/test062.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test063.tcl b/test/tcl/test063.tcl index 2509547f..37abdcc7 100644 --- a/test/tcl/test063.tcl +++ b/test/tcl/test063.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test064.tcl b/test/tcl/test064.tcl index 4672c3c3..c7ddccf4 100644 --- a/test/tcl/test064.tcl +++ b/test/tcl/test064.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test065.tcl b/test/tcl/test065.tcl index 07bb5531..b1799373 100644 --- a/test/tcl/test065.tcl +++ b/test/tcl/test065.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test066.tcl b/test/tcl/test066.tcl index 7d431845..66563016 100644 --- a/test/tcl/test066.tcl +++ b/test/tcl/test066.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test067.tcl b/test/tcl/test067.tcl index 31536b16..0fef74a5 100644 --- a/test/tcl/test067.tcl +++ b/test/tcl/test067.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test068.tcl b/test/tcl/test068.tcl index 2751ea2c..8d3766ba 100644 --- a/test/tcl/test068.tcl +++ b/test/tcl/test068.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test069.tcl b/test/tcl/test069.tcl index 4ef4daa6..de06c1ad 100644 --- a/test/tcl/test069.tcl +++ b/test/tcl/test069.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test070.tcl b/test/tcl/test070.tcl index 41038a3b..da7f38fb 100644 --- a/test/tcl/test070.tcl +++ b/test/tcl/test070.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test071.tcl b/test/tcl/test071.tcl index c74023aa..6bfd4d95 100644 --- a/test/tcl/test071.tcl +++ b/test/tcl/test071.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test072.tcl b/test/tcl/test072.tcl index 5fa549ec..a02d6f3a 100644 --- a/test/tcl/test072.tcl +++ b/test/tcl/test072.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test073.tcl b/test/tcl/test073.tcl index 8577d3c0..e9aacc9a 100644 --- a/test/tcl/test073.tcl +++ b/test/tcl/test073.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test074.tcl b/test/tcl/test074.tcl index 8d558ffa..e80a8acb 100644 --- a/test/tcl/test074.tcl +++ b/test/tcl/test074.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test076.tcl b/test/tcl/test076.tcl index 40174466..73dd18ce 100644 --- a/test/tcl/test076.tcl +++ b/test/tcl/test076.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test077.tcl b/test/tcl/test077.tcl index e1f9c874..7036eea8 100644 --- a/test/tcl/test077.tcl +++ b/test/tcl/test077.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test078.tcl b/test/tcl/test078.tcl index ae271ed2..d82eade9 100644 --- a/test/tcl/test078.tcl +++ b/test/tcl/test078.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test079.tcl b/test/tcl/test079.tcl index 3e27fff0..cd98feae 100644 --- a/test/tcl/test079.tcl +++ b/test/tcl/test079.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test081.tcl b/test/tcl/test081.tcl index adf14e8f..00121b88 100644 --- a/test/tcl/test081.tcl +++ b/test/tcl/test081.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test082.tcl b/test/tcl/test082.tcl index 62823356..7f591ec4 100644 --- a/test/tcl/test082.tcl +++ b/test/tcl/test082.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test083.tcl b/test/tcl/test083.tcl index 9adcb4e3..112b10b6 100644 --- a/test/tcl/test083.tcl +++ b/test/tcl/test083.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test084.tcl b/test/tcl/test084.tcl index c62f8f8c..0b690e1e 100644 --- a/test/tcl/test084.tcl +++ b/test/tcl/test084.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test085.tcl b/test/tcl/test085.tcl index 998752e7..428878b7 100644 --- a/test/tcl/test085.tcl +++ b/test/tcl/test085.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test086.tcl b/test/tcl/test086.tcl index b463c606..f6aa5058 100644 --- a/test/tcl/test086.tcl +++ b/test/tcl/test086.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test087.tcl b/test/tcl/test087.tcl index 284b738b..921bd1ae 100644 --- a/test/tcl/test087.tcl +++ b/test/tcl/test087.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test088.tcl b/test/tcl/test088.tcl index 7d978e69..9d57f498 100644 --- a/test/tcl/test088.tcl +++ b/test/tcl/test088.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test089.tcl b/test/tcl/test089.tcl index 9212df7a..0bb72213 100644 --- a/test/tcl/test089.tcl +++ b/test/tcl/test089.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test090.tcl b/test/tcl/test090.tcl index 5a37f5a9..457b4364 100644 --- a/test/tcl/test090.tcl +++ b/test/tcl/test090.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test091.tcl b/test/tcl/test091.tcl index f2d94f62..d736fe4a 100644 --- a/test/tcl/test091.tcl +++ b/test/tcl/test091.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test092.tcl b/test/tcl/test092.tcl index a2484148..92ceff58 100644 --- a/test/tcl/test092.tcl +++ b/test/tcl/test092.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test093.tcl b/test/tcl/test093.tcl index 1245e01b..316b3bca 100644 --- a/test/tcl/test093.tcl +++ b/test/tcl/test093.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test094.tcl b/test/tcl/test094.tcl index 0ed43c95..dec38fa7 100644 --- a/test/tcl/test094.tcl +++ b/test/tcl/test094.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test095.tcl b/test/tcl/test095.tcl index f1793dca..e55abeaa 100644 --- a/test/tcl/test095.tcl +++ b/test/tcl/test095.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test096.tcl b/test/tcl/test096.tcl index d2300cb6..b6c1b80a 100644 --- a/test/tcl/test096.tcl +++ b/test/tcl/test096.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test097.tcl b/test/tcl/test097.tcl index 72065f8d..ed75cc62 100644 --- a/test/tcl/test097.tcl +++ b/test/tcl/test097.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test098.tcl b/test/tcl/test098.tcl index 3dfa8668..079e3360 100644 --- a/test/tcl/test098.tcl +++ b/test/tcl/test098.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2002, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test099.tcl b/test/tcl/test099.tcl index d2053af4..02a87708 100644 --- a/test/tcl/test099.tcl +++ b/test/tcl/test099.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test100.tcl b/test/tcl/test100.tcl index e59c1c1b..1b9a77bc 100644 --- a/test/tcl/test100.tcl +++ b/test/tcl/test100.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test101.tcl b/test/tcl/test101.tcl index d52158c0..a2f4ced0 100644 --- a/test/tcl/test101.tcl +++ b/test/tcl/test101.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test102.tcl b/test/tcl/test102.tcl index faa3f0b9..58f7bd27 100644 --- a/test/tcl/test102.tcl +++ b/test/tcl/test102.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -11,8 +11,7 @@ proc test102 { method {nsets 1000} {tnum "102"} args } { set args [convert_args $method $args] set omethod [convert_method $method] - if { [is_rbtree $method] == 1 || - [is_heap $method] == 1 || [is_record_based $method] == 0} { + if { [is_rbtree $method] == 1 || [is_record_based $method] == 0} { puts "Test$tnum skipping for method $method" return } diff --git a/test/tcl/test103.tcl b/test/tcl/test103.tcl index 28a8ef0b..93904dcb 100644 --- a/test/tcl/test103.tcl +++ b/test/tcl/test103.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test106.tcl b/test/tcl/test106.tcl index b78d3168..ac518bee 100644 --- a/test/tcl/test106.tcl +++ b/test/tcl/test106.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test107.tcl b/test/tcl/test107.tcl index b7b3a9f0..2d08ce63 100644 --- a/test/tcl/test107.tcl +++ b/test/tcl/test107.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test109.tcl b/test/tcl/test109.tcl index 1808ce93..05acb3d6 100644 --- a/test/tcl/test109.tcl +++ b/test/tcl/test109.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test110.tcl b/test/tcl/test110.tcl index eca73432..6eb952a8 100644 --- a/test/tcl/test110.tcl +++ b/test/tcl/test110.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2004, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test111.tcl b/test/tcl/test111.tcl index 6ad16ec6..a9649ddc 100644 --- a/test/tcl/test111.tcl +++ b/test/tcl/test111.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test112.tcl b/test/tcl/test112.tcl index 20a8aae6..eeb55141 100644 --- a/test/tcl/test112.tcl +++ b/test/tcl/test112.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test113.tcl b/test/tcl/test113.tcl index 4e7dfdb1..8d6bfce6 100644 --- a/test/tcl/test113.tcl +++ b/test/tcl/test113.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test114.tcl b/test/tcl/test114.tcl index 540b1b00..088a426e 100644 --- a/test/tcl/test114.tcl +++ b/test/tcl/test114.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test115.tcl b/test/tcl/test115.tcl index 85a3cf09..f6b3a2b8 100644 --- a/test/tcl/test115.tcl +++ b/test/tcl/test115.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test116.tcl b/test/tcl/test116.tcl index a683fed0..fd4895df 100644 --- a/test/tcl/test116.tcl +++ b/test/tcl/test116.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test117.tcl b/test/tcl/test117.tcl index 2fb9ca38..04954fe3 100644 --- a/test/tcl/test117.tcl +++ b/test/tcl/test117.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test119.tcl b/test/tcl/test119.tcl index 7475c16e..cabfe89d 100644 --- a/test/tcl/test119.tcl +++ b/test/tcl/test119.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test120.tcl b/test/tcl/test120.tcl index 830bbafd..bb9192b7 100644 --- a/test/tcl/test120.tcl +++ b/test/tcl/test120.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test121.tcl b/test/tcl/test121.tcl index 65b3ef45..bfd17f52 100644 --- a/test/tcl/test121.tcl +++ b/test/tcl/test121.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test122.tcl b/test/tcl/test122.tcl index 6dd87767..242a90a2 100644 --- a/test/tcl/test122.tcl +++ b/test/tcl/test122.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2006, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test123.tcl b/test/tcl/test123.tcl index 3aa0bfbb..bcfa92ff 100644 --- a/test/tcl/test123.tcl +++ b/test/tcl/test123.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test124.tcl b/test/tcl/test124.tcl index 053f2ae8..32ee1365 100644 --- a/test/tcl/test124.tcl +++ b/test/tcl/test124.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2008, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test125.tcl b/test/tcl/test125.tcl index e8f40cd6..1eb6eb10 100644 --- a/test/tcl/test125.tcl +++ b/test/tcl/test125.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2009, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test126.tcl b/test/tcl/test126.tcl index 87563a0d..21939eff 100644 --- a/test/tcl/test126.tcl +++ b/test/tcl/test126.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -13,24 +13,37 @@ # TEST and make sure if the correct items are deleted. proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} - {subdb 0} {secondary 0} args } { + {subdb 0} {secondary 0} {sort_multiple 0} args } { source ./include.tcl # For rrecno, when keys are deleted, the ones after will move forward, # and the keys change, which is not good to verify after delete. # So, we skip rrecno temporarily. - # Heap databases do not current support bulk operations - if {[is_rrecno $method] || [is_heap $method] } { + if {[is_rrecno $method] } { puts "Skipping test$tnum for $method test." return } + # It is only makes sense for btree database to sort bulk buffer. + if {$sort_multiple && ![is_btree $method]} { + puts "Skipping test$tnum for $method with -sort_multiple." + return + } + + # For compressed databases, we need to sort the items in + # the bulk buffer before doing the bulk put/delete operations. + if {[is_compressed $args] && !$sort_multiple} { + puts "Skipping test$tnum for compressed databases\ + without -sort_multiple." + return + } + set subname "" set sub_msg "" # Check if we use sub database. if { $subdb } { - if {[is_queue $method]} { + if {[is_queue $method] || [is_heap $method]} { puts "Skipping test$tnum with sub database for $method." return } @@ -78,6 +91,11 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} set args [convert_args $method $args] set omethod [convert_method $method] + set extra_op "" + if {$sort_multiple} { + set extra_op "-sort_multiple" + } + puts "Test$tnum: $method ($args)\ Database bulk update $sub_msg $sec_msg." @@ -102,6 +120,7 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} # Open a simple dupsort btree database. # In order to be consistent, we need to use all the passed-in # am-unrelated flags. + set sec_args [convert_args "btree" $sec_args] set sec_db [eval {berkdb_open_noerr -create -mode 0644} $sec_args \ -dup -dupsort -btree $sec_testfile $sec_subname] error_check_good secdb_open [is_valid_db $sec_db] TRUE @@ -123,7 +142,7 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} # First, we put half the entries using put -multiple. # Then, we put the rest half using put -multiple_key. - puts "\tTest$tnum.a: Bulk put data using -multiple." + puts "\tTest$tnum.a: Bulk put data using -multiple $extra_op." set key_list1 {} set data_list1 {} while { [gets $did str] != -1 && $count < $nentries / 2 } { @@ -133,19 +152,27 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} set key $str set str [reverse $str] } + set data [make_fixed_length $method $str] lappend key_list1 $key - lappend data_list1 [make_fixed_length $method $str] + lappend data_list1 $data incr count + if { [is_heap $method] } { + set ret [eval {$db put} $txn {$key $data}] + } } - set ret [eval {$db put} $txn -multiple {$key_list1 $data_list1}] - error_check_good {put(-multiple)} $ret 0 + if { [is_heap $method] == 0 } { + set ret [eval {$db put} $txn -multiple $extra_op \ + {$key_list1 $data_list1}] + error_check_good "put(-multiple $extra_op)" $ret 0 + } # Put again, should succeed - set ret [eval {$db put} $txn -multiple {$key_list1 $data_list1}] - error_check_good {put_again(-multiple)} $ret 0 - - puts "\tTest$tnum.b: Bulk put data using -multiple_key." + set ret [eval {$db put} $txn -multiple $extra_op \ + {$key_list1 $data_list1}] + error_check_good "put_again(-multiple $extra_op)" $ret 0 + + puts "\tTest$tnum.b: Bulk put data using -multiple_key $extra_op." set pair_list1 {} while { [gets $did str] != -1 && $count < $nentries } { if { [is_record_based $method] == 1 } { @@ -154,16 +181,24 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} set key $str set str [reverse $str] } - lappend pair_list1 $key [make_fixed_length $method $str] + set data [make_fixed_length $method $str] + lappend pair_list1 $key $data incr count + if { [is_heap $method] } { + set ret [eval {$db put} $txn $key $data] + } + } + + if { [is_heap $method] == 0 } { + set ret [eval {$db put} $txn -multiple_key $extra_op \ + {$pair_list1}] + error_check_good "put(-multiple_key $extra_op)" $ret 0 } - set ret [eval {$db put} $txn -multiple_key {$pair_list1}] - error_check_good {put(-multiple_key)} $ret 0 - # Put again, should succeed - set ret [eval {$db put} $txn -multiple_key {$pair_list1}] - error_check_good {put_again(-multiple_key)} $ret 0 + set ret [eval {$db put} $txn -multiple_key $extra_op \ + {$pair_list1}] + error_check_good "put_again(-multiple_key $extra_op)" $ret 0 close $did @@ -188,32 +223,34 @@ proc test126 {method { nentries 10000 } { tnum "126" } {callback 1} $key_list1 $data_list1 $txn } - puts "\tTest$tnum.d: Bulk delete data using -multiple." + puts "\tTest$tnum.d: Bulk delete data using -multiple $extra_op." set key_list2 {} for { set i 0 } { $i < $nentries} { incr i 3 } { lappend key_list2 [lindex $key_list1 $i] } - set ret [eval {$db del} $txn -multiple {$key_list2}] - error_check_good {del(-multiple)} $ret 0 + set ret [eval {$db del} $txn -multiple $extra_op {$key_list2}] + error_check_good "del(-multiple $extra_op)" $ret 0 # Delete again, should return DB_NOTFOUND/DB_KEYEMPTY. - set ret [catch {eval {$db del} $txn -multiple {$key_list2}} res] + set ret [catch {eval {$db del} $txn -multiple $extra_op \ + {$key_list2}} res] error_check_good {Check DB_NOTFOUND/DB_KEYEMPTY} \ [expr [is_substr $res DB_NOTFOUND] || \ [is_substr $res DB_KEYEMPTY]] 1 - puts "\tTest$tnum.e: Bulk delete data using -multiple_key." + puts "\tTest$tnum.e: Bulk delete data using -multiple_key $extra_op." set pair_list2 {} for { set i 1 } { $i < $nentries} { incr i 3} { lappend pair_list2 [lindex $key_list1 $i] \ [lindex $data_list1 $i] } - set ret [eval {$db del} $txn -multiple_key {$pair_list2}] - error_check_good {del(-multiple_key)} $ret 0 + set ret [eval {$db del} $txn -multiple_key $extra_op {$pair_list2}] + error_check_good "del(-multiple_key $extra_op)" $ret 0 # Delete again, should return DB_NOTFOUND/DB_KEYEMPTY. - set ret [catch {eval {$db del} $txn -multiple_key {$pair_list2}} res] + set ret [catch {eval {$db del} $txn -multiple_key $extra_op \ + {$pair_list2}} res] error_check_good {Check DB_NOTFOUND/DB_KEYEMPTY} \ [expr [is_substr $res DB_NOTFOUND] || \ [is_substr $res DB_KEYEMPTY]] 1 diff --git a/test/tcl/test127.tcl b/test/tcl/test127.tcl index 939c6004..c8ab35b2 100644 --- a/test/tcl/test127.tcl +++ b/test/tcl/test127.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -16,7 +16,7 @@ # TEST and make sure if the correct items are deleted. proc test127 {method { nentries 10000 } { ndups 5} { tnum "127" } - {subdb 0} args } { + {subdb 0} {sort_multiple 0} args } { source ./include.tcl global alphabet @@ -25,6 +25,20 @@ proc test127 {method { nentries 10000 } { ndups 5} { tnum "127" } return } + # It is only makes sense for btree database to sort bulk buffer. + if {$sort_multiple && ![is_btree $method]} { + puts "Skipping test$tnum for $method with -sort_multiple." + return + } + + # For compressed databases, we need to sort the items in + # the bulk buffer before doing the bulk put/delete operations. + if {[is_compressed $args] && !$sort_multiple} { + puts "Skipping test$tnum for compressed databases\ + without -sort_multiple." + return + } + set args [convert_args $method $args] set subname "" @@ -39,38 +53,47 @@ proc test127 {method { nentries 10000 } { ndups 5} { tnum "127" } set save_msg "$save_msg using sub databases" } - # If we are using an env, then testfile should just be the db name. + # If we are using an env, then basename should just be the db name. # Otherwise it is the test directory and the name. set eindex [lsearch -exact $args "-env"] set txnenv 0 set txn "" if { $eindex == -1 } { - set testfile $testdir/test$tnum.db + set basename $testdir/test$tnum set env NULL + set orig_testdir $testdir } else { - set testfile test$tnum.db + set basename test$tnum incr eindex set env [lindex $args $eindex] set txnenv [is_txnenv $env] if { $txnenv == 1 } { append args " -auto_commit " } - set testdir [get_home $env] + set orig_testdir [get_home $env] } - cleanup $testdir $env + set extra_op "" + if {$sort_multiple} { + set extra_op "-sort_multiple" + } + if {[is_compressed $args]} { + set options [list "-dup -dupsort"] + } else { + set options [list "-dup -dupsort" "-dup"] + } set i 0 - foreach ex_args [list "-dup -dupsort" "-dup"] { + foreach ex_args $options { set dboargs [concat $args $ex_args] - set fname $testfile + set fname $basename.db set dbname $subname puts "Test$tnum: $method ($dboargs)\ Database bulk update $save_msg." if {$subdb} { set dbname $subname.$i } else { - set fname $testfile.$i + set fname $basename.$i.db } test127_sub $fname $dbname $dboargs incr i @@ -87,10 +110,15 @@ proc test127_sub {fname dbname dboargs} { upvar subdb subdb upvar txnenv txnenv upvar env env + upvar extra_op extra_op + upvar orig_testdir orig_testdir + + set testdir $orig_testdir + cleanup $testdir $env set sorted [is_substr $dboargs "-dupsort"] set omethod [convert_method $method] - + set db [eval {berkdb_open_noerr -create -mode 0644} \ $dboargs $omethod $fname $dbname] error_check_good dbopen [is_valid_db $db] TRUE @@ -106,7 +134,7 @@ proc test127_sub {fname dbname dboargs} { # First, we put half the entries using put -multiple. # Then, we put the rest half using put -multiple_key. - puts "\tTest$tnum.a: Bulk put data using -multiple." + puts "\tTest$tnum.a: Bulk put data using -multiple $extra_op." set key_list1 {} set data_list1 {} set key_list {} @@ -122,24 +150,25 @@ proc test127_sub {fname dbname dboargs} { } lappend datas_list $datas } - set ret [eval {$db put} $txn -multiple {$key_list1 $data_list1}] - error_check_good {put(-multiple)} $ret 0 + set ret [eval {$db put} $txn -multiple $extra_op \ + {$key_list1 $data_list1}] + error_check_good "put(-multiple $extra_op)" $ret 0 - # Put again without -overwritedup, should return DB_KEYEXIST. + # Put again without -overwritedup, should return DB_KEYEXIST. set ret [catch {eval {$db put} \ - $txn -multiple {$key_list1 $data_list1}} res] + $txn -multiple $extra_op {$key_list1 $data_list1}} res] if {$sorted} { error_check_good \ {Check DB_KEYEXIST} [is_substr $res DB_KEYEXIST] 1 } else { - error_check_good {put_again(-multiple)} $ret 0 + error_check_good "put_again(-multiple $extra_op)" $ret 0 } # Put again with -overwritedup, should succeed set ret [eval {$db put} \ - $txn -multiple -overwritedup {$key_list1 $data_list1}] - error_check_good {put_again(-multiple -overwritedup)} $ret 0 + $txn -multiple $extra_op -overwritedup {$key_list1 $data_list1}] + error_check_good "put_again(-multiple $extra_op -overwritedup)" $ret 0 - puts "\tTest$tnum.b: Bulk put data using -multiple_key." + puts "\tTest$tnum.b: Bulk put data using -multiple_key $extra_op." set pair_list1 {} for { set i [expr $nentries / 2 ]} { $i <= $nentries} { incr i } { lappend key_list $i @@ -151,40 +180,41 @@ proc test127_sub {fname dbname dboargs} { } lappend datas_list $datas } - set ret [eval {$db put} $txn -multiple_key {$pair_list1}] - error_check_good {put(-multiple_key)} $ret 0 + set ret [eval {$db put} $txn -multiple_key $extra_op {$pair_list1}] + error_check_good "put(-multiple_key $extra_op)" $ret 0 # Put again without -overwritedup, should return DB_KEYEXIST. set ret [catch { - eval {$db put} $txn -multiple_key {$pair_list1}} res] + eval {$db put} $txn -multiple_key $extra_op {$pair_list1}} res] if {$sorted} { error_check_good \ {Check DB_KEYEXIST} [is_substr $res DB_KEYEXIST] 1 } else { - error_check_good {put_again(-multiple_key)} $ret 0 + error_check_good "put_again(-multiple_key $extra_op)" $ret 0 } # Put again with -overwritedup, should succeed set ret [eval \ - {$db put} $txn -multiple_key -overwritedup {$pair_list1}] + {$db put} $txn -multiple_key $extra_op -overwritedup {$pair_list1}] error_check_good \ - {put_again(-multiple_key -overwritedup)} $ret 0 + "put_again(-multiple_key $extra_op -overwritedup)" $ret 0 puts "\tTest$tnum.c: Verify the data after bulk put." test127_check_prirecords $db $key_list $datas_list $txn $sorted - puts "\tTest$tnum.d: Bulk delete data using -multiple." + puts "\tTest$tnum.d: Bulk delete data using -multiple $extra_op." set key_list2 {} for { set i 1 } { $i <= $nentries} { incr i 2 } { lappend key_list2 $i } - set ret [eval {$db del} $txn -multiple {$key_list2}] - error_check_good {del(-multiple)} $ret 0 + set ret [eval {$db del} $txn -multiple $extra_op {$key_list2}] + error_check_good "del(-multiple $extra_op)" $ret 0 # Delete again, should return DB_NOTFOUND. - set ret [catch {eval {$db del} $txn -multiple {$key_list2}} res] + set ret [catch {eval {$db del} $txn -multiple $extra_op \ + {$key_list2}} res] error_check_good {Check DB_NOTFOUND} [is_substr $res DB_NOTFOUND] 1 - puts "\tTest$tnum.e: Bulk delete using -multiple_key." + puts "\tTest$tnum.e: Bulk delete using -multiple_key $extra_op." set pair_list2 {} for { set i 2 } { $i <= $nentries} { incr i 2} { for { set j 1 } { $j <= $ndups / 2 } { incr j } { @@ -193,18 +223,21 @@ proc test127_sub {fname dbname dboargs} { } } - set ret [eval {$db del} $txn -multiple_key {$pair_list2}] - error_check_good {del(-multiple_key)} $ret 0 + set ret [eval {$db del} $txn -multiple_key $extra_op {$pair_list2}] + error_check_good "del(-multiple_key $extra_op)" $ret 0 # Delete again, should return DB_NOTFOUND. - set ret [catch {eval {$db del} $txn -multiple_key {$pair_list2}} res] + set ret [catch {eval {$db del} $txn -multiple_key $extra_op \ + {$pair_list2}} res] if {$sorted} { error_check_good {Check DB_NOTFOUND} [is_substr $res DB_NOTFOUND] 1 } else { - error_check_good "del(-multiple_key) 2 round" $ret 0 - set ret [catch {eval {$db del} $txn -multiple_key {$pair_list2}} res] - error_check_good "del(-multiple_key) 3 round" $ret 0 - set ret [catch {eval {$db del} $txn -multiple_key {$pair_list2}} res] + error_check_good "del(-multiple_key $extra_op) 2 round" $ret 0 + set ret [catch {eval {$db del} $txn -multiple_key $extra_op \ + {$pair_list2}} res] + error_check_good "del(-multiple_key $extra_op) 3 round" $ret 0 + set ret [catch {eval {$db del} $txn -multiple_key $extra_op \ + {$pair_list2}} res] error_check_good {Check DB_NOTFOUND} [is_substr $res DB_NOTFOUND] 1 } diff --git a/test/tcl/test128.tcl b/test/tcl/test128.tcl index d164b10c..03e062c0 100644 --- a/test/tcl/test128.tcl +++ b/test/tcl/test128.tcl @@ -1,13 +1,17 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # # TEST test128 -# TEST Test database bulk update for sub database and duplicate database. +# TEST Test database bulk update for non-duplicate databases, with different +# TEST configurations. # TEST -# TEST This is essentially test126 with sub database and secondary database. +# TEST This is essentially test126 with the following configurations: +# TEST * sub database. +# TEST * secondary database. +# TEST * bulk buffer pre-sort. proc test128 {method { nentries 10000 } {callback 1} args } { source ./include.tcl @@ -18,17 +22,23 @@ proc test128 {method { nentries 10000 } {callback 1} args } { set nodump 0 } # Test using sub database - eval {test126 $method $nentries "128" $callback 1 0} $args + eval {test126 $method $nentries "128" $callback 1 0 0} $args eval {verify_dir $testdir "" 1 0 $nodump} eval {salvage_dir $testdir "" 1} # Test using secondary database - eval {test126 $method $nentries "128" $callback 0 1} $args + eval {test126 $method $nentries "128" $callback 0 1 0} $args eval {verify_dir $testdir "" 1 0 $nodump} eval {salvage_dir $testdir "" 1} - # Test using both sub database and secondary database - eval {test126 $method $nentries "128" $callback 1 1} $args + # Test with -sort_multiple + eval {test126 $method $nentries "128" $callback 0 0 1} $args + eval {verify_dir $testdir "" 1 0 $nodump} + eval {salvage_dir $testdir "" 1} + + # Test using both sub database and secondary database, + # and with -sort_multiple + eval {test126 $method $nentries "128" $callback 1 1 1} $args } diff --git a/test/tcl/test129.tcl b/test/tcl/test129.tcl index ee13f3ad..c8cd5b19 100644 --- a/test/tcl/test129.tcl +++ b/test/tcl/test129.tcl @@ -1,18 +1,38 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # # TEST test129 -# TEST Test database bulk update for duplicate sub database. +# TEST Test database bulk update for duplicate database, with different +# TEST configurations. # TEST -# TEST This is essentially test127 with sub database. +# TEST This is essentially test127 with the following configurations: +# TEST * sub database. +# TEST * bulk buffer pre-sort. proc test129 {method { nentries 10000 } { ndups 5} args } { - - # Test using both sub database and secondary database - eval {test127 $method $nentries $ndups "129" 1} $args + source ./include.tcl + + if { [is_partition_callback $args] == 1 } { + set nodump 1 + } else { + set nodump 0 + } + + # Test using sub database. + eval {test127 $method $nentries $ndups "129" 1 0} $args + eval {verify_dir $testdir "" 1 0 $nodump} + eval {salvage_dir $testdir "" 1} + + # Test with -sort_multiple. + eval {test127 $method $nentries $ndups "129" 0 1} $args + eval {verify_dir $testdir "" 1 0 $nodump} + eval {salvage_dir $testdir "" 1} + + # Test using sub database, and with -sort_multiple. + eval {test127 $method $nentries $ndups "129" 1 1} $args } diff --git a/test/tcl/test130.tcl b/test/tcl/test130.tcl index b41cb6be..08985140 100644 --- a/test/tcl/test130.tcl +++ b/test/tcl/test130.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test131.tcl b/test/tcl/test131.tcl index e062ddd4..f29cd38b 100644 --- a/test/tcl/test131.tcl +++ b/test/tcl/test131.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -81,16 +81,10 @@ proc test131 {method {nentries 1000} {tnum "131"} {ndups 5} {subdb 0} cleanup $testdir $env - # To simplify the case, just set the type of foreign database as # btree or hash. And for the secondary database, the type is dupsort - # hash/btree. For foreign and secondary databases, we just pass - # the original args, since the converted args does not work for them. - # For example, if the primary database is rbtree, convert_args will - # generate "-recnum" which is invalid to the foreign and secondary - # databases. + # hash/btree. set origargs $args - set secargs $args set args [convert_args $method $args] set omethod [convert_method $method] @@ -132,8 +126,8 @@ proc test131 {method {nentries 1000} {tnum "131"} {ndups 5} {subdb 0} set foreign_proc [lindex $subtest 0] set foreign_arg [lindex $subtest 1] set foreign_vrfy [lindex $subtest 2] - set foreign_dbtype [lindex $typepair 0] - set sec_dbtype [lindex $typepair 1] + set foreign_method [lindex $typepair 0] + set sec_method [lindex $typepair 1] if {$subdb} { set pri_subname "primary_db$i" set sec_subname "secondary_db$i" @@ -149,8 +143,8 @@ proc test131 {method {nentries 1000} {tnum "131"} {ndups 5} {subdb 0} # Skip partition range test and compression test # when there are non-btree databases. - if {![is_btree $foreign_dbtype] || \ - ![is_btree $sec_dbtype]} { + if {![is_btree $foreign_method] || \ + ![is_btree $sec_method]} { set skip 0 if {[is_partitioned $origargs] && \ ![is_partition_callback $origargs]} { @@ -174,8 +168,9 @@ proc test131 {method {nentries 1000} {tnum "131"} {ndups 5} {subdb 0} } # Open the foreign database. puts "\tTest$tnum.$i.a Open and truncate the databases." + set foreign_args [convert_args $foreign_method $origargs] set foreign_db [eval berkdb_open_noerr -create \ - -mode 0644 $foreign_dbtype $origargs \ + -mode 0644 $foreign_method $foreign_args \ {$foreign_file} $foreign_subname] error_check_good foreign_db_open \ [is_valid_db $foreign_db] TRUE @@ -187,8 +182,9 @@ proc test131 {method {nentries 1000} {tnum "131"} {ndups 5} {subdb 0} [is_valid_db $pri_db] TRUE # Open the secondary database. + set secargs [convert_args $sec_method $origargs] set sec_db [eval berkdb_open_noerr -create -mode 0644 \ - $sec_dbtype $secargs -dup -dupsort \ + $sec_method $secargs -dup -dupsort \ {$sec_file} $sec_subname] error_check_good sec_db_open \ [is_valid_db $sec_db] TRUE diff --git a/test/tcl/test132.tcl b/test/tcl/test132.tcl index 7a7bcfa0..217977f6 100644 --- a/test/tcl/test132.tcl +++ b/test/tcl/test132.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/test133.tcl b/test/tcl/test133.tcl index f728465e..7e6e88ff 100644 --- a/test/tcl/test133.tcl +++ b/test/tcl/test133.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -70,16 +70,21 @@ proc test133 {method {nentries 1000} {tnum "133"} {subdb 0} args} { } cleanup $testdir $env - set sec_args $args + set orig_args $args set args [convert_args $method $args] puts "Test$tnum: $method ($args)\ Cursor Cleanup Test $sub_msg." - - set secdb_types {"-btree" "-hash"} + # Hash does not have compression support. + if {[is_compressed $orig_args]} { + set secdb_types {"-btree"} + } else { + set secdb_types {"-btree" "-hash"} + } set i 0 foreach sec_method $secdb_types { + set sec_args [convert_args $sec_method $orig_args] test133_sub "\tTest$tnum.$i" $basename $subdb $method $args \ $sec_method $sec_args $i incr i diff --git a/test/tcl/test134.tcl b/test/tcl/test134.tcl index 32893794..6d682461 100644 --- a/test/tcl/test134.tcl +++ b/test/tcl/test134.tcl @@ -1,15 +1,15 @@ -# See the file LICENSE for redistribution information. -# -# Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. -# -# $Id$ -# -# TEST test134 -# TEST Test cursor cleanup for sub databases. - -proc test134 {method {nentries 1000} args} { - source ./include.tcl - - eval {test133 $method $nentries "134" 1} $args - -} +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test134 +# TEST Test cursor cleanup for sub databases. + +proc test134 {method {nentries 1000} args} { + source ./include.tcl + + eval {test133 $method $nentries "134" 1} $args + +} diff --git a/test/tcl/test135.tcl b/test/tcl/test135.tcl new file mode 100644 index 00000000..c9a1769a --- /dev/null +++ b/test/tcl/test135.tcl @@ -0,0 +1,310 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test135 +# TEST Test operations on similar overflow records. [#20329] +# TEST Open 3 kinds of databases: one is not dup, and one is dup-unsorted +# TEST while another one is dup-sorted. +# TEST Then we put some similar but not identical overflow records into +# TEST these databases. +# TEST Also, we try to remove some records from these databases. +# TEST We'll verify the records after put and after deletion. +# TEST Here is how we define the 'similar overflow' in this test: +# TEST * Both the key.size and data.size are not small than DB's pagesize: +# TEST The key.size is around 2*pagesize and data.size equals to pagesize. +# TEST * The keys are of same length, and they only differ in a small piece. +# TEST The location of difference could be in the start/middle/end. +# TEST * For dup databases, the dup datas have same rule as the key rule +# TEST mentioned above. + +proc test135 {method {keycnt 10} {datacnt 10} {subdb 0} {tnum "135"} args} { + source ./include.tcl + + # We are only testing key-based methods. + if {[is_record_based $method]} { + puts "Skipping test$tnum for $method test." + return + } + + set sub_msg "" + # Check if we use sub database. + if { $subdb } { + if {[is_partitioned $args]} { + puts "Skipping test$tnum with sub database\ + for partitioned $method test." + return + } + set sub_msg "using sub databases" + } + + # Skip for specified pagesizes. This test uses a very small + # pagesize to make it run fast. + set pgindex [lsearch -exact $args "-pagesize"] + if { $pgindex != -1 } { + puts "Test$tnum: Skipping for specific pagesizes" + return + } + + set pgsize 512 + + # If we are using an env, then testfile should just be the db name. + # Otherwise it is the test directory and the name. + set eindex [lsearch -exact $args "-env"] + set txnenv 0 + if { $eindex == -1 } { + if {$subdb} { + puts "Skipping test$tnum $sub_msg for non-env test." + return + } + set basename $testdir/test$tnum + set env NULL + } else { + set basename test$tnum + incr eindex + set env [lindex $args $eindex] + set txnenv [is_txnenv $env] + if { $txnenv == 1 } { + append args " -auto_commit " + } + set testdir [get_home $env] + } + + cleanup $testdir $env + set args [convert_args $method $args] + + puts "Test$tnum: $method ($args)\ + Similar Overflow Records Operation Test $sub_msg." + + set i 0 + set dupargs [list "" "-dup" "-dup -dupsort"] + if {[is_rbtree $method]} { + set dupargs [list ""] + } elseif {[is_compressed $args]} { + set dupargs [list "" "-dup -dupsort"] + } + foreach duparg $dupargs { + # kloc specifies where the keys differ + foreach kloc [list "start" "middle" "end"] { + # dloc specifies where the dup datas differ + foreach dloc [list "start" "middle" "end"] { + test135_sub \ + "\tTest$tnum.$i ($duparg $kloc $dloc)" \ + $duparg $kloc $dloc $basename $subdb \ + $method $i $args + incr i + } + } + } +} + +proc test135_sub { prefix duparg kloc dloc basename use_subdb + method indx dboargs } { + global alphabet + upvar txnenv txnenv + upvar env env + upvar keycnt keycnt + upvar datacnt datacnt + upvar pgsize pgsize + + if { $use_subdb } { + set testfile $basename.db + set subname "db$indx" + } else { + set testfile $basename-$indx.db + set subname "" + } + + set isdup [is_substr $duparg "-dup"] + + puts "$prefix.a: Open the database." + set omethod [convert_method $method] + set db [eval {berkdb_open_noerr -create -mode 0644} \ + -pagesize $pgsize $dboargs $duparg $omethod $testfile $subname] + error_check_good dbopen [is_valid_db $db] TRUE + + set txn "" + if { $txnenv == 1 } { + set t [$env txn] + error_check_good txn [is_valid_txn $t $env] TRUE + set txn "-txn $t" + } + + set app_data(0) 0 + set alpha_len [string length $alphabet] + set kbits [test135_countbits $alpha_len $keycnt] + set dbits [test135_countbits $alpha_len $datacnt] + + # The key and data are composed of characters from 'a' to 'z' and they + # have the format of: + # $prefix$str$suffix + # Both prefix and suffix are strings with all characters set to 'a'. + # Here is an example to compose the str: + # Assume we have 100 keys, and as 100 > 26('a'-'z', 26 chars), + # we need at least two characters to represent 100 different strs. + # These 100 strs should be: aa, ab, ..., az, ...., bz, ...., dv + puts "$prefix.b: Putting records into the database." + for {set klen [expr 2 * $pgsize - 50]} \ + {$klen < [expr 2 * $pgsize + 50]} {incr klen 10} { + set kpos [test135_getdiffpos $klen $kloc $kbits 10] + set dpos [test135_getdiffpos $pgsize $dloc $dbits $alpha_len] + set kprefix [repeat "a" $kpos] + set ksuffix [repeat "a" \ + [expr $klen - $kbits - $kpos]] + set dprefix [repeat "a" $dpos] + set dsuffix [repeat "a" \ + [expr $pgsize - $dbits - $dpos]] + for {set i 0} {$i < $keycnt} {incr i} { + set k [test135_tostr $alphabet $alpha_len $kbits $i] + if {$isdup} { + for {set j 0} {$j < $datacnt} {incr j} { + set d [test135_tostr $alphabet \ + $alpha_len $dbits $j] + set ret [eval $db put $txn \ + $kprefix$k$ksuffix \ + $dprefix$d$dsuffix] + error_check_good db_put $ret 0 + } + } else { + set d [test135_tostr $alphabet \ + $alpha_len $dbits 1] + set ret [eval $db put $txn $kprefix$k$ksuffix \ + $dprefix$d$dsuffix] + error_check_good db_put $ret 0 + } + } + set app_data($klen) [list $kprefix $ksuffix \ + $dprefix $dsuffix] + } + + puts "$prefix.c: Verify records after putting." + for {set klen [expr 2 * $pgsize - 50]} \ + {$klen < [expr 2 * $pgsize + 50]} {incr klen 10} { + set applist $app_data($klen) + set kprefix [lindex $applist 0] + set ksuffix [lindex $applist 1] + set dprefix [lindex $applist 2] + set dsuffix [lindex $applist 3] + for {set i 0} {$i < $keycnt} {incr i} { + set k [test135_tostr $alphabet $alpha_len $kbits $i] + if {$isdup} { + for {set j 0} {$j < $datacnt} {incr j} { + set d [test135_tostr $alphabet \ + $alpha_len $dbits $j] + set ret [eval $db get -get_both $txn \ + $kprefix$k$ksuffix \ + $dprefix$d$dsuffix] + error_check_good db_get [llength $ret] 1 + } + } else { + set d [test135_tostr $alphabet \ + $alpha_len $dbits 1] + set ret [eval $db get -get_both $txn \ + $kprefix$k$ksuffix $dprefix$d$dsuffix] + error_check_good db_get [llength $ret] 1 + } + } + } + + puts "$prefix.d: Delete some records from the database." + for {set klen [expr 2 * $pgsize - 50]} \ + {$klen < [expr 2 * $pgsize + 50]} {incr klen 10} { + set applist $app_data($klen) + set kprefix [lindex $applist 0] + set ksuffix [lindex $applist 1] + for {set i 0} {$i < $keycnt} {incr i 2} { + set k [test135_tostr $alphabet $alpha_len $kbits $i] + set ret [eval $db del $txn $kprefix$k$ksuffix] + error_check_good db_del $ret 0 + } + } + + puts "$prefix.e: Verify records after deleting." + for {set klen [expr 2 * $pgsize - 50]} \ + {$klen < [expr 2 * $pgsize + 50]} {incr klen 10} { + set applist $app_data($klen) + set kprefix [lindex $applist 0] + set ksuffix [lindex $applist 1] + set dprefix [lindex $applist 2] + set dsuffix [lindex $applist 3] + for {set i 0} {$i < $keycnt} {incr i 2} { + set k [test135_tostr $alphabet $alpha_len $kbits $i] + set ret [eval $db get $txn $kprefix$k$ksuffix] + error_check_good db_get [llength $ret] 0 + } + for {set i 1} {$i < $keycnt} {incr i 2} { + set k [test135_tostr $alphabet $alpha_len $kbits $i] + if {$isdup} { + for {set j 0} {$j < $datacnt} {incr j} { + set d [test135_tostr $alphabet \ + $alpha_len $dbits $j] + set ret [eval $db get -get_both $txn \ + $kprefix$k$ksuffix \ + $dprefix$d$dsuffix] + error_check_good db_get [llength $ret] 1 + } + } else { + set d [test135_tostr $alphabet \ + $alpha_len $dbits 1] + set ret [eval $db get -get_both $txn \ + $kprefix$k$ksuffix $dprefix$d$dsuffix] + error_check_good db_get [llength $ret] 1 + } + } + } + + if { $txnenv == 1 } { + error_check_good txn_commit [$t commit] 0 + } + error_check_good db_close [$db close] 0 +} + +# Determines how many bits we need to represent a scope of values from 0. +# For example, if we want to represent values from 0-99, we need +# at least two decimal bits. +proc test135_countbits {radix maxval} { + set cnt 1 + while {$maxval > 0} { + set maxval [expr $maxval / $radix] + if {!$maxval} { + break + } else { + incr cnt + } + } + return $cnt +} + +# Return the string representation of a value. +# For example, if we want to represent 21 in 3 decimal bits, +# the returned value should be "021" +proc test135_tostr {src radix cnt val} { + set str "" + for {set i 0} {$i < $cnt} {incr i} { + set indx [expr $val % $radix] + set val [expr $val / $radix] + set str [string index $src $indx]$str + } + return $str +} + +# Return the location where the difference begins. +proc test135_getdiffpos {sz loc bits mbits} { + set lower 0 + set upper [expr $sz - $bits] + switch -exact $loc { + "start" { + set upper [expr $mbits - $bits] + } + "middle" { + set upper [expr $sz / 2 - $mbits / 2 - $bits] + set lower [expr $upper - $mbits + 1] + } + "end" { + set lower [expr $sz - $mbits] + } + } + return [berkdb random_int $lower $upper] +} diff --git a/test/tcl/test136.tcl b/test/tcl/test136.tcl new file mode 100644 index 00000000..ebe5a703 --- /dev/null +++ b/test/tcl/test136.tcl @@ -0,0 +1,16 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test136 +# TEST Test operations on similar overflow records. [#20329] +# TEST Here, we use subdatabases. + +proc test136 {method {keycnt 10} {datacnt 10} args} { + source ./include.tcl + + eval {test135 $method $keycnt $datacnt 1 "136"} $args +} + diff --git a/test/tcl/test137.tcl b/test/tcl/test137.tcl new file mode 100644 index 00000000..535d6f5b --- /dev/null +++ b/test/tcl/test137.tcl @@ -0,0 +1,218 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test137 +# TEST Test Automatic Resource Management. [#16188][#20281] +# TEST Open an environment, and open a database in it. +# TEST Do some operations in the database, including: +# TEST insert, dump, delete +# TEST Close the environment without closing the database. +# TEST Re-open the database and verify the records are the ones we expected. + +proc test137 { method {nentries 1000} {start 0} {skip 0} {use_encrypt 0} + {tnum "137"} {envtype "ds"} args } { + source ./include.tcl + global encrypt + global has_crypto + + # This test needs its own env. + set eindex [lsearch -exact $args "-env"] + if { $eindex != -1 } { + incr eindex + set env [lindex $args $eindex] + puts "Test$tnum skipping for env $env" + return + } + + # Skip if use_encrypt and encryption is not supported. + if { $use_encrypt && $has_crypto == 0 } { + puts "Skipping test$tnum for non-crypto release." + return + } + + # Do not use db encryption flags from the $args -- this test + # does its own encryption testing at the env level. + convert_encrypt $args + if { $encrypt } { + puts "Test$tnum skipping DB encryption" + return + } + + # We can not specify chksum option to opening db when using + # an encrypted env. + set chksum_indx [lsearch -exact $args "-chksum"] + if { $chksum_indx != -1 && $use_encrypt } { + puts "Test$tnum skipping DB chksum" + return + } + + set encmsg "non-encrypt" + if { $use_encrypt } { + set encmsg "encrypt" + } + + set args [convert_args $method $args] + set omethod [convert_method $method] + + env_cleanup $testdir + set env [test137_openenv $envtype $testdir $use_encrypt] + set envargs "-env $env" + set txnenv [string equal $envtype "tds"] + if { $txnenv == 1 } { + set nentries 200 + append args " -auto_commit" + } + + set testfile test$tnum.db + set t1 $testdir/t1 + set t2 $testdir/t2 + + puts "Test$tnum: $method \ + ($envtype,$encmsg,$args) $nentries equal key/data pairs" + + set did [open $dict] + # The "start" variable determines the record number to start + # with, if we're using record numbers. The "skip" variable + # determines the dictionary entry to start with. + # In normal use, skip will match start. + puts "\tTest$tnum: Starting at $start with dictionary entry $skip" + if { $skip != 0 } { + for { set count 0 } { $count < $skip } { incr count } { + gets $did str + } + } + + set db [eval {berkdb_open \ + -create -mode 0644} $envargs $args $omethod $testfile] + error_check_good dbopen [is_valid_db $db] TRUE + + set txn "" + if { $txnenv == 1 } { + set t [$env txn] + error_check_good txn [is_valid_txn $t $env] TRUE + set txn "-txn $t" + } + + puts "\tTest$tnum.a: put loop" + # Here is the loop where we put and get each key/data pair + set count 0 + set key_list {} + set data_list {} + while { [gets $did str] != -1 && $count < $nentries } { + if { [is_record_based $method] == 1 } { + set key [expr $count + 1 + $start] + } else { + set key $str + set str [reverse $str] + } + set ret [eval \ + {$db put} $txn {$key [chop_data $method $str]}] + error_check_good db_put $ret 0 + lappend key_list $key + lappend data_list $str + incr count + } + close $did + + puts "\tTest$tnum.b: dump file and close env without closing database" + dump_file $db $txn $t1 NONE + if { $txnenv == 1 } { + error_check_good txn_commit [$t commit] 0 + } + error_check_good env_close [$env close] 0 + # Clean the tcl handle only. + catch {$db close -handle_only} res + + puts "\tTest$tnum.c: open the env and database again" + set env [test137_openenv $envtype $testdir $use_encrypt] + set envargs "-env $env" + set db [eval {berkdb_open \ + -create -mode 0644} $envargs $args $omethod $testfile] + error_check_good dbopen [is_valid_db $db] TRUE + + if { $txnenv == 1 } { + set t [$env txn] + error_check_good txn [is_valid_txn $t $env] TRUE + set txn "-txn $t" + } + + puts "\tTest$tnum.d: dump file and check" + dump_file $db $txn $t2 NONE + error_check_good Test$tnum:diff($t1,$t2) \ + [filecmp $t1 $t2] 0 + + puts "\tTest$tnum.e: delete loop" + # We delete starting from the last record, since for rrecno, if we + # delete previous records, the ones after will change their keys. + for {set i [expr [llength $key_list] - 1]} {$i >= 0} \ + {incr i -[berkdb random_int 1 5]} { + set key [lindex $key_list $i] + set ret [eval $db del $txn {$key}] + error_check_good db_del $ret 0 + } + + puts "\tTest$tnum.f:\ + dump file and close env without closing database again" + dump_file $db $txn $t1 NONE + if { $txnenv == 1 } { + error_check_good txn_commit [$t commit] 0 + } + error_check_good env_close [$env close -forcesync] 0 + catch {$db close -handle_only} res + + # We remove the environment to make sure the regions files + # are deleted(including mpool files), so we can verify if + # the database has been synced during a force-synced env close. + error_check_good env_remove [berkdb envremove -force -home $testdir] 0 + + puts "\tTest$tnum.g: open, dump and check again" + set env [test137_openenv $envtype $testdir $use_encrypt] + set envargs "-env $env" + set db [eval {berkdb_open \ + -create -mode 0644} $envargs $args $omethod $testfile] + error_check_good dbopen [is_valid_db $db] TRUE + + if { $txnenv == 1 } { + set t [$env txn] + error_check_good txn [is_valid_txn $t $env] TRUE + set txn "-txn $t" + } + + dump_file $db $txn $t2 NONE + error_check_good Test$tnum:diff($t1,$t2) \ + [filecmp $t1 $t2] 0 + + if { $txnenv == 1 } { + error_check_good txn_commit [$t commit] 0 + } + error_check_good db_close [$db close] 0 + error_check_good env_close [$env close] 0 +} + +proc test137_openenv {envtype testdir use_encrypt} { + global passwd + + set encargs "" + if {$use_encrypt} { + set encargs " -encryptaes $passwd " + } + switch -exact "$envtype" { + "ds" { + set env [eval berkdb_env_noerr -create -mode 0644 \ + $encargs -home $testdir] + } + "cds" { + set env [eval berkdb_env_noerr -create -mode 0644 \ + $encargs -cdb -home $testdir] + } + "tds" { + set env [eval berkdb_env_noerr -create -mode 0644 \ + $encargs -txn -lock -log -thread -home $testdir] + } + } + error_check_good env_open [is_valid_env $env] TRUE + return $env +} diff --git a/test/tcl/test138.tcl b/test/tcl/test138.tcl new file mode 100644 index 00000000..01641c6a --- /dev/null +++ b/test/tcl/test138.tcl @@ -0,0 +1,24 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test138 +# TEST Test Automatic Resource Management. [#16188][#20281] +# TEST Here, we test the following cases: +# TEST Non-encrypt for cds +# TEST Non-encrypt for tds +# TEST Encrypt for ds +# TEST Encrypt for cds +# TEST Encrypt for tds + +proc test138 { method {nentries 1000} {start 0} {skip 0} args } { + source ./include.tcl + + eval {test137 $method $nentries $start $skip 0 "138" "cds"} $args + eval {test137 $method $nentries $start $skip 0 "138" "tds"} $args + eval {test137 $method $nentries $start $skip 1 "138" "ds"} $args + eval {test137 $method $nentries $start $skip 1 "138" "cds"} $args + eval {test137 $method $nentries $start $skip 1 "138" "tds"} $args +} diff --git a/test/tcl/test139.tcl b/test/tcl/test139.tcl new file mode 100644 index 00000000..c6bc38c2 --- /dev/null +++ b/test/tcl/test139.tcl @@ -0,0 +1,138 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test139 +# TEST +# TEST Verify an open database. +# TEST Create and populate a database, leave open, and run +# TEST db->verify. +# TEST Delete half the data, verify, compact, verify again. +proc test139 { method {pagesize 512} {nentries 1000} {tnum "139"} args } { + source ./include.tcl + + set eindex [lsearch -exact $args "-env"] + # + # If we are using an env, then skip this test. It needs its own. + if { $eindex != -1 } { + incr eindex + set env [lindex $args $eindex] + puts "Test$tnum skipping for env $env" + return + } + + set args [convert_args $method $args] + set encargs "" + set args [split_encargs $args encargs] + set omethod [convert_method $method] + + env_cleanup $testdir + set testfile test$tnum.db + + set env [eval {berkdb_env -create -mode 0644} $encargs -home $testdir] + error_check_good dbenv [is_valid_env $env] TRUE + set envargs "-env $env" + + puts "Test$tnum: $method ($args) Verify an open database." + set pgindex [lsearch -exact $args "-pagesize"] + if { $pgindex == -1 } { + append args " -pagesize $pagesize " + } + set did [open $dict] + + set db [eval {berkdb_open -env $env -create \ + -mode 0644} $args $omethod $testfile] + error_check_good dbopen [is_valid_db $db] TRUE + + puts "\tTest$tnum.a: Populate the db." + set count 0 + while { [gets $did str] != -1 && $count < $nentries } { + if { [is_record_based $method] == 1 } { + global kvals + + set key [expr $count + 1] + if { 0xffffffff > 0 && $key > 0xffffffff } { + set key [expr $key - 0x100000000] + } + if { $key == 0 || $key - 0xffffffff == 1 } { + incr key + incr count + } + set kvals($key) [pad_data $method $str] + } else { + set key $str + set str [reverse $str] + } + + set ret [eval {$db put $key [chop_data $method $str]}] + error_check_good put $ret 0 + + # Sync the first item so we have something on disk. + if { $count == 0 } { + error_check_good db_sync [$db sync] 0 + } + + incr count + } + + close $did + + # Now verify. + puts "\tTest$tnum.b: Verify the db while still open." + set ret [eval {berkdb dbverify} $envargs $testfile] + + # Sync, verify again. + error_check_good db_sync [$db sync] 0 + set ret [eval {berkdb dbverify} $envargs $testfile] + + # Cursor delete,leaving every third entry. Since rrecno + # renumbers, delete starting at nentries and work backwards. + puts "\tTest$tnum.c: Delete many entries from database." + set did [open $dict] + + for { set i $nentries } { $i > 0 } { incr i -1 } { + if { [is_record_based $method] == 1 } { + set key $i + } else { + set key [gets $did] + } + + # Leave every n'th item. + set n 3 + if { [expr $i % $n] != 0 } { + set ret [eval {$db del $key}] + error_check_good del $ret 0 + } + } + close $did + + error_check_good db_sync [$db sync] 0 + + puts "\tTest$tnum.d: Verify the db after deletes." + set ret [eval {berkdb dbverify} $envargs $testfile] + + # Compact, if it's possible for the access method. + if { ![is_queue $method] == 1 && ![is_heap $method] == 1 } { + puts "\tTest$tnum.d: Compact database." + if {[catch {eval {$db compact -freespace}} ret] } { + error "FAIL: db compact: $ret" + } + } + + puts "\tTest$tnum.d: Verify the db after deletes." + set ret [eval {berkdb dbverify} $envargs $testfile] + + error_check_good db_sync [$db sync] 0 + puts "\tTest$tnum.e: Verify the db after sync." + set ret [eval {berkdb dbverify} $envargs $testfile] + + # Clean up. + puts "\tTest$tnum.: Clean up." + error_check_good db_close [$db close] 0 + if { $env != "NULL" } { + error_check_good env_close [$env close] 0 + } +} + diff --git a/test/tcl/test140.tcl b/test/tcl/test140.tcl new file mode 100644 index 00000000..b5a67f5f --- /dev/null +++ b/test/tcl/test140.tcl @@ -0,0 +1,260 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test140 +# TEST Test expansion and contraction of hash chains with +# TEST deletion, compaction, and recovery. +# TEST +# TEST On each cycle, populate a database to create reasonably +# TEST long hash chains, say 8 - 10 entries. Delete some +# TEST entries, check for consistency, compact, and check +# TEST for consistency again. We both commit and abort the +# TEST compact, and in the case of the abort, compare +# TEST the recovered database to the pre-compact database. + +proc test140 { method {tnum "140"} args } { + source ./include.tcl + global alphabet + global passwd + global util_path + + # This is a hash-only test. + if { [is_hash $method] != 1} { + puts "Skipping test$tnum for method $method." + return + } + + # Skip for specified pagesizes. This test uses a small + # pagesize to generate long chains. + set pgindex [lsearch -exact $args "-pagesize"] + if { $pgindex != -1 } { + puts "Test$tnum: Skipping for specific pagesizes" + return + } + + # This test uses recovery, so it sets up its own + # transactional environment. + set eindex [lsearch -exact $args "-env"] + if { $eindex != -1 } { + incr eindex + set env [lindex $args $eindex] + puts "Test$tnum skipping for env $env" + return + } + set args [convert_args $method $args] + set omethod [convert_method $method] + set encargs "" + set dumpargs "" + set args [split_encargs $args encargs] + if { $encargs != "" } { + set dumpargs " -P $passwd " + } + set nonoverflow [repeat $alphabet 2] + set overflow [repeat $alphabet 250] + set testfile test$tnum.db + + puts "Test$tnum: $method ($args $encargs)\ + Hash testing with deletion, compaction, and recovery." + + foreach testtype { "two gaps" "one gap" "one overflow"\ + "before overflow" "after overflow" } { + foreach txnend { "commit" "abort" } { + + env_cleanup $testdir + set env [eval {berkdb_env_noerr} -create -txn \ + $encargs -mode 0644 -home $testdir] + error_check_good env_open [is_valid_env $env] TRUE + + # Populate. + set msg "Populate: test $testtype with $txnend" + puts "\tTest$tnum.a: $msg." + set db [eval {berkdb_open_noerr -create -hash -ffactor 1 \ + -auto_commit -env $env -nelem 10 -pagesize 512 \ + -hashproc ident_test140} $args {$testfile}] + error_check_good dbopen [is_valid_db $db] TRUE + + set t [$env txn] + set txn "-txn $t" + + for { set i 0 } { $i < 8 } { incr i } { + for { set j 0 } { $j < 32 } { incr j } { + set ret [eval {$db put} $txn \ + {$i.$j.XXX \ + $i.$j.$nonoverflow}] + error_check_good put $ret 0 + } + } + + if { [is_substr $testtype "overflow"] == 1 } { + puts "\t\tTest$tnum.a.1: Adding overflow entry." + set i 3 + set j 3 + set ret [eval {$db put} $txn \ + {$i.$j.$overflow $i.$j.$overflow}] + error_check_good put $ret 0 + } + + error_check_good txn_commit [$t commit] 0 + $db sync + + # Delete a bunch of entries. We do different + # patterns of deletions on each pass. + puts "\tTest$tnum.b: Delete with $testtype." + set t [$env txn] + set txn "-txn $t" + + # Delete several contiguous entries, creating + # one large hole in the chain. + if { $testtype == "one gap" } { + for { set i 0 } { $i < 8 } { incr i } { + for { set j 8 } { $j < 24 } { incr j } { + set ret [eval {$db del} \ + $txn {$i.$j.XXX}] + error_check_good del $ret 0 + } + } + } + + # Knock two holes in the chain, so there's a piece + # that not "connected" to anything. + if { $testtype == "two gaps" } { + for { set i 0 } { $i < 8 } { incr i } { + for { set j 8 } { $j < 14 } { incr j } { + set ret [eval {$db del} \ + $txn {$i.$j.XXX}] + error_check_good del $ret 0 + } + } + for { set i 0 } { $i < 8 } { incr i } { + for { set j 20 } { $j < 26 } { incr j } { + set ret [eval {$db del} \ + $txn {$i.$j.XXX}] + error_check_good del $ret 0 + } + } + } + + # Delete the overflow entry. + if { $testtype == "one overflow" } { + set ret [eval {$db del} $txn {3.3.$overflow}] + error_check_good del_overflow $ret 0 + } + + # Delete the entry before the overflow entry. + if { $testtype == "before overflow" } { + set ret [eval {$db del} $txn {3.2.XXX}] + error_check_good del_overflow $ret 0 + } + + # Delete the entry after the overflow entry. + if { $testtype == "after overflow" } { + set ret [eval {$db del} $txn {3.4.XXX}] + error_check_good del_overflow $ret 0 + } + + error_check_good txn_commit [$t commit] 0 + $db sync + + # Verify. + puts "\tTest$tnum.c: Verify." + set ret [eval {berkdb dbverify -noorderchk} \ + -env $env {$testfile}] + + # Compact. Save a copy of the pre-compaction file. + set ret [eval {exec $util_path/db_dump} $dumpargs \ + {-p -f $testdir/file.init $testdir/$testfile} ] + filesort $testdir/file.init \ + $testdir/file.init.sorted + puts "\tTest$tnum.d: Compact and $txnend." + + set t [$env txn] + set txn "-txn $t" + + if {[catch {eval {$db compact} $txn \ + { -freespace}} ret] } { + error "FAIL: db compact: $ret" + } + $db sync + + # End the transaction. For an abort, check + # file consistency between a copy made before + # the txn started, the file after the abort, + # and the recovered file. + if { $txnend == "abort" } { + error_check_good abort [$t abort] 0 + $db sync + + set ret [eval {exec $util_path/db_dump -p} \ + $dumpargs {-f $testdir/file.afterabort \ + $testdir/$testfile} ] + filesort $testdir/file.afterabort \ + $testdir/file.afterabort.sorted + + puts -nonewline "\t\tTest$tnum.d1:\ + About to run recovery ... " + flush stdout + + set stat [catch {eval {exec\ + $util_path/db_recover} $dumpargs \ + {-h $testdir}} result] + if { $stat == 1 } { + error "Recovery error: $result." + } + puts "complete" + + puts "\t\tTest$tnum.d2: Dump\ + the recovered file." + # Dump the recovered file. + set ret [eval {exec $util_path/db_dump -p} \ + $dumpargs {-f $testdir/file.recovered \ + $testdir/$testfile} ] + filesort $testdir/file.recovered \ + $testdir/file.recovered.sorted + + puts "\t\tTest$tnum.d3: Compare\ + initial file to aborted file." + error_check_good filecmp_orig_abort \ + [filecmp $testdir/file.init.sorted \ + $testdir/file.afterabort.sorted] 0 + puts "\t\tTest$tnum.d3: Compare\ + initial file to recovered file." + error_check_good filecmp_orig_abort \ + [filecmp $testdir/file.init.sorted \ + $testdir/file.recovered.sorted] 0 + + # Clean up. + catch {$db close} dbret + catch {$env close} envret + } else { + error_check_good commit [$t commit] 0 + $db close + $env close + } + } + } + + # The run_all db_verify will fail since we have a custom + # hash, so clean up before leaving the test. + env_cleanup $testdir +} + +# This proc is used for identifying hash buckets; it requires +# a key that starts with an integer, then has a dot ".", +# then anything else. +proc ident_test140 { key } { + set idx [string first . $key] + + # This handles the case where we are saving a + # hash on the initial db create. + if { $idx == -1 } { + return 9999 + } + + set item [string range $key 0 [expr $idx - 1]] + set bucket [format "%04d" $item] + return $bucket +} + diff --git a/test/tcl/test141.tcl b/test/tcl/test141.tcl new file mode 100644 index 00000000..19860f77 --- /dev/null +++ b/test/tcl/test141.tcl @@ -0,0 +1,145 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test141 +# TEST Test moving a large part of a hash table to a continguous +# TEST block of free pages. +# TEST +# TEST Create a database with a btree and a hash subdb. Remove +# TEST all the data from the first (btree) db and then compact +# TEST to cause the hash db to get moved. + +proc test141 { method {nentries 10000} {tnum "141"} args } { + source ./include.tcl + global alphabet + global passwd + + # This is a hash-only test. + if { [is_hash $method] != 1} { + puts "Skipping test$tnum for method $method." + return + } + + # Skip for partitioning; this test uses subdatabases. + if { [is_partitioned $args] == 1 } { + puts "Test$tnum skipping for partitioned $method" + return + } + + # This test creates its own transactional env. + set eindex [lsearch -exact $args "-env"] + if { $eindex != -1 } { + incr eindex + set env [lindex $args $eindex] + puts "Test$tnum skipping for env $env" + return + } + set args [convert_args $method $args] + set omethod [convert_method $method] + set encargs "" + set args [split_encargs $args encargs] + + set testfile test$tnum.db + set data [repeat $alphabet 5] + + puts "Test$tnum: $method ($args $encargs)\ + Hash testing where we move a large block of entries." + + env_cleanup $testdir + set env [eval {berkdb_env_noerr} -create -txn -pagesize 512 \ + {-cachesize { 0 1048576 1 }} $encargs -home $testdir] + error_check_good env_open [is_valid_env $env] TRUE + + # Populate a btree subdb. + puts "\tTest$tnum.a: Create and populate a btree subdb." + set bdb [eval {berkdb_open_noerr -create -btree \ + -auto_commit -env $env} $args {$testfile BTREE}] + error_check_good db_open [is_valid_db $bdb] TRUE + + set t [$env txn] + set txn "-txn $t" + + for { set i 0 } { $i < $nentries } { incr i } { + set ret [eval {$bdb put} $txn {$i $i.$data}] + error_check_good db_put $ret 0 + } + + error_check_good txn_commit [$t commit] 0 + $bdb sync + + # Now a small hash subdb. + puts "\tTest$tnum.b: Create and populate a hash subdb." + set hdb [eval {berkdb_open_noerr -create -hash \ + -auto_commit -env $env} $args {$testfile HASH}] + error_check_good dbopen [is_valid_db $hdb] TRUE + + set t [$env txn] + set txn "-txn $t" + + for { set i 0 } { $i < 100 } { incr i } { + set ret [eval {$hdb put} $txn {$i $i.$data}] + error_check_good put $ret 0 + } + + error_check_good txn_commit [$t commit] 0 + $hdb sync + + # Delete the contents of the btree subdatabase. + set t [$env txn] + set txn "-txn $t" + for { set i 0 } { $i < $nentries } { incr i } { + set ret [eval {$bdb del} $txn {$i}] + error_check_good db_del $ret 0 + } + error_check_good txn_commit [$t commit] 0 + $bdb sync + + # Compact. + puts "\tTest$tnum.d: Compact the btree." + set orig_size [file size $testdir/$testfile] + + set t [$env txn] + set txn "-txn $t" + + if {[catch {eval {$bdb compact} $txn \ + { -freespace}} ret] } { + error "FAIL: db compact: $ret" + } + + error_check_good txn_commit [$t commit] 0 + $bdb sync + + # The btree compaction is not expected to reduce + # file size because the last page of the file is hash. + set after_bt_compact_size [file size $testdir/$testfile] + error_check_good file_size\ + [expr $orig_size == $after_bt_compact_size] 1 + + puts "\tTest$tnum.d: Compact the hash." + set t [$env txn] + set txn "-txn $t" + + if {[catch {eval {$hdb compact} $txn \ + { -freespace}} ret] } { + error "FAIL: db compact: $ret" + } + + error_check_good txn_commit [$t commit] 0 + $hdb sync + + # Now we expect the file to be much smaller. + set after_h_compact_size [file size $testdir/$testfile] + error_check_good file_size_reduced\ + [expr $orig_size > [expr $after_h_compact_size * 5]] 1 + + # The run_all db_verify will fail since we have a custom + # hash, so clean up before leaving the test. + error_check_good bdb_close [$bdb close] 0 + error_check_good hdb_close [$hdb close] 0 + error_check_good env_close [$env close] 0 + env_cleanup $testdir +} + diff --git a/test/tcl/test142.tcl b/test/tcl/test142.tcl new file mode 100644 index 00000000..22d92b2e --- /dev/null +++ b/test/tcl/test142.tcl @@ -0,0 +1,413 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# TEST test142 +# TEST Tests exclusive database handles. +# TEST 1. Test that exclusive database handles return an error in incompatible +# TEST environments. +# TEST 2. Test that an exclusive subdatabase handle does not block opening a +# TEST handle on another database in the same file. +# TEST 3. Run script tests on a subdatabase with both wait and no wait +# TEST configuration. +# TEST 4. Run script tests on a database with both wait and no wait +# TEST configuration. +proc test142 {method {tnum "142"} args } { + source ./include.tcl + source $tcl_utils/multi_proc_utils.tcl + + # Skip this test if threads are not enabled + if [catch {package require Thread}] { + puts "Skipping test$tnum: requires Tcl Thread package." + return 0 + } + + set script1 [test142_script1] + set script2 [test142_script2] + set nowaits {0 1} + set omethod [convert_method $method] + set args [convert_args $method $args] + set testfile test$tnum.db + set exclfile excl.db + set cryargs {} + set homedir $testdir + + puts "Test$tnum: Exclusive database handles ($method $args)" + + # Check if we are using a transactional environment. + set eindex [lsearch $args "-env"] + set txnenv 1 + set threaded 0 + set opened 0 + set env 0 + set args2 $args + set noerr_env 0 + if { $eindex != -1 } { + set env [lindex $args $eindex+1] + set args2 [lreplace $args $eindex $eindex+1] + set txnenv [is_txnenv $env] + set sys [$env get_open_flags] + if { [lsearch $sys -thread] != -1 } { + set threaded 1 + } + set homedir [$env get_home] + } else { + set eindex [lsearch $args "-encryptaes"] + if { $eindex != -1 } { + set cryargs [lrange $args $eindex $eindex+1] + set args [lreplace $args $eindex $eindex+1] + set eindex [lsearch $args2 "-encryptaes"] + set args2 [lreplace $args2 $eindex $eindex+1] + lappend args -encrypt + lappend args2 -encrypt + } + set opened 1 + set env [eval {berkdb_env_noerr -create -txn \ + -cachesize { 0 1048576 1 }} $cryargs -home $homedir] + error_check_good envopen [is_valid_env $env] TRUE + lappend args -env + lappend args $env + set noerr_env 1 + } + cleanup $homedir $env + + # Check that opening the database exclusively fails + # on threaded or non-transactional environments + if { $txnenv == 0 || $threaded == 1 } { + puts "\tTest$tnum.a: Exclusive open fails with threaded or non-txn env." + foreach nowait $nowaits { + set ret [catch {eval {berkdb_open_noerr -create \ + -mode 0644 $omethod -lk_exclusive $nowait} $args \ + {$testfile}} db] + error_check_bad dbopen $ret 0 + } + return + } + + if { $noerr_env } { + puts "\t Test$tnum.b: Exclusive databases can have only 1 active txn." + set db [eval {berkdb_open_noerr -create -mode 0644 \ + -auto_commit $omethod -lk_exclusive 0} $args \ + ./multitxn.db ] + error_check_good dbopen [is_valid_db $db] TRUE + set txn1 [$env txn] + set txn2 [$env txn] + set did [open $dict] + set key "" + gets $did str + if { [is_record_based $omethod] == 1 } { + set key 1 + } else { + set key $str + } + set ret [eval {$db put} -txn $txn1 \ + {$key [chop_data $omethod $str]}] + error_check_good multi_txn $ret 0 + catch { eval {$db put} -txn $txn2 \ + {$key [chop_data $omethod $str]}} ret + error_check_bad multi_txn $ret 0 + $txn2 abort + $txn1 commit + $db close + } + + # Queue and heap databases do not support multiple databases + # in a single file. + if { ![is_queue $omethod] && ![is_heap $omethod] && + ![is_partitioned $args]} { + # Create a database with sub databases. + puts "\tTest$tnum.c: Open a database with subdbs." + set ret [catch {eval {berkdb_open} -create -auto_commit \ + -mode 0644 $omethod $args $exclfile one} db1] + error_check_good db1open $ret 0 + set ret [catch {eval {berkdb_open} -create -auto_commit \ + -mode 0644 $omethod $args $exclfile two} db2] + error_check_good db2open $ret 0 + $db1 close + $db2 close + + # Check that and exclusive subdatabase handle does not + # interfere with opening another subdatabase in the same file + foreach nowait $nowaits { + puts "\tTest$tnum.d: Open one subdb exclusively, another not, for nowait value $nowait." + set ret [catch {eval {berkdb_open $omethod \ + -lk_exclusive $nowait} \ + $args -auto_commit $exclfile one} db1] + error_check_good db1exclopen$nowait $ret 0 + set ret [catch {eval {berkdb_open $omethod} \ + $args -auto_commit $exclfile two} db2] + error_check_good db2exclopen$nowait $ret 0 + $db1 close + $db2 close + } + + if { [is_repenv $env] } { + puts "\tTest$tnum.e Skipping scripts in replication environment." + return; + } + + # Run the scripts with the sub databases + foreach nowait $nowaits { + puts "\tTest$tnum.f: Test scripts with subdatabases, for nowait value $nowait." + set myports [available_ports 2] + set myPort1 [lindex $myports 0] + set myPort2 [lindex $myports 1] + set arg_list1 [list $omethod $nowait $args2 \ + $exclfile $cryargs $myPort1 $myPort2 \ + $homedir one] + set arg_list2 [list $omethod $nowait $args2 \ + $exclfile $cryargs $myPort2 $myPort1 \ + $homedir one] + do_multi_proc_test test${tnum}excl1_$nowait \ + [list $script1 $script2] \ + [list $arg_list1 $arg_list2] + } + } + + if { [is_repenv $env] } { + puts "\tTest$tnum.g Skipping scripts in replication environment." + return; + } + + # Run the scripts with the passed in database files + foreach nowait $nowaits { + puts "\tTest$tnum.h: Test scripts with passed-in db files, for nowait value $nowait." + set myports [available_ports 2] + set myPort1 [lindex $myports 0] + set myPort2 [lindex $myports 1] + set arg_list1 [list $omethod $nowait $args2 $testfile \ + $cryargs $myPort1 $myPort2 $homedir] + set arg_list2 [list $omethod $nowait $args2 $testfile \ + $cryargs $myPort2 $myPort1 $homedir] + do_multi_proc_test test${tnum}excl2_$nowait \ + [list $script1 $script2] [list $arg_list1 $arg_list2] + } + + if { $opened } { + $env close + } +} + +# Script 1 +# 1. Opens an exclusive database handle +# 2. Populates the database. +# 3. Confirms that Script 2 is blocked trying to open a handle on +# the same database. +# 4. Close the exclusive handle. +# 5. Try reopening the exclusive handle, which will fail if nowait is +# true, and will succeed after blocking if it is false. +proc test142_script1 {} { + set script1 { + source ./include.tcl + source $test_path/test.tcl + source $test_path/testutils.tcl + source $tcl_utils/multi_proc_utils.tcl + + set usage \ + "script omethod nowait args testfile cyrargs myPort clientPort homedir databaseName" + + # Verify usage + set cmd_args [lindex $argv 0] + if { [llength $cmd_args] < 8 } { + puts stderr "FAIL:[timestamp] Usage: $usage" + exit + } + set omethod [lindex $cmd_args 0] + set nowait [lindex $cmd_args 1] + set args [lindex $cmd_args 2] + set testfile [lindex $cmd_args 3] + set cryargs [lindex $cmd_args 4] + set myPort [lindex $cmd_args 5] + set clientPort [lindex $cmd_args 6] + set homedir [lindex $cmd_args 7] + set databasename "" + if { [llength $cmd_args] > 8 } { + set databasename [lindex $cmd_args 8] + } + set timeout 10 + + # Join the environment + puts "Joining the environment in $homedir." + set dbenv [eval {berkdb_env -txn} $cryargs -home $homedir] + error_check_good envopen [is_valid_env $dbenv] TRUE + + # open the exclusive database handle. + puts "Opening the exclusive database handle." + set db [eval berkdb_open -create -mode 0644 -auto_commit \ + $omethod -lk_exclusive $nowait -env $dbenv $args \ + $testfile $databasename] + error_check_good dbopen [is_valid_db $db] TRUE + + set ret [do_sync $myPort $clientPort $timeout] + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + $db close + $dbenv close + exit -1 + } + + # Check that inserting works. + puts "Populating the database." + set t [$dbenv txn] + populate $db $omethod $t 10 0 0 + + # close the database handle, this will not release + # the handle lock, because the transaction is holding it + puts "Closing the exclusive database handle." + $db close + + # This sync will fail because script2 is blocked trying + # to open a handle on the exclusive database. + puts "Confirming script 2 is blocked." + set ret [do_sync $myPort $clientPort $timeout] + if { $ret == 0 } { + puts stderr \ + "FAIL: Synchronization succeeded where it should have failed." + $db close + $dbenv close + exit -1 + } + # Now commit the transaction, releaseing the handle lock and + # allowing the script 2 to proceed. + error_check_good commit [eval {$t commit}] 0 + set ret [do_sync $myPort $clientPort $timeout] + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + $dbenv close + exit -1 + } + + puts "Opening another exclusive database handle." + set ret [catch {eval berkdb_open_noerr -auto_commit \ + -lk_exclusive $nowait $omethod -env $dbenv $args \ + $testfile $databasename} db] + if { $nowait == 1 } { + error_check_bad dbopenwait $ret 0 + # wakeup script2 + set ret [do_sync $myPort $clientPort $timeout] + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + $dbenv close + exit -1 + } + } else { + error_check_good dbopennowait $ret 0 + $db close + set ret [do_sync $myPort $clientPort $timeout] + if { $ret == 0 } { + puts stderr \ + "FAIL: Synchronization succeeded where it should have failed." + $dbenv close + exit -1 + } + } + + $dbenv close + } + + # Do not put anything here, this proc depends on the + # return of set script1 +} + +# Script 2 +# 1. Lets Script 1 open an exclusive handle on the database. +# 2. Opens a handle on the database, this blocks until Script 1 closes +# its exclusive handle. +# 3. Populates the database. +# 4. Tries to synchronize with Script 1, which will fail if nowait is +# false because Script 1 is blocked trying to open an exclusive handle +# on the database, and will succeed if nowait is true the exclusive +# handle in Script 1 would have returned an error immediately. +proc test142_script2 {} { + set script2 { + source ./include.tcl + source $test_path/test.tcl + source $test_path/testutils.tcl + source $tcl_utils/multi_proc_utils.tcl + + set usage \ + "script omethod nowait args testfile myPort clientPort homedir databaseName" + + # Verify usage + set cmd_args [lindex $argv 0] + if { [llength $cmd_args] < 8 } { + puts stderr "FAIL:[timestamp] Usage: $usage" + exit + } + set omethod [lindex $cmd_args 0] + set nowait [lindex $cmd_args 1] + set args [lindex $cmd_args 2] + set testfile [lindex $cmd_args 3] + set cryargs [lindex $cmd_args 4] + set myPort [lindex $cmd_args 5] + set clientPort [lindex $cmd_args 6] + set homedir [lindex $cmd_args 7] + set databasename "" + if { [llength $cmd_args] > 8 } { + set databasename [lindex $cmd_args 8] + } + set timeout 10 + + # Wait for script1 to open the exlusive database + puts "Waiting for script 1 to open the exclusive database." + set ret [do_sync $myPort $clientPort $timeout] + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + exit + } + + # Join the environment + puts "Opening the environment in $homedir." + set dbenv [eval {berkdb_env -txn} $cryargs -home $homedir] + error_check_good envopen [is_valid_env $dbenv] TRUE + + # This will block until script 1 closes the exclusive database + puts "Opening the database." + set db [eval berkdb_open -auto_commit $omethod -env $dbenv \ + $args $testfile $databasename] + error_check_good dbopen [is_valid_db $db] TRUE + set db [eval berkdb_open -auto_commit \ + $omethod -env $dbenv $args $testfile $databasename] + error_check_good dbopen [is_valid_db $db] TRUE + + # Wakeup script1 + set ret [do_sync $myPort $clientPort $timeout] + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + $db close + $dbenv close + exit -1 + } + + # Check that inserting works. + puts "Populating the database." + set t [$dbenv txn] + populate $db $omethod $t 10 0 0 + error_check_good commit [eval {$t commit}] 0 + + # This will succeed if nowait == 1, and fail otherwise + set ret [do_sync $myPort $clientPort $timeout] + if { $nowait == 1 } { + if { $ret != 0 } { + puts stderr "FAIL: Synchronization failed." + $db close + $dbenv close + exit -1 + } + } elseif { $ret == 0 } { + puts stderr \ + "FAIL: Synchronization succeeded when it should have failed." + $db close + $dbenv close + exit -1 + } + + $db close + $dbenv close + } + + # Do not put anything here, this proc depends on the + # return of set script2 +} diff --git a/test/tcl/testparams.tcl b/test/tcl/testparams.tcl index 333176f5..dd50eea8 100644 --- a/test/tcl/testparams.tcl +++ b/test/tcl/testparams.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ @@ -50,17 +50,17 @@ set test_names(rep) [list rep001 rep002 rep003 rep005 rep006 rep007 \ rep068 rep069 rep070 rep071 rep072 rep073 rep074 rep075 rep076 rep077 \ rep078 rep079 rep080 rep081 rep082 rep083 rep084 rep085 rep086 rep087 \ rep088 rep089 rep090 rep091 rep092 rep093 rep094 rep095 rep096 rep097 \ - rep098] + rep098 rep099 rep100 rep101 rep102] set test_names(skip_for_env_private) [list rep002 rep003 rep004 rep005 \ rep014 rep016 rep017 rep018 rep020 rep022 rep026 rep028 rep031 \ rep033 rep035 rep036 rep038 rep039 rep040 rep041 rep042 rep043 rep044 \ rep045 rep048 rep054 rep055 rep056 rep057 rep059 rep060 rep061 rep063 \ rep065 rep066 rep067 rep068 rep069 rep070 rep072 rep076 rep078 \ - rep079 rep081 rep082 rep083 rep088 rep095 rep096 rep098 ] + rep079 rep081 rep082 rep083 rep088 rep095 rep096 rep098 rep100] set test_names(skip_for_inmem_db) [list rep002 rep003 rep004 rep008 rep009 \ rep011 rep015 rep017 rep018 rep027 rep036 rep042 rep043 rep056 rep057 \ rep058 rep059 rep065 rep068 rep078 rep079 rep081 rep082 rep083 rep084 \ - rep085 rep086 rep087 rep088 rep090 ] + rep085 rep086 rep087 rep088 rep090 rep099 rep100] set test_names(skip_for_inmem_rep) [list rep089] set test_names(auto_repmgr) [list repmgr001 repmgr002 repmgr003 ] set test_names(basic_repmgr) [list basic_repmgr_test \ @@ -70,7 +70,8 @@ set test_names(multi_repmgr) [list repmgr100 repmgr101 repmgr102 \ repmgr110 repmgr111 repmgr112] set test_names(other_repmgr) [list repmgr007 repmgr009 repmgr010 repmgr011 \ repmgr012 repmgr013 repmgr017 repmgr018 repmgr023 repmgr024 repmgr025 \ - repmgr026 repmgr027 repmgr028 repmgr029 repmgr030 repmgr031 repmgr032] + repmgr026 repmgr027 repmgr028 repmgr029 repmgr030 repmgr031 repmgr032 \ + repmgr033 repmgr034] set test_names(rsrc) [list rsrc001 rsrc002 rsrc003 rsrc004] set test_names(sdb) [list sdb001 sdb002 sdb003 sdb004 sdb005 sdb006 \ sdb007 sdb008 sdb009 sdb010 sdb011 sdb012 sdb013 sdb014 sdb015 sdb016 \ @@ -92,7 +93,8 @@ set test_names(test) [list test001 test002 test003 test004 test005 \ test096 test097 test098 test099 test100 test101 test102 test103 test107 \ test109 test110 test111 test112 test113 test114 test115 test116 test117 \ test119 test120 test121 test122 test123 test124 test125 test126 test127 \ - test128 test129 test130 test131 test132 test133 test134] + test128 test129 test130 test131 test132 test133 test134 test135 test136 \ + test137 test138 test139 test140 test141 test142] set test_names(txn) [list txn001 txn002 txn003 txn004 txn005 txn006 \ txn007 txn008 txn009 txn010 txn011 txn012 txn013 txn014] @@ -111,7 +113,7 @@ foreach test $skip_for_rep_commit { } } -# Source all the tests, whether we're running one or many. + # Source all the tests, whether we're running one or many. foreach sub $subs { foreach test $test_names($sub) { source $test_path/$test.tcl @@ -146,6 +148,8 @@ source $test_path/sijointest.tcl source $test_path/siutils.tcl source $test_path/testutils.tcl source $test_path/upgrade.tcl +source $test_path/../tcl_utils/multi_proc_utils.tcl +source $test_path/../tcl_utils/common_test_utils.tcl set parms(recd001) 0 set parms(recd002) 0 @@ -265,6 +269,10 @@ set parms(rep095) {200 "095"} set parms(rep096) {20 "096"} set parms(rep097) {"097"} set parms(rep098) {200 "098"} +set parms(rep099) {200 "099"} +set parms(rep100) {10 "100"} +set parms(rep101) {100 "101"} +set parms(rep102) {100 "102"} set parms(repmgr007) {100 "007"} set parms(repmgr009) {10 "009"} set parms(repmgr010) {100 "010"} @@ -281,6 +289,7 @@ set parms(repmgr027) {"027"} set parms(repmgr028) {"028"} set parms(repmgr030) {100 "030"} set parms(repmgr032) {"032"} +set parms(repmgr034) {3 "034"} set parms(repmgr100) "" set parms(repmgr101) "" set parms(repmgr102) "" @@ -450,8 +459,8 @@ set parms(test122) {"122"} set parms(test123) "" set parms(test124) 1000 set parms(test125) "" -set parms(test126) {10000 "126" 1 0 0} -set parms(test127) {10000 5 "127" 0} +set parms(test126) {10000 "126" 1 0 0 0} +set parms(test127) {10000 5 "127" 0 0} set parms(test128) {10000 1} set parms(test129) {10000 5} set parms(test130) {10000 3 "130"} @@ -459,6 +468,14 @@ set parms(test131) {1000 "131" 5 0 0} set parms(test132) {1000 5} set parms(test133) {1000 "133" 0} set parms(test134) {1000} +set parms(test135) {10 10 0 "135"} +set parms(test136) {10 10} +set parms(test137) {1000 0 0 0 "137" "ds"} +set parms(test138) {1000 0 0} +set parms(test139) {512 1000 "139"} +set parms(test140) {"140"} +set parms(test141) {10000 "141"} +set parms(test142) {"142"} # Shell script tests. Each list entry is a {directory filename rundir} list, # invoked with "/bin/sh filename". diff --git a/test/tcl/testutils.tcl b/test/tcl/testutils.tcl index d7757999..48872bf6 100644 --- a/test/tcl/testutils.tcl +++ b/test/tcl/testutils.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -3031,6 +3031,73 @@ proc fileextract { superset subset outfile } { return 0 } +# Verify an in-memory database +proc dbverify_inmem { filename {directory $testdir} \ + { pref "" } { quiet 0 } { nodump 0 } { cachesize 0 } { unref 1 } } { + global encrypt + global passwd + + set ret 0 + + # We need to have an env in order to share in-memory dbs. Pick + # a fairly generous default cachesize if we haven't specified something + # else. + + if { $cachesize == 0 } { + set cachesize [expr 1024 * 1024] + } + set encarg "" + if { $encrypt != 0 } { + set encarg " -encryptaes $passwd" + } + + set env [eval {berkdb_env -create -home $directory} $encarg \ + {-cachesize [list 0 $cachesize 0]}] + set earg " -env $env " + + # The 'unref' flag means that we report unreferenced pages + # at all times. This is the default behavior. + # If we have a test which leaves unreferenced pages on systems + # where HAVE_FTRUNCATE is not on, then we call verify_dir with + # unref == 0. + set uflag "-unref" + if { $unref == 0 } { + set uflag "" + } + + set db " \"\" $filename" + if { [catch {eval {berkdb dbverify} $uflag $earg $db} res] != 0 } { + puts $res + puts "FAIL:[timestamp] Verification of $filename failed." + set ret 1 + continue + } else { + error_check_good verify:$db $res 0 + if { $quiet == 0 } { + puts "${pref}Verification of $filename succeeded." + } + } + + # Skip the dump if it's dangerous to do it. + if { $nodump == 0 } { + if { [catch {eval dumploadtest_inmem $filename $directory} res] != 0 } { + puts $res + puts "FAIL:[timestamp] Dump/load of $filename failed." + set ret 1 + continue + } else { + error_check_good dumpload:$db $res 0 + if { $quiet == 0 } { + puts "${pref}Dump/load of $filename succeeded." + } + } + } + + error_check_good vrfyenv_close [$env close] 0 + + return $ret +} + # Verify all .db files in the specified directory. proc verify_dir { {directory $testdir} { pref "" } \ { noredo 0 } { quiet 0 } { nodump 0 } { cachesize 0 } { unref 1 } } { @@ -3182,6 +3249,72 @@ proc db_compare { olddb newdb olddbname newdbname } { return 0 } +proc dumploadtest_inmem { db envdir } { + global util_path + global encrypt + global passwd + + set newdbname $db-dumpload.db + + set encarg "" + set utilflag "-h $envdir" + set keyflag "-k" + set heapdb 0 + + if { $encrypt != 0 } { + set encarg "-encryptany $passwd" + set utilflag "$utilflag -P $passwd" + } + + # Open original database to find dbtype. + set env [eval {berkdb_env -home $envdir} $encarg] + set earg " -env $env " + + set olddb [eval {berkdb_open -rdonly} $encarg $earg {"" $db}] + error_check_good olddb($db) [is_valid_db $olddb] TRUE + if { [is_heap [$olddb get_type]] } { + set heapdb 1 + set keyflag "" + } + error_check_good orig_db_close($db) [$olddb close] 0 + error_check_good env_close [$env close] 0 + + set dumpflags "$utilflag $keyflag -m $db" + + # Dump/load the whole file, including all subdbs. + set rval [catch {eval {exec $util_path/db_dump} $dumpflags | \ + $util_path/db_load $utilflag $newdbname} res] + error_check_good db_dump/db_load($db:$res) $rval 0 + + # If the old file was empty, there's no new file and we're done. + if { [file exists $newdbname] == 0 } { + return 0 + } + + # Dump/load doesn't preserve order in a heap db, don't run db_compare + if { $heapdb == 1 } { + eval berkdb dbremove $encarg $newdbname + return 0 + } + + # Open original database. + set env [eval {berkdb_env -create -home $envdir} $encarg \ + {-cachesize [list 0 $cachesize 0]}] + + set olddb [eval {berkdb_open -rdonly} $encarg $earg {"" $db}] + error_check_good olddb($db) [is_valid_db $olddb] TRUE + + # Open the new database. + set newdb [eval {berkdb_open -rdonly} $encarg $earg $newdbname] + error_check_good newdb($db) [is_valid_db $newdb] TRUE + db_compare $olddb $newdb $db $newdbname + error_check_good new_db_close($db) [$newdb close] 0 + + error_check_good orig_db_close($db) [$olddb close] 0 + eval berkdb dbremove $encarg -env $env $newdbname + error_check_good env_close [$env close] 0 +} + proc dumploadtest { db } { global util_path global encrypt @@ -3642,7 +3775,20 @@ proc sanitized_pid { } { return $mypid } +# Determine the native page size of the OS for on-disk dbs. # +proc get_native_pagesize { } { + set stat [catch {set db [berkdb_open -create -btree native.db] } res] + if { $stat == 0 } { + set native_pagesize [$db get_pagesize] + error_check_good db_close [$db close] 0 + fileremove -f native.db + return $native_pagesize + } else { + puts "FAIL: Could not determine on-disk page size: $res" + } +} + # Extract the page size field from a stat record. Return -1 if # none is found. # @@ -3837,7 +3983,7 @@ proc is_debug { } { proc adjust_logargs { logtype {lbufsize 0} } { if { $logtype == "in-memory" } { if { $lbufsize == 0 } { - set lbuf [expr 1 * [expr 1024 * 1024]] + set lbuf [expr 2 * [expr 1024 * 1024]] set logargs " -log_inmemory -log_buffer $lbuf " } else { set logargs " -log_inmemory -log_buffer $lbufsize " diff --git a/test/tcl/txn001.tcl b/test/tcl/txn001.tcl index 39260625..9aba9d47 100644 --- a/test/tcl/txn001.tcl +++ b/test/tcl/txn001.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn002.tcl b/test/tcl/txn002.tcl index a1a84e01..982567f4 100644 --- a/test/tcl/txn002.tcl +++ b/test/tcl/txn002.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn003.tcl b/test/tcl/txn003.tcl index a844d80c..a9a714e5 100644 --- a/test/tcl/txn003.tcl +++ b/test/tcl/txn003.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn004.tcl b/test/tcl/txn004.tcl index 7bbd4544..60b8b8b7 100644 --- a/test/tcl/txn004.tcl +++ b/test/tcl/txn004.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn005.tcl b/test/tcl/txn005.tcl index f45e2a37..b8f9d7c3 100644 --- a/test/tcl/txn005.tcl +++ b/test/tcl/txn005.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn006.tcl b/test/tcl/txn006.tcl index ae931ef8..5960770c 100644 --- a/test/tcl/txn006.tcl +++ b/test/tcl/txn006.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn007.tcl b/test/tcl/txn007.tcl index 2f6bb88c..04681d3e 100644 --- a/test/tcl/txn007.tcl +++ b/test/tcl/txn007.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn008.tcl b/test/tcl/txn008.tcl index 384a6f2d..27b790bd 100644 --- a/test/tcl/txn008.tcl +++ b/test/tcl/txn008.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn009.tcl b/test/tcl/txn009.tcl index 561174b6..ef5086fd 100644 --- a/test/tcl/txn009.tcl +++ b/test/tcl/txn009.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn010.tcl b/test/tcl/txn010.tcl index ef1de2d8..e3333c32 100644 --- a/test/tcl/txn010.tcl +++ b/test/tcl/txn010.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn011.tcl b/test/tcl/txn011.tcl index 6b1ab398..75ca4d34 100644 --- a/test/tcl/txn011.tcl +++ b/test/tcl/txn011.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2003, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn012.tcl b/test/tcl/txn012.tcl index 9e3946dc..834594d0 100644 --- a/test/tcl/txn012.tcl +++ b/test/tcl/txn012.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn012script.tcl b/test/tcl/txn012script.tcl index 45698073..ecf32ddf 100644 --- a/test/tcl/txn012script.tcl +++ b/test/tcl/txn012script.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn013.tcl b/test/tcl/txn013.tcl index ec9aa39c..b8ece03b 100644 --- a/test/tcl/txn013.tcl +++ b/test/tcl/txn013.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txn014.tcl b/test/tcl/txn014.tcl index 8f95e5ad..8b798ae5 100644 --- a/test/tcl/txn014.tcl +++ b/test/tcl/txn014.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2005, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/txnscript.tcl b/test/tcl/txnscript.tcl index 795b1b4b..b845b36c 100644 --- a/test/tcl/txnscript.tcl +++ b/test/tcl/txnscript.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl/update.tcl b/test/tcl/update.tcl index 201068d3..01db9676 100644 --- a/test/tcl/update.tcl +++ b/test/tcl/update.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ diff --git a/test/tcl/upgrade.tcl b/test/tcl/upgrade.tcl index c470e922..5976bd68 100644 --- a/test/tcl/upgrade.tcl +++ b/test/tcl/upgrade.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 1999, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ diff --git a/test/tcl/wrap.tcl b/test/tcl/wrap.tcl index 9ab1cd37..77c25db5 100644 --- a/test/tcl/wrap.tcl +++ b/test/tcl/wrap.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # @@ -11,6 +11,7 @@ source ./include.tcl source $test_path/testutils.tcl +source $tcl_utils/multi_proc_utils.tcl # Arguments: if { $argc < 2 } { @@ -41,8 +42,9 @@ set parentsentinel $testdir/begin.$parentpid set f [open $parentsentinel w] close $f -# Create a Tcl subprocess that will actually run the test. -set t [open "|$tclsh_path >& $logfile" w] +# Create a subprocess that will actually run the test. +set nameexec [info nameofexecutable] +set t [open "|$nameexec >& $logfile" w] # Create a sentinel for the subprocess. set childpid [pid $t] diff --git a/test/tcl/wrap_reptest.tcl b/test/tcl/wrap_reptest.tcl index e3d12836..57fed3d3 100644 --- a/test/tcl/wrap_reptest.tcl +++ b/test/tcl/wrap_reptest.tcl @@ -1,6 +1,6 @@ # See the file LICENSE for redistribution information. # -# Copyright (c) 2000, 2011 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2012 Oracle and/or its affiliates. All rights reserved. # # $Id$ # diff --git a/test/tcl_utils/common_test_utils.tcl b/test/tcl_utils/common_test_utils.tcl new file mode 100644 index 00000000..7b1c220c --- /dev/null +++ b/test/tcl_utils/common_test_utils.tcl @@ -0,0 +1,67 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2012, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# Utility functions for tests in Core and SQL + +# Return a list of TCP port numbers that are not currently in use on +# the local system. Note that this doesn't actually reserve the +# ports, so it's possible that by the time the caller tries to use +# them, another process could have taken one of them. But for our +# purposes that's unlikely enough that this is still useful: it's +# still better than trying to find hard-coded port numbers that will +# always be available. +# +# Using a starting baseport value that falls in the non-ephemeral port +# range on most platforms. Can override starting baseport by setting +# environment variable BDBBASEPORT. +# +# Must test explicit 127.0.0.1 host rather than localhost because +# localhost can be configured differently on different platforms or +# machines and that can cause this routine to return ports that are +# actually in use. +# +proc available_ports { n { rangeincr 10 } } { + global env + + if { [info exists env(BDBBASEPORT)] } { + set baseport $env(BDBBASEPORT) + } else { + set baseport 30100 + } + + # Try sets of contiguous ports ascending from baseport. + for { set i $baseport } { $i < $baseport + $rangeincr * 100 } \ + { incr i $rangeincr } { + set ports {} + set socks {} + set numports $n + set curport $i + + # Try one set of contiguous ports. + while { [incr numports -1] >= 0 } { + incr curport + if [catch { socket -server Unused \ + -myaddr 127.0.0.1 $curport } sock] { + # A port is unavailable, try another set. + break + } + lappend socks $sock + lappend ports $curport + } + foreach sock $socks { + close $sock + } + if { $numports == -1 } { + # We have all the ports we need. + break + } + } + if { $numports == -1 } { + return $ports + } else { + error "available_ports: could not get ports for $baseport" + } +} diff --git a/test/tcl_utils/multi_proc_utils.tcl b/test/tcl_utils/multi_proc_utils.tcl new file mode 100644 index 00000000..88b727d5 --- /dev/null +++ b/test/tcl_utils/multi_proc_utils.tcl @@ -0,0 +1,320 @@ +# See the file LICENSE for redistribution information. +# +# Copyright (c) 2012, 2012 Oracle and/or its affiliates. All rights reserved. +# +# $Id$ +# +# Utility functions for multi process tests in Core and SQL + +# The SQL test suite shell (testfixture) lacks some basic Tcl functions +# that are required by do_multi_proc_test and do_sync, like clock. +# So load the tcl library if it has not already been loaded. +proc load_tcl_library {} { + global tcl_platform + set nameexec [info nameofexecutable] + if { [string match *testfixture* $nameexec] } { + set loaded [info loaded] + if { [lsearch $loaded tcl*] == -1 && + [lsearch $loaded libtcl*] == -1 } { + set isWindows 0 + set os $tcl_platform(platform) + set tclversion [info tclversion] + if { [string equal -nocase "windows" $os] } { + # Get the version number and strip the . from it + for {set x 0} {$x < [string length $tclversion]} {incr x} { + set char [string index $tclversion $x] + if { [string equal \. $char] } { + set tclversion [string replace $tclversion $x $x] + } + } + load tcl$tclversion[info sharedlibextension] Tcl + } else { + load libtcl$tclversion[info sharedlibextension] Tcl + } + } + } +} + +load_tcl_library + +# do_multi_proc_test - Takes a list of scripts and executes them +# as separate processes, and reports any errors or test failures +# to the error log for Core tests, and the error counter for +# SQL tests. Look at db/test/sql/bdb_multi_proc.test for a +# test example. Output from the tests are redirected to +# TESTOUTPUT/err_[script number]_[testname].txt +# +# name - Name of the test. +# scripts - A list of scripts that will be writen to separate +# files then executed by tclsh for Core tests, and testfixture +# for SQL tests. +# args_lists - A list of lists containing arguments to pass +# to the test scripts. +# verbose - Print verbose output to the script error log. +proc do_multi_proc_test { name scripts args_lists {verbose 0} } { + set working_dir [pwd] + if [ catch {source ./include.tcl} ] { + eval cd .. + if [ catch {source ./include.tcl} ] { + eval cd .. + source ./include.tcl + } + } + source $test_path/testutils.tcl + set error_dir [pwd]/TESTOUTPUT + + # May have to create the test directory if in the SQL suite + if { [file exists $testdir] == 0 } { + file mkdir $testdir + } + # Create the error directory if not already there. + if { [file exists $error_dir] == 0 } { + file mkdir $error_dir + } + + # Write script files as $counter_$name.tcl + set counter 1 + set fileNames {} + set errLogs {} + foreach script $scripts { + set fileName "${counter}_${name}.tcl" + lappend fileNames $fileName + lappend errLogs "err_${counter}_${name}.txt" + incr counter + set aFile [open $fileName w] + puts $aFile $script + flush $aFile + close $aFile + } + + # Run scripts + sentinel_init + set pidlist {} + set working_dir [pwd] + # For core the executable is tclsh, for SQL it is testfixture + set exec_name [info nameofexecutable] + foreach fileName $fileNames errLog $errLogs arg_list $args_lists { + if { $verbose } { + puts "Starting script $working_dir/$fileName with arguments $arg_list, and writing to error log $error_dir/$errLog" + } + + lappend pidlist [exec $exec_name $test_path/wrap.tcl \ + $working_dir/$fileName \ + $error_dir/$errLog $arg_list &] + } + + # Wait for scripts to finish + watch_procs $pidlist 1 600 0 + + # Clean up old script files + foreach fileName $fileNames { + catch {file delete -force -- $fileName} + } + + # Check for errors in the script logs + foreach errLog $errLogs { + set fd [open $error_dir/$errLog r] + # If this is the SQL test suite check for the success + # message, and if it is not found call fail_test, + # otherwise we are in the Core test suite so call error + set procs [info procs fail_test] + set proc_name [lindex $procs 0] + if { [string match fail_test $proc_name] } { + set success 0 + while { [gets $fd str] != -1 } { + if { [string match "0 errors out of * tests" $str] } { + set success 1 + break + } + } + if {!$success} { + fail_test $errLog + } + } else { + while { [gets $fd str] != -1 } { + if { [string match FAIL:* $str] || + [string match Error:* $str] } { + close $fd + error "FAIL: found message $str" + } + } + } + close $fd + } + eval cd $working_dir +} + +global ::sync_server_results +# do_sync - Synchronizes a set of processes. Works by forcing each process +# to block until it can connect to the servers of each other process, +# and receive a connection on its server from the other processes. +# Returns 0 on successful synchronization, and -1 on failure. +# For an example of how to use this, go to +# db/test/sql/bdb_multi_proc.test. +# +# myPort - Port that the other processes should connect to this process. +# clientPorts - A list of ports for all other processes to +# synchronize with. +# timeout - The number of seconds after which the function will abandon +# trying to synchronize with the other processes and will return -1. +# verbose - If set to non-0 prints verbose output. +# +# Note that this procedure is probably not thread safe. +# It is meant to be used to synchronize processes, not threads with +# shared memory. The Thread Tcl library already has functions for +# synchronizing threads. +proc do_sync { myPort clientPorts timeout {verbose 0} } { + package require Thread + #Get the number of clients + set numClients [llength $clientPorts] + unset -nocomplain ::sync_server_results + + # Accept connections to the server until timeout is reached + set server_thread [thread::create { + global ::numCon + global ::numClients + global ::server_connections + # Called by the server to keep track of how many connections have + # occured. + proc my_connections {sock addr port} { + puts $sock "success" + close $sock + incr ::numCon + # Race condition does not matter here since we can set + # server_connections to 0 twice without a problem + if { $::numCon >= $::numClients } { + set ::server_connections 0 + } + } + proc run_server { myPort clients timeout verbose} { + set ::numCon 0 + set ::numClients $clients + + # Loop until the server connects to all clients or the timeout + # is hit. This is in case one of the client sockets grabed + # the server port as its local port. + set id [after [expr {int($timeout * 1000)}] \ + set ::server_connections -1] + while { [info exists ::server_connections] == 0 } { + if [catch { socket -server my_connections -myaddr 127.0.0.1 \ + $myPort } server ] { + #if {$verbose} { + # puts "Could not create server at $myPort because of: $server. RETRYING" + #} + catch { close $server } + } else { + vwait ::server_connections + after cancel $id + close $server + } + } + if { $verbose } { + if { $::server_connections == -1 } { + puts "Failure, server at port $myPort reached timeout of $timeout seconds before recieving $::numClients connections." + } else { + puts "Success, server at port $myPort completed connections to $::numClients clients before timeout of $timeout seconds." + } + } + catch {close $server} + set ::sync_server_results $::server_connections + } + thread::wait + }] + #start the server thread + if { $verbose } { + puts "[timestamp]Starting server at port $myPort." + } + thread::send -async $server_thread \ + "run_server $myPort $numClients $timeout $verbose" \ + ::sync_server_results + + # Try to connect to each client. If timeout, set an error + # return value and quit trying to connect. + global ::clientconnected + unset -nocomplain ::clientconnected + # After the timeout is reached, set ::clientconnected. + set id [after [expr {int($timeout * 1000)}] \ + set ::clientconnected -1] + foreach clientPort $clientPorts { + set returnVal -1 + if { $verbose } { + puts "[timestamp] Attempting to contact the server at $clientPort." + } + # Loop until the client connects to the server or the timeout + # is hit. + while { $returnVal == -1 && [info exists ::clientconnected] == 0 } { + update + if [ catch { socket 127.0.0.1 $clientPort } s ] { + #if {$verbose} { + # puts "[timestamp] Could not connect to server at $clientPort because of: $s, RETRYING" + #} + catch {close $s} + } else { + if { $verbose } { + puts "[timestamp] Client connection info: [fconfigure $s -sockname]" + } + # Sometimes the client socket will pick the port it is trying + # to connect to as the port to use on its side, resulting in + # it connecting to itself + set portInfo [fconfigure $s -sockname] + set portOffset [string last " " $portInfo] + incr portOffset + set portInfo [string range $portInfo $portOffset end] + if { $portInfo == $clientPort } { + set returnVal -1 + } else { + set line "Could not read server" + if { ![eof $s] } { + set line [gets $s] + } + if { $verbose } { + puts "[timestamp] Read the following from the server: $line" + } + if { [string match success* $line] } { + set returnVal 0 + } else { + set returnVal -1 + } + } + catch {close $s} + } + } + if { $returnVal == -1 } { + if { $verbose } { + puts "[timestamp] Failed to connect to server at port $clientPort before timeout of $timeout" + } + break + } + if { $verbose } { + puts "[timestamp] Succeeded in completing connection to server at $clientPort" + } + } + after cancel $id + if { $verbose } { + if { $returnVal == -1 } { + puts "[timestamp] Failed to connect ot all servers at ports: $clientPorts" + } else { + puts "[timestamp] Succeeded in connecting to all servers at ports: $clientPorts" + } + } + + # wait on the server thread to finish if we have not already + # timed out + if { [eval info exists ::sync_server_results] == 0 } { + vwait ::sync_server_results + } + thread::release $server_thread + if { $verbose } { + if { $::sync_server_results == -1 } { + puts "[timestamp] Failed, server at port $myPort failed to connect to all clients by timeout $timeout seconds." + } else { + puts "[timestamp] Succeeded, server at port $myPort suceeded in connecting to al clients." + } + } + if { $::sync_server_results == -1 } { + set returnVal -1 + } + after 500 + set returnVal +} + diff --git a/test/xa/chk.xa b/test/xa/chk.xa index 186ba7c9..c7601f16 100644 --- a/test/xa/chk.xa +++ b/test/xa/chk.xa @@ -94,7 +94,7 @@ export LD_LIBRARY_PATH PATH echo "TEST 1" func_clean -src1/tuxconfig.sh +utilities/tuxconfig.sh 200103 src1/run.sh if test "$?" -ne 0; then exit 1 @@ -109,14 +109,14 @@ fi echo "TEST 3" # multi threaded test func_clean -src3/tuxconfig.sh 0 +utilities/multi_tuxconfig.sh 200104 src3/run.sh 0 if test "$?" -ne 0; then exit 1 fi # multi threaded test where one thread dies func_clean -src3/tuxconfig.sh 1 +utilities/tuxconfig.sh 200105 src3/run.sh 1 if test "$?" -ne 0; then exit 1 @@ -124,10 +124,21 @@ fi echo "TEST 4" # multi threaded test func_clean -src4/tuxconfig.sh 0 +utilities/multi_tuxconfig.sh 200103 src4/run.sh 0 if test "$?" -ne 0; then exit 1 fi +echo "TEST 5" +# MVCC tests. +for i in {0..2} +do + func_clean + utilities/multi_1thr_tuxconfig.sh $((200106 + $i)) + src5/run.sh $i + if test "$?" -ne 0; then + exit 1 + fi +done exit 0 diff --git a/test/xa/src1/client.c b/test/xa/src1/client.c index b5571097..b4a738f0 100644 --- a/test/xa/src1/client.c +++ b/test/xa/src1/client.c @@ -1,7 +1,13 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * Basic smoke test for XA transactions. The client randomly sends requests * to each of the servers to insert data into table 1, and inserts the - * same data into table 3 using regular transactions. + * same data into table 2 using regular transactions. */ #include @@ -23,43 +29,37 @@ #include "datafml.h" #include "hdbrec.h" #include "htimestampxa.h" +#include "../utilities/bdb_xa_util.h" -#define HOME "../data3" +#define HOME "../data2" #define TABLE1 "../data/table1.db" -#define TABLE3 "../data3/table3.db" +#define TABLE2 "../data2/table2.db" -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - -DB_ENV *dbenv; char *progname; /* Client run-time name. */ -int check_data(DB *); -char *db_buf(DBT *); int usage(void); int main(int argc, char* argv[]) { - DB *dbp3; + DB *dbp2; DBT key, data; FBFR *buf, *replyBuf; HDbRec rec; TPINIT *initBuf; + DB_ENV *dbenv2, *dbenv1; long len, replyLen, seqNo; int ch, cnt, cnt_abort, cnt_commit, cnt_server1, i, ret; char *target; char *home = HOME; u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | - DB_INIT_LOCK | DB_CREATE | DB_THREAD | DB_RECOVER | DB_REGISTER; - u_int32_t dbflags = DB_CREATE | DB_THREAD; + DB_INIT_LOCK | DB_CREATE | DB_RECOVER | DB_REGISTER; + u_int32_t dbflags = DB_CREATE; progname = argv[0]; - dbp3 = NULL; + dbenv2 = dbenv1 = NULL; + dbp2 = NULL; buf = replyBuf = NULL; initBuf = NULL; cnt = 1000; @@ -98,29 +98,29 @@ main(int argc, char* argv[]) printf("%s: tpalloc(\"TPINIT\") OK\n", progname); /* Create the DB environment. */ - if ((ret = db_env_create(&dbenv, 0)) != 0 || - (ret = dbenv->open(dbenv, home, flags, 0)) != 0) { + if ((ret = db_env_create(&dbenv2, 0)) != 0 || + (ret = dbenv2->open(dbenv2, home, flags, 0)) != 0) { fprintf(stderr, "%s: %s: %s\n", progname, home, db_strerror(ret)); goto err; } - dbenv->set_errfile(dbenv, stderr); + dbenv2->set_errfile(dbenv2, stderr); if (verbose) printf("%s: opened %s OK\n", progname, home); /* - * Open table #3 -- Data is inserted into table 1 using XA - * transactions, and inserted into table 3 using regular transactions. + * Open table #2 -- Data is inserted into table 1 using XA + * transactions, and inserted into table 2 using regular transactions. */ - if ((ret = db_create(&dbp3, dbenv, 0)) != 0 || - (ret = dbp3->open(dbp3, - NULL, TABLE3, NULL, DB_BTREE, dbflags, 0660)) != 0) { + if ((ret = db_create(&dbp2, dbenv2, 0)) != 0 || + (ret = dbp2->open(dbp2, + NULL, TABLE2, NULL, DB_BTREE, dbflags, 0660)) != 0) { fprintf(stderr, - "%s: %s %s\n", progname, TABLE3, db_strerror(ret)); + "%s: %s %s\n", progname, TABLE2, db_strerror(ret)); goto err; } if (verbose) - printf("%s: opened %s OK\n", progname, TABLE3); + printf("%s: opened %s OK\n", progname, TABLE2); /* Allocate send buffer. */ len = Fneeded(1, 3 * sizeof(long)); @@ -180,19 +180,19 @@ main(int argc, char* argv[]) printf("%s: tpcommit() OK\n", progname); /* - * Store a copy of the key/data pair into table #3 - * on success, we'll compare table #1 and table #3 + * Store a copy of the key/data pair into table #2 + * on success, we'll compare table #1 and table #2 * after the run finishes. */ seqNo = rec.SeqNo; key.data = &seqNo; key.size = sizeof(seqNo); - data.data = &rec; - data.size = sizeof(rec); + data.data = &seqNo; + data.size = sizeof(seqNo); if ((ret = - dbp3->put(dbp3, NULL, &key, &data, 0)) != 0) { + dbp2->put(dbp2, NULL, &key, &data, 0)) != 0) { fprintf(stderr, "%s: DB->put: %s %s\n", - progname, TABLE3, db_strerror(ret)); + progname, TABLE2, db_strerror(ret)); goto err; } } else { @@ -212,7 +212,14 @@ main(int argc, char* argv[]) printf("%s: %d sent to server #1, %d sent to server #2\n", progname, cnt_server1, cnt - cnt_server1); - ret = check_data(dbp3); + /* Check that database 1 and database 2 are identical. */ + if (dbp2 != NULL) + (void)dbp2->close(dbp2, 0); + dbp2 = NULL; + if ((ret = db_env_create(&dbenv1, 0)) != 0 || + (ret = dbenv1->open(dbenv1, "../data", flags, 0)) != 0) + goto err; + ret = check_data(dbenv1, TABLE1, dbenv2, TABLE2, progname); if (0) { tuxedo_err: fprintf(stderr, "%s: TUXEDO ERROR: %s (code %d)\n", @@ -233,10 +240,12 @@ err: ret = EXIT_FAILURE; tpfree((char *)buf); if (initBuf != NULL) tpfree((char *)initBuf); - if (dbp3 != NULL) - (void)dbp3->close(dbp3, 0); - if (dbenv != NULL) - (void)dbenv->close(dbenv, 0); + if (dbp2 != NULL) + (void)dbp2->close(dbp2, 0); + if (dbenv1 != NULL) + (void)dbenv1->close(dbenv1, 0); + if (dbenv2 != NULL) + (void)dbenv2->close(dbenv2, 0); tpterm(); if (verbose) @@ -245,112 +254,6 @@ err: ret = EXIT_FAILURE; return (ret); } -/* - * check_data -- - * Compare committed data with our local copy, stored in table3. - */ -int -check_data(dbp3) - DB *dbp3; -{ - DB *dbp1; - DBC *dbc1, *dbc3; - DBT key1, data1, key3, data3; - int ret, ret1, ret3; - DB_ENV *dbenv1; - u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | - DB_INIT_LOCK | DB_THREAD; - - dbp1 = NULL; - dbc1 = dbc3 = NULL; - dbenv1 = NULL; - - if ((ret = db_env_create(&dbenv1, 0)) != 0 || - (ret = dbenv1->open(dbenv1, "../data", flags, 0)) != 0) - goto err; - /* Open table #1. */ - if ((ret = db_create(&dbp1, dbenv1, 0)) != 0 || - (ret = dbp1->open( - dbp1, NULL, TABLE1, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - fprintf(stderr, - "%s: %s: %s\n", progname, TABLE1, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened %s OK\n", progname, TABLE1); - - /* Open cursors. */ - if ((ret = dbp1->cursor(dbp1, NULL, &dbc1, 0)) != 0 || - (ret = dbp3->cursor(dbp3, NULL, &dbc3, 0)) != 0) { - fprintf(stderr, - "%s: DB->cursor: %s\n", progname, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened cursors OK\n", progname); - - /* Compare the two databases. */ - memset(&key1, 0, sizeof(key1)); - memset(&data1, 0, sizeof(data1)); - memset(&key3, 0, sizeof(key3)); - memset(&data3, 0, sizeof(data3)); - for (;;) { - ret1 = dbc1->c_get(dbc1, &key1, &data1, DB_NEXT); - ret3 = dbc3->c_get(dbc3, &key3, &data3, DB_NEXT); - if (verbose) { - printf("get: key1: %s\n", db_buf(&key1)); - printf("get: key3: %s\n", db_buf(&key3)); - printf("get: data1: %s\n", db_buf(&data1)); - printf("get: data3: %s\n", db_buf(&data3)); - } - if (ret1 != 0 || ret3 != 0) - break; - /* - * Only compare the first N bytes, the saved message chunks - * are different. - */ - if (key1.size != key3.size || - memcmp(key1.data, key3.data, key1.size) != 0 || - data1.size != data3.size || - memcmp(data1.data, data3.data, - sizeof(long) + sizeof(HTimestampData)) != 0) - goto mismatch; - } - if (ret1 != DB_NOTFOUND || ret3 != DB_NOTFOUND) { -mismatch: fprintf(stderr, - "%s: DB_ERROR: databases 1 and 3 weren't identical\n", - progname); - ret = 1; - } - -err: if (dbc1 != NULL) - (void)dbc1->c_close(dbc1); - if (dbc3 != NULL) - (void)dbc3->c_close(dbc3); - if (dbp1 != NULL) - (void)dbp1->close(dbp1, 0); - if(dbenv1 != NULL) - (void)dbenv1->close(dbenv1, 0); - - return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -char * -db_buf(dbt) - DBT *dbt; -{ - static u_char buf[1024]; - size_t len; - u_char *p, *b; - - for (p = dbt->data, len = dbt->size, b = buf; len > 0; ++p, --len) - if (isprint(*p)) - b += sprintf((char *)b, "%c", *p); - else - b += sprintf((char *)b, "%#o", *p); - return ((char *)buf); -} - int usage() { diff --git a/test/xa/src1/datafml.h b/test/xa/src1/datafml.h index 143b484e..24362a59 100644 --- a/test/xa/src1/datafml.h +++ b/test/xa/src1/datafml.h @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* fname fldid */ /* ----- ----- */ #define SEQ_NO ((FLDID32)33554833) /* number: 401 type: long */ diff --git a/test/xa/src1/hdbrec.h b/test/xa/src1/hdbrec.h index 16932f60..527c2640 100644 --- a/test/xa/src1/hdbrec.h +++ b/test/xa/src1/hdbrec.h @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + #ifndef HDBREC_H #define HDBREC_H diff --git a/test/xa/src1/htimestampxa.c b/test/xa/src1/htimestampxa.c index 0e73e6aa..86f5c3c0 100644 --- a/test/xa/src1/htimestampxa.c +++ b/test/xa/src1/htimestampxa.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + #include #include diff --git a/test/xa/src1/htimestampxa.h b/test/xa/src1/htimestampxa.h index 975b315e..c80fd98b 100644 --- a/test/xa/src1/htimestampxa.h +++ b/test/xa/src1/htimestampxa.h @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + #ifndef HTIMESTAMPXA_H #define HTIMESTAMPXA_H diff --git a/test/xa/src1/run.sh b/test/xa/src1/run.sh index eb5ff3ec..38aa4506 100644 --- a/test/xa/src1/run.sh +++ b/test/xa/src1/run.sh @@ -19,7 +19,7 @@ tmadmin << END_OF_TMADMIN END_OF_TMADMIN } -mkdir $RUN/data3 +mkdir $RUN/data2 # Everything else is done in run/bin. cd $RUN/bin @@ -34,11 +34,12 @@ test "$DVERBOSE" == 1 && { DVERBOSE_FLAG="-v" } COMPILE_FLAGS="$CFLAGS $COMPILE_FLAGS -g -I../../.." +UTILITY_FILES="-f ../../src1/htimestampxa.c -f ../../utilities/bdb_xa_util.c" msg "BUILDING CLIENT" CFLAGS="$COMPILE_FLAGS"; export CFLAGS buildclient -r BERKELEY-DB $DVERBOSE_FLAG -o client \ - -f ../../src1/htimestampxa.c -f ../../src1/client.c + $UTILITY_FILES -f ../../src1/client.c test "$?" -eq 0 || { echo "FAIL: buildclient failed." exit 1 @@ -48,7 +49,7 @@ msg "BUILDING SERVER #1" CFLAGS="$COMPILE_FLAGS -DSERVER1"; export CFLAGS buildserver -r BERKELEY-DB $DVERBOSE_FLAG -o server1 \ -s TestTxn1:TestTxn1 \ - -f ../../src1/htimestampxa.c -f ../../src1/server.c + $UTILITY_FILES -f ../../src1/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 @@ -58,7 +59,7 @@ msg "BUILDING SERVER #2" CFLAGS="$COMPILE_FLAGS -DSERVER2"; export CFLAGS buildserver $DVERBOSE_FLAG -r BERKELEY-DB -o server2 \ -s TestTxn2:TestTxn2 \ - -f ../../src1/htimestampxa.c -f ../../src1/server.c + $UTILITY_FILES -f ../../src1/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 diff --git a/test/xa/src1/server.c b/test/xa/src1/server.c index 0ed21cfe..d517b67c 100644 --- a/test/xa/src1/server.c +++ b/test/xa/src1/server.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * This is the code for the two servers used in the first XA test. Server 1 * and Server 2 are both called by the client to insert data into table 1 @@ -23,6 +29,7 @@ #include "datafml.h" #include "hdbrec.h" #include "htimestampxa.h" +#include "../utilities/bdb_xa_util.h" /* * The two servers are largely identical, #ifdef the source code. @@ -38,88 +45,30 @@ void TXN_FUNC(TPSVCINFO *); #define HOME "../data" -#define TABLE1 "table1.db" -#define TABLE2 "table2.db" -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - -DB *db1, *db2; /* Table handles. */ +#define NUMDB 2 int cnt_forward; /* Forwarded requests. */ int cnt_request; /* Total requests. */ -char *progname; /* Server run-time name. */ - -char *db_buf(DBT *); +char *progname; /* Server run-time name. */ /* * Called when each server is started. It creates and opens the - * two databases. + * two database handles. */ int tpsvrinit(int argc, char* argv[]) { - int ret; - progname = argv[0]; - if (verbose) - printf("%s: called\n", progname); - - /* Open resource managers. */ - if (tx_open() == TX_ERROR) { - fprintf(stderr, "tx_open: TX_ERROR\n"); - return (-1); - } - - /* Seed random number generator. */ - srand((u_int)(time(NULL) | getpid())); - - /* Open permanent XA handles. */ - if ((ret = db_create(&db1, NULL, DB_XA_CREATE)) != 0) { - fprintf(stderr, "db_create: %s\n", db_strerror(ret)); - return (-1); - } - db1->set_errfile(db1, stderr); - if ((ret = db1->open(db1, NULL, - TABLE1, NULL, DB_BTREE, DB_AUTO_COMMIT | DB_CREATE, 0660)) != 0) { - fprintf(stderr, "DB open: %s: %s\n", TABLE1, db_strerror(ret)); - return (-1); - } - if ((ret = db_create(&db2, NULL, DB_XA_CREATE)) != 0) { - fprintf(stderr, "db_create: %s\n", db_strerror(ret)); - return (-1); - } - db2->set_errfile(db2, stderr); - if ((ret = db2->open(db2, NULL, - TABLE2, NULL, DB_BTREE, DB_AUTO_COMMIT | DB_CREATE, 0660)) != 0) { - fprintf(stderr, "DB open: %s: %s\n", TABLE2, db_strerror(ret)); - return (-1); - } - - if (verbose) - printf("%s: tpsvrinit: initialization done\n", progname); - - return (0); + return (init_xa_server(NUMDB, progname, 0)); } /* Called when the servers are shutdown. This closes the databases. */ void tpsvrdone() { - if (db1 != NULL) - (void)db1->close(db1, 0); - if (db2 != NULL) - (void)db2->close(db2, 0); - - tx_close(); - - if (verbose) - printf("%s: tpsvrdone: shutdown done\n", progname); - + close_xa_server(NUMDB, progname); printf("%s: %d requests, %d requests forwarded to the other server\n", progname, cnt_request, cnt_forward); } @@ -137,7 +86,7 @@ TXN_FUNC(TPSVCINFO *msg) FBFR *replyBuf; HDbRec rcrd; long replyLen, seqNo; - int ret; + int ret, i; ++cnt_request; @@ -182,29 +131,27 @@ fml_err: fprintf(stderr, "%s: FML ERROR: %s (code %d)\n", key.data = &seqNo; key.size = sizeof(seqNo); memset(&data, 0, sizeof(data)); - data.data = &rcrd; - data.size = sizeof(rcrd); + data.data = &seqNo; + data.size = sizeof(seqNo); - strcpy(rcrd.Msg, "Table1"); /* Table 1. */ if (verbose) { - printf("put1: key: %s\n", db_buf(&key)); - printf("put1: data: %s\n", db_buf(&data)); - } - if ((ret = db1->put(db1, NULL, &key, &data, 0)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - goto abort; - fprintf(stderr, "%s: %s: Table1->put: %s\n", - progname, TXN_STRING, db_strerror(ret)); - goto err; + __db_prdbt(&key, 0, "put: key: %s\n", stdout, + pr_callback, 0, 0); + __db_prdbt(&data, 0, "put: data: %s\n", stdout, + pr_callback, 0, 0); } - strcpy(rcrd.Msg, "Table2"); /* Table 2. */ - if ((ret = db2->put(db2, NULL, &key, &data, 0)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - goto abort; - fprintf(stderr, "%s: %s: Table2->put: %s\n", - progname, TXN_STRING, db_strerror(ret)); - goto err; + for (i = 0; i < NUMDB; i++) { + strcpy(rcrd.Msg, db_names[i]); + if ((ret = dbs[i]->put(dbs[i], NULL, &key, + &data, 0)) != 0) { + if (ret == DB_LOCK_DEADLOCK) + goto abort; + fprintf(stderr, "%s: %s: %s->put: %s\n", + progname, TXN_STRING, db_names[i], + db_strerror(ret)); + goto err; + } } /* @@ -227,18 +174,3 @@ abort: if (verbose) err: tpreturn(TPFAIL, 1L, 0, 0L, 0); } -char * -db_buf(dbt) - DBT *dbt; -{ - static u_char buf[1024]; - size_t len; - u_char *p, *b; - - for (p = dbt->data, len = dbt->size, b = buf; len > 0; ++p, --len) - if (isprint(*p)) - b += sprintf((char *)b, "%c", *p); - else - b += sprintf((char *)b, "%#o", *p); - return ((char *)buf); -} diff --git a/test/xa/src2/bdb1.c b/test/xa/src2/bdb1.c index be8032f3..3aef6505 100644 --- a/test/xa/src2/bdb1.c +++ b/test/xa/src2/bdb1.c @@ -1,15 +1,13 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* -* Copyright (c) 1997 BEA Systems, Inc. -* All Rights Reserved -* -* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF -* BEA Systems, Inc. -* The copyright notice above does not evidence any -* actual or intended publication of such source code. -* -* This server is called by the client. It inserts a value into db1 then -* calls bdb2 to insert a value into db2. -*/ + * This server is called by the client. It inserts a value into db1 then + * calls bdb2 to insert a value into db2. + */ #include #include @@ -22,17 +20,14 @@ #include #include #include +#include "../utilities/bdb_xa_util.h" -#define DATABASE1 "data1.db" +#define NUMDB 1 -static u_int32_t open_flags = DB_CREATE | DB_AUTO_COMMIT; -static DB *gdbp; static int times = 1; static long seq = 1; -static DB* getdbp(){ - return gdbp; -} +static char *progname; /* Open the database when the server is started. */ int @@ -40,8 +35,10 @@ tpsvrinit(argc, argv) int argc; char **argv; { - int ret; char ch; + + progname = argv[0]; + /* Some compilers warn if argc and argv aren't used. */ while ((ch = getopt(argc, argv, "t:")) != EOF) switch (ch) { @@ -51,30 +48,14 @@ char **argv; } - tpopen(); - - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&gdbp, NULL, DB_XA_CREATE)) != 0) { - userlog("db_create: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - - if ((ret = gdbp->open(gdbp, NULL, DATABASE1, NULL, DB_BTREE, open_flags, - 0664)) != 0) { - userlog("open: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - - return(0); + return (init_xa_server(NUMDB, progname, 0)); } /* Close the database when the server is shutdown. */ void tpsvrdone(void) { - DB* dbp = getdbp(); - dbp->close(dbp, 0); - tpclose(); + close_xa_server(NUMDB, progname); } /* Insert a value into db1, then call bdb2 to insert that value into db2. */ @@ -84,11 +65,11 @@ TPSVCINFO *rqst; { long rcvlen; int ret, i; - DB *dbp = getdbp(); DBT key, data; size_t len; int ch; char *p, *t, buf[1024]; + DB *dbp = dbs[0]; tpbegin(10,0); @@ -178,7 +159,7 @@ TPSVCINFO *rqst; int ret,count; DBT key, value; DBC *cursorp; - DB *dbp = getdbp(); + DB *dbp = dbs[0]; tpbegin(60*10,0); diff --git a/test/xa/src2/bdb2.c b/test/xa/src2/bdb2.c index b0b6a49f..a185ca65 100644 --- a/test/xa/src2/bdb2.c +++ b/test/xa/src2/bdb2.c @@ -1,15 +1,13 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* -* Copyright (c) 1997 BEA Systems, Inc. -* All Rights Reserved -* -* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF -* BEA Systems, Inc. -* The copyright notice above does not evidence any -* actual or intended publication of such source code. -* -* This server is only called by bdb1. It takes the data sent by bdb1 and -* inserts it into db2. -*/ + * This server is only called by bdb1. It takes the data sent by bdb1 and + * inserts it into db2. + */ #include #include @@ -21,45 +19,10 @@ #include #include #include +#include "../utilities/bdb_xa_util.h" -#define DATABASE1 "data1.db" -#define DATABASE2 "data2.db" - -static DB *dbp1; -static DB *dbp2; - -static int opendb(){ - int ret; - u_int32_t open_flags = DB_CREATE | DB_AUTO_COMMIT; - - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&dbp1, NULL, DB_XA_CREATE)) != 0) { - userlog("db_create: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - - if ((ret = db_create(&dbp2, NULL, DB_XA_CREATE)) != 0) { - userlog("db_create: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - - if ((ret = dbp1->open(dbp1, NULL, DATABASE1, NULL, DB_BTREE, open_flags, - 0664)) != 0) { - userlog("open: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - if ((ret = dbp2->open(dbp2, NULL, DATABASE2, NULL, DB_BTREE, open_flags, - 0664)) != 0) { - userlog("open: %s", db_strerror(ret)); - return (EXIT_FAILURE); - } - return 0; -} - -static void closedb(){ - (void)dbp1->close(dbp1, 0); - (void)dbp2->close(dbp2, 0); -} +#define NUMDB 2 +static char *progname; /* Write the given data into the given database. */ static int writedb(DB * dbp, void *buf, u_int32_t size){ @@ -83,7 +46,7 @@ static int writedb(DB * dbp, void *buf, u_int32_t size){ return (EXIT_SUCCESS); default: userlog("put: %s", db_strerror(ret)); - return -1; + return (-1); } } @@ -93,25 +56,16 @@ tpsvrinit(argc, argv) int argc; char **argv; { - int ret; - /* Some compilers warn if argc and argv aren't used. */ - argc = argc; - argv = argv; + progname = argv[0]; - tpopen(); - if (ret = opendb() != 0){ - userlog("put: %s", db_strerror(ret)); - } - - return(0); + return (init_xa_server(NUMDB, progname, 0)); } /* Close the database when the server is shutdown. */ void tpsvrdone(void) { - closedb(); - tpclose(); + close_xa_server(NUMDB,progname); } /* @@ -139,7 +93,7 @@ TPSVCINFO *rqst; data.flags = DB_DBT_MALLOC; /* Get the data that the calling server inserted into db1 */ - switch (ret = dbp1->get(dbp1, NULL, &key, &data, DB_READ_UNCOMMITTED)){ + switch (ret = dbs[0]->get(dbs[0], NULL, &key, &data, DB_READ_UNCOMMITTED)){ case 0: break; case DB_LOCK_DEADLOCK: @@ -150,7 +104,7 @@ TPSVCINFO *rqst; } /* Write the data to db2 */ - if(writedb(dbp2, data.data, data.size) != 0){ + if(writedb(dbs[1], data.data, data.size) != 0){ tpreturn(TPSUCCESS, 1L, rqst->data, 0L, 0); } tpreturn(TPSUCCESS, 0, rqst->data, 0L, 0); diff --git a/test/xa/src2/client.c b/test/xa/src2/client.c index 517671ac..698e9bbe 100644 --- a/test/xa/src2/client.c +++ b/test/xa/src2/client.c @@ -1,31 +1,24 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* -* Copyright (c) 1997 BEA Systems, Inc. -* All Rights Reserved -* -* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF -* BEA Systems, Inc. -* The copyright notice above does not evidence any -* actual or intended publication of such source code. -* -* This client is part of Test 2 of the XA test suite. It calls bdb1, which -* in turn calls bdb2. In the test several clients are executed at once to test -* how XA performs with multiple processes. -*/ + * This client is part of Test 2 of the XA test suite. It calls bdb1, which + * in turn calls bdb2. In the test several clients are executed at once to test + * how XA performs with multiple processes. + */ #include #include #include "atmi.h" /* TUXEDO Header File */ +#include "../utilities/bdb_xa_util.h" void my_exit(); char *sendbuf, *rcvbuf; -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - void my_exit(string) char *string; diff --git a/test/xa/src2/run.sh b/test/xa/src2/run.sh index 361a28dd..7340134e 100644 --- a/test/xa/src2/run.sh +++ b/test/xa/src2/run.sh @@ -42,19 +42,24 @@ test "$DVERBOSE" == 1 && { DVERBOSE_FLAG="-v" } CFLAGS="$COMPILE_FLAGS -I$DB_INSTALL/include -L$DB_INSTALL/lib"; export CFLAGS -buildserver $DVERBOSE_FLAG -f ../../src2/bdb1.c -o bdb1 -r "BERKELEY-DB" -s WRITE -s CURSOR +UTILITY_FILES="-f ../../utilities/bdb_xa_util.c" + +buildserver $DVERBOSE_FLAG $UTILITY_FILES \ +-f ../../src2/bdb1.c -o bdb1 -r "BERKELEY-DB" -s WRITE -s CURSOR test "$?" -eq 0 || { echo "FAIL: buildserver 1 failed." exit 1 } -buildserver $DVERBOSE_FLAG -f ../../src2/bdb2.c -o bdb2 -r "BERKELEY-DB" -s WRITE2 +buildserver $DVERBOSE_FLAG $UTILITY_FILES \ +-f ../../src2/bdb2.c -o bdb2 -r "BERKELEY-DB" -s WRITE2 test "$?" -eq 0 || { echo "FAIL: buildserver 2 failed." exit 1 } -buildclient $DVERBOSE_FLAG -f ../../src2/client.c -o client +buildclient $DVERBOSE_FLAG $UTILITY_FILES \ +-r "BERKELEY-DB" -f ../../src2/client.c -o client test "$?" -eq 0 || { echo "FAIL: buildclient failed." exit 1 diff --git a/test/xa/src3/client.c b/test/xa/src3/client.c index e01fd34e..48ba10e4 100644 --- a/test/xa/src3/client.c +++ b/test/xa/src3/client.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * This is the multithreaded test for XA. The client creates several threads * and uses each thread to send requests to the servers, which are also @@ -25,22 +31,17 @@ #include +#include "../utilities/bdb_xa_util.h" + #define HOME "../data" #define TABLE1 "../data/table1.db" #define TABLE2 "../data/table2.db" #define NUM_SERVERS 3 -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif static int expected_error = 0; char *progname; /* Client run-time name. */ -int check_data(void); - int usage() { @@ -207,12 +208,16 @@ main(int argc, char* argv[]) pthread_t threads[NUM_SERVERS]; void *results = NULL; char *names[NUM_SERVERS]; + DB_ENV *dbenv; + u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | + DB_INIT_LOCK | DB_CREATE | DB_THREAD | DB_RECOVER | DB_REGISTER; names[0] = "1"; names[1] = "2"; names[2] = "3"; progname = argv[0]; num_threads = 2; + dbenv = NULL; while ((ch = getopt(argc, argv, "n:vk")) != EOF) switch (ch) { @@ -259,103 +264,23 @@ main(int argc, char* argv[]) } /* If the kill thread was not used, check the data in the two tables.*/ - if (num_threads < NUM_SERVERS) - ret = check_data(); + if (num_threads < NUM_SERVERS) { + /* Join the DB environment. */ + if ((ret = db_env_create(&dbenv, 0)) != 0 || + (ret = dbenv->open(dbenv, HOME, flags, 0)) != 0) { + fprintf(stderr, + "%s: %s: %s\n", progname, HOME, db_strerror(ret)); + goto err; + } + ret = check_data(dbenv, TABLE1, dbenv, TABLE2, progname); + } if (0) { err: ret = EXIT_FAILURE; } + if (dbenv != NULL) + dbenv->close(dbenv, 0); return (ret); } -/* - * check_data -- - * Compare committed data in the two tables, should be identical. - */ -int -check_data() -{ - DB *dbp1, *dbp2; - DBC *dbc1, *dbc2; - DB_ENV *dbenv; - DBT key1, data1, key2, data2; - int ret, ret1, ret2; - u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | - DB_INIT_LOCK | DB_CREATE | DB_THREAD | DB_RECOVER | DB_REGISTER; - char *home = HOME; - - dbp1 = dbp2 = NULL; - dbc1 = dbc2 = NULL; - dbenv = NULL; - - /* Join the DB environment. */ - if ((ret = db_env_create(&dbenv, 0)) != 0 || - (ret = dbenv->open(dbenv, home, flags, 0)) != 0) { - fprintf(stderr, - "%s: %s: %s\n", progname, home, db_strerror(ret)); - goto err; - } - - /* Open the tables. */ - if ((ret = db_create(&dbp1, dbenv, 0)) != 0 || - (ret = db_create(&dbp2, dbenv, 0)) != 0 || - ((ret = dbp1->open( - dbp1, NULL, TABLE1, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) || - ((ret = dbp2->open( - dbp2, NULL, TABLE2, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0)) { - fprintf(stderr, - "%s: %s: %s\n", progname, TABLE1, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened tables OK\n", progname); - - /* Open cursors. */ - if ((ret = dbp1->cursor(dbp1, NULL, &dbc1, 0)) != 0 || - (ret = dbp2->cursor(dbp2, NULL, &dbc2, 0)) != 0) { - fprintf(stderr, - "%s: DB->cursor: %s\n", progname, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened cursors OK\n", progname); - - /* Compare the two databases, they should be identical. */ - memset(&key1, 0, sizeof(key1)); - memset(&data1, 0, sizeof(data1)); - memset(&key2, 0, sizeof(key2)); - memset(&data2, 0, sizeof(data2)); - for (;;) { - - ret1 = dbc1->c_get(dbc1, &key1, &data1, DB_NEXT); - ret2 = dbc2->c_get(dbc2, &key2, &data2, DB_NEXT); - if (ret1 != 0 || ret2 != 0) - break; - if (key1.size != key2.size || - memcmp(key1.data, key2.data, key1.size) != 0 || - data1.size != data2.size || - memcmp(data1.data, data2.data, data1.size) != 0) - goto mismatch; - } - if (ret1 != DB_NOTFOUND || ret2 != DB_NOTFOUND) { -mismatch: fprintf(stderr, - "%s: DB_ERROR: databases 1 and 2 weren't identical\n", - progname); - ret = 1; - } - -err: if (dbc1 != NULL) - (void)dbc1->c_close(dbc1); - if (dbc2 != NULL) - (void)dbc2->c_close(dbc2); - if (dbp1 != NULL) - (void)dbp1->close(dbp1, 0); - if (dbp2 != NULL) - (void)dbp2->close(dbp2, 0); - if (dbenv != NULL) - (void)dbenv->close(dbenv, 0); - - return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - diff --git a/test/xa/src3/run.sh b/test/xa/src3/run.sh index f48aaf0a..9088a953 100644 --- a/test/xa/src3/run.sh +++ b/test/xa/src3/run.sh @@ -33,11 +33,12 @@ test "$DVERBOSE" == 1 && { DVERBOSE_FLAG="-v" } COMPILE_FLAGS="$CFLAGS $COMPILE_FLAGS -g -I../../.." +UTILITY_FILES="-f ../../utilities/bdb_xa_util.c" msg "BUILDING CLIENT" CFLAGS="$COMPILE_FLAGS"; export CFLAGS buildclient -r BERKELEY-DB $DVERBOSE_FLAG -o client \ - -f ../../src3/client.c +$UTILITY_FILES -f ../../src3/client.c test "$?" -eq 0 || { echo "FAIL: buildclient failed." exit 1 @@ -46,7 +47,7 @@ test "$?" -eq 0 || { msg "BUILDING SERVER #1" CFLAGS="$COMPILE_FLAGS -DSERVER1"; export CFLAGS buildserver -r BERKELEY-DB $DVERBOSE_FLAG -t -o server1 \ - -s TestThread1:TestThread1 -f ../../src3/server.c + -s TestThread1:TestThread1 $UTILITY_FILES -f ../../src3/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 @@ -55,7 +56,7 @@ test "$?" -eq 0 || { msg "BUILDING SERVER #2" CFLAGS="$COMPILE_FLAGS -DSERVER2"; export CFLAGS buildserver -r BERKELEY-DB $DVERBOSE_FLAG -t -o server2 \ - -s TestThread2:TestThread2 -f ../../src3/server.c + -s TestThread2:TestThread2 $UTILITY_FILES -f ../../src3/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 @@ -119,4 +120,4 @@ test -s stderr && { exitval=1 } -exit $exitval \ No newline at end of file +exit $exitval diff --git a/test/xa/src3/server.c b/test/xa/src3/server.c index 22cdca23..a534c015 100644 --- a/test/xa/src3/server.c +++ b/test/xa/src3/server.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * Multi-threaded servers that insert data into databases 1 and 2 at the * request of the client, and can die at the request of the client. @@ -13,6 +19,8 @@ #include +#include "../utilities/bdb_xa_util.h" + /* * The two servers are largely identical, #ifdef the source code. */ @@ -27,85 +35,25 @@ void TXN_FUNC(TPSVCINFO *); #define HOME "../data" -#define TABLE1 "table1.db" -#define TABLE2 "table2.db" - -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - -DB *db1, *db2; /* Table handles. */ +#define NUMDB 2 int cnt_request; /* Total requests. */ char *progname; /* Server run-time name. */ -/* Called once when the server is started. Creates and opens the databases. */ +/* Called once when the server is started. Creates and opens 2 databases. */ int tpsvrinit(int argc, char* argv[]) { - int ret; - int dbflags = DB_AUTO_COMMIT | DB_CREATE | DB_THREAD; - progname = argv[0]; - if (verbose) - printf("%s: called\n", progname); - - /* Open resource managers. */ - if (tx_open() == TX_ERROR) { - fprintf(stderr, "tx_open: TX_ERROR\n"); - return (-1); - } - - /* Seed random number generator. */ - srand((u_int)(time(NULL) | getpid())); - - /* Open XA database handles. */ - if ((ret = db_create(&db1, NULL, DB_XA_CREATE)) != 0) { - fprintf(stderr, "db_create: %s\n", db_strerror(ret)); - return (-1); - } - db1->set_errfile(db1, stderr); - if ((ret = db1->open(db1, NULL, - TABLE1, NULL, DB_BTREE, dbflags, 0660)) != 0) { - fprintf(stderr, "DB open: %s: %s\n", TABLE1, db_strerror(ret)); - return (-1); - } - if ((ret = db_create(&db2, NULL, DB_XA_CREATE)) != 0) { - fprintf(stderr, "db_create: %s\n", db_strerror(ret)); - return (-1); - } - db2->set_errfile(db2, stderr); - if ((ret = db2->open(db2, NULL, - TABLE2, NULL, DB_BTREE, dbflags, 0660)) != 0) { - fprintf(stderr, "DB open: %s: %s\n", TABLE2, db_strerror(ret)); - return (-1); - } - - if (verbose) - printf("%s: tpsvrinit: initialization done\n", progname); - - return (0); + return (init_xa_server(NUMDB, progname, 0)); } /* Called once when the servers are shutdown. Closes the databases. */ void tpsvrdone() - { - if (verbose) - printf("%s: tpsvrdone: shutdown done\n", progname); - if (db1 != NULL) - (void)db1->close(db1, 0); - if (db2 != NULL) - (void)db2->close(db2, 0); - db1 = db2 = NULL; - - tx_close(); - - if (verbose) - printf("%s: tpsvrdone: shutdown done\n", progname); +{ + close_xa_server(NUMDB, progname); } /* * Called by the client to insert data into the databases. Also can kill this @@ -139,23 +87,20 @@ TXN_FUNC(TPSVCINFO *msg) /* Insert data into the tables. */ if (verbose) { - printf("put1: key: n"); - printf("put1: data:\n"); + printf("put: key: n"); + printf("pu1: data:\n"); } - if ((ret = db1->put(db1, NULL, &key, &data, 0)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - goto abort; - fprintf(stderr, "%s: %s: Table1->put: %s\n", - progname, TXN_STRING, db_strerror(ret)); - goto err; - } - - if ((ret = db2->put(db2, NULL, &key, &data, 0)) != 0) { - if (ret == DB_LOCK_DEADLOCK) - goto abort; - fprintf(stderr, "%s: %s: Table2->put: %s\n", - progname, TXN_STRING, db_strerror(ret)); - goto err; + /* Insert data into the tables. */ + for (i = 0; i < NUMDB; i++) { + if ((ret = dbs[i]->put(dbs[i], NULL, &key, + &data, 0)) != 0) { + if (ret == DB_LOCK_DEADLOCK) + goto abort; + fprintf(stderr, "%s: %s: %s->put: %s\n", + progname, TXN_STRING, db_names[i], + db_strerror(ret)); + goto err; + } } /* Returns a commit or abort command to the client. */ diff --git a/test/xa/src4/client.c b/test/xa/src4/client.c index 7c3bb720..716f293b 100644 --- a/test/xa/src4/client.c +++ b/test/xa/src4/client.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * #19612 Data not rolled back when transaction aborted after timout. */ @@ -18,20 +24,15 @@ #include +#include "../utilities/bdb_xa_util.h" + #define HOME "../data" #define TABLE1 "../data/table1.db" #define TABLE2 "../data/table2.db" -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - DB_ENV *dbenv; char *progname; /* Client run-time name. */ -int check_data(); int usage(void); int @@ -128,7 +129,7 @@ main(int argc, char* argv[]) } - ret = check_data(); + ret = check_data(dbenv, TABLE1, dbenv, TABLE2, progname); } if (0) { @@ -156,86 +157,6 @@ err: ret = EXIT_FAILURE; return (ret); } -/* - * check_data -- - * Check that both databases are empty. - */ -int -check_data() -{ - DB *dbp1, *dbp2; - DBC *dbc1, *dbc2; - DBT key1, data1, key2, data2; - int ret, ret1, ret2; - u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | - DB_INIT_LOCK | DB_THREAD; - - dbp1 = dbp2 = NULL; - dbc1 = dbc2 = NULL; - - /* Open table #1. */ - if ((ret = db_create(&dbp1, dbenv, 0)) != 0 || - (ret = dbp1->open( - dbp1, NULL, TABLE1, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - fprintf(stderr, - "%s: %s: %s\n", progname, TABLE1, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened %s OK\n", progname, TABLE1); - - /* Open table #2. */ - if ((ret = db_create(&dbp2, dbenv, 0)) != 0 || - (ret = dbp2->open( - dbp2, NULL, TABLE2, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { - fprintf(stderr, - "%s: %s: %s\n", progname, TABLE2, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened %s OK\n", progname, TABLE2); - - /* Open cursors. */ - if ((ret = dbp1->cursor(dbp1, NULL, &dbc1, 0)) != 0 || - (ret = dbp2->cursor(dbp2, NULL, &dbc2, 0)) != 0) { - fprintf(stderr, - "%s: DB->cursor: %s\n", progname, db_strerror(ret)); - goto err; - } - if (verbose) - printf("%s: opened cursors OK\n", progname); - - /* Compare the two databases. */ - memset(&key1, 0, sizeof(key1)); - memset(&data1, 0, sizeof(data1)); - memset(&key2, 0, sizeof(key2)); - memset(&data2, 0, sizeof(data2)); - ret1 = dbc1->get(dbc1, &key1, &data1, DB_NEXT); - ret2 = dbc2->get(dbc2, &key2, &data2, DB_NEXT); - if (ret1 != DB_NOTFOUND || ret2 !=DB_NOTFOUND) { - fprintf(stderr, - "%s: DB_ERROR: databases 1 and 2 weren't identical\n", - progname); - ret = 1; - } - -err: if (dbc1 != NULL) - (void)dbc1->close(dbc1); - if (dbc2 != NULL) - (void)dbc2->close(dbc2); - if (dbp1 != NULL) - (void)dbp1->close(dbp1, 0); - if (dbp2 != NULL) - (void)dbp2->close(dbp2, 0); - - if (verbose && ret == 0) - printf("%s: data check passed.\n", progname); - else if (verbose) - printf("%s: data check failed.\n", progname); - - return (ret); -} - int usage() { diff --git a/test/xa/src4/run.sh b/test/xa/src4/run.sh index f602b1d9..6c4ff831 100644 --- a/test/xa/src4/run.sh +++ b/test/xa/src4/run.sh @@ -32,11 +32,12 @@ test "$DVERBOSE" == 1 && { DVERBOSE_FLAG="-v" } COMPILE_FLAGS="$CFLAGS $COMPILE_FLAGS -g -I../../.." +UTILITY_FILES="-f ../../utilities/bdb_xa_util.c" msg "BUILDING CLIENT" CFLAGS="$COMPILE_FLAGS"; export CFLAGS buildclient -r BERKELEY-DB $DVERBOSE_FLAG -o client \ - -f ../../src4/client.c + $UTILITY_FILES -f ../../src4/client.c test "$?" -eq 0 || { echo "FAIL: buildclient failed." exit 1 @@ -46,7 +47,7 @@ msg "BUILDING SERVER #1" CFLAGS="$COMPILE_FLAGS -DSERVER1"; export CFLAGS buildserver -r BERKELEY-DB $DVERBOSE_FLAG -o server1 \ -s TestTxn1:TestTxn1 \ - -f ../../src4/server.c + $UTILITY_FILES -f ../../src4/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 @@ -56,7 +57,7 @@ msg "BUILDING SERVER #2" CFLAGS="$COMPILE_FLAGS -DSERVER2"; export CFLAGS buildserver $DVERBOSE_FLAG -r BERKELEY-DB -o server2 \ -s TestTxn2:TestTxn2 \ - -f ../../src4/server.c + $UTILITY_FILES -f ../../src4/server.c test "$?" -eq 0 || { echo "FAIL: buildserver failed." exit 1 @@ -114,4 +115,4 @@ test -s stderr && { exitval=1 } -exit $exitval \ No newline at end of file +exit $exitval diff --git a/test/xa/src4/server.c b/test/xa/src4/server.c index ce891310..e189ad45 100644 --- a/test/xa/src4/server.c +++ b/test/xa/src4/server.c @@ -1,3 +1,9 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + /* * This code is for servers used in test 4. Server 1 inserts * into database 1 and Server 2 inserts into database 2, then @@ -5,6 +11,8 @@ */ #include +#include "../utilities/bdb_xa_util.h" + #include #include #include @@ -26,24 +34,15 @@ #ifdef SERVER1 #define TXN_FUNC TestTxn1 #define TXN_STRING "TestTxn1" -#define TABLE "table1.db" #endif #ifdef SERVER2 #define TXN_FUNC TestTxn2 #define TXN_STRING "TestTxn2" -#define TABLE "table2.db" #endif void TXN_FUNC(TPSVCINFO *); #define HOME "../data" - -#ifdef VERBOSE -static int verbose = 1; /* Debugging output. */ -#else -static int verbose = 0; -#endif - -DB *db; /* Table handle. */ +#define NUMDB 2 char *progname; /* Server run-time name. */ @@ -53,61 +52,40 @@ char *progname; /* Server run-time name. */ int tpsvrinit(int argc, char* argv[]) { - int ret; - progname = argv[0]; - if (verbose) - printf("%s: called\n", progname); - - /* Open resource managers. */ - if (tx_open() == TX_ERROR) { - fprintf(stderr, "tx_open: TX_ERROR\n"); - return (-1); - } - - /* Seed random number generator. */ - srand((u_int)(time(NULL) | getpid())); - - /* Open permanent XA handles. */ - if ((ret = db_create(&db, NULL, DB_XA_CREATE)) != 0) { - fprintf(stderr, "db_create: %s\n", db_strerror(ret)); - return (-1); - } - db->set_errfile(db, stderr); - if ((ret = db->open(db, NULL, - TABLE, NULL, DB_BTREE, DB_AUTO_COMMIT | DB_CREATE, 0660)) != 0) { - fprintf(stderr, "DB open: %s: %s\n", TABLE, db_strerror(ret)); - return (-1); - } - - if (verbose) - printf("%s: tpsvrinit: initialization done\n", progname); - - return (0); + return (init_xa_server(NUMDB, progname, 0)); } /* Called when the servers are shutdown. This closes the database. */ void tpsvrdone() { - if (db != NULL) - (void)db->close(db, 0); - - tx_close(); - - if (verbose) - printf("%s: tpsvrdone: shutdown done\n", progname); + close_xa_server(NUMDB, progname); } /* - * This function is called by the client. Here Server 1 and Server 2 insert - * data into a table using XA transactions. */ + * This function is called by the client. Here, on Server 1 data is + * inserted into table 1 and it returns successfully. On Server 2 data + * is inserted into table 2, but then it sleeps for 30 seconds then + * returns, in order to force a timeout and to make sure that the data + * is rolled back in both databases. + */ void TXN_FUNC(TPSVCINFO *msg) { DBT data; DBT key; - int ret, val; + int ret, val, i; + DB *db; + const char *name; +#ifdef SERVER1 + i = 0; +#else + i = 1; +#endif + + db = dbs[i]; + name = db_names[i]; val = 1; @@ -118,16 +96,16 @@ TXN_FUNC(TPSVCINFO *msg) data.data = &val; data.size = sizeof(val); - /* Table 1. */ if (verbose) { - printf("put: key in %s: %i\n", val, TABLE); - printf("put: data in %s: %i\n", val, TABLE); + printf("put: key in %s: %i\n", val, db_names[0]); + printf("put: data in %s: %i\n", val, db_names[0]); } if ((ret = db->put(db, NULL, &key, &data, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) goto abort; - fprintf(stderr, "%s: %s: Table->put: %s\n", - progname, TXN_STRING, db_strerror(ret)); + fprintf(stderr, "%s: %s: %s->put: %s\n", + progname, TXN_STRING, name, + db_strerror(ret)); goto err; } diff --git a/test/xa/src5/DB_CONFIG b/test/xa/src5/DB_CONFIG new file mode 100644 index 00000000..8be28194 --- /dev/null +++ b/test/xa/src5/DB_CONFIG @@ -0,0 +1,3 @@ +set_flags DB_MULTIVERSION +set_flags DB_TXN_SNAPSHOT + diff --git a/test/xa/src5/client.c b/test/xa/src5/client.c new file mode 100644 index 00000000..2d2b13c6 --- /dev/null +++ b/test/xa/src5/client.c @@ -0,0 +1,342 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +/* + * This is the MVCC test for XA. It runs 3 tests, which are as follows: + * 1. No MVCC + * 2. MVCC enabled by DB_CONFIG + * 3. MVCC enabled by flags + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../utilities/bdb_xa_util.h" + +#define HOME "../data" +#define TABLE1 "../data/table1.db" +#define TABLE2 "../data/table2.db" +#define NUM_TESTS 4 +#define NUM_THREADS 2 +#define TIMEOUT 60 + +static int error = 1; + +char *progname; /* Client run-time name. */ + +int +usage() +{ + fprintf(stderr, "usage: %s [-v] -t[0|1|2]\n", progname); + return (EXIT_FAILURE); +} + +enum test_type{NO_MVCC, MVCC_DBCONFIG, MVCC_FLAG}; + +struct thread_args { + char *thread_name; + int type_test; +}; + +/* Used to sync the threads. */ +static pthread_cond_t cond_vars[NUM_TESTS*3]; +static int counters[NUM_TESTS*3]; + +void init_tests(char *ops[], int success[], int type, int thread_num); + +/* + * + */ +void * +call_server_thread(void *arguments) +{ + char *thread_name, *ops[NUM_TESTS]; + int ttype; + struct thread_args args; + int commit, j, success[NUM_TESTS], thread_num, ret; + void *result = NULL; + TPINIT *initBuf = NULL; + FBFR *replyBuf = NULL; + long replyLen = 0; + + + args = *((struct thread_args *)arguments); + thread_name = args.thread_name; + thread_num = atoi(thread_name); + ttype = args.type_test; + init_tests(ops, success, ttype, thread_num); + + if (verbose) + printf("%s:%s: starting thread %i\n", progname, thread_name, + thread_num); + + /* Allocate init buffer */ + if ((initBuf = (TPINIT *)tpalloc("TPINIT", NULL, TPINITNEED(0))) == 0) + goto tuxedo_err; + initBuf->flags = TPMULTICONTEXTS; + + if (tpinit(initBuf) == -1) + goto tuxedo_err; + if (verbose) + printf("%s:%s: tpinit() OK\n", progname, thread_name); + + /* Allocate reply buffer. */ + replyLen = 1024; + if ((replyBuf = (FBFR*)tpalloc("FML32", NULL, replyLen)) == NULL) + goto tuxedo_err; + if (verbose) + printf("%s:%s: tpalloc(\"FML32\"), reply buffer OK\n", + progname, thread_name); + + for (j = 0; j < NUM_TESTS; j++) { + commit = 1; + + /* Sync both threads. */ + if ((ret = sync_thr(&(counters[j*3]), NUM_THREADS, + &(cond_vars[j*3]))) != 0) { + fprintf(stderr, + "%s:%s: Error syncing threads: %i \n", + progname, thread_name, ret); + goto end; + } + + /* Begin the XA transaction. */ + if (tpbegin(TIMEOUT, 0L) == -1) + goto tuxedo_err; + if (verbose) + printf("%s:%s: tpbegin() OK\n", progname, thread_name); + + /* Force thread 2 to wait till thread 1 does its operation.*/ + if (thread_num == 2) { + if ((ret = sync_thr(&(counters[(j*3)+1]), NUM_THREADS, + &(cond_vars[(j*3)+1]))) != 0) { + fprintf(stderr, + "%s:%s: Error syncing thread 1: %i \n", + progname, thread_name, ret); + goto end; + } + } + if (verbose) + printf("%s:%s: calling server %s\n", progname, + thread_name, ops[j]); + + /* Read or insert into the database. */ + if (tpcall(ops[j], NULL, 0L, (char **)&replyBuf, + &replyLen, 0) == -1) + goto tuxedo_err; + + /* Wake up thread 2.*/ + if (thread_num == 1) { + if ((ret = sync_thr(&(counters[(j*3)+1]), NUM_THREADS, + &(cond_vars[(j*3)+1]))) != 0) { + fprintf(stderr, + "%s:%s: Error syncing thread 1: %i \n", + progname, thread_name, ret); + goto end; + } + } + + /* Sync both threads. */ + if ((ret = sync_thr(&(counters[(j*3)+2]), NUM_THREADS, + &(cond_vars[(j*3)+2]))) != 0) { + fprintf(stderr, + "%s:%s: Error syncing threads: %i \n", + progname, thread_name, ret); + goto end; + } + + /* + * Commit or abort the transaction depending the what the + * server returns. Check that it matched expectation + * (We abort on LOCK_NOTGRANTED and DEADLOCK errors, and + * commit otherwise. Other errors result in returning + * without committing or aborting. + */ + commit = !tpurcode; + if (commit != success[j]) { + fprintf(stderr, + "%s:%s: Expected: %i Got: %i.\n", + progname, thread_name, success[j], commit); + if (verbose) { + printf("%s:%s: Expected: %i Got: %i.\n", + progname, thread_name, success[j], commit); + } + } + + if (commit) { + if (tpcommit(0L) == -1) + goto tuxedo_err; + if (verbose) { + printf("%s:%s: tpcommit() OK\n", progname, + thread_name); + } + } else { + if (tpabort(0L) == -1) { + goto tuxedo_err; + } + if (verbose) { + printf("%s:%s: tpabort() OK\n", progname, + thread_name); + } + } + } + + if (0) { +tuxedo_err: fprintf(stderr, "%s:%s: TUXEDO ERROR: %s (code %d)\n", + progname, thread_name, tpstrerror(tperrno), tperrno); + /* + * Does not matter what result is, as long as it is not + * NULL on error. + */ + result = (void *)&error; + } +end: tpterm(); + if (verbose) + printf("%s:%s: tpterm() OK\n", progname, thread_name); + + if (initBuf != NULL) + tpfree((char *)initBuf); + + if (replyBuf != NULL) + tpfree((char *)replyBuf); + + return(result); +} + +/* + * Create the threads to call the servers, and check that data in the two + * databases is identical. + */ +int +main(int argc, char* argv[]) +{ + int ch, i, ret, ttype; + pthread_t threads[NUM_THREADS]; + struct thread_args args[NUM_THREADS]; + void *results = NULL; + char *names[] = {"1", "2"}; + + progname = argv[0]; + i = 1; + verbose = 0; + + while ((ch = getopt(argc, argv, "vt")) != EOF) { + switch (ch) { + case 't': + ttype = atoi(argv[++i]); + break; + case 'v': + verbose = 1; + break; + case '?': + default: + return (usage()); + } + i++; + } + argc -= optind; + argv += optind; + + if (ttype > 2 || ttype < 0) + return (usage()); + + if (verbose) + printf("%s: called with type %i\n", progname, ttype); + + for(i = 0; i < (NUM_TESTS*3); i++) { + pthread_cond_init(&cond_vars[i], NULL); + counters[i] = 0; + } + + /* Create threads for different contexts*/ + for (i = 0; i < NUM_THREADS; i++) { + args[i].thread_name = names[i]; + args[i].type_test = ttype; + if (verbose) + printf("calling server thread\n"); + if ((ret = pthread_create(&threads[i], NULL, + call_server_thread, &(args[i]))) != 0) { + fprintf(stderr, "%s: failed to create thread %s.\n", + progname, ret); + goto err; + } + } + + /* Wait for each thread to finish. */ + for (i = 0; i < NUM_THREADS; i++) { + if ((ret = pthread_join(threads[i], &results)) != 0) { + fprintf(stderr, "%s: failed to join thread %s.\n", + progname, ret); + goto err; + } + if (results != NULL) + goto err; + } + + if (0) { +err: ret = EXIT_FAILURE; + } + + for(i = 0; i < (NUM_TESTS*2); i++) + pthread_cond_destroy(&cond_vars[i]); + + return (ret); +} + +static char *rdb1 = "read_db1"; +static char *wdb1 = "write_db1"; + +/* + * Operation Success + * Thread 1 Thread 2 no MVCC MVCC + * write write no no + * write read no yes + * read read yes yes + * read write no yes + */ +void init_tests(char *ops[], int success[], int type, int thread_num) +{ + if (thread_num == 1) { + ops[0] = wdb1; + ops[1] = wdb1; + ops[2] = rdb1; + ops[3] = rdb1; + /* Thread 1 is always successful. */ + success[0] = 1; + success[1] = 1; + success[2] = 1; + success[3] = 1; + } else { + ops[0] = wdb1; + ops[1] = rdb1; + ops[2] = rdb1; + ops[3] = wdb1; + if (type == NO_MVCC) { + success[0] = 0; + success[1] = 0; + success[2] = 1; + success[3] = 0; + } else { + success[0] = 0; + success[1] = 1; + success[2] = 1; + success[3] = 1; + } + } +} diff --git a/test/xa/src5/run.sh b/test/xa/src5/run.sh new file mode 100644 index 00000000..504f2f48 --- /dev/null +++ b/test/xa/src5/run.sh @@ -0,0 +1,119 @@ +#! /bin/sh +# +# MVCC tests, consists of 3 rounds which test: +# 1. No MVCC +# 2. MVCC enabled by DB_CONFIG +# 3. MVCC enable by flags. + +msg() +{ + test "$DVERBOSE" == 1 && { + echo "========" + echo "======== $1" + echo "========" + } +} + +init_tmadmin() +{ +tmadmin << END_OF_TMADMIN + crdl -z $TLOGDEVICE -b 500 + crlog -m cluster3 +END_OF_TMADMIN +} + + +# Everything else is done in run/bin. +cd $RUN/bin + +# If testing DB_CONFIG enabled MVCC move the file to the +# environment directory +if [ $1 -eq 1 ]; then + cp ../../src5/DB_CONFIG ../data/DB_CONFIG +fi + +# The CFLAGS variable defines the pre-processor defines -- start with +# whatever the user set, and add our own stuff. +# +# For debugging output, add -DDVERBOSE + +test "$DVERBOSE" == 1 && { + COMPILE_FLAGS="-DDVERBOSE" + DVERBOSE_FLAG="-v" +} +COMPILE_FLAGS="$CFLAGS $COMPILE_FLAGS -g -I../../.." +UTILITY_FILES="-f ../../utilities/bdb_xa_util.c" + +msg "BUILDING CLIENT" +CFLAGS="$COMPILE_FLAGS"; export CFLAGS +buildclient -r BERKELEY-DB $DVERBOSE_FLAG -o client \ +$UTILITY_FILES -f ../../src5/client.c +test "$?" -eq 0 || { + echo "FAIL: buildclient failed." + exit 1 +} + +msg "BUILDING SERVER for DATABASE 1" +# Build the server database with DB_MULITVERSION +if [ $1 -eq 2 ]; then + COMPILE_FLAGS="-DMVCC_FLAG $COMPILE_FLAGS" +fi +CFLAGS="$COMPILE_FLAGS"; export CFLAGS +buildserver -r BERKELEY-DB $DVERBOSE_FLAG -t -o server1 \ + -s read_db1 -s write_db1 $UTILITY_FILES -f ../../src5/server.c +test "$?" -eq 0 || { + echo "FAIL: buildserver 1 failed." + exit 1 +} + +msg "BUILDING THE RESOURCE MANAGER." +buildtms -o DBRM -r BERKELEY-DB + +init_tmadmin + +# Boot Tuxedo. +# You should see something like: +# +# Booting admin processes ... +# +# exec BBL -A : +# process id=13845 ... Started. +# +# Booting server processes ... +# +# exec DBRM -A : +# process id=13846 ... Started. +# exec DBRM -A : +# process id=13847 ... Started. +# exec server1 -A : +# process id=13848 ... Started. +# exec server2 -A : +# process id=13849 ... Started. +# 5 processes started. +msg "BOOTING TUXEDO." +tmboot -y + +exitval=0 +./client -t $1 $DVERBOSE_FLAG 2>> stderr +test "$?" -ne 0 && { + echo "FAIL: client failed" + exitval=1 + break; +} + +msg "SHUTTING DOWN THE TRANSACTION MANAGER." +echo 'y' | tmshutdown + +# Copy out any server output. +echo "STDOUT:" +cat stdout + +# Copy out any server errors. +test -s stderr && { + echo "STDERR:" + cat stderr + echo "FAIL: stderr file not empty" + exitval=1 +} + +exit $exitval diff --git a/test/xa/src5/server.c b/test/xa/src5/server.c new file mode 100644 index 00000000..ea725320 --- /dev/null +++ b/test/xa/src5/server.c @@ -0,0 +1,150 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "../utilities/bdb_xa_util.h" + +#define KEY_VALUE 0 +#define READ_STRING "read_db1" +#define WRITE_STRING "write_db1" + +void write_db1(TPSVCINFO *); +void read_db1(TPSVCINFO *); + +#define HOME "../data" +#define NUMDB 1 + +char *progname; /* Server run-time name. */ + +/* Called once when the server is started. Creates and opens 2 databases. */ +int +tpsvrinit(int argc, char* argv[]) +{ + int mvcc = 0; + +#ifdef MVCC_FLAG + mvcc = 1; +#endif + progname = argv[0]; + return (init_xa_server(NUMDB, progname, mvcc)); +} + +/* Called once when the servers are shutdown. Closes the databases. */ +void +tpsvrdone() +{ + close_xa_server(NUMDB, progname); +} + + +void +write_db1(TPSVCINFO *msg) +{ + int ret, commit, key_value, data_value; + DBT key, data; + DB *db; + + db = dbs[0]; + memset(&key, 0, sizeof key); + memset(&data, 0, sizeof data); + commit = 1; + + key_value = data_value = KEY_VALUE; + data.data = &data_value; + data.size = sizeof(data_value); + key.data = &key_value; + key.size = sizeof(key_value); + + /* Insert data into the tables. */ + if (verbose) { + printf("put: key: %i ", key_value); + printf("put: data: %i\n", data_value); + } + /* Insert data into the tables. */ + if ((ret = db->put(db, NULL, &key, + &data, 0)) != 0) { + if (ret == DB_LOCK_DEADLOCK || + ret == DB_LOCK_NOTGRANTED) + goto abort; + fprintf(stderr, "%s: %s: %s->put: %s\n", + progname, WRITE_STRING, db_names[0], + db_strerror(ret)); + goto err; + } + + /* Returns a commit or abort command to the client. */ + if (verbose) + printf("%s: %s: commit\n", progname, WRITE_STRING); + tpreturn(TPSUCCESS, 0L, 0, 0L, 0); + if (0) { +abort: if (verbose) + printf("%s: %s: abort\n", progname, WRITE_STRING); + tpreturn(TPSUCCESS, 1L, 0, 0L, 0); + } + return; + +err: tpreturn(TPFAIL, 1L, 0, 0L, 0); +} + +void +read_db1(TPSVCINFO *msg) +{ + int ret, db_num, commit, key_value; + DBT key, data; + DB *db; + + db = dbs[0]; + memset(&key, 0, sizeof key); + memset(&data, 0, sizeof data); + commit = 1; + + db_num = key_value = KEY_VALUE; + key.data = &key_value; + key.size = sizeof(key_value); + data.flags = DB_DBT_MALLOC; + + /* Insert data into the tables. */ + if (verbose) { + printf("get: key: %i ", key_value); + printf("get: data.\n"); + } + /* Get data from the table. */ + if ((ret = db->get(db, NULL, &key, &data, 0)) != 0) { + if (ret == DB_LOCK_DEADLOCK || + ret == DB_LOCK_NOTGRANTED) + goto abort; + fprintf(stderr, "%s: %s: %s->get: %s\n", + progname, READ_STRING, db_names[0], + db_strerror(ret)); + goto err; + } + if (data.data != NULL) + free(data.data); + + /* Returns a commit or abort command to the client. */ + if (verbose) + printf("%s: %s: commit\n", progname, READ_STRING); + tpreturn(TPSUCCESS, 0L, 0, 0L, 0); + if (0) { +abort: if (verbose) + printf("%s: %s: abort\n", progname, READ_STRING); + tpreturn(TPSUCCESS, 1L, 0, 0L, 0); + } + return; + +err: tpreturn(TPFAIL, 1L, 0, 0L, 0); +} + diff --git a/test/xa/utilities/bdb_xa_util.c b/test/xa/utilities/bdb_xa_util.c new file mode 100644 index 00000000..a1182b3f --- /dev/null +++ b/test/xa/utilities/bdb_xa_util.c @@ -0,0 +1,259 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +#include "../utilities/bdb_xa_util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * The sync function syncs all threads by putting them to + * sleep until the last thread enters and sync function and + * forces the rest to wake up. + */ +pthread_mutex_t sync_mutex = PTHREAD_MUTEX_INITIALIZER; + +int sync_thr(counter, num_threads, cond_var) +int *counter; +int num_threads; +pthread_cond_t *cond_var; +{ + int ret; + + ret = 0; + + pthread_mutex_lock(&sync_mutex); + *counter = *counter + 1; + if ((*counter) == num_threads) + pthread_cond_signal( cond_var ); + else + ret = pthread_cond_wait( cond_var, + &sync_mutex); + pthread_mutex_unlock(&sync_mutex); + + return ret; +} + +/* + * Print callback for __db_prdbt. + */ +int +pr_callback(handle, str_arg) + void *handle; + const void *str_arg; +{ + char *str; + FILE *f; + + str = (char *)str_arg; + f = (FILE *)handle; + + if (fprintf(f, "%s", str) != (int)strlen(str)) + return (-1); + + return (0); +} + +/* + * Initialize an XA server and allocate and open its database handles + */ +int +init_xa_server(num_db, progname, use_mvcc) + int num_db; + const char *progname; + int use_mvcc; +{ + int ret, i, j; + u_int32_t temp; + u_int32_t flags = DB_AUTO_COMMIT|DB_CREATE|DB_THREAD; + + if (use_mvcc) + flags |= DB_MULTIVERSION; + + if (verbose) + printf("%s: called\n", progname); + + /* Open resource managers. */ + if (tx_open() == TX_ERROR) { + fprintf(stderr, "tx_open: TX_ERROR\n"); + return (-1); + } + + /* Seed random number generator. */ + srand((u_int)(time(NULL) | getpid())); + + for (i = 0; i < MAX_NUMDB; i++) + dbs[i] = NULL; + + /* + * Open XA database handles. Databases must be opened + * outside of a global transaction + * because the open event is held in process local memory. + */ + for (i = 0; i < num_db; i++) { + if ((ret = db_create(&dbs[i], NULL, DB_XA_CREATE)) != 0) { + fprintf(stderr, "db_create: %s\n", db_strerror(ret)); + goto err; + } + + dbs[i]->set_errfile(dbs[i], stderr); + if ((ret = dbs[i]->open(dbs[i], NULL, + db_names[i], NULL, DB_BTREE, flags, 0664)) != 0) { + fprintf(stderr, "DB open: %s: %s\n", db_names[i], + db_strerror(ret)); + goto err; + } + } + + if (verbose) + printf("%s: tpsvrinit: initialization done\n", progname); + + return (0); + + /* Clean up on error. */ +err: for (i = 0; i < num_db; i++) { + if (dbs[i] != NULL) + (void) dbs[i]->close(dbs[i], 0); + dbs[i] = NULL; + } + return (-1); +} + +/* + * Called when the servers are shutdown. This closes all open + * database handles. + */ +void +close_xa_server(num_db, progname) + int num_db; + const char *progname; +{ + int i; + + for (i = 0; i < num_db; i++) { + if (dbs[i] != NULL) + (void) dbs[i]->close(dbs[i], 0); + dbs[i] = NULL; + } + + tx_close(); + + if (verbose) + printf("%s: tpsvrdone: shutdown done\n", progname); +} + +/* + * check_data -- + * Compare data between two databases to ensure that they are identical. + */ +int check_data(dbenv1, name1, dbenv2, name2, progname) + DB_ENV *dbenv1; + const char *name1; + DB_ENV *dbenv2; + const char *name2; + const char * progname; +{ + DB *dbp1, *dbp2; + DBC *dbc1, *dbc2; + DBT key1, data1, key2, data2; + int ret, ret1, ret2; + u_int32_t flags = DB_INIT_MPOOL | DB_INIT_LOG | DB_INIT_TXN | + DB_INIT_LOCK | DB_THREAD; + + dbp1 = dbp2 = NULL; + dbc1 = dbc2 = NULL; + + /* Open table #1. */ + if ((ret = db_create(&dbp1, dbenv1, 0)) != 0 || + (ret = dbp1->open( + dbp1, NULL, name1, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { + fprintf(stderr, + "%s: %s: %s\n", progname, name1, db_strerror(ret)); + goto err; + } + if (verbose) + printf("%s: opened %s OK\n", progname, name1); + + /* Open table #2. */ + if ((ret = db_create(&dbp2, dbenv2, 0)) != 0 || + (ret = dbp2->open( + dbp2, NULL, name2, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) { + fprintf(stderr, + "%s: %s: %s\n", progname, name2, db_strerror(ret)); + goto err; + } + if (verbose) + printf("%s: opened %s OK\n", progname, name2); + + /* Open cursors. */ + if ((ret = dbp1->cursor(dbp1, NULL, &dbc1, 0)) != 0 || + (ret = dbp2->cursor(dbp2, NULL, &dbc2, 0)) != 0) { + fprintf(stderr, + "%s: DB->cursor: %s\n", progname, db_strerror(ret)); + goto err; + } + if (verbose) + printf("%s: opened cursors OK\n", progname); + + /* Compare the two databases. */ + memset(&key1, 0, sizeof(key1)); + memset(&data1, 0, sizeof(data1)); + memset(&key2, 0, sizeof(key2)); + memset(&data2, 0, sizeof(data2)); + for (;;) { + ret1 = dbc1->get(dbc1, &key1, &data1, DB_NEXT); + ret2 = dbc2->get(dbc2, &key2, &data2, DB_NEXT); + if (ret1 != 0 || ret2 != 0) + break; + if (verbose) { + __db_prdbt(&key1, 0, "get: key1: %s\n", stdout, + pr_callback , 0, 0); + __db_prdbt(&key2, 0, "get: key2: %s\n", stdout, + pr_callback, 0, 0); + __db_prdbt(&data1, 0, "get: data1: %s\n", stdout, + pr_callback, 0, 0); + __db_prdbt(&data2, 0, "get: data2: %s\n", stdout, + pr_callback, 0, 0); + } + /* Compare the key and data. */ + if (key1.size != key2.size || + memcmp(key1.data, key2.data, key1.size) != 0 || + data1.size != data2.size || + memcmp(data1.data, data2.data, + data1.size) != 0) + goto mismatch; + } + if (ret1 != ret2) { +mismatch: fprintf(stderr, + "%s: DB_ERROR: databases 1 and 2 weren't identical\n", + progname); + ret = 1; + } + +err: if (dbc1 != NULL) + (void)dbc1->close(dbc1); + if (dbc2 != NULL) + (void)dbc2->close(dbc2); + if (dbp1 != NULL) + (void)dbp1->close(dbp1, 0); + if (dbp2 != NULL) + (void)dbp2->close(dbp2, 0); + + if (verbose) { + if (ret == 0) + printf("Data check succeeded.\n", progname); + else + printf("Data check failed.\n", progname); + } + + return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +} diff --git a/test/xa/utilities/bdb_xa_util.h b/test/xa/utilities/bdb_xa_util.h new file mode 100644 index 00000000..2f960143 --- /dev/null +++ b/test/xa/utilities/bdb_xa_util.h @@ -0,0 +1,57 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. + */ + +#include +#include + +/* Maximum number of db handles that init/close_xa_server will handle. */ +#define MAX_NUMDB 4 + +/* Names for the databases. */ +static char *db_names[] = {"table1.db", "table2.db", "table3.db", "table4.db"}; + +/* Debugging output. */ +#ifdef VERBOSE +static int verbose = 1; +#else +static int verbose = 0; +#endif + +/* Table handles. */ +DB *dbs[MAX_NUMDB]; + +/* + * This function syncs all threads threads by putting them to + * sleep until the last thread enters and sync function and + * forces the rest to wake up. + * counter - A counter starting at 0 shared by all threads + * num_threads - the number of threads being synced. + */ +int sync_thr(int *counter, int num_threads, pthread_cond_t *cond_var); + +/* + * Print callback for __db_prdbt. + */ +int pr_callback(void *handle, const void *str_arg); +/* + * Initialize an XA server and allocates and opens database handles. + * The number of database handles it opens is the value of the argument + * num_db. + */ +int init_xa_server(int num_db, const char *progname, int use_mvcc); + +/* + * Called when the servers are shutdown. This closes all open + * database handles. num_db is the number of open database handles. + */ +void close_xa_server(int num_db, const char *progname); + +/* + * check_data -- + * Compare data between two databases to ensure that they are identical. + */ +int check_data(DB_ENV *dbenv1, const char *name1, DB_ENV *dbenv2, + const char *name2, const char *progname); diff --git a/test/xa/utilities/multi_1thr_tuxconfig.sh b/test/xa/utilities/multi_1thr_tuxconfig.sh new file mode 100644 index 00000000..982aa890 --- /dev/null +++ b/test/xa/utilities/multi_1thr_tuxconfig.sh @@ -0,0 +1,59 @@ +#! /bin/sh +# +# Build the configuration file for multithreaded tests -- +# We do this work in the shell script because we have to fill in +# lots of shell variables. +# +# Usage: ./multi_tuxconfig.sh + +if test $# -ne 1; then + echo "Usage: ./multi_1thr_tuxconfig.sh \n" + exit 1 +fi + + + IPCKEY=$1 + MACHINE_NAME=`uname -n` + cat > $RUN/config/ubb.cfg << END_OF_UBB_FILE +*RESOURCES +IPCKEY $IPCKEY +DOMAINID domain3 +MASTER cluster3 +MAXACCESSERS 16 +MAXSERVERS 6 +MAXSERVICES 16 +MODEL SHM +LDBAL N + +*MACHINES +DEFAULT: + APPDIR="$APPDIR" + TUXCONFIG="$TUXCONFIG" + TLOGDEVICE="$TLOGDEVICE" + TUXDIR="$TUXDIR" +# Machine name is 30 characters max +"$MACHINE_NAME" LMID=cluster3 + +*GROUPS +# Group name is 30 characters max +group_tm LMID=cluster3 GRPNO=1 TMSNAME=DBRM TMSCOUNT=2 OPENINFO="BERKELEY-DB:$RUN/data" + +*SERVERS +DEFAULT: + CLOPT="-A" + MINDISPATCHTHREADS=1 + MAXDISPATCHTHREADS=8 + +# Server name is 78 characters max (same for any pathname) +server1 SRVGRP=group_tm SRVID=1 MAXGEN=3 RESTART=Y + +*SERVICES +DEFAULT: + SVCTIMEOUT=20 +# Service name is 15 characters max +# server1 +read_db1 +write_db1 + +END_OF_UBB_FILE + tmloadcf -y $RUN/config/ubb.cfg diff --git a/test/xa/utilities/multi_tuxconfig.sh b/test/xa/utilities/multi_tuxconfig.sh new file mode 100644 index 00000000..a1715784 --- /dev/null +++ b/test/xa/utilities/multi_tuxconfig.sh @@ -0,0 +1,60 @@ +#! /bin/sh +# +# Build the configuration file for multithreaded tests -- +# We do this work in the shell script because we have to fill in +# lots of shell variables. +# +# Usage: ./multi_tuxconfig.sh + +if test $# -ne 1; then + echo "Usage: ./multi_tuxconfig.sh \n" + exit 1 +fi + + + IPCKEY=$1 + MACHINE_NAME=`uname -n` + cat > $RUN/config/ubb.cfg << END_OF_UBB_FILE +*RESOURCES +IPCKEY $IPCKEY +DOMAINID domain3 +MASTER cluster3 +MAXACCESSERS 16 +MAXSERVERS 6 +MAXSERVICES 16 +MODEL SHM +LDBAL N + +*MACHINES +DEFAULT: + APPDIR="$APPDIR" + TUXCONFIG="$TUXCONFIG" + TLOGDEVICE="$TLOGDEVICE" + TUXDIR="$TUXDIR" +# Machine name is 30 characters max +"$MACHINE_NAME" LMID=cluster3 + +*GROUPS +# Group name is 30 characters max +group_tm LMID=cluster3 GRPNO=1 TMSNAME=DBRM TMSCOUNT=2 OPENINFO="BERKELEY-DB:$RUN/data" + +*SERVERS +DEFAULT: + CLOPT="-A" + MINDISPATCHTHREADS=1 + MAXDISPATCHTHREADS=8 + +# Server name is 78 characters max (same for any pathname) +server1 SRVGRP=group_tm SRVID=1 MAXGEN=3 RESTART=Y +server2 SRVGRP=group_tm SRVID=2 MAXGEN=3 RESTART=Y + +*SERVICES +DEFAULT: + SVCTIMEOUT=20 +# Service name is 15 characters max +# server1 +TestThread1 +# server2 +TestThread2 +END_OF_UBB_FILE + tmloadcf -y $RUN/config/ubb.cfg diff --git a/test/xa/utilities/tuxconfig.sh b/test/xa/utilities/tuxconfig.sh new file mode 100644 index 00000000..072b4d6b --- /dev/null +++ b/test/xa/utilities/tuxconfig.sh @@ -0,0 +1,54 @@ +#! /bin/sh +# +# Build the configuration file for single thread tests -- +# We do this work in the shell script because we have to fill in +# lots of shell variables. +# +# Usage: ./tuxconfig.sh + +if test $# -ne 1; then + echo "Usage: ./tuxconfig.sh \n" + exit 1 +fi + IPCKEY=$1 + MACHINE_NAME=`uname -n` + cat > $RUN/config/ubb.cfg << END_OF_UBB_FILE +*RESOURCES +IPCKEY $IPCKEY +DOMAINID domain3 +MASTER cluster3 +MAXACCESSERS 10 +MAXSERVERS 5 +MAXSERVICES 10 +MODEL SHM +LDBAL N + +*MACHINES +DEFAULT: + APPDIR="$APPDIR" + TUXCONFIG="$TUXCONFIG" + TLOGDEVICE="$TLOGDEVICE" + TUXDIR="$TUXDIR" +# Machine name is 30 characters max +"$MACHINE_NAME" LMID=cluster3 + +*GROUPS +# Group name is 30 characters max +group_tm LMID=cluster3 GRPNO=1 TMSNAME=DBRM TMSCOUNT=2 OPENINFO="BERKELEY-DB:$RUN/data" + +*SERVERS +DEFAULT: + CLOPT="-A" + +# Server name is 78 characters max (same for any pathname) +server1 SRVGRP=group_tm SRVID=1 MAXGEN=3 RESTART=Y +server2 SRVGRP=group_tm SRVID=2 MAXGEN=3 RESTART=Y + +*SERVICES +# Service name is 15 characters max +# server1 +TestTxn1 +# server2 +TestTxn2 +END_OF_UBB_FILE + tmloadcf -y $RUN/config/ubb.cfg diff --git a/util/db_archive.c b/util/db_archive.c index a643c194..5ce651e6 100644 --- a/util/db_archive.c +++ b/util/db_archive.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); @@ -61,6 +61,12 @@ main(argc, argv) LF_SET(DB_ARCH_LOG); break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5135", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_checkpoint.c b/util/db_checkpoint.c index 31bef6e5..e7ba4c83 100644 --- a/util/db_checkpoint.c +++ b/util/db_checkpoint.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); @@ -74,6 +74,12 @@ main(argc, argv) logfile = optarg; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5134", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_deadlock.c b/util/db_deadlock.c index f3c852cb..52c59178 100644 --- a/util/db_deadlock.c +++ b/util/db_deadlock.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); @@ -87,6 +87,12 @@ main(argc, argv) logfile = optarg; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5136", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_dump.c b/util/db_dump.c index b901a854..8c90d087 100644 --- a/util/db_dump.c +++ b/util/db_dump.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -14,7 +14,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int db_init __P((DB_ENV *, char *, int, u_int32_t, int *)); @@ -97,6 +97,12 @@ main(argc, argv) nflag = 1; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5130", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { @@ -167,9 +173,9 @@ main(argc, argv) return (EXIT_FAILURE); } - if ((mflag || sflag) && rflag) { + if (sflag && rflag) { fprintf(stderr, DB_STR_A("5114", - "%s: the -r or R options may not be specified with -m or -s\n", + "%s: the -r or R options may not be specified with -s\n", "%s\n"), progname); return (EXIT_FAILURE); } @@ -233,7 +239,7 @@ retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { */ if (rflag) { /* The verify method is a destructor. */ - ret = dbp->verify(dbp, filename, NULL, stdout, + ret = dbp->verify(dbp, filename, dbname, stdout, DB_SALVAGE | (Rflag ? DB_AGGRESSIVE : 0) | (pflag ? DB_PRINTABLE : 0)); diff --git a/util/db_dump185.c b/util/db_dump185.c index 49bceb95..b2689e5f 100644 --- a/util/db_dump185.c +++ b/util/db_dump185.c @@ -1,14 +1,14 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif #include diff --git a/util/db_hotbackup.c b/util/db_hotbackup.c index 8b976f30..d11909cc 100644 --- a/util/db_hotbackup.c +++ b/util/db_hotbackup.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,40 +12,30 @@ #include "dbinc/log.h" #include "dbinc/db_page.h" #include "dbinc/qam.h" -#include "dbinc/partition.h" #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif enum which_open { OPEN_ORIGINAL, OPEN_HOT_BACKUP }; -int backup_dir_clean __P((DB_ENV *, char *, char *, int *, int, int)); -int data_copy __P((DB_ENV *, char *, char *, char *, int, int)); -int env_data_copy __P((DB_ENV *, char *, char *, int, const char *)); int env_init __P((DB_ENV **, char *, char **, char ***, char *, enum which_open, int)); int main __P((int, char *[])); -int read_log_dir __P((DB_ENV *, char *, int, char *, char *, int *, int, int)); -int read_data_dir __P((DB_ENV *, - char *, char *, char *, int, int, int, int, const char *)); -void save_error __P((const DB_ENV *, const char *, const char *)); int usage __P((void)); int version_check __P((void)); +void __db_util_msg __P((const DB_ENV *, const char *)); const char *progname; -/* - * For backporting. - */ -#if (DB_VERSION_MAJOR < 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR < 2)) -#define DB_STR_A(code, string, fmt) string -#define PART_PREFIX "__dbp." -#ifndef DB_WIN32 -#include "db_copy.c" -#endif -#endif +void __db_util_msg(dbenv, msgstr) + const DB_ENV *dbenv; + const char *msgstr; +{ + COMPQUIET(dbenv, NULL); + printf("%s: %s\n", progname, msgstr); +} int main(argc, argv) @@ -57,9 +47,9 @@ main(argc, argv) time_t now; DB_ENV *dbenv; u_int data_cnt, data_next; - int ch, checkpoint, copy_min, db_config, debug, env_copy, exitval; - int remove_max, ret, update, verbose, hotbackup_flag_set, relative; - char *backup_dir, **data_dir, **dir, *home, *log_dir, *passwd; + int ch, checkpoint, db_config, debug, env_copy, exitval; + int ret, update, verbose; + char *backup_dir, **data_dir, *home, *log_dir, *passwd; char home_buf[DB_MAXPATHLEN], time_buf[CTIME_BUFLEN]; u_int32_t flags; @@ -87,11 +77,10 @@ main(argc, argv) env_copy = 1; checkpoint = db_config = data_cnt = data_next = debug = - exitval = update = verbose = hotbackup_flag_set = 0; + exitval = update = verbose = 0; data_dir = NULL; backup_dir = home = passwd = NULL; log_dir = NULL; - copy_min = remove_max = 0; while ((ch = getopt(argc, argv, "b:cDd:Fgh:l:P:uVv")) != EOF) switch (ch) { case 'b': @@ -114,7 +103,8 @@ main(argc, argv) data_cnt * sizeof(*data_dir))) == NULL) { fprintf(stderr, "%s: %s\n", progname, strerror(errno)); - return (EXIT_FAILURE); + exitval = (EXIT_FAILURE); + goto clean; } } data_dir[data_next++] = optarg; @@ -133,13 +123,21 @@ main(argc, argv) log_dir = optarg; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, "%s: %s", progname, + DB_STR("5133", + "Password may not be specified twice\n")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { + fprintf(stderr, "%s: ", progname); fprintf(stderr, DB_STR_A("5026", - "%s: strdup: %s\n", "%s %s\n"), - progname, strerror(errno)); - return (EXIT_FAILURE); + "strdup: %s\n", "%s\n"), strerror(errno)); + exitval = (EXIT_FAILURE); + goto clean; } break; case 'u': @@ -147,19 +145,23 @@ main(argc, argv) break; case 'V': printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); + exitval = (EXIT_SUCCESS); + goto clean; case 'v': verbose = 1; break; case '?': default: - return (usage()); + exitval = usage(); + goto clean; } argc -= optind; argv += optind; - if (argc != 0) - return (usage()); + if (argc != 0) { + exitval = usage(); + goto clean; + } /* NULL-terminate any list of data directories. */ if (data_dir != NULL) { @@ -169,17 +171,20 @@ main(argc, argv) * we must have directories relative to the environment. */ if (checkpoint == 1) { - fprintf(stderr, DB_STR_A("5027", - "%s: cannot specify -d and -c\n", "%s\n"), - progname); - return (usage()); + fprintf(stderr, "%s: %s", + DB_STR("5027", "cannot specify -d and -c\n"), + progname); + + exitval = usage(); + goto clean; } } if (db_config && (data_dir != NULL || log_dir != NULL)) { - fprintf(stderr, DB_STR_A("5028", - "%s: cannot specify -D and -d or -l\n", "%s\n"), progname); - return (usage()); + fprintf(stderr, "%s: %s", DB_STR("5028", + "cannot specify -D and -d or -l\n"), progname); + exitval = usage(); + goto clean; } /* Handle possible interruptions. */ @@ -196,97 +201,85 @@ main(argc, argv) home = home_buf; if ((ret = __os_getenv( NULL, "DB_HOME", &home, sizeof(home_buf))) != 0) { + fprintf(stderr, "%s: ", progname); fprintf(stderr, DB_STR_A("5029", - "%s failed to get environment variable DB_HOME: %s\n", - "%s %s\n"), progname, db_strerror(ret)); - return (EXIT_FAILURE); + "failed to get environment variable DB_HOME: %s\n", + "%s"), db_strerror(ret)); + exitval = (EXIT_FAILURE); + goto clean; } /* * home set to NULL if __os_getenv failed to find DB_HOME. */ } if (home == NULL) { - fprintf(stderr, DB_STR_A("5030", - "%s: no source database environment specified\n", - "%s\n"), progname); - return (usage()); + fprintf(stderr, "%s: %s", DB_STR("5030", + "no source database environment specified\n"), progname); + exitval = usage(); + goto clean; } if (backup_dir == NULL) { - fprintf(stderr, DB_STR_A("5031", - "%s: no target backup directory specified\n", "%s\n"), + fprintf(stderr, "%s: %s", DB_STR("5031", + "no target backup directory specified\n"), progname); - return (usage()); + exitval = usage(); + goto clean; } if (verbose) { (void)time(&now); - printf(DB_STR_A("5032", "%s: hot backup started at %s", - "%s %s"), progname, __os_ctime(&now, time_buf)); + printf("%s: ", progname); + printf(DB_STR_A("5032", "hot backup started at %s", + "%s"), __os_ctime(&now, time_buf)); } /* Open the source environment. */ if (env_init(&dbenv, home, (db_config || log_dir != NULL) ? &log_dir : NULL, - db_config ? &data_dir : NULL, - passwd, OPEN_ORIGINAL, verbose) != 0) + &data_dir, passwd, OPEN_ORIGINAL, verbose) != 0) goto err; if (env_copy) { if ((ret = dbenv->get_open_flags(dbenv, &flags)) != 0) goto err; if (flags & DB_PRIVATE) { - fprintf(stderr, DB_STR_A("5129", - "%s: Cannot copy data from a PRIVATE environment\n", - "%s"), progname); + fprintf(stderr, "%s: %s", progname, DB_STR("5129", + "Cannot copy data from a PRIVATE environment\n")); goto err; } } if (log_dir != NULL) { if (db_config && __os_abspath(log_dir)) { - fprintf(stderr, DB_STR_A("5033", - "%s: DB_CONFIG must not contain an absolute " - "path for the log directory\n", "%s\n"), progname); + fprintf(stderr, "%s: %s", progname, DB_STR("5033", + "DB_CONFIG must not contain an absolute " + "path for the log directory\n")); goto err; } } -#if (DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR > 0)) - /* - * Record in the environment that a hot backup is in progress. - * This disables the bulk loading optimization for the - * duration of the backup. This increments a persistent - * counter in the database's environment, so it is essential - * that the corresponding decrement takes place upon - * completion of the backup. - */ - if ((ret = dbenv->set_flags(dbenv, DB_HOTBACKUP_IN_PROGRESS, 1))) { - fprintf(stderr, DB_STR_A("5034", - "%s: dbenv->set_flags(DB_HOTBACKUP_IN_PROGRESS, 1): %s\n", - "%s %s\n"), progname, db_strerror(ret)); - goto err; - } - hotbackup_flag_set = 1; -#endif - /* * If the -c option is specified, checkpoint the source home * database environment, and remove any unnecessary log files. */ if (checkpoint) { - if (verbose) - printf(DB_STR_A("5035", "%s: %s: force checkpoint\n", - "%s %s\n"), progname, home); + if (verbose) { + printf("%s: ", progname); + printf(DB_STR_A("5035", "%s: force checkpoint\n", + "%s"), home); + } if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, DB_FORCE)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->txn_checkpoint"); goto err; } if (!update) { - if (verbose) + if (verbose) { + printf("%s: ", progname); printf(DB_STR_A("5036", - "%s: %s: remove unnecessary log files\n", - "%s %s\n"), progname, home); + "%s: remove unnecessary log files\n", + "%s"), home); + } if ((ret = dbenv->log_archive(dbenv, NULL, DB_ARCH_REMOVE)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->log_archive"); @@ -295,107 +288,14 @@ main(argc, argv) } } - /* - * If the target directory for the backup does not exist, create it - * with mode read-write-execute for the owner. Ignore errors here, - * it's simpler and more portable to just always try the create. If - * there's a problem, we'll fail with reasonable errors later. - */ - (void)__os_mkdir(NULL, backup_dir, DB_MODE_700); + flags = DB_CREATE | DB_BACKUP_CLEAN | DB_BACKUP_FILES; + if (update) + LF_SET(DB_BACKUP_UPDATE); - /* - * If -u was specified, remove all log files; if -u was not specified, - * remove all files. - * - * Potentially there are two directories to clean, the log directory - * and the target directory. First, clean up the log directory if - * it's different from the target directory, then clean up the target - * directory. - */ - if (db_config && log_dir != NULL && - backup_dir_clean( - dbenv, backup_dir, log_dir, &remove_max, update, verbose) != 0) + if (!db_config) + LF_SET(DB_BACKUP_SINGLE_DIR); + if ((ret = dbenv->backup(dbenv, backup_dir, flags)) != 0) goto err; - if (backup_dir_clean(dbenv, - backup_dir, NULL, &remove_max, update, verbose) != 0) - goto err; - - /* - * If the -u option was not specified, copy all database files found in - * the database environment home directory, or any directory specified - * using the -d option, into the target directory for the backup. - */ - if (!update) { - if (read_data_dir(dbenv, home, backup_dir, - home, verbose, db_config, env_copy, 0, passwd) != 0) - goto err; - /* - * Use a DB_CONFIG if it exists and neither -D/-d was set. - */ - relative = 0; - if (!db_config && data_dir == NULL) { - (void)dbenv->get_data_dirs( - dbenv, (const char ***)&data_dir); - relative = 1; - } - - if (data_dir != NULL) - for (dir = data_dir; *dir != NULL; ++dir) { - /* - * Don't allow absolute path names taken from - * the DB_CONFIG file -- running recovery with - * them would corrupt the source files. - */ - if (db_config && __os_abspath(*dir)) { - fprintf(stderr, DB_STR_A("5037", -"%s: data directory '%s' is absolute path, not permitted with -D option\n", - "%s %s\n"), progname, *dir); - goto err; - } - if (read_data_dir(dbenv, home, backup_dir, - *dir, verbose, db_config, - env_copy, relative, passwd) != 0) - goto err; - } - } - - /* - * Copy all log files found in the directory specified by the -l option - * (or in the database environment home directory, if no -l option was - * specified), into the target directory for the backup. - * - * The log directory defaults to the home directory. - */ - if (read_log_dir(dbenv, home, db_config, backup_dir, - log_dir, ©_min, update, verbose) != 0) - goto err; - /* - * If we're updating a snapshot, the lowest-numbered log file copied - * into the backup directory should be less than, or equal to, the - * highest-numbered log file removed from the backup directory during - * cleanup. - */ - if (update && remove_max < copy_min && - !(remove_max == 0 && copy_min == 1)) { - fprintf(stderr, DB_STR_A("5038", - "%s: the largest log file removed (%d) must be greater\n", - "%s %d\n"), progname, remove_max); - fprintf(stderr, DB_STR_A("5039", - "%s: than or equal the smallest log file copied (%d)\n", - "%s %d\n"), progname, copy_min); - goto err; - } - -#if (DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR > 0)) - /* Turn off the hotbackup flag in the environment now. */ - if ((ret = dbenv->set_flags(dbenv, DB_HOTBACKUP_IN_PROGRESS, 0))) { - fprintf(stderr, - "%s: dbenv->set_flags(DB_HOTBACKUP_IN_PROGRESS, 0): %s\n", - progname, db_strerror(ret)); - goto err; - } - hotbackup_flag_set = 0; -#endif /* Close the source environment. */ if ((ret = dbenv->close(dbenv, 0)) != 0) { @@ -405,9 +305,11 @@ main(argc, argv) goto err; } /* Perform catastrophic recovery on the hot backup. */ - if (verbose) - printf(DB_STR_A("5040", "%s: %s: run catastrophic recovery\n", - "%s %s\n"), progname, backup_dir); + if (verbose) { + printf("%s: ", progname); + printf(DB_STR_A("5040", "%s: run catastrophic recovery\n", + "%s"), backup_dir); + } if (env_init(&dbenv, backup_dir, NULL, NULL, passwd, OPEN_HOT_BACKUP, verbose) != 0) goto err; @@ -417,10 +319,13 @@ main(argc, argv) * For debugging purposes, leave them around. */ if (debug == 0) { - if (verbose) + if (verbose) { + printf("%s: ", progname); printf(DB_STR_A("5041", - "%s: %s: remove unnecessary log files\n", - "%s %s\n"), progname, backup_dir); + "%s: remove unnecessary log files\n", + "%s"), backup_dir); + } + if ((ret = dbenv->log_archive(dbenv, NULL, DB_ARCH_REMOVE)) != 0) { dbenv->err(dbenv, ret, "DB_ENV->log_archive"); @@ -431,15 +336,7 @@ main(argc, argv) if (0) { err: exitval = 1; } -#if (DB_VERSION_MAJOR > 5 || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR > 0)) - if (hotbackup_flag_set && - (ret = dbenv->set_flags(dbenv, DB_HOTBACKUP_IN_PROGRESS, 0))) { - exitval = 1; - fprintf(stderr, - "%s: dbenv->set_flags(DB_HOTBACKUP_IN_PROGRESS, 0): %s\n", - progname, db_strerror(ret)); - } -#endif + if (dbenv != NULL && (ret = dbenv->close(dbenv, 0)) != 0) { exitval = 1; fprintf(stderr, @@ -449,20 +346,26 @@ err: exitval = 1; if (exitval == 0) { if (verbose) { (void)time(&now); + printf("%s: ", progname); printf(DB_STR_A("5042", - "%s: hot backup completed at %s", - "%s %s"), progname, __os_ctime(&now, time_buf)); + "hot backup completed at %s", "%s"), + __os_ctime(&now, time_buf)); } } else { - fprintf(stderr, DB_STR_A("5043", "%s: HOT BACKUP FAILED!\n", - "%s\n"), progname); + fprintf(stderr, "%s: %s", progname, + DB_STR("5043", "HOT BACKUP FAILED!\n")); } /* Resend any caught signal. */ __db_util_sigresend(); - return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +clean: + if (data_cnt > 0) + free(data_dir); + if (passwd != NULL) + free(passwd); + return (exitval == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } /* @@ -477,7 +380,9 @@ env_init(dbenvp, home, log_dirp, data_dirp, passwd, which, verbose) int verbose; { DB_ENV *dbenv; - int ret; + const char *log_dir, **data_dir; + char buf[DB_MAXPATHLEN]; + int homehome, ret; *dbenvp = NULL; @@ -490,6 +395,10 @@ env_init(dbenvp, home, log_dirp, data_dirp, passwd, which, verbose) return (1); } + if (verbose) { + (void)dbenv->set_verbose(dbenv, DB_VERB_BACKUP, 1); + dbenv->set_msgcall(dbenv, __db_util_msg); + } dbenv->set_errfile(dbenv, stderr); setbuf(stderr, NULL); dbenv->set_errpfx(dbenv, progname); @@ -519,6 +428,41 @@ env_init(dbenvp, home, log_dirp, data_dirp, passwd, which, verbose) switch (which) { case OPEN_ORIGINAL: + if (data_dirp != NULL && *data_dirp != NULL) { + /* + * Backward compatibility: older versions + * did not have data dirs relative to home. + * Check to see if there is a sub-directory with + * the same name has the home directory. If not + * trim the home directory from the data directory + * passed in. + */ + (void) sprintf(buf, "%s/%s", home, home); + homehome = 0; + (void)__os_exists(dbenv->env, buf, &homehome); + + for (data_dir = (const char **)*data_dirp; + *data_dir != NULL; data_dir++) { + if (!homehome && + !strncmp(home, *data_dir, strlen(home))) { + if (strchr(PATH_SEPARATOR, + (*data_dir)[strlen(home)]) != NULL) + (*data_dir) += strlen(home) + 1; + /* Just in case an extra / was added. */ + else if (strchr(PATH_SEPARATOR, + home[strlen(home) - 1]) != NULL) + (*data_dir) += strlen(home); + } + + if ((ret = dbenv->add_data_dir( + dbenv, *data_dir)) != 0) { + dbenv->err(dbenv, ret, + "DB_ENV->add_data_dir: %s", + *data_dir); + return (1); + } + } + } /* * Opening the database environment we're trying to back up. * We try to attach to a pre-existing environment; if that @@ -532,8 +476,21 @@ env_init(dbenvp, home, log_dirp, data_dirp, passwd, which, verbose) dbenv->err(dbenv, ret, "DB_ENV->open: %s", home); return (1); } - if (log_dirp != NULL && *log_dirp == NULL) - (void)dbenv->get_lg_dir(dbenv, (const char **)log_dirp); + if (log_dirp != NULL) { + (void)dbenv->get_lg_dir(dbenv, &log_dir); + if (*log_dirp == NULL) + *log_dirp = (char*)log_dir; + else if (strcmp(*log_dirp, log_dir)) { + fprintf(stderr, DB_STR_A("5057", + "%s: cannot specify -l with conflicting DB_CONFIG file\n", + "%s\n"), progname); + return (usage()); + } else { + fprintf(stderr, "%s: %s", DB_STR("5058", + "use of -l with DB_CONFIG file is deprecated\n"), + progname); + } + } if (data_dirp != NULL && *data_dirp == NULL) (void)dbenv->get_data_dirs( dbenv, (const char ***)data_dirp); @@ -566,571 +523,6 @@ env_init(dbenvp, home, log_dirp, data_dirp, passwd, which, verbose) return (0); } -/* - * backup_dir_clean -- - * Clean out the backup directory. - */ -int -backup_dir_clean(dbenv, backup_dir, log_dir, remove_maxp, update, verbose) - DB_ENV *dbenv; - char *backup_dir, *log_dir; - int *remove_maxp, update, verbose; -{ - ENV *env; - int cnt, fcnt, ret, v; - char **names, *dir, buf[DB_MAXPATHLEN], path[DB_MAXPATHLEN]; - - env = dbenv->env; - - /* We may be cleaning a log directory separate from the target. */ - if (log_dir != NULL) { - if ((size_t)snprintf(buf, sizeof(buf), "%s%c%s", - backup_dir, PATH_SEPARATOR[0] ,log_dir) >= sizeof(buf)) { - dbenv->errx(dbenv, DB_STR_A("5044", - "%s%c%s: path too long", "%s %c %s"), - backup_dir, PATH_SEPARATOR[0] ,log_dir); - return (1); - } - dir = buf; - } else - dir = backup_dir; - - /* Get a list of file names. */ - if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) { - if (log_dir != NULL && !update) - return (0); - dbenv->err(dbenv, ret, DB_STR_A("5045", "%s: directory read", - "%s"), dir); - return (1); - } - for (cnt = fcnt; --cnt >= 0;) { - /* - * Skip non-log files (if update was specified). - */ - if (strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1)) { - if (update) - continue; - } else { - /* Track the highest-numbered log file removed. */ - v = atoi(names[cnt] + sizeof(LFPREFIX) - 1); - if (*remove_maxp < v) - *remove_maxp = v; - } - if ((size_t)snprintf(path, sizeof(path), "%s%c%s", - dir, PATH_SEPARATOR[0], names[cnt]) >= sizeof(path)) { - dbenv->errx(dbenv, DB_STR_A("5046", - "%s%c%s: path too long", "%s %c %s"), - dir, PATH_SEPARATOR[0], names[cnt]); - return (1); - } - if (verbose) - printf(DB_STR_A("5047", "%s: removing %s\n", - "%s %s\n"), progname, path); - if (__os_unlink(env, path, 0) != 0) - return (1); - } - - __os_dirfree(env, names, fcnt); - - if (verbose && *remove_maxp != 0) - printf(DB_STR_A("5048", - "%s: highest numbered log file removed: %d\n", "%s %d\n"), - progname, *remove_maxp); - - return (0); -} - -/* - * read_data_dir -- - * Read a directory looking for databases to copy. - */ -int -read_data_dir(dbenv, - home, backup_dir, dir, verbose, db_config, env_copy, relative, passwd) - DB_ENV *dbenv; - char *home, *backup_dir, *dir; - int verbose, db_config, env_copy, relative; - const char *passwd; -{ - ENV *env; - int cnt, fcnt, ret; - char *bd, **names; - char buf[DB_MAXPATHLEN], bbuf[DB_MAXPATHLEN]; - - env = dbenv->env; - - bd = backup_dir; - if (db_config && dir != home) { - /* Build a path name to the destination. */ - if ((size_t)(cnt = snprintf(bbuf, sizeof(bbuf), "%s%c%s%c", - backup_dir, PATH_SEPARATOR[0], - dir, PATH_SEPARATOR[0])) >= sizeof(buf)) { - dbenv->errx(dbenv, DB_STR_A("5049", - "%s%c%s: path too long", "%s %c %s"), - backup_dir, PATH_SEPARATOR[0], dir); - return (1); - } - bd = bbuf; - - /* Create the path. */ - if ((ret = __db_mkpath(env, bd)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("5050", - "%s: cannot create", "%s"), bd); - return (1); - } - /* step on the trailing '/' */ - bd[cnt - 1] = '\0'; - - } - if ((relative && !__os_abspath(dir)) || (db_config && dir != home)) { - /* Build a path name to the source. */ - if ((size_t)snprintf(buf, sizeof(buf), - "%s%c%s", home, PATH_SEPARATOR[0], dir) >= sizeof(buf)) { - dbenv->errx(dbenv, DB_STR_A("5051", - "%s%c%s: path too long", "%s %c %s"), - home, PATH_SEPARATOR[0], dir); - return (1); - } - dir = buf; - } - /* Get a list of file names. */ - if ((ret = __os_dirlist(env, dir, 0, &names, &fcnt)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("5052", "%s: directory read", - "%s"), dir); - return (1); - } - for (cnt = fcnt; --cnt >= 0;) { - /* - * Skip files in DB's name space (but not Queue extent files or - * the replicated system database, we need them). - */ - if (!strncmp(names[cnt], LFPREFIX, sizeof(LFPREFIX) - 1)) - continue; - if (!strncmp(names[cnt], - DB_REGION_PREFIX, sizeof(DB_REGION_PREFIX) - 1) && - (env_copy || strncmp(names[cnt], - QUEUE_EXTENT_PREFIX, sizeof(QUEUE_EXTENT_PREFIX) - 1)) -#ifdef HAVE_PARTITION - && - strncmp(names[cnt], - PART_PREFIX, sizeof(PART_PREFIX) - 1) -#endif -#if (DB_VERSION_MAJOR >= 5) - && - strncmp(names[cnt], - REPSYSDBNAME, sizeof(REPSYSDBNAME) - 1) -#endif - ) - continue; - - /* - * Skip DB_CONFIG. - */ - if (!db_config && - !strncmp(names[cnt], "DB_CONFIG", sizeof("DB_CONFIG"))) - continue; - - /* - * Copy the file. - * By default we copy through the environment, this works - * in all cases. If the OS or Filesystem supports atomic - * reads then we can read directly from the filesystem. - * This is known to be true only for UNIX based operating - * systems and not LINUX or Windows based operating systems. - */ - if (env_copy) - ret = env_data_copy(dbenv, - names[cnt], bd, verbose, passwd); - /* The file might not be a database. */ - if (!env_copy || ret == ENOENT || ret == EINVAL) - ret = data_copy(dbenv, names[cnt], dir, bd, 0, verbose); - if (ret != 0) - return (1); - } - - __os_dirfree(env, names, fcnt); - - return (0); -} - -/* - * read_log_dir -- - * Read a directory looking for log files to copy. If home - * is passed then we are possibly using a log dir in the destination, - * following DB_CONFIG configuration. - */ -int -read_log_dir(dbenv, home, db_config, backup_dir, log_dir, copy_minp, - update, verbose) - DB_ENV *dbenv; - char *home, *backup_dir, *log_dir; - int *copy_minp, db_config, update, verbose; -{ - ENV *env; - u_int32_t aflag; - int cnt, ret, v; - char **begin, **names, *backupd, *logd; - char from[DB_MAXPATHLEN], to[DB_MAXPATHLEN]; - char cfpath[DB_MAXPATHLEN]; - - env = dbenv->env; - - /* - * If the log directory is specified from DB_CONFIG then it is - * located relative to the the log file source dircectory. If - * the log directory is set from the -l argument and it is not an - * absolute path it is also located relative to the log file source - * directory. Otherwise the log file source directory is home. - */ - if (db_config && log_dir != NULL) { - if ((size_t)snprintf(from, sizeof(from), "%s%c%s", - home, PATH_SEPARATOR[0], log_dir) >= sizeof(from)) { - dbenv->errx(dbenv, DB_STR_A("5053", - "%s%c%s: path too long", "%s %c %s"), - home, PATH_SEPARATOR[0], log_dir); - return (1); - } - logd = strdup(from); - - /* - * With a DB_CONFIG file, logs are copied to the specified - * location relative to the backup_dir. Otherwise the logs are - * copied to the backup_dir. - */ - if ((size_t)(cnt = snprintf(to, sizeof(to), - "%s%c%s%c", backup_dir, PATH_SEPARATOR[0], - log_dir, PATH_SEPARATOR[0])) >= sizeof(to)) { - dbenv->errx(dbenv, DB_STR_A("5054", - "%s%c%s: path too long", "%s %c %s"), - backup_dir, PATH_SEPARATOR[0], log_dir); - return (1); - } - backupd = strdup(to); - - /* Create the backup log directory. */ - if ((ret = __db_mkpath(env, backupd)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("5055", - "%s: cannot create", "%s"), backupd); - return (1); - } - /* Step on the trailing '/'. */ - backupd[cnt - 1] = '\0'; - } else { - /* - * Use a DB_CONFIG if it exists and neither -D/-l was set. - */ - if (log_dir == NULL) { - (void)dbenv->get_lg_dir(dbenv, (const char **)&log_dir); - - if (log_dir) - logd = log_dir; - else - logd = log_dir = home; - } else { - logd = log_dir; - /* - * Do we have -l and an existing DB_CONFIG? That is a - * usage problem, but for backward compatibility, keep - * going if log_dir happens to be the same as the - * DB_CONFIG path. - */ - if ((size_t)snprintf(cfpath, sizeof(cfpath), - "%s%c%s", home, PATH_SEPARATOR[0], "DB_CONFIG") >= - sizeof(cfpath)) { - dbenv->errx(dbenv,DB_STR_A("5056", - "%s%c%s: path too long", "%s %c %s"), - home, PATH_SEPARATOR[0], "DB_CONFIG"); - return (1); - } - if (__os_exists(NULL, cfpath, NULL) == 0) { - if (strcmp(log_dir,dbenv->db_log_dir)) { - fprintf(stderr, DB_STR_A("5057", - "%s: cannot specify -l with conflicting DB_CONFIG file\n", - "%s\n"), progname); - return (usage()); - } else - fprintf(stderr, DB_STR_A("5058", - "%s: use of -l with DB_CONFIG file is deprecated\n", - "%s\n"), progname); - } - } - - if (logd != home && !__os_abspath(logd)) { - if ((size_t)snprintf(from, sizeof(from), - "%s%c%s", home, PATH_SEPARATOR[0], log_dir) - >= sizeof(from)) { - dbenv->errx(dbenv, DB_STR_A("5059", - "%s%c%s: path too long", - "%s %c %s"), home, - PATH_SEPARATOR[0], log_dir); - return 1; - } - logd = strdup(from); - } - backupd = backup_dir; - } - -again: aflag = DB_ARCH_LOG; - - /* - * If this is an update and we are deleting files, first process - * those files that can be removed, then repeat with the rest. - */ - if (update) - aflag = 0; - - /* Flush the log to get latest info. */ - if ((ret = dbenv->log_flush(dbenv, NULL)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_flush"); - return (1); - } - - /* Get a list of file names to be copied. */ - if ((ret = dbenv->log_archive(dbenv, &names, aflag)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->log_archive"); - return (1); - } - if (names == NULL) - goto done; - begin = names; - for (; *names != NULL; names++) { - /* Track the lowest-numbered log file copied. */ - v = atoi(*names + sizeof(LFPREFIX) - 1); - if (*copy_minp == 0 || *copy_minp > v) - *copy_minp = v; - - if ((size_t)snprintf(from, sizeof(from), "%s%c%s", - logd, PATH_SEPARATOR[0], *names) >= sizeof(from)) { - dbenv->errx(dbenv, DB_STR_A("5060", - "%s%c%s: path too long", "%s %c %s"), - logd, PATH_SEPARATOR[0], *names); - return (1); - } - - /* - * If we're going to remove the file, attempt to rename the - * instead of copying and then removing. The likely failure - * is EXDEV (source and destination are on different volumes). - * Fall back to a copy, regardless of the error. We don't - * worry about partial contents, the copy truncates the file - * on open. - */ - if (update) { - if ((size_t)snprintf(to, sizeof(to), "%s%c%s", - backupd, PATH_SEPARATOR[0], *names) >= sizeof(to)) { - dbenv->errx(dbenv, DB_STR_A("5061", - "%s%c%s: path too long", "%s %c %s"), - backupd, PATH_SEPARATOR[0], *names); - return (1); - } - if (__os_rename(env, from, to, 1) == 0) { - if (verbose) - printf(DB_STR_A("5062", - "%s: moving %s to %s\n", - "%s %s %s\n"), - progname, from, to); - continue; - } - } - - /* Copy the file. */ - if (data_copy(dbenv, *names, logd, backupd, 1, verbose) != 0) - return (1); - - if (update) { - if (verbose) - printf(DB_STR_A("5063", "%s: removing %s\n", - "%s %s\n"), progname, from); - if ((ret = __os_unlink(env, from, 0)) != 0) { - dbenv->err(dbenv, ret, DB_STR_A("5064", - "unlink of %s failed", "%s"), from); - return (1); - } - } - - } - - free(begin); -done: if (update) { - update = 0; - goto again; - } - - if (verbose && *copy_minp != 0) - printf(DB_STR_A("5065", - "%s: lowest numbered log file copied: %d\n", "%s %d\n"), - progname, *copy_minp); - if (logd != log_dir) - free(logd); - if (backupd != backup_dir) - free(backupd); - - return (0); -} - -/* - * data_copy -- - * Copy a file into the backup directory. - */ -int -data_copy(dbenv, file, from_dir, to_dir, log, verbose) - DB_ENV *dbenv; - char *file, *from_dir, *to_dir; - int log, verbose; -{ - DB_FH *rfhp, *wfhp; - ENV *env; - size_t nr, nw; - int ret; - char *buf; - - rfhp = wfhp = NULL; - env = dbenv->env; - ret = 0; - - if (verbose) - printf(DB_STR_A("5066", "%s: copying %s%c%s to %s%c%s\n", - "%s %s %c %s %s %c %s\n"), progname, from_dir, - PATH_SEPARATOR[0], file, to_dir, PATH_SEPARATOR[0], file); - - /* - * We MUST copy multiples of the page size, atomically, to ensure a - * database page is not updated by another thread of control during - * the copy. - * - * !!! - * The current maximum page size for Berkeley DB is 64KB; we will have - * to increase this value if the maximum page size is ever more than a - * megabyte - */ - if ((buf = malloc(MEGABYTE)) == NULL) { - dbenv->err(dbenv, errno, DB_STR_A("5067", - "%lu buffer allocation", "%lu"), (u_long)MEGABYTE); - return (1); - } - - /* Open the input file. */ - if (snprintf(buf, MEGABYTE, "%s%c%s", - from_dir, PATH_SEPARATOR[0], file) >= MEGABYTE) { - dbenv->errx(dbenv, DB_STR_A("5068", "%s%c%s: path too long", - "%s %c %s"), from_dir, PATH_SEPARATOR[0], file); - goto err; - } - if ((ret = __os_open(env, buf, 0, DB_OSO_RDONLY, 0, &rfhp)) != 0) { - if (ret == ENOENT && !log) { - ret = 0; - if (verbose) - printf(DB_STR_A("5069", - "%s: %s%c%s not present\n", "%s %s %c %s\n"), - progname, from_dir, PATH_SEPARATOR[0], file); - goto done; - } - dbenv->err(dbenv, ret, "%s", buf); - goto err; - } - - /* Open the output file. */ - if (snprintf(buf, MEGABYTE, "%s%c%s", - to_dir, PATH_SEPARATOR[0], file) >= MEGABYTE) { - dbenv->errx(dbenv, DB_STR_A("5070", "%s%c%s: path too long", - "%s %c %s"), to_dir, PATH_SEPARATOR[0], file); - goto err; - } - if ((ret = __os_open(env, buf, 0, - DB_OSO_CREATE | DB_OSO_TRUNC, DB_MODE_600, &wfhp)) != 0) { - dbenv->err(dbenv, ret, "%s", buf); - goto err; - } - - /* Copy the data. */ - while ((ret = __os_read(env, rfhp, buf, MEGABYTE, &nr)) == 0 && - nr > 0) - if ((ret = __os_write(env, wfhp, buf, nr, &nw)) != 0) - break; - - if (0) { -err: ret = 1; - } -done: if (buf != NULL) - free(buf); - - if (rfhp != NULL && __os_closehandle(env, rfhp) != 0) - ret = 1; - - /* We may be running on a remote filesystem; force the flush. */ - if (wfhp != NULL) { - if (__os_fsync(env, wfhp) != 0) - ret = 1; - if (__os_closehandle(env, wfhp) != 0) - ret = 1; - } - return (ret); -} - -char *saved_prefix; -char *saved_errstr; -void save_error(dbenv, prefix, errstr) - const DB_ENV *dbenv; - const char *prefix; - const char *errstr; -{ - COMPQUIET(dbenv, NULL); - saved_prefix = strdup(prefix); - saved_errstr = strdup(errstr); -} - -/* - * env_data_copy -- - * Copy a file into the backup directory through the environment. - */ -int -env_data_copy(dbenv, file, to_dir, verbose, passwd) - DB_ENV *dbenv; - char *file, *to_dir; - int verbose; - const char *passwd; -{ - FILE *savefile; - int ret; - - ret = 0; - - if (verbose) - printf(DB_STR_A("5066", "%s: copying database %s to %s%c%s", - "%s %s %s %c %s"), progname, - file, to_dir, PATH_SEPARATOR[0], file); - - dbenv->set_errcall(dbenv, save_error); - dbenv->get_errfile(dbenv, &savefile); - dbenv->set_errfile(dbenv, NULL); - if ((ret = db_copy(dbenv, file, to_dir, passwd)) != 0) { - if (ret != ENOENT && ret != EINVAL) { - if (saved_errstr != NULL) - fprintf(stderr, "%s: %s\n", - saved_prefix, saved_errstr); - else - fprintf(stderr, " %s\n", db_strerror(ret)); - } else if (verbose) - printf(": not a database\n"); - - dbenv->set_errcall(dbenv, NULL); - dbenv->set_errfile(dbenv, savefile); - goto err; - } - dbenv->set_errcall(dbenv, NULL); - dbenv->set_errfile(dbenv, savefile); - - if (verbose) - printf("\n"); - -err: if (saved_prefix != NULL) - free(saved_prefix); - if (saved_errstr != NULL) - free(saved_errstr); - saved_prefix = saved_errstr = NULL; - return (ret); -} - int usage() { @@ -1147,9 +539,10 @@ version_check() /* Make sure we're loaded with the right version of the DB library. */ (void)db_version(&v_major, &v_minor, &v_patch); if (v_major != DB_VERSION_MAJOR || v_minor != DB_VERSION_MINOR) { + fprintf(stderr, "%s: ", progname); fprintf(stderr, DB_STR_A("5071", - "%s: version %d.%d doesn't match library version %d.%d\n", - "%s %d %d %d %d\n"), progname, + "version %d.%d doesn't match library version %d.%d\n", + "%d %d %d %d\n"), DB_VERSION_MAJOR, DB_VERSION_MINOR, v_major, v_minor); return (EXIT_FAILURE); diff --git a/util/db_load.c b/util/db_load.c index 4d78727d..af4c7800 100644 --- a/util/db_load.c +++ b/util/db_load.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -14,7 +14,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif typedef struct { /* XXX: Globals. */ @@ -77,9 +77,7 @@ main(argc, argv) else ++progname; - if ((exitval = version_check()) != 0) - goto done; - + clist = NULL; ldg.progname = progname; ldg.lineno = 0; ldg.endodata = ldg.endofile = 0; @@ -89,6 +87,9 @@ main(argc, argv) ldg.home = NULL; ldg.passwd = NULL; + if ((exitval = version_check()) != 0) + goto done; + mode = NOTSET; ldf = 0; exitval = existed = 0; @@ -209,7 +210,8 @@ main(argc, argv) goto done; case 'V': printf("%s\n", db_version(NULL, NULL, NULL)); - return (EXIT_SUCCESS); + exitval = (EXIT_SUCCESS); + goto done; case '?': default: exitval = usage(); @@ -263,7 +265,10 @@ err: exitval = 1; /* Resend any caught signal. */ __db_util_sigresend(); - free(clist); + +done: + if (clist != NULL) + free(clist); if (ldg.passwd != NULL) free(ldg.passwd); @@ -274,7 +279,6 @@ err: exitval = 1; * 0 is implementation-defined by the ANSI C standard. I don't see * any good solutions that don't involve API changes. */ -done: return (exitval == 0 ? (existed == 0 ? 0 : 1) : 2); } @@ -755,6 +759,7 @@ err: dbenv->err(dbenv, ret, "DB_ENV->open"); NUMBER(name, value, "extentsize", set_q_extentsize, u_int32_t); \ NUMBER(name, value, "h_ffactor", set_h_ffactor, u_int32_t); \ NUMBER(name, value, "h_nelem", set_h_nelem, u_int32_t); \ + NUMBER(name, value, "heap_regionsize", set_heap_regionsize, u_int32_t);\ NUMBER(name, value, "re_len", set_re_len, u_int32_t); \ STRING(name, value, "re_pad", set_re_pad); \ FLAG(name, value, "recnum", DB_RECNUM); \ diff --git a/util/db_log_verify.c b/util/db_log_verify.c index 518dfc2a..be4dd1de 100644 --- a/util/db_log_verify.c +++ b/util/db_log_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id: db_log_verify.c,v 0f73af5ae3da 2010/05/10 05:38:40 alexander $ */ diff --git a/util/db_printlog.c b/util/db_printlog.c index b5120b9b..03a8f375 100644 --- a/util/db_printlog.c +++ b/util/db_printlog.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -21,7 +21,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int db_printlog_print_app_record __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); @@ -101,6 +101,12 @@ main(argc, argv) nflag = 1; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5138", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { @@ -303,6 +309,10 @@ main(argc, argv) err: exitval = 1; } + if (dtab.int_dispatch != NULL) + __os_free(env, dtab.int_dispatch); + if (dtab.ext_dispatch != NULL) + __os_free(env, dtab.ext_dispatch); /* * Call __db_close to free the dummy DB handles that were used * by the print routines. @@ -631,8 +641,8 @@ open_rep_db(dbenv, dbpp, dbcp) } dbp = *dbpp; - if ((ret = - dbp->open(dbp, NULL, REPDBNAME, NULL, DB_BTREE, 0, 0)) != 0) { + if ((ret = dbp->open(dbp, NULL, + REPDBNAME, NULL, DB_BTREE, DB_RDONLY, 0)) != 0) { dbenv->err(dbenv, ret, "DB->open"); goto err; } diff --git a/util/db_recover.c b/util/db_recover.c index 20550de9..61657afa 100644 --- a/util/db_recover.c +++ b/util/db_recover.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif void db_recover_feedback __P((DB_ENV *, int, int)); @@ -63,6 +63,12 @@ main(argc, argv) home = optarg; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5137", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_replicate.c b/util/db_replicate.c index be7be62f..bb81dd6e 100644 --- a/util/db_replicate.c +++ b/util/db_replicate.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 2010, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); diff --git a/util/db_stat.c b/util/db_stat.c index a2f3943a..a12e1122 100644 --- a/util/db_stat.c +++ b/util/db_stat.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif typedef enum { T_NOTSET, T_DB, @@ -149,6 +149,12 @@ main(argc, argv) nflag = 1; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5139", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_stat/dd.sh b/util/db_stat/dd.sh index f6a1117d..f069506a 100644 --- a/util/db_stat/dd.sh +++ b/util/db_stat/dd.sh @@ -1,6 +1,6 @@ #! /bin/sh # -# Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2010,2012 Oracle and/or its affiliates. All rights reserved. # # Display environment's deadlocks based on "db_stat -Co" output. diff --git a/util/db_tuner.c b/util/db_tuner.c index 0ff51215..00fad903 100644 --- a/util/db_tuner.c +++ b/util/db_tuner.c @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ * @@ -54,7 +54,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif /* @@ -139,7 +139,6 @@ main(argc, argv) char *argv[]; { extern char *optarg; - extern int optind; DB *dbp; DB_ENV *dbenv; DBTYPE dbtype; diff --git a/util/db_upgrade.c b/util/db_upgrade.c index de39c639..8200322b 100644 --- a/util/db_upgrade.c +++ b/util/db_upgrade.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); @@ -55,6 +55,12 @@ main(argc, argv) nflag = 1; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5131", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { diff --git a/util/db_verify.c b/util/db_verify.c index 736ecc47..9ec28817 100644 --- a/util/db_verify.c +++ b/util/db_verify.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -12,7 +12,7 @@ #ifndef lint static const char copyright[] = - "Copyright (c) 1996, 2011 Oracle and/or its affiliates. All rights reserved.\n"; + "Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.\n"; #endif int main __P((int, char *[])); @@ -31,9 +31,9 @@ main(argc, argv) DB *dbp, *dbp1; DB_ENV *dbenv; u_int32_t flags, cache; - int ch, exitval, nflag, private; + int ch, exitval, mflag, nflag, private; int quiet, resize, ret; - char *home, *passwd; + char *dname, *fname, *home, *passwd; if ((progname = __db_rpath(argv[0])) == NULL) progname = argv[0]; @@ -46,18 +46,27 @@ main(argc, argv) dbenv = NULL; dbp = NULL; cache = MEGABYTE; - exitval = nflag = quiet = 0; + exitval = mflag = nflag = quiet = 0; flags = 0; home = passwd = NULL; - while ((ch = getopt(argc, argv, "h:NoP:quV")) != EOF) + while ((ch = getopt(argc, argv, "h:mNoP:quV")) != EOF) switch (ch) { case 'h': home = optarg; break; + case 'm': + mflag = 1; + break; case 'N': nflag = 1; break; case 'P': + if (passwd != NULL) { + fprintf(stderr, DB_STR("5132", + "Password may not be specified twice")); + free(passwd); + return (EXIT_FAILURE); + } passwd = strdup(optarg); memset(optarg, 0, strlen(optarg)); if (passwd == NULL) { @@ -88,6 +97,14 @@ main(argc, argv) if (argc <= 0) return (usage()); + if (mflag) { + dname = argv[0]; + fname = NULL; + } else { + fname = argv[0]; + dname = NULL; + } + /* Handle possible interruptions. */ __db_util_siginit(); @@ -187,7 +204,7 @@ retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { } ret = dbp1->open(dbp1, - NULL, argv[0], NULL, DB_UNKNOWN, DB_RDONLY, 0); + NULL, fname, dname, DB_UNKNOWN, DB_RDONLY, 0); /* * If we get here, we can check the cache/page. @@ -213,7 +230,7 @@ retry: if ((ret = db_env_create(&dbenv, 0)) != 0) { } /* The verify method is a destructor. */ - ret = dbp->verify(dbp, argv[0], NULL, NULL, flags); + ret = dbp->verify(dbp, fname, dname, NULL, flags); dbp = NULL; if (ret != 0) exitval = 1; diff --git a/util/dtrace/apicalls.d b/util/dtrace/apicalls.d index a6d3d0e5..7b6042cf 100755 --- a/util/dtrace/apicalls.d +++ b/util/dtrace/apicalls.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apicalls.d - Summarize DB API function calls * diff --git a/util/dtrace/apitimes.d b/util/dtrace/apitimes.d index 1d6c703d..bc34617e 100755 --- a/util/dtrace/apitimes.d +++ b/util/dtrace/apitimes.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apitimes.d - Summarize time spent in DB API functions * diff --git a/util/dtrace/apitrace.d b/util/dtrace/apitrace.d index c9258265..990f157b 100755 --- a/util/dtrace/apitrace.d +++ b/util/dtrace/apitrace.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -s /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apitrace.d - Trace the primary BDB API calls * diff --git a/util/dtrace/cache.d b/util/dtrace/cache.d index 1e118e0c..04ecaf7c 100755 --- a/util/dtrace/cache.d +++ b/util/dtrace/cache.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * cache.d - Display DB cache activity * diff --git a/util/dtrace/dbdefs.d b/util/dtrace/dbdefs.d index 38a68ca3..cc49c323 100755 --- a/util/dtrace/dbdefs.d +++ b/util/dtrace/dbdefs.d @@ -1,7 +1,7 @@ /* * See the file LICENSE for redistribution information. * - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * dbdefs.d - DTrace declarations of DB data structures. */ diff --git a/util/dtrace/locktimes.d b/util/dtrace/locktimes.d index b9664223..d89af0f2 100755 --- a/util/dtrace/locktimes.d +++ b/util/dtrace/locktimes.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * locktimesid.d - Display lock wait times grouped by filename. * diff --git a/util/dtrace/locktimesid.d b/util/dtrace/locktimesid.d index f5329faf..cc9477e5 100755 --- a/util/dtrace/locktimesid.d +++ b/util/dtrace/locktimesid.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * lockstimesi.d - Display lock wait times grouped by fileid. * diff --git a/util/dtrace/mutex.d b/util/dtrace/mutex.d index c9bd45f6..a78b7bc8 100755 --- a/util/dtrace/mutex.d +++ b/util/dtrace/mutex.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * mutex.d - Display DB mutex wait times. * diff --git a/util/dtrace/showerror.d b/util/dtrace/showerror.d index 5961837e..ebcc7f72 100755 --- a/util/dtrace/showerror.d +++ b/util/dtrace/showerror.d @@ -1,6 +1,6 @@ #!/usr/sbin/dtrace -qs /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * showerror.d - Capture context about certain DB errors. * diff --git a/util/systemtap/apicalls.stp b/util/systemtap/apicalls.stp index a8bf92ce..f593433a 100755 --- a/util/systemtap/apicalls.stp +++ b/util/systemtap/apicalls.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apicalls - Summarize DB API call count grouped by thread. * diff --git a/util/systemtap/apitimes.stp b/util/systemtap/apitimes.stp index c9d06da2..f038bb44 100755 --- a/util/systemtap/apitimes.stp +++ b/util/systemtap/apitimes.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apitimes - Graph the time spent in DB API calls grouped by thread or processid * diff --git a/util/systemtap/apitrace.stp b/util/systemtap/apitrace.stp index e69ee7b5..ffe66043 100755 --- a/util/systemtap/apitrace.stp +++ b/util/systemtap/apitrace.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * apitrace - Display DB API calls and return values * diff --git a/util/systemtap/cache.stp b/util/systemtap/cache.stp index c13451ec..8054f8d7 100755 --- a/util/systemtap/cache.stp +++ b/util/systemtap/cache.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * cache.stp - Display DB cache activity groups by file. * diff --git a/util/systemtap/locktimes.stp b/util/systemtap/locktimes.stp index 5997e4b8..ff23ca21 100755 --- a/util/systemtap/locktimes.stp +++ b/util/systemtap/locktimes.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * lockstimes.d - Display lock wait times grouped by filename * diff --git a/util/systemtap/locktimesid.stp b/util/systemtap/locktimesid.stp index 7c7df439..e9ad27f6 100755 --- a/util/systemtap/locktimesid.stp +++ b/util/systemtap/locktimesid.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * lockstimesid.d - Display lock wait times grouped by fileid. * diff --git a/util/systemtap/mutex.stp b/util/systemtap/mutex.stp index b615a401..5e3d50ee 100755 --- a/util/systemtap/mutex.stp +++ b/util/systemtap/mutex.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * mutex.stp - Display DB mutex wait times. * diff --git a/util/systemtap/showerror.stp b/util/systemtap/showerror.stp index 4c7fc433..e6886fa2 100755 --- a/util/systemtap/showerror.stp +++ b/util/systemtap/showerror.stp @@ -1,6 +1,6 @@ #!/usr/bin/stap /* - * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved. * * showerror.stp - Capture context about certain DB errors. *