@ -301,7 +301,7 @@ void StressTest::FinishInitDb(SharedState* shared) {
exit ( 1 ) ;
exit ( 1 ) ;
}
}
}
}
if ( FLAGS_use_txn ) {
if ( FLAGS_use_txn & & ! FLAGS_use_optimistic_txn ) {
// It's OK here without sync because unsynced data cannot be lost at this
// It's OK here without sync because unsynced data cannot be lost at this
// point
// point
// - even with sync_fault_injection=1 as the
// - even with sync_fault_injection=1 as the
@ -556,6 +556,7 @@ void StressTest::PreloadDbAndReopenAsReadOnly(int64_t number_of_keys,
delete db_ ;
delete db_ ;
db_ = nullptr ;
db_ = nullptr ;
txn_db_ = nullptr ;
txn_db_ = nullptr ;
optimistic_txn_db_ = nullptr ;
db_preload_finished_ . store ( true ) ;
db_preload_finished_ . store ( true ) ;
auto now = clock_ - > NowMicros ( ) ;
auto now = clock_ - > NowMicros ( ) ;
@ -634,55 +635,66 @@ Status StressTest::NewTxn(WriteOptions& write_opts, Transaction** txn) {
}
}
write_opts . disableWAL = FLAGS_disable_wal ;
write_opts . disableWAL = FLAGS_disable_wal ;
static std : : atomic < uint64_t > txn_id = { 0 } ;
static std : : atomic < uint64_t > txn_id = { 0 } ;
TransactionOptions txn_options ;
if ( FLAGS_use_optimistic_txn ) {
txn_options . use_only_the_last_commit_time_batch_for_recovery =
* txn = optimistic_txn_db_ - > BeginTransaction ( write_opts ) ;
FLAGS_use_only_the_last_commit_time_batch_for_recovery ;
return Status : : OK ( ) ;
txn_options . lock_timeout = 600000 ; // 10 min
} else {
txn_options . deadlock_detect = true ;
TransactionOptions txn_options ;
* txn = txn_db_ - > BeginTransaction ( write_opts , txn_options ) ;
txn_options . use_only_the_last_commit_time_batch_for_recovery =
auto istr = std : : to_string ( txn_id . fetch_add ( 1 ) ) ;
FLAGS_use_only_the_last_commit_time_batch_for_recovery ;
Status s = ( * txn ) - > SetName ( " xid " + istr ) ;
txn_options . lock_timeout = 600000 ; // 10 min
return s ;
txn_options . deadlock_detect = true ;
* txn = txn_db_ - > BeginTransaction ( write_opts , txn_options ) ;
auto istr = std : : to_string ( txn_id . fetch_add ( 1 ) ) ;
Status s = ( * txn ) - > SetName ( " xid " + istr ) ;
return s ;
}
}
}
Status StressTest : : CommitTxn ( Transaction * txn , ThreadState * thread ) {
Status StressTest : : CommitTxn ( Transaction * txn , ThreadState * thread ) {
if ( ! FLAGS_use_txn ) {
if ( ! FLAGS_use_txn ) {
return Status : : InvalidArgument ( " CommitTxn when FLAGS_use_txn is not set " ) ;
return Status : : InvalidArgument ( " CommitTxn when FLAGS_use_txn is not set " ) ;
}
}
assert ( txn_db_ ) ;
Status s = Status : : OK ( ) ;
Status s = txn - > Prepare ( ) ;
if ( FLAGS_use_optimistic_txn ) {
std : : shared_ptr < const Snapshot > timestamped_snapshot ;
assert ( optimistic_txn_db_ ) ;
if ( s . ok ( ) ) {
s = txn - > Commit ( ) ;
if ( thread & & FLAGS_create_timestamped_snapshot_one_in & &
} else {
thread - > rand . OneIn ( FLAGS_create_timestamped_snapshot_one_in ) ) {
assert ( txn_db_ ) ;
uint64_t ts = db_stress_env - > NowNanos ( ) ;
s = txn - > Prepare ( ) ;
s = txn - > CommitAndTryCreateSnapshot ( /*notifier=*/ nullptr , ts ,
std : : shared_ptr < const Snapshot > timestamped_snapshot ;
& timestamped_snapshot ) ;
if ( s . ok ( ) ) {
if ( thread & & FLAGS_create_timestamped_snapshot_one_in & &
std : : pair < Status , std : : shared_ptr < const Snapshot > > res ;
thread - > rand . OneIn ( FLAGS_create_timestamped_snapshot_one_in ) ) {
if ( thread - > tid = = 0 ) {
uint64_t ts = db_stress_env - > NowNanos ( ) ;
uint64_t now = db_stress_env - > NowNanos ( ) ;
s = txn - > CommitAndTryCreateSnapshot ( /*notifier=*/ nullptr , ts ,
res = txn_db_ - > CreateTimestampedSnapshot ( now ) ;
& timestamped_snapshot ) ;
if ( res . first . ok ( ) ) {
assert ( res . second ) ;
std : : pair < Status , std : : shared_ptr < const Snapshot > > res ;
assert ( res . second - > GetTimestamp ( ) = = now ) ;
if ( thread - > tid = = 0 ) {
if ( timestamped_snapshot ) {
uint64_t now = db_stress_env - > NowNanos ( ) ;
assert ( res . second - > GetTimestamp ( ) >
res = txn_db_ - > CreateTimestampedSnapshot ( now ) ;
timestamped_snapshot - > GetTimestamp ( ) ) ;
if ( res . first . ok ( ) ) {
assert ( res . second ) ;
assert ( res . second - > GetTimestamp ( ) = = now ) ;
if ( timestamped_snapshot ) {
assert ( res . second - > GetTimestamp ( ) >
timestamped_snapshot - > GetTimestamp ( ) ) ;
}
} else {
assert ( ! res . second ) ;
}
}
} else {
assert ( ! res . second ) ;
}
}
} else {
s = txn - > Commit ( ) ;
}
}
} else {
s = txn - > Commit ( ) ;
}
}
}
if ( thread & & FLAGS_create_timestamped_snapshot_one_in > 0 & &
if ( thread & & FLAGS_create_timestamped_snapshot_one_in > 0 & &
thread - > rand . OneInOpt ( 50000 ) ) {
thread - > rand . OneInOpt ( 50000 ) ) {
uint64_t now = db_stress_env - > NowNanos ( ) ;
uint64_t now = db_stress_env - > NowNanos ( ) ;
constexpr uint64_t time_diff = static_cast < uint64_t > ( 1000 ) * 1000 * 1000 ;
constexpr uint64_t time_diff = static_cast < uint64_t > ( 1000 ) * 1000 * 1000 ;
txn_db_ - > ReleaseTimestampedSnapshotsOlderThan ( now - time_diff ) ;
txn_db_ - > ReleaseTimestampedSnapshotsOlderThan ( now - time_diff ) ;
}
}
}
delete txn ;
delete txn ;
return s ;
return s ;
@ -2311,24 +2323,39 @@ void StressTest::PrintEnv() const {
fprintf ( stdout , " Format version : %d \n " , FLAGS_format_version ) ;
fprintf ( stdout , " Format version : %d \n " , FLAGS_format_version ) ;
fprintf ( stdout , " TransactionDB : %s \n " ,
fprintf ( stdout , " TransactionDB : %s \n " ,
FLAGS_use_txn ? " true " : " false " ) ;
FLAGS_use_txn ? " true " : " false " ) ;
if ( FLAGS_use_txn ) {
if ( FLAGS_use_txn ) {
fprintf ( stdout , " Two write queues: : %s \n " ,
fprintf ( stdout , " TransactionDB Type : %s \n " ,
FLAGS_two_write_queues ? " true " : " false " ) ;
FLAGS_use_optimistic_txn ? " Optimistic " : " Pessimistic " ) ;
fprintf ( stdout , " Write policy : %d \n " ,
if ( FLAGS_use_optimistic_txn ) {
static_cast < int > ( FLAGS_txn_write_policy ) ) ;
fprintf ( stdout , " OCC Validation Type : %d \n " ,
if ( static_cast < uint64_t > ( TxnDBWritePolicy : : WRITE_PREPARED ) = =
static_cast < int > ( FLAGS_occ_validation_policy ) ) ;
FLAGS_txn_write_policy | |
if ( static_cast < uint64_t > ( OccValidationPolicy : : kValidateParallel ) = =
static_cast < uint64_t > ( TxnDBWritePolicy : : WRITE_UNPREPARED ) = =
FLAGS_occ_validation_policy ) {
FLAGS_txn_write_policy ) {
fprintf ( stdout , " Share Lock Buckets : %s \n " ,
fprintf ( stdout , " Snapshot cache bits : %d \n " ,
FLAGS_share_occ_lock_buckets ? " true " : " false " ) ;
static_cast < int > ( FLAGS_wp_snapshot_cache_bits ) ) ;
if ( FLAGS_share_occ_lock_buckets ) {
fprintf ( stdout , " Commit cache bits : %d \n " ,
fprintf ( stdout , " Lock Bucket Count : %d \n " ,
static_cast < int > ( FLAGS_wp_commit_cache_bits ) ) ;
static_cast < int > ( FLAGS_occ_lock_bucket_count ) ) ;
}
}
fprintf ( stdout , " last cwb for recovery : %s \n " ,
}
FLAGS_use_only_the_last_commit_time_batch_for_recovery ? " true "
} else {
: " false " ) ;
fprintf ( stdout , " Two write queues: : %s \n " ,
FLAGS_two_write_queues ? " true " : " false " ) ;
fprintf ( stdout , " Write policy : %d \n " ,
static_cast < int > ( FLAGS_txn_write_policy ) ) ;
if ( static_cast < uint64_t > ( TxnDBWritePolicy : : WRITE_PREPARED ) = =
FLAGS_txn_write_policy | |
static_cast < uint64_t > ( TxnDBWritePolicy : : WRITE_UNPREPARED ) = =
FLAGS_txn_write_policy ) {
fprintf ( stdout , " Snapshot cache bits : %d \n " ,
static_cast < int > ( FLAGS_wp_snapshot_cache_bits ) ) ;
fprintf ( stdout , " Commit cache bits : %d \n " ,
static_cast < int > ( FLAGS_wp_commit_cache_bits ) ) ;
}
fprintf ( stdout , " last cwb for recovery : %s \n " ,
FLAGS_use_only_the_last_commit_time_batch_for_recovery ? " true "
: " false " ) ;
}
}
}
fprintf ( stdout , " Stacked BlobDB : %s \n " ,
fprintf ( stdout , " Stacked BlobDB : %s \n " ,
@ -2477,6 +2504,7 @@ void StressTest::PrintEnv() const {
void StressTest : : Open ( SharedState * shared ) {
void StressTest : : Open ( SharedState * shared ) {
assert ( db_ = = nullptr ) ;
assert ( db_ = = nullptr ) ;
assert ( txn_db_ = = nullptr ) ;
assert ( txn_db_ = = nullptr ) ;
assert ( optimistic_txn_db_ = = nullptr ) ;
if ( ! InitializeOptionsFromFile ( options_ ) ) {
if ( ! InitializeOptionsFromFile ( options_ ) ) {
InitializeOptionsFromFlags ( cache_ , filter_policy_ , options_ ) ;
InitializeOptionsFromFlags ( cache_ , filter_policy_ , options_ ) ;
}
}
@ -2704,36 +2732,65 @@ void StressTest::Open(SharedState* shared) {
break ;
break ;
}
}
} else {
} else {
TransactionDBOptions txn_db_options ;
if ( FLAGS_use_optimistic_txn ) {
assert ( FLAGS_txn_write_policy < = TxnDBWritePolicy : : WRITE_UNPREPARED ) ;
OptimisticTransactionDBOptions optimistic_txn_db_options ;
txn_db_options . write_policy =
optimistic_txn_db_options . validate_policy =
static_cast < TxnDBWritePolicy > ( FLAGS_txn_write_policy ) ;
static_cast < OccValidationPolicy > ( FLAGS_occ_validation_policy ) ;
if ( FLAGS_unordered_write ) {
assert ( txn_db_options . write_policy = = TxnDBWritePolicy : : WRITE_PREPARED ) ;
if ( FLAGS_share_occ_lock_buckets ) {
options_ . unordered_write = true ;
optimistic_txn_db_options . shared_lock_buckets =
options_ . two_write_queues = true ;
MakeSharedOccLockBuckets ( FLAGS_occ_lock_bucket_count ) ;
txn_db_options . skip_concurrency_control = true ;
} else {
optimistic_txn_db_options . occ_lock_buckets =
FLAGS_occ_lock_bucket_count ;
optimistic_txn_db_options . shared_lock_buckets = nullptr ;
}
s = OptimisticTransactionDB : : Open (
options_ , optimistic_txn_db_options , FLAGS_db , cf_descriptors ,
& column_families_ , & optimistic_txn_db_ ) ;
if ( ! s . ok ( ) ) {
fprintf ( stderr , " Error in opening the OptimisticTransactionDB [%s] \n " ,
s . ToString ( ) . c_str ( ) ) ;
fflush ( stderr ) ;
}
assert ( s . ok ( ) ) ;
{
db_ = optimistic_txn_db_ ;
db_aptr_ . store ( optimistic_txn_db_ , std : : memory_order_release ) ;
}
} else {
} else {
options_ . two_write_queues = FLAGS_two_write_queues ;
TransactionDBOptions txn_db_options ;
}
assert ( FLAGS_txn_write_policy < = TxnDBWritePolicy : : WRITE_UNPREPARED ) ;
txn_db_options . wp_snapshot_cache_bits =
txn_db_options . write_policy =
static_cast < size_t > ( FLAGS_wp_snapshot_cache_bits ) ;
static_cast < TxnDBWritePolicy > ( FLAGS_txn_write_policy ) ;
txn_db_options . wp_commit_cache_bits =
if ( FLAGS_unordered_write ) {
static_cast < size_t > ( FLAGS_wp_commit_cache_bits ) ;
assert ( txn_db_options . write_policy = =
PrepareTxnDbOptions ( shared , txn_db_options ) ;
TxnDBWritePolicy : : WRITE_PREPARED ) ;
s = TransactionDB : : Open ( options_ , txn_db_options , FLAGS_db ,
options_ . unordered_write = true ;
cf_descriptors , & column_families_ , & txn_db_ ) ;
options_ . two_write_queues = true ;
if ( ! s . ok ( ) ) {
txn_db_options . skip_concurrency_control = true ;
fprintf ( stderr , " Error in opening the TransactionDB [%s] \n " ,
} else {
s . ToString ( ) . c_str ( ) ) ;
options_ . two_write_queues = FLAGS_two_write_queues ;
fflush ( stderr ) ;
}
}
txn_db_options . wp_snapshot_cache_bits =
assert ( s . ok ( ) ) ;
static_cast < size_t > ( FLAGS_wp_snapshot_cache_bits ) ;
txn_db_options . wp_commit_cache_bits =
static_cast < size_t > ( FLAGS_wp_commit_cache_bits ) ;
PrepareTxnDbOptions ( shared , txn_db_options ) ;
s = TransactionDB : : Open ( options_ , txn_db_options , FLAGS_db ,
cf_descriptors , & column_families_ , & txn_db_ ) ;
if ( ! s . ok ( ) ) {
fprintf ( stderr , " Error in opening the TransactionDB [%s] \n " ,
s . ToString ( ) . c_str ( ) ) ;
fflush ( stderr ) ;
}
assert ( s . ok ( ) ) ;
// Do not swap the order of the following.
// Do not swap the order of the following.
{
{
db_ = txn_db_ ;
db_ = txn_db_ ;
db_aptr_ . store ( txn_db_ , std : : memory_order_release ) ;
db_aptr_ . store ( txn_db_ , std : : memory_order_release ) ;
}
}
}
}
}
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -2811,10 +2868,12 @@ void StressTest::Reopen(ThreadState* thread) {
}
}
assert ( s . ok ( ) ) ;
assert ( s . ok ( ) ) ;
}
}
assert ( txn_db_ = = nullptr | | db_ = = txn_db_ ) ;
assert ( ( txn_db_ = = nullptr & & optimistic_txn_db_ = = nullptr ) | |
( db_ = = txn_db_ | | db_ = = optimistic_txn_db_ ) ) ;
delete db_ ;
delete db_ ;
db_ = nullptr ;
db_ = nullptr ;
txn_db_ = nullptr ;
txn_db_ = nullptr ;
optimistic_txn_db_ = nullptr ;
num_times_reopened_ + + ;
num_times_reopened_ + + ;
auto now = clock_ - > NowMicros ( ) ;
auto now = clock_ - > NowMicros ( ) ;