Skip to content

Commit

Permalink
Extend read library
Browse files Browse the repository at this point in the history
  • Loading branch information
romz-pl committed Sep 3, 2019
1 parent 19515a0 commit 8f47e27
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 227 deletions.
1 change: 0 additions & 1 deletion storage/innobase/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ SET(INNOBASE_SOURCES
pars/pars0pars.cc
pars/pars0sym.cc
que/que0que.cc
read/read0read.cc
row/row0ext.cc
row/row0ftsort.cc
row/row0import.cc
Expand Down
8 changes: 1 addition & 7 deletions storage/innobase/include/trx0trx.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,13 +445,7 @@ from innodb_lock_wait_timeout via trx_t::mysql_thd.
@return lock wait timeout in seconds */
#define trx_lock_wait_timeout_get(t) thd_lock_wait_timeout((t)->mysql_thd)

/**
Determine if the transaction is a non-locking autocommit select
(implied read-only).
@param t transaction
@return true if non-locking autocommit select transaction. */
#define trx_is_autocommit_non_locking(t) \
((t)->auto_commit && (t)->will_lock == 0)
#include <innodb/trx_trx/trx_is_autocommit_non_locking.h>

/**
Determine if the transaction is a non-locking autocommit select
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/libs/read/include/innodb/read/ReadView.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class ReadView {
Opens a read view where exactly the transactions serialized before this
point in time are seen in the view.
@param id Creator transaction id */
inline void prepare(trx_id_t id);
void prepare(trx_id_t id);

/**
Copy state from another view. Must call copy_complete() to finish.
Expand Down
125 changes: 124 additions & 1 deletion storage/innobase/libs/read/src/MVCC.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#include <innodb/read/MVCC.h>

#include <innodb/allocator/UT_DELETE.h>
#include <innodb/read/ReadView.h>
#include <innodb/allocator/UT_NEW_NOKEY.h>
#include <innodb/logger/error.h>
#include <innodb/read/ReadView.h>
#include <innodb/sync_mutex/mutex_enter.h>
#include <innodb/trx_sys/trx_sys.h>
#include <innodb/trx_sys/trx_sys_get_max_trx_id.h>
#include <innodb/trx_sys/trx_sys_mutex_exit.h>
#include <innodb/trx_trx/trx_is_autocommit_non_locking.h>
#include <innodb/trx_trx/trx_t.h>
#include <innodb/trx_sys/trx_sys_mutex_enter.h>

/** Constructor
@param size Number of views to pre-allocate */
Expand Down Expand Up @@ -169,3 +176,119 @@ void MVCC::view_close(ReadView *&view, bool own_mutex) {
}
}

/**
Allocate and create a view.
@param view view owned by this class created for the
caller. Must be freed by calling view_close()
@param trx transaction instance of caller */
void MVCC::view_open(ReadView *&view, trx_t *trx) {
ut_ad(!srv_read_only_mode);

/** If no new RW transaction has been started since the last view
was created then reuse the the existing view. */
if (view != NULL) {
uintptr_t p = reinterpret_cast<uintptr_t>(view);

view = reinterpret_cast<ReadView *>(p & ~1);

ut_ad(view->m_closed);

/* NOTE: This can be optimised further, for now we only
resuse the view iff there are no active RW transactions.
There is an inherent race here between purge and this
thread. Purge will skip views that are marked as closed.
Therefore we must set the low limit id after we reset the
closed status after the check. */

if (trx_is_autocommit_non_locking(trx) && view->empty()) {
view->m_closed = false;

if (view->m_low_limit_id == trx_sys_get_max_trx_id()) {
return;
} else {
view->m_closed = true;
}
}

mutex_enter(&trx_sys->mutex);

UT_LIST_REMOVE(m_views, view);

} else {
mutex_enter(&trx_sys->mutex);

view = get_view();
}

if (view != NULL) {
view->prepare(trx->id);

UT_LIST_ADD_FIRST(m_views, view);

ut_ad(!view->is_closed());

ut_ad(validate());
}

trx_sys_mutex_exit();
}

/** Clones the oldest view and stores it in view. No need to
call view_close(). The caller owns the view that is passed in.
This function is called by Purge to determine whether it should
purge the delete marked record or not.
@param view Preallocated view, owned by the caller */

void MVCC::clone_oldest_view(ReadView *view) {
mutex_enter(&trx_sys->mutex);

ReadView *oldest_view = get_oldest_view();

if (oldest_view == NULL) {
view->prepare(0);

trx_sys_mutex_exit();

} else {
view->copy_prepare(*oldest_view);

trx_sys_mutex_exit();

view->copy_complete();
}
}

/**
@return the number of active views */

ulint MVCC::size() const {
trx_sys_mutex_enter();

ulint size = 0;

for (const ReadView *view = UT_LIST_GET_FIRST(m_views); view != NULL;
view = UT_LIST_GET_NEXT(m_view_list, view)) {
if (!view->is_closed()) {
++size;
}
}

trx_sys_mutex_exit();

return (size);
}


/**
Set the view creator transaction id. Note: This shouldbe set only
for views created by RW transactions.
@param view Set the creator trx id for this view
@param id Transaction id to set */

void MVCC::set_view_creator_trx_id(ReadView *view, trx_id_t id) {
ut_ad(id > 0);
ut_ad(mutex_own(&trx_sys->mutex));

view->creator_trx_id(id);
}
34 changes: 34 additions & 0 deletions storage/innobase/libs/read/src/ReadView.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <innodb/read/ReadView.h>

#include <innodb/allocator/UT_NEW_ARRAY_NOKEY.h>
#include <innodb/trx_trx/trx_t.h>
#include <innodb/trx_sys/trx_sys.h>

/** Minimum number of elements to reserve in ReadView::ids_t */
static const ulint MIN_TRX_IDS = 32;
Expand Down Expand Up @@ -234,3 +236,35 @@ void ReadView::copy_complete() {
m_creator_trx_id = 0;
}

/**
Opens a read view where exactly the transactions serialized before this
point in time are seen in the view.
@param id Creator transaction id */

void ReadView::prepare(trx_id_t id) {
ut_ad(mutex_own(&trx_sys->mutex));

m_creator_trx_id = id;

m_low_limit_no = m_low_limit_id = m_up_limit_id = trx_sys->max_trx_id;

if (!trx_sys->rw_trx_ids.empty()) {
copy_trx_ids(trx_sys->rw_trx_ids);
} else {
m_ids.clear();
}

ut_ad(m_up_limit_id <= m_low_limit_id);

if (UT_LIST_GET_LEN(trx_sys->serialisation_list) > 0) {
const trx_t *trx;

trx = UT_LIST_GET_FIRST(trx_sys->serialisation_list);

if (trx->no < m_low_limit_no) {
m_low_limit_no = trx->no;
}
}

m_closed = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <innodb/univ/univ.h>

#include <innodb/trx_trx/trx_t.h>

/**
Determine if the transaction is a non-locking autocommit select
(implied read-only).
@param t transaction
@return true if non-locking autocommit select transaction. */
#define trx_is_autocommit_non_locking(t) \
((t)->auto_commit && (t)->will_lock == 0)
1 change: 1 addition & 0 deletions storage/innobase/libs/trx_trx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_library( ${LIB_NAME} STATIC
TrxVersion.cpp
hit_list_t.cpp
trx_mod_tables_t.cpp
trx_is_autocommit_non_locking.cpp
)

target_compile_options( ${LIB_NAME} PRIVATE )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <innodb/trx_trx/trx_is_autocommit_non_locking.h>
Loading

0 comments on commit 8f47e27

Please sign in to comment.