Skip to content
Permalink
Browse files
MDEV-16136: Simplify trx_lock_t memory management
Allocate trx->lock.rec_pool and trx->lock.table_pool directly from trx_t.
Remove unnecessary use of std::vector.

In order to do this, move some definitions from lock0priv.h to
lock0types.h, so that ib_lock_t will not be an opaque type.
  • Loading branch information
dr-m committed Aug 16, 2018
1 parent b795134 commit 3ce8a0f
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 275 deletions.
@@ -834,69 +834,6 @@ lock_trx_has_rec_x_lock(
MY_ATTRIBUTE((warn_unused_result));
#endif /* UNIV_DEBUG */

/**
Allocate cached locks for the transaction.
@param trx allocate cached record locks for this transaction */
void
lock_trx_alloc_locks(trx_t* trx);

/** Lock modes and types */
/* @{ */
#define LOCK_MODE_MASK 0xFUL /*!< mask used to extract mode from the
type_mode field in a lock */
/** Lock types */
/* @{ */
#define LOCK_TABLE 16U /*!< table lock */
#define LOCK_REC 32U /*!< record lock */
#define LOCK_TYPE_MASK 0xF0UL /*!< mask used to extract lock type from the
type_mode field in a lock */
#if LOCK_MODE_MASK & LOCK_TYPE_MASK
# error "LOCK_MODE_MASK & LOCK_TYPE_MASK"
#endif

#define LOCK_WAIT 256U /*!< Waiting lock flag; when set, it
means that the lock has not yet been
granted, it is just waiting for its
turn in the wait queue */
/* Precise modes */
#define LOCK_ORDINARY 0 /*!< this flag denotes an ordinary
next-key lock in contrast to LOCK_GAP
or LOCK_REC_NOT_GAP */
#define LOCK_GAP 512U /*!< when this bit is set, it means that the
lock holds only on the gap before the record;
for instance, an x-lock on the gap does not
give permission to modify the record on which
the bit is set; locks of this type are created
when records are removed from the index chain
of records */
#define LOCK_REC_NOT_GAP 1024U /*!< this bit means that the lock is only on
the index record and does NOT block inserts
to the gap before the index record; this is
used in the case when we retrieve a record
with a unique key, and is also used in
locking plain SELECTs (not part of UPDATE
or DELETE) when the user has set the READ
COMMITTED isolation level */
#define LOCK_INSERT_INTENTION 2048U/*!< this bit is set when we place a waiting
gap type record lock request in order to let
an insert of an index record to wait until
there are no conflicting locks by other
transactions on the gap; note that this flag
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
#define LOCK_PREDICATE 8192U /*!< Predicate lock */
#define LOCK_PRDT_PAGE 16384U /*!< Page lock */


#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_MODE_MASK
# error
#endif
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_PREDICATE|LOCK_PRDT_PAGE)&LOCK_TYPE_MASK
# error
#endif
/* @} */

/** Lock operation struct */
struct lock_op_t{
dict_table_t* table; /*!< table to be locked */
@@ -42,19 +42,6 @@ those functions in lock/ */
#define UINT32_MAX (4294967295U)
#endif

/** A table lock */
struct lock_table_t {
dict_table_t* table; /*!< database table in dictionary
cache */
UT_LIST_NODE_T(lock_t)
locks; /*!< list of locks on the same
table */
/** Print the table lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std::ostream& print(std::ostream& out) const;
};

/** Print the table lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
@@ -77,131 +64,11 @@ operator<<(std::ostream& out, const lock_table_t& lock)
return(lock.print(out));
}

/** Record lock for a page */
struct lock_rec_t {
ib_uint32_t space; /*!< space id */
ib_uint32_t page_no; /*!< page number */
ib_uint32_t n_bits; /*!< number of bits in the lock
bitmap; NOTE: the lock bitmap is
placed immediately after the
lock struct */

/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
std::ostream& print(std::ostream& out) const;
};

/** Print the record lock into the given output stream
@param[in,out] out the output stream
@return the given output stream. */
inline
std::ostream& lock_rec_t::print(std::ostream& out) const
{
out << "[lock_rec_t: space=" << space << ", page_no=" << page_no
<< ", n_bits=" << n_bits << "]";
return(out);
}

inline
std::ostream&
operator<<(std::ostream& out, const lock_rec_t& lock)
{
return(lock.print(out));
}

/** Lock struct; protected by lock_sys->mutex */
struct lock_t {
trx_t* trx; /*!< transaction owning the
lock */
UT_LIST_NODE_T(lock_t)
trx_locks; /*!< list of the locks of the
transaction */

dict_index_t* index; /*!< index for a record lock */

lock_t* hash; /*!< hash chain node for a record
lock. The link node in a singly linked
list, used during hashing. */

/* Statistics for how long lock has been held and time
how long this lock had to be waited before it was granted */
time_t requested_time; /*!< Lock request time */
ulint wait_time; /*!< Time waited this lock or 0 */

union {
lock_table_t tab_lock;/*!< table lock */
lock_rec_t rec_lock;/*!< record lock */
} un_member; /*!< lock details */

ib_uint32_t type_mode; /*!< lock type, mode, LOCK_GAP or
LOCK_REC_NOT_GAP,
LOCK_INSERT_INTENTION,
wait flag, ORed */

/** Determine if the lock object is a record lock.
@return true if record lock, false otherwise. */
bool is_record_lock() const
{
return(type() == LOCK_REC);
}

bool is_waiting() const
{
return(type_mode & LOCK_WAIT);
}

bool is_gap() const
{
return(type_mode & LOCK_GAP);
}

bool is_record_not_gap() const
{
return(type_mode & LOCK_REC_NOT_GAP);
}

bool is_insert_intention() const
{
return(type_mode & LOCK_INSERT_INTENTION);
}

ulint type() const {
return(type_mode & LOCK_TYPE_MASK);
}

enum lock_mode mode() const
{
return(static_cast<enum lock_mode>(type_mode & LOCK_MODE_MASK));
}

/** Print the lock object into the given output stream.
@param[in,out] out the output stream
@return the given output stream. */
std::ostream& print(std::ostream& out) const;

/** Convert the member 'type_mode' into a human readable string.
@return human readable string */
std::string type_mode_string() const;

const char* type_string() const
{
switch (type_mode & LOCK_TYPE_MASK) {
case LOCK_REC:
return("LOCK_REC");
case LOCK_TABLE:
return("LOCK_TABLE");
default:
ut_error;
}
}
};

/** Convert the member 'type_mode' into a human readable string.
@return human readable string */
inline
std::string
lock_t::type_mode_string() const
ib_lock_t::type_mode_string() const
{
std::ostringstream sout;
sout << type_string();
@@ -227,7 +94,7 @@ lock_t::type_mode_string() const

inline
std::ostream&
lock_t::print(std::ostream& out) const
ib_lock_t::print(std::ostream& out) const
{
out << "[lock_t: type_mode=" << type_mode << "("
<< type_mode_string() << ")";
@@ -244,7 +111,7 @@ lock_t::print(std::ostream& out) const

inline
std::ostream&
operator<<(std::ostream& out, const lock_t& lock)
operator<<(std::ostream& out, const ib_lock_t& lock)
{
return(lock.print(out));
}

0 comments on commit 3ce8a0f

Please sign in to comment.