文档中没有相关内容,帮你简单解释一下吧。
n_fields不是表的字段数,而是下面打印出来的调试信息行数
0: len 4; hex 8000000a; asc ;; //聚簇索引键
1: len 6; hex 000000004565; asc Ee;; //最后一个修改的事务ID,转换成十进制就是17765,和日志内容 trx id 17766相对应
2: len 7; hex 4f000001df0871; asc O q;; //undo回滚段记录信息
具体原理可以查看这个源码
storage/innobase/include/lock0priv.h
space id、page no、n_bits信息在这里
/** Record lock for a page */
struct lock_rec_t {
space_id_t space; /*!< space id */
page_no_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);
}
死锁检查部分代码
dberr_t deadlock_check(lock_t* lock);
/**
Check the outcome of the deadlock check
@param[in,out] victim_trx Transaction selected for rollback
@param[in,out] lock Lock being requested
@return DB_LOCK_WAIT, DB_DEADLOCK or DB_SUCCESS_LOCKED_REC */
dberr_t check_deadlock_result(const trx_t* victim_trx, lock_t* lock);
/**
Setup the context from the requirements */
void init(const page_t* page)
{
ut_ad(lock_mutex_own());
ut_ad(!srv_read_only_mode);
ut_ad(m_index->is_clustered()
|| !dict_index_is_online_ddl(m_index));
ut_ad(m_thr == NULL || m_trx == thr_get_trx(m_thr));
m_size = is_predicate_lock(m_mode)
? lock_size(m_mode) : lock_size(page);
/** If rec is the supremum record, then we reset the
gap and LOCK_REC_NOT_GAP bits, as all locks on the
supremum are automatically of the gap type */
if (m_rec_id.m_heap_no == PAGE_HEAP_NO_SUPREMUM) {
ut_ad(!(m_mode & LOCK_REC_NOT_GAP));
m_mode &= ~(LOCK_GAP | LOCK_REC_NOT_GAP);
}
}
/**
Calculate the record lock physical size required for a predicate lock.
@param[in] mode For predicate locks the lock mode
@return the size of the lock data structure required in bytes */
static size_t lock_size(ulint mode)
{
ut_ad(is_predicate_lock(mode));
/* The lock is always on PAGE_HEAP_NO_INFIMUM(0),
so we only need 1 bit (which is rounded up to 1
byte) for lock bit setting */
size_t n_bytes;
if (mode & LOCK_PREDICATE) {
const ulint align = UNIV_WORD_SIZE - 1;
/* We will attach the predicate structure
after lock. Make sure the memory is
aligned on 8 bytes, the mem_heap_alloc
will align it with MEM_SPACE_NEEDED
anyway. */
n_bytes = (1 + sizeof(lock_prdt_t) + align) & ~align;
/* This should hold now */
ut_ad(n_bytes == sizeof(lock_prdt_t) + UNIV_WORD_SIZE);
} else {
n_bytes = 1;
}
return(n_bytes);
}
/**
Calculate the record lock physical size required, non-predicate lock.
@param[in] page For non-predicate locks the buffer page
@return the size of the lock data structure required in bytes */
static size_t lock_size(const page_t* page)
{
ulint n_recs = page_dir_get_n_heap(page);
/* Make lock bitmap bigger by a safety margin */
return(1 + ((n_recs + LOCK_PAGE_BITMAP_MARGIN) / 8));
}
/**
@return true if the requested lock mode is for a predicate
or page lock */
static bool is_predicate_lock(ulint mode)
{
return(mode & (LOCK_PREDICATE | LOCK_PRDT_PAGE));
}