MySQL Disk--EXT4无符号INT溢出问题
EXT4无符号INT溢出问题
jbd2会为每个transaction分配一个unsigned int的tid用来记录操作次数,如fdatasync操作对应i_datasync_tid。参数j_commit_request用于记录jdb日志commit次数,随着jbd2日志的不断提交不断增长。在执行fdatasync()时会产生如下调用:
fdatasync()
==>ext4_sync_file()
==>jbd2_log_start_commit(journal, commit_tid)
==>tid_geq(journal->j_commit_request, target)
jbd2_log_start_commit函数:
int __jbd2_log_start_commit(journal_t *journal, tid_t target)
{
/*
* Are we already doing a recent enough commit?
*/
if (!tid_geq(journal->j_commit_request, target)) {
/*
* We want a new commit: OK, mark the request and wakup the
* commit thread. We do _not_ do the commit ourselves.
*/
journal->j_commit_request = target;
jbd_debug(1, "JBD: requesting commit %d/%d\n",
journal->j_commit_request,
journal->j_commit_sequence);
wake_up(&journal->j_wait_commit);
return 1;
}
return 0;
}
并通过tid_geq来判断transaction是否需要commit:
static inline int tid_geq(tid_t x, tid_t y)
{
int difference = (x - y);
return (difference >= 0);
}
由于tid是无符号INT类型,当tid_geq函数中x和y相差较大时,便会出现类型溢出问题,如2177452108-0=2177452108,因为溢出得到-2117515188,导致tid_geq函数返回True,使得后续函数调用中出现异常。