Access to empty vector by using operator[] may cause stdlib++
assertions to fail. Replaced the vector data access to use data()
method which is valid operation even if the vector is empty.
Added unit test to reproduce assertion with empty mutable_buffer access.
Added -D_GLIBCXX_ASSERTIONS preprocessor option to debug builds
to catch standard library misuse.
Added gcc 8 and gcc9 into travis build matrix.
- Do not use [[noreturn]] with GCC older than 4.8.
- Use if/else instead of ternary operator in transaction
commit_or_rollback_by_xid() to avoid debug build failure with
GCC 4.7.
Remove methods `is_xa()`, `is_xa_prepare()`, and `xid()` from
client_service interface. Instead, transactions are explicitly
assigned their xid, through at start of XA.
* Add method `restore_prepared_transaction` to `client_state` class
which restores a transaction state from storage given its xid.
* Add method `commit_or_rollback_by_xid` to terminate prepared XA
transactions by xid.
* Make sure that transactions in prepared state are not rolled back
when their master fails/partitions away.
Class streaming_context can now keep track of database specific log
position for streaming. Previously, it was assumed that the log
position was based of off the buffer size which was filled in
client_service::prepare_fragment_for_replication(). However, for XA
the buffer may contain data that is not in the log. Therefore,
subsequent calls to prepare_fragment_for_replication() could not find
the appropriate log_position based on the certified_bytes(), which
would returns the total number of bytes return in the buffers that
were certified.
next_fragment is called outside the scope of a high_priority_switch,
and we may be in a different thread context then the streaming applier
was created in
Force fragment replication when XA transaction is prepared, with
prepare fragment. Commit fragment happens in before_commit().
Adjusted fragment removal, which cannot happen in atomically with the
executing transaction.
Added a wsrep::thread_service interface to allow application to
inject instrumented thread, mutex and condition variable implementation
for provider.
The interface is defined in include/wsrep/thread_service.hpp.
Sample implementation is provided in dbsim/db_threads.[h|c]pp.
This patch will also clean up some remaining dependencies to
wsrep-API compilation units so that the dependency to wsrep-API
is header only. This will extending the provider support to
later wsrep-API versions.
In convert_streaming_client_to_applier() the new streaming applier
is created and deleted if the server has been disconnected. However,
releasing streaming applier may modify thread local storage. Call
store_globals() to restore thread local storage before returning.
Sanity checks to detect concurrency bugs were assuming a threading
model where each client state would always be processed within
single thread of execution. This however may be too strong assumption
if the application uses some kind of thread pooling.
This patch relaxes those assumptions by removing current_thread_id_
from client_state and relaxing assertions against owning_thread_id_.
This patch also adds a new method
wait_rollback_complete_and_acquire_ownership() into
client_state. This method is idempotent and can be used to gain
control to client_state before before_command() is called.
The method will wait until possible background rollback process is
over and marks the state to s_exec to protect the state against
new background rollbacks.
Other fixes/improvements:
- High priority globals state is restored after discarding streaming.
- Allowed server_state transition donor -> synced.
- Client state method store_globals() was renamed to acquire_ownership()
to better describe the intent. Method store_globals() was left for
backwards compatibility and marked deprecated.
- populate and pass real error description buffer to provider in case
of applying error
- return 0 from server_state::on_apply() if error voting confirmed
consistency
- remove fragments and rollback after fragment applying failure
- always release streaming applier on commit or rollback
Added version header which contains definitions for major, minor
and patch version numbers, as well as for lowest and highest supported
wsrep-API versions. The library versioning follows Semantic Versioning.
Handle CMake policy CMP0048 in top level CMakeLists.txt.
Write wsrep-lib logging facility output from unit tests into file.
The argument --wsrep-log-file can be controlled where the
log from wsrep-lib is written during unit tests. The default is
'wsrep-lib_test.log' in the working directory. In order to
get the log written into stdout, use empty value,
i.e. --wsrep-log-file=''.
Made travis test run a bit more verbose.
Fixes a bug where the fact that an SR master leaves the primary view
gets missed. When two consecutive primary views have the same
membership we now assume that every SR needs to be rolled back, as the
system may have been through a state of only non-primary components.
If abort_or_interrupt() is called in aborting or aborted state,
investigate if the transaction was BF aborted. If yes, raise the
deadlock error if error has not been set yet and assert in debug build.
Changed prev_state variable name to state_at_enter in transaction
bf_abort(), and use only that variable to determine transaction
state in the rest of the method.
Moved the check for transaction state before certification step
into separate method abort_or_interrupted() which will check the state
and adjust state and client_state error status accordingly.
Moved the check for abort_or_interrupted() to happen before
the state is changed to certifying and write set data is appended.
This makes the check atomic and reduces the probability of race
conditions. After this check we rely on provider side transaction
state management and error reporting until the certification step
is over.
Change to public API: Pass client_state mutex wrappend in unique_lock
object to client_service::interrupted() call. This way the DBMS side
has a control to the lock object in case it needs to unlock it
temporarily. The underlying mutex will always be locked when the lock
object is passed via interrupted() call.
Other: Allow server_state change from donor to connected. This may
happen if the joiner crashes during SST and the provider reports
it before the DBMS side SST mechanism detects the error.
The streaming_rollback() was not called from transaction::bf_abort()
if a streaming transaction was BF aborted in executing state. This
was because the condition to enter streaming_rollback() checked
if the transaction state is executing. However, the transaction
state had already been changed to must_abort before.
As a fix, save the state to local variable when entering
bf_abort() and check against saved state in condition to enter
streaming_rollback().
Added unit test for the correct behavior in the case when streaming
transaction is BF aborted in executing state.
Silenced warning about failing to replicate rollback fragment.
This is pretty normal condition and may happen during shutdown/
configuration changes when SR transactions are rolled back.
If the application uses caching for client sessions, the
client_state object may be reused. This will cause the opened
client session to have unexpected value for sync_wait_gtid and
last_written_gtid.
In order to work around the problem, reset sync_wait_gtid and
last_written_gtid in client_state::open().
A high priority transaction T2 which calls commit_order_enter() with
client_state mutex locked may cause a deadlock if an another high
priority transaction T1 ordered before tries to access the transaction
T2 state.
As a fix, make sure that commit_order_enter() is never called with
client_state mutex locked.