log0log.ic
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:9k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Database log
  3. (c) 1995 Innobase Oy
  4. Created 12/9/1995 Heikki Tuuri
  5. *******************************************************/
  6. #include "os0file.h"
  7. #include "mach0data.h"
  8. #include "mtr0mtr.h"
  9. /**********************************************************
  10. Checks by parsing that the catenated log segment for a single mtr is
  11. consistent. */
  12. ibool
  13. log_check_log_recs(
  14. /*===============*/
  15. byte* buf, /* in: pointer to the start of the log segment
  16. in the log_sys->buf log buffer */
  17. ulint len, /* in: segment length in bytes */
  18. dulint buf_start_lsn); /* in: buffer start lsn */
  19. /****************************************************************
  20. Gets a log block flush bit. */
  21. UNIV_INLINE
  22. ibool
  23. log_block_get_flush_bit(
  24. /*====================*/
  25. /* out: TRUE if this block was the first
  26. to be written in a log flush */
  27. byte* log_block) /* in: log block */
  28. {
  29. if (LOG_BLOCK_FLUSH_BIT_MASK
  30. & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
  31. return(TRUE);
  32. }
  33. return(FALSE);
  34. }
  35. /****************************************************************
  36. Sets the log block flush bit. */
  37. UNIV_INLINE
  38. void
  39. log_block_set_flush_bit(
  40. /*====================*/
  41. byte* log_block, /* in: log block */
  42. ibool val) /* in: value to set */
  43. {
  44. ulint field;
  45. field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
  46. if (val) {
  47. field = field | LOG_BLOCK_FLUSH_BIT_MASK;
  48. } else {
  49. field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
  50. }
  51. mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
  52. }
  53. /****************************************************************
  54. Gets a log block number stored in the header. */
  55. UNIV_INLINE
  56. ulint
  57. log_block_get_hdr_no(
  58. /*=================*/
  59. /* out: log block number stored in the block
  60. header */
  61. byte* log_block) /* in: log block */
  62. {
  63. return(~LOG_BLOCK_FLUSH_BIT_MASK 
  64. & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
  65. }
  66. /****************************************************************
  67. Sets the log block number stored in the header; NOTE that this must be set
  68. before the flush bit! */
  69. UNIV_INLINE
  70. void
  71. log_block_set_hdr_no(
  72. /*=================*/
  73. byte* log_block, /* in: log block */
  74. ulint n) /* in: log block number: must be > 0 and
  75. < LOG_BLOCK_FLUSH_BIT_MASK */
  76. {
  77. ut_ad(n > 0);
  78. ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
  79. mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
  80. }
  81. /****************************************************************
  82. Gets a log block data length. */
  83. UNIV_INLINE
  84. ulint
  85. log_block_get_data_len(
  86. /*===================*/
  87. /* out: log block data length measured as a
  88. byte offset from the block start */
  89. byte* log_block) /* in: log block */
  90. {
  91. return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
  92. }
  93. /****************************************************************
  94. Sets the log block data length. */
  95. UNIV_INLINE
  96. void
  97. log_block_set_data_len(
  98. /*===================*/
  99. byte* log_block, /* in: log block */
  100. ulint len) /* in: data length */
  101. {
  102. mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
  103. }
  104. /****************************************************************
  105. Gets a log block first mtr log record group offset. */
  106. UNIV_INLINE
  107. ulint
  108. log_block_get_first_rec_group(
  109. /*==========================*/
  110. /* out: first mtr log record group byte offset
  111. from the block start, 0 if none */
  112. byte* log_block) /* in: log block */
  113. {
  114. return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
  115. }
  116. /****************************************************************
  117. Sets the log block first mtr log record group offset. */
  118. UNIV_INLINE
  119. void
  120. log_block_set_first_rec_group(
  121. /*==========================*/
  122. byte* log_block, /* in: log block */
  123. ulint offset) /* in: offset, 0 if none */
  124. {
  125. mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
  126. }
  127. /****************************************************************
  128. Gets a log block checkpoint number field (4 lowest bytes). */
  129. UNIV_INLINE
  130. ulint
  131. log_block_get_checkpoint_no(
  132. /*========================*/
  133. /* out: checkpoint no (4 lowest bytes) */
  134. byte* log_block) /* in: log block */
  135. {
  136. return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
  137. }
  138. /****************************************************************
  139. Sets a log block checkpoint number field (4 lowest bytes). */
  140. UNIV_INLINE
  141. void
  142. log_block_set_checkpoint_no(
  143. /*========================*/
  144. byte* log_block, /* in: log block */
  145. dulint no) /* in: checkpoint no */
  146. {
  147. mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO,
  148. ut_dulint_get_low(no));
  149. }
  150. /****************************************************************
  151. Gets a log block number stored in the trailer. */
  152. UNIV_INLINE
  153. ulint
  154. log_block_get_trl_no(
  155. /*=================*/
  156. /* out: log block number stored in the block
  157. trailer */
  158. byte* log_block) /* in: log block */
  159. {
  160. return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
  161. - LOG_BLOCK_TRL_NO));
  162. }
  163. /****************************************************************
  164. Sets the log block number stored in the trailer. */
  165. UNIV_INLINE
  166. void
  167. log_block_set_trl_no(
  168. /*=================*/
  169. byte* log_block, /* in: log block */
  170. ulint n) /* in: log block number */
  171. {
  172. mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_NO,
  173.   n);
  174. }
  175. /****************************************************************
  176. Converts a lsn to a log block number. */
  177. UNIV_INLINE
  178. ulint
  179. log_block_convert_lsn_to_no(
  180. /*========================*/
  181. /* out: log block number, it is > 0 and <= 1G */
  182. dulint lsn) /* in: lsn of a byte within the block */
  183. {
  184. ulint no;
  185. no = ut_dulint_get_low(lsn) / OS_FILE_LOG_BLOCK_SIZE;
  186. no += (ut_dulint_get_high(lsn) % OS_FILE_LOG_BLOCK_SIZE)
  187. * 2 * (0x80000000 / OS_FILE_LOG_BLOCK_SIZE);
  188. no = no & 0x3FFFFFFF;
  189. return(no + 1);
  190. }
  191. /****************************************************************
  192. Initializes a log block in the log buffer. */
  193. UNIV_INLINE
  194. void
  195. log_block_init(
  196. /*===========*/
  197. byte* log_block, /* in: pointer to the log buffer */
  198. dulint lsn) /* in: lsn within the log block */
  199. {
  200. ulint no;
  201. ut_ad(mutex_own(&(log_sys->mutex)));
  202. no = log_block_convert_lsn_to_no(lsn);
  203. log_block_set_hdr_no(log_block, no);
  204. log_block_set_trl_no(log_block, no);
  205. log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
  206. log_block_set_first_rec_group(log_block, 0);
  207. }
  208. /****************************************************************
  209. Writes to the log the string given. The log must be released with
  210. log_release. */
  211. UNIV_INLINE
  212. dulint
  213. log_reserve_and_write_fast(
  214. /*=======================*/
  215. /* out: end lsn of the log record, ut_dulint_zero if
  216. did not succeed */
  217. byte* str, /* in: string */
  218. ulint len, /* in: string length */
  219. dulint* start_lsn,/* out: start lsn of the log record */
  220. ibool* success)/* out: TRUE if success */
  221. {
  222. log_t* log = log_sys;
  223. ulint data_len;
  224. dulint lsn;
  225. *success = TRUE;
  226. mutex_enter(&(log->mutex));
  227. data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
  228. if (log->online_backup_state
  229.     || (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE)) {
  230.      /* The string does not fit within the current log block
  231.      or the log block would become full */
  232.      *success = FALSE;
  233. mutex_exit(&(log->mutex));
  234.      return(ut_dulint_zero);
  235. }
  236. *start_lsn = log->lsn;
  237. ut_memcpy(log->buf + log->buf_free, str, len);
  238. log_block_set_data_len(ut_align_down(log->buf + log->buf_free,
  239.   OS_FILE_LOG_BLOCK_SIZE),
  240. data_len);
  241. #ifdef UNIV_LOG_DEBUG
  242. log->old_buf_free = log->buf_free;
  243. log->old_lsn = log->lsn;
  244. #endif
  245. log->buf_free += len;
  246. ut_ad(log->buf_free <= log->buf_size);
  247. lsn = ut_dulint_add(log->lsn, len);
  248. log->lsn = lsn;
  249. #ifdef UNIV_LOG_DEBUG
  250. log_check_log_recs(log->buf + log->old_buf_free,
  251. log->buf_free - log->old_buf_free, log->old_lsn);
  252. #endif
  253. return(lsn);
  254. }
  255. /***************************************************************************
  256. Releases the log mutex. */
  257. UNIV_INLINE
  258. void
  259. log_release(void)
  260. /*=============*/
  261. {
  262. mutex_exit(&(log_sys->mutex));
  263. }
  264. /****************************************************************
  265. Gets the current lsn. */
  266. UNIV_INLINE
  267. dulint
  268. log_get_lsn(void)
  269. /*=============*/
  270. /* out: current lsn */
  271. {
  272. dulint lsn;
  273. mutex_enter(&(log_sys->mutex));
  274. lsn = log_sys->lsn;
  275. mutex_exit(&(log_sys->mutex));
  276. return(lsn);
  277. }
  278. /***************************************************************************
  279. Checks if there is need for a log buffer flush or a new checkpoint, and does
  280. this if yes. Any database operation should call this when it has modified
  281. more than about 4 pages. NOTE that this function may only be called when the
  282. OS thread owns no synchronization objects except the dictionary mutex. */
  283. UNIV_INLINE
  284. void
  285. log_free_check(void)
  286. /*================*/
  287. {
  288. /* ut_ad(sync_thread_levels_empty()); */
  289. if (log_sys->check_flush_or_checkpoint) {
  290. log_check_margins();
  291. }
  292. }
  293. /****************************************************************************
  294. Gets the online backup lsn. */
  295. UNIV_INLINE
  296. dulint
  297. log_get_online_backup_lsn_low(void)
  298. /*===============================*/
  299. /* out: online_backup_lsn, the caller must
  300. own the log_sys mutex */
  301. {
  302. ut_ad(mutex_own(&(log_sys->mutex)));
  303. ut_ad(log_sys->online_backup_state);
  304. return(log_sys->online_backup_lsn);
  305. }
  306. /****************************************************************************
  307. Gets the online backup state. */
  308. UNIV_INLINE
  309. ibool
  310. log_get_online_backup_state_low(void)
  311. /*=================================*/
  312. /* out: online backup state, the caller must
  313. own the log_sys mutex */
  314. {
  315. ut_ad(mutex_own(&(log_sys->mutex)));
  316. return(log_sys->online_backup_state);
  317. }