在mysql源码中含有大量的函数ut_ad ut_d ut_a,又都是宏定义,记录下相关函数,便于初学者看代码易于理解
为源代码编译 DEBUG模式下才有作用,在release版本中不存在,代码中也就是没有相关的代码
为源代码编译 DEBUG模式和release版本都存在
ut_a ut_ad 类似于C语言中 assert 的断言功能,当()中的表达式不为真则mysql主程序直接退出
仅是判断函数或者变量是否是预期的值,仅仅是判断的功能,不会对流程起任何作用,仅用来保护流程
ut_d函数 在DEBUG 模式下才有用作,()中的表达式才会执行,只是用来调试的,在生成环境中根本就不存在
/** Abort execution if EXPR does not evaluate to nonzero.
@param EXPR assertion expression that should hold */
#define ut_a(EXPR) do { \
if (UNIV_UNLIKELY(!(ulint) (EXPR))) { \
ut_dbg_assertion_failed(#EXPR, \
__FILE__, (ulint) __LINE__); \
} \
} while (0)
/** Abort execution. */
#define ut_error \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__)
#ifdef UNIV_DEBUG
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) ut_a(EXPR) /*在DEBUG 版本中 也是调用 ut_a ut_a ut_d 在DEBUG模式下完全一样*/
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) EXPR
#else
/** Debug assertion. Does nothing unless UNIV_DEBUG is defined. */
#define ut_ad(EXPR) /*在release版本 为空*/
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) /*在release版本 为空*/
#endif
ut_a ut_d 在DEBUG模式下完全一样
找了一个函数,具体解析
byte*
mlog_write_initial_log_record_low(
mlog_id_t type,
ulint space_id,
ulint page_no,
byte* log_ptr,
mtr_t* mtr)
{
/*把宏定义的实现做具体的解析*/
ut_ad(type <= MLOG_BIGGEST_TYPE);
....
}
ut_ad(type <= MLOG_BIGGEST_TYPE);/*具体实现如下*/
do {
/*这个指令是gcc引入的,作用是允许程序员将最有可能执行的分支告诉编译器。
这个指令的写法为:__builtin_expect(EXP, N)。
意思是:EXP==N的概率很大
!(ulint) (type <= MLOG_BIGGEST_TYPE) 为0 的概率很大
*/
if (__builtin_expect(!(ulint) (type <= MLOG_BIGGEST_TYPE), (0)))
{
/*打印日志 执行中断调用abort();*/
ut_dbg_assertion_failed("type <= MLOG_BIGGEST_TYPE",
"/storage/innobase/include/mtr0log.ic", (ulint) 198);
}
} while (0);
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /*!< in: the failed assertion (optional) */
const char* file, /*!< in: source file containing the assertion */
ulint line) /*!< in: line number of the assertion */
{
/*输出错误日志的时间*/
ut_print_timestamp(stderr);
#ifdef UNIV_HOTBACKUP
fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
file, line);
#else /* UNIV_HOTBACKUP */
fprintf(stderr,
" InnoDB: Assertion failure in thread " ULINTPF
" in file %s line " ULINTPF "\n",
os_thread_pf(os_thread_get_curr_id()),
innobase_basename(file), line);
#endif /* UNIV_HOTBACKUP */
if (expr) {
fprintf(stderr,
"InnoDB: Failing assertion: %s\n", expr);
}
fputs("InnoDB: We intentionally generate a memory trap.\n"
"InnoDB: Submit a detailed bug report"
" to http://bugs.mysql.com.\n"
"InnoDB: If you get repeated assertion failures"
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
fflush(stdout);
/*进程中断退出*/
abort();
}
/**********************************************************//**
Prints a timestamp to a file. */
void
ut_print_timestamp(
/*===============*/
FILE* file) /*!< in: file where to print */
{
ulint thread_id = 0;
#ifndef UNIV_INNOCHECKSUM
thread_id = os_thread_pf(os_thread_get_curr_id());
#endif /* !UNIV_INNOCHECKSUM */
#ifdef _WIN32
SYSTEMTIME cal_tm;
GetLocalTime(&cal_tm);
fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#llx",
(int) cal_tm.wYear,
(int) cal_tm.wMonth,
(int) cal_tm.wDay,
(int) cal_tm.wHour,
(int) cal_tm.wMinute,
(int) cal_tm.wSecond,
static_cast<ulonglong>(thread_id));
#else
struct tm* cal_tm_ptr;
time_t tm;
struct tm cal_tm;
time(&tm);
localtime_r(&tm, &cal_tm);
cal_tm_ptr = &cal_tm;
fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %#lx",
cal_tm_ptr->tm_year + 1900,
cal_tm_ptr->tm_mon + 1,
cal_tm_ptr->tm_mday,
cal_tm_ptr->tm_hour,
cal_tm_ptr->tm_min,
cal_tm_ptr->tm_sec,
thread_id);
#endif
}
。