delete from t_lock_1 where a=10
2018-05-24T09:31:53.082148Z 26 [Note] InnoDB: * (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 209 page no 3 n bits 72 index PRIMARY of table test
.t_lock_1
trx id 17766 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 8000000a; asc ;;
1: len 6; hex 000000004565; asc Ee;;
2: len 7; hex 4f000001df0871; asc O q;;
mysql初学者,
上面是我人为的模拟死锁后,show innodb status的部分输出;
下面是 t_lock_1的表定义,
mysql> desc t_lock_1; | |||||
---|---|---|---|---|---|
Field | Type | Null | Key | Default | Extra |
a | int(11) | NO | PRI | NULL |
1 row in set (0.00 sec)
mysql> show create table t_lock_1\G;
1. row **
Table: t_lock_1
Create Table: CREATE TABLE t_lock_1
(
a
int(11) NOT NULL,
PRIMARY KEY (a
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
疑问是下面的部分:
Record lock, heap no 2 PHYSICAL RECORD: n_fields 3; compact format; info bits 32
0: len 4; hex 8000000a; asc ;;
1: len 6; hex 000000004565; asc Ee;;
2: len 7; hex 4f000001df0871; asc O q;;
疑问一:
n_fields 3 ,表示的是包括3个字段,(这个理解应该没错吧)
我的t_lock_1就一个字段,那下面的怎么出现3列?
疑问2:
hex 8000000a ,有啥方法转出十进制的数?
文档中没有相关内容,帮你简单解释一下吧。
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));
}
收起