mysql 源码-- ut_ad ut_d ut_a 函数模式解析

在mysql源码中含有大量的函数ut_ad ut_d ut_a,又都是宏定义,记录下相关函数,便于初学者看代码易于理解

ut_ad ut_d

为源代码编译 DEBUG模式下才有作用,在release版本中不存在,代码中也就是没有相关的代码

ut_a

为源代码编译 DEBUG模式和release版本都存在

ut_a ut_ad 函数的作用

ut_a ut_ad 类似于C语言中 assert 的断言功能,当()中的表达式不为真则mysql主程序直接退出
仅是判断函数或者变量是否是预期的值,仅仅是判断的功能,不会对流程起任何作用,仅用来保护流程

ut_d函数的作用

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 函数说明

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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值