Skip to content

Commit b063820

Browse files
committed
Check local sequential consistency in dbsim
- Release commit time critical section in callback - Check the consistency inside commit order critical section Other: Add 2pc switch to dbsim
1 parent 3de594b commit b063820

8 files changed

+115
-43
lines changed

Diff for: dbsim/db_client.cpp

+34-5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ int db::client::client_command(F f)
9191
return err;
9292
}
9393

94+
static void release_commit_critical_section(void* ptr)
95+
{
96+
auto* crit = static_cast<db::server::commit_critical_section*>(ptr);
97+
if (crit->lock.owns_lock())
98+
{
99+
crit->lock.unlock();
100+
}
101+
}
102+
94103
void db::client::run_one_transaction()
95104
{
96105
if (params_.sync_wait)
@@ -145,15 +154,35 @@ void db::client::run_one_transaction()
145154
err = err || client_command(
146155
[&]()
147156
{
148-
// wsrep::log_debug() << "Commit";
157+
auto commit_crit = server_.get_commit_critical_section();
158+
if (not params_.check_sequential_consistency) {
159+
commit_crit.lock.unlock();
160+
}
161+
162+
client_state_.append_data({&commit_crit.commit_seqno,
163+
sizeof(commit_crit.commit_seqno)});
164+
165+
wsrep::provider::seq_cb seq_cb {
166+
&commit_crit,
167+
release_commit_critical_section
168+
};
169+
149170
assert(err == 0);
150-
if (do_2pc())
171+
if (params_.do_2pc)
151172
{
152-
err = err || client_state_.before_prepare();
173+
err = err || client_state_.before_prepare(&seq_cb);
153174
err = err || client_state_.after_prepare();
154175
}
155-
err = err || client_state_.before_commit();
156-
if (err == 0) se_trx_.commit(transaction.ws_meta().gtid());
176+
err = err || client_state_.before_commit(&seq_cb);
177+
if (err == 0)
178+
{
179+
se_trx_.commit(transaction.ws_meta().gtid());
180+
if (params_.check_sequential_consistency)
181+
{
182+
server_.check_sequential_consistency(
183+
client_state_.id(), commit_crit.commit_seqno);
184+
}
185+
}
157186
err = err || client_state_.ordered_commit();
158187
err = err || client_state_.after_commit();
159188
if (err)

Diff for: dbsim/db_client.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ namespace db
6262
void start();
6363
wsrep::client_state& client_state() { return client_state_; }
6464
wsrep::client_service& client_service() { return client_service_; }
65-
bool do_2pc() const { return false; }
6665
private:
6766
friend class db::server_state;
6867
friend class db::client_service;

Diff for: dbsim/db_high_priority_service.cpp

+12-1
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ int db::high_priority_service::adopt_transaction(const wsrep::transaction&)
5252

5353
int db::high_priority_service::apply_write_set(
5454
const wsrep::ws_meta&,
55-
const wsrep::const_buffer&,
55+
const wsrep::const_buffer& buf,
5656
wsrep::mutable_buffer&)
5757
{
5858
client_.se_trx_.start(&client_);
5959
client_.se_trx_.apply(client_.client_state().transaction());
60+
assert(buf.size() > sizeof(uint64_t));
61+
::memcpy(&commit_seqno_, buf.data() + buf.size() - sizeof(uint64_t),
62+
sizeof(uint64_t));
6063
return 0;
6164
}
6265

@@ -82,6 +85,14 @@ int db::high_priority_service::commit(const wsrep::ws_handle& ws_handle,
8285
client_.client_state_.prepare_for_ordering(ws_handle, ws_meta, true);
8386
int ret(client_.client_state_.before_commit());
8487
if (ret == 0) client_.se_trx_.commit(ws_meta.gtid());
88+
89+
/* Local client session replaying. */
90+
if (ws_meta.server_id() == server_.server_state().id()
91+
&& client_.params_.check_sequential_consistency)
92+
{
93+
server_.check_sequential_consistency(ws_meta.client_id(),
94+
commit_seqno_);
95+
}
8596
ret = ret || client_.client_state_.ordered_commit();
8697
ret = ret || client_.client_state_.after_commit();
8798
return ret;

Diff for: dbsim/db_high_priority_service.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ namespace db
6969
high_priority_service& operator=(const high_priority_service&);
7070
db::server& server_;
7171
db::client& client_;
72+
uint64_t commit_seqno_;
7273
};
7374

7475
class replayer_service : public db::high_priority_service

Diff for: dbsim/db_params.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ db::params db::parse_args(int argc, char** argv)
9595
"Configure TLS service stubs.\n0 default disabled\n1 enabled\n"
9696
"2 enabled with short read/write and renegotiation simulation\n"
9797
"3 enabled with error simulation.")
98+
("check-sequential-consistency",
99+
po::value<bool>(&params.check_sequential_consistency),
100+
"Check if the provider provides sequential consistency")
101+
("do-2pc",
102+
po::value<bool>(&params.do_2pc),
103+
"Run commits in 2pc")
98104
;
99105
try
100106
{

Diff for: dbsim/db_params.hpp

+21-36
Original file line numberDiff line numberDiff line change
@@ -27,42 +27,27 @@ namespace db
2727
{
2828
struct params
2929
{
30-
size_t n_servers;
31-
size_t n_clients;
32-
size_t n_transactions;
33-
size_t n_rows;
34-
size_t max_data_size; // Maximum size of write set data payload.
35-
bool random_data_size; // If true, randomize data payload size.
36-
size_t alg_freq;
37-
bool sync_wait;
38-
std::string topology;
39-
std::string wsrep_provider;
40-
std::string wsrep_provider_options;
41-
std::string status_file;
42-
int debug_log_level;
43-
int fast_exit;
44-
int thread_instrumentation;
45-
bool cond_checks;
46-
int tls_service;
47-
params()
48-
: n_servers(0)
49-
, n_clients(0)
50-
, n_transactions(0)
51-
, n_rows(1000)
52-
, max_data_size(8)
53-
, random_data_size(false)
54-
, alg_freq(0)
55-
, sync_wait(false)
56-
, topology()
57-
, wsrep_provider()
58-
, wsrep_provider_options()
59-
, status_file("status.json")
60-
, debug_log_level(0)
61-
, fast_exit(0)
62-
, thread_instrumentation()
63-
, cond_checks()
64-
, tls_service()
65-
{ }
30+
size_t n_servers{0};
31+
size_t n_clients{0};
32+
size_t n_transactions{0};
33+
size_t n_rows{1000};
34+
size_t max_data_size{8}; // Maximum size of write set data payload.
35+
bool random_data_size{false}; // If true, randomize data payload size.
36+
/* Asymmetric lock granularity frequency. */
37+
size_t alg_freq{0};
38+
/* Whether to sync wait before start of transaction. */
39+
bool sync_wait{false};
40+
std::string topology{};
41+
std::string wsrep_provider{};
42+
std::string wsrep_provider_options{};
43+
std::string status_file{"status.json"};
44+
int debug_log_level{0};
45+
int fast_exit{0};
46+
int thread_instrumentation{0};
47+
bool cond_checks{false};
48+
int tls_service{0};
49+
bool check_sequential_consistency{false};
50+
bool do_2pc{false};
6651
};
6752

6853
params parse_args(int argc, char** argv);

Diff for: dbsim/db_server.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ db::server::server(simulator& simulator,
6868
, appliers_()
6969
, clients_()
7070
, client_threads_()
71+
, commit_mutex_()
72+
, next_commit_seqno_()
73+
, committed_seqno_()
7174
{
7275
wsrep::log::logger_fn(logger_fn);
7376
}
@@ -165,3 +168,16 @@ void db::server::log_state_change(enum wsrep::server_state::state from,
165168
wsrep::log_info() << "State changed " << from << " -> " << to;
166169
reporter_.report_state(to);
167170
}
171+
172+
void db::server::check_sequential_consistency(wsrep::client_id client_id,
173+
uint64_t commit_seqno)
174+
{
175+
if (committed_seqno_ >= commit_seqno)
176+
{
177+
wsrep::log_error() << "Sequentiality violation for " << client_id
178+
<< " commit seqno " << commit_seqno << " previous "
179+
<< committed_seqno_;
180+
::abort();
181+
}
182+
committed_seqno_ = commit_seqno;
183+
}

Diff for: dbsim/db_server.hpp

+25
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,27 @@ namespace db
6161
wsrep::high_priority_service* streaming_applier_service();
6262
void log_state_change(enum wsrep::server_state::state,
6363
enum wsrep::server_state::state);
64+
65+
/* Sequential consistency checks */
66+
struct commit_critical_section
67+
{
68+
wsrep::unique_lock<wsrep::default_mutex> lock;
69+
uint64_t commit_seqno;
70+
commit_critical_section(wsrep::default_mutex& mutex,
71+
uint64_t& next_commit_seqno)
72+
: lock{ mutex }
73+
, commit_seqno{ ++next_commit_seqno }
74+
{
75+
}
76+
commit_critical_section(commit_critical_section&&) = default;
77+
};
78+
commit_critical_section get_commit_critical_section() {
79+
return { commit_mutex_, next_commit_seqno_ };
80+
}
81+
/* Check that commits remain sequential according commit_seqno.
82+
* This method must be called inside commit order critical section. */
83+
void check_sequential_consistency(wsrep::client_id client_id,
84+
uint64_t commit_seqno);
6485
private:
6586
void start_client(size_t id);
6687

@@ -76,6 +97,10 @@ namespace db
7697
std::vector<boost::thread> appliers_;
7798
std::vector<std::shared_ptr<db::client>> clients_;
7899
std::vector<boost::thread> client_threads_;
100+
101+
wsrep::default_mutex commit_mutex_;
102+
uint64_t next_commit_seqno_;
103+
uint64_t committed_seqno_;
79104
};
80105
}
81106

0 commit comments

Comments
 (0)