mtr0log.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /******************************************************
  2. Mini-transaction log routines
  3. (c) 1995 Innobase Oy
  4. Created 12/7/1995 Heikki Tuuri
  5. *******************************************************/
  6. #include "mtr0log.h"
  7. #ifdef UNIV_NONINL
  8. #include "mtr0log.ic"
  9. #endif
  10. #include "buf0buf.h"
  11. #include "dict0boot.h"
  12. #include "log0recv.h"
  13. /************************************************************
  14. Catenates n bytes to the mtr log. */
  15. void
  16. mlog_catenate_string(
  17. /*=================*/
  18. mtr_t* mtr, /* in: mtr */
  19. byte* str, /* in: string to write */
  20. ulint len) /* in: string length */
  21. {
  22. dyn_array_t* mlog;
  23. if (mtr_get_log_mode(mtr) == MTR_LOG_NONE) {
  24. return;
  25. }
  26. mlog = &(mtr->log);
  27. dyn_push_string(mlog, str, len);
  28. }
  29. /************************************************************
  30. Writes the initial part of a log record consisting of one-byte item
  31. type and four-byte space and page numbers. Also pushes info
  32. to the mtr memo that a buffer page has been modified. */
  33. void
  34. mlog_write_initial_log_record(
  35. /*==========================*/
  36. byte* ptr, /* in: pointer to (inside) a buffer frame holding the
  37. file page where modification is made */
  38. byte type, /* in: log item type: MLOG_1BYTE, ... */
  39. mtr_t* mtr) /* in: mini-transaction handle */
  40. {
  41. byte* log_ptr;
  42. ut_ad(type <= MLOG_BIGGEST_TYPE);
  43. ut_ad(type > MLOG_8BYTES);
  44. if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
  45. fprintf(stderr,
  46. "InnoDB: Error: trying to write to a stray memory location %pn", ptr);
  47. ut_error;
  48. }
  49. log_ptr = mlog_open(mtr, 11);
  50. /* If no logging is requested, we may return now */
  51. if (log_ptr == NULL) {
  52. return;
  53. }
  54. log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr);
  55. mlog_close(mtr, log_ptr);
  56. }
  57. /************************************************************
  58. Parses an initial log record written by mlog_write_initial_log_record. */
  59. byte*
  60. mlog_parse_initial_log_record(
  61. /*==========================*/
  62. /* out: parsed record end, NULL if not a complete
  63. record */
  64. byte* ptr, /* in: buffer */
  65. byte* end_ptr,/* in: buffer end */
  66. byte* type, /* out: log record type: MLOG_1BYTE, ... */
  67. ulint* space, /* out: space id */
  68. ulint* page_no)/* out: page number */
  69. {
  70. if (end_ptr < ptr + 1) {
  71. return(NULL);
  72. }
  73. *type = (byte)((ulint)*ptr & ~MLOG_SINGLE_REC_FLAG);
  74. ut_ad(*type <= MLOG_BIGGEST_TYPE);
  75. ptr++;
  76. if (end_ptr < ptr + 2) {
  77. return(NULL);
  78. }
  79. ptr = mach_parse_compressed(ptr, end_ptr, space);
  80. if (ptr == NULL) {
  81. return(NULL);
  82. }
  83. ptr = mach_parse_compressed(ptr, end_ptr, page_no);
  84. return(ptr);
  85. }
  86. /************************************************************
  87. Parses a log record written by mlog_write_ulint or mlog_write_dulint. */
  88. byte*
  89. mlog_parse_nbytes(
  90. /*==============*/
  91. /* out: parsed record end, NULL if not a complete
  92. record or a corrupt record */
  93. ulint type, /* in: log record type: MLOG_1BYTE, ... */
  94. byte* ptr, /* in: buffer */
  95. byte* end_ptr,/* in: buffer end */
  96. byte* page) /* in: page where to apply the log record, or NULL */
  97. {
  98. ulint offset;
  99. ulint val;
  100. dulint dval;
  101. ut_a(type <= MLOG_8BYTES);
  102. if (end_ptr < ptr + 2) {
  103. return(NULL);
  104. }
  105. offset = mach_read_from_2(ptr);
  106. ptr += 2;
  107. if (offset >= UNIV_PAGE_SIZE) {
  108. recv_sys->found_corrupt_log = TRUE;
  109. return(NULL);
  110. }
  111. if (type == MLOG_8BYTES) {
  112. ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval);
  113. if (ptr == NULL) {
  114. return(NULL);
  115. }
  116. if (page) {
  117. mach_write_to_8(page + offset, dval);
  118. }
  119. return(ptr);
  120. }
  121. ptr = mach_parse_compressed(ptr, end_ptr, &val);
  122. if (ptr == NULL) {
  123. return(NULL);
  124. }
  125. if (type == MLOG_1BYTE) {
  126. if (val > 0xFFUL) {
  127. recv_sys->found_corrupt_log = TRUE;
  128. return(NULL);
  129. }
  130. } else if (type == MLOG_2BYTES) {
  131. if (val > 0xFFFFUL) {
  132. recv_sys->found_corrupt_log = TRUE;
  133. return(NULL);
  134. }
  135. } else {
  136. if (type != MLOG_4BYTES) {
  137. recv_sys->found_corrupt_log = TRUE;
  138. return(NULL);
  139. }
  140. }
  141. if (page) {
  142. if (type == MLOG_1BYTE) {
  143. mach_write_to_1(page + offset, val);
  144. } else if (type == MLOG_2BYTES) {
  145. mach_write_to_2(page + offset, val);
  146. } else {
  147. ut_a(type == MLOG_4BYTES);
  148. mach_write_to_4(page + offset, val);
  149. }
  150. }
  151. return(ptr);
  152. }
  153. /************************************************************
  154. Writes 1 - 4 bytes to a file page buffered in the buffer pool.
  155. Writes the corresponding log record to the mini-transaction log. */
  156. void
  157. mlog_write_ulint(
  158. /*=============*/
  159. byte* ptr, /* in: pointer where to write */
  160. ulint val, /* in: value to write */
  161. byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
  162. mtr_t* mtr) /* in: mini-transaction handle */
  163. {
  164. byte* log_ptr;
  165. if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
  166. fprintf(stderr,
  167. "InnoDB: Error: trying to write to a stray memory location %pn", ptr);
  168. ut_error;
  169. }
  170. if (type == MLOG_1BYTE) {
  171. mach_write_to_1(ptr, val);
  172. } else if (type == MLOG_2BYTES) {
  173. mach_write_to_2(ptr, val);
  174. } else {
  175. ut_ad(type == MLOG_4BYTES);
  176. mach_write_to_4(ptr, val);
  177. }
  178. log_ptr = mlog_open(mtr, 11 + 2 + 5);
  179. /* If no logging is requested, we may return now */
  180. if (log_ptr == NULL) {
  181. return;
  182. }
  183. log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr);
  184. mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr));
  185. log_ptr += 2;
  186. log_ptr += mach_write_compressed(log_ptr, val);
  187. mlog_close(mtr, log_ptr);
  188. }
  189. /************************************************************
  190. Writes 8 bytes to a file page buffered in the buffer pool.
  191. Writes the corresponding log record to the mini-transaction log. */
  192. void
  193. mlog_write_dulint(
  194. /*==============*/
  195. byte* ptr, /* in: pointer where to write */
  196. dulint val, /* in: value to write */
  197. mtr_t* mtr) /* in: mini-transaction handle */
  198. {
  199. byte* log_ptr;
  200. if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
  201. fprintf(stderr,
  202. "InnoDB: Error: trying to write to a stray memory location %pn", ptr);
  203. ut_error;
  204. }
  205. ut_ad(ptr && mtr);
  206. mach_write_to_8(ptr, val);
  207. log_ptr = mlog_open(mtr, 11 + 2 + 9);
  208. /* If no logging is requested, we may return now */
  209. if (log_ptr == NULL) {
  210. return;
  211. }
  212. log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_8BYTES,
  213. log_ptr, mtr);
  214. mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr));
  215. log_ptr += 2;
  216. log_ptr += mach_dulint_write_compressed(log_ptr, val);
  217. mlog_close(mtr, log_ptr);
  218. }
  219. /************************************************************
  220. Writes a string to a file page buffered in the buffer pool. Writes the
  221. corresponding log record to the mini-transaction log. */
  222. void
  223. mlog_write_string(
  224. /*==============*/
  225. byte* ptr, /* in: pointer where to write */
  226. byte* str, /* in: string to write */
  227. ulint len, /* in: string length */
  228. mtr_t* mtr) /* in: mini-transaction handle */
  229. {
  230. byte* log_ptr;
  231. if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) {
  232. fprintf(stderr,
  233. "InnoDB: Error: trying to write to a stray memory location %pn", ptr);
  234. ut_error;
  235. }
  236. ut_ad(ptr && mtr);
  237. ut_a(len < UNIV_PAGE_SIZE);
  238. ut_memcpy(ptr, str, len);
  239. log_ptr = mlog_open(mtr, 30);
  240. /* If no logging is requested, we may return now */
  241. if (log_ptr == NULL) {
  242. return;
  243. }
  244. log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_WRITE_STRING,
  245. log_ptr, mtr);
  246. mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr));
  247. log_ptr += 2;
  248. mach_write_to_2(log_ptr, len);
  249. log_ptr += 2;
  250. mlog_close(mtr, log_ptr);
  251. mlog_catenate_string(mtr, str, len);
  252. }
  253. /************************************************************
  254. Parses a log record written by mlog_write_string. */
  255. byte*
  256. mlog_parse_string(
  257. /*==============*/
  258. /* out: parsed record end, NULL if not a complete
  259. record */
  260. byte* ptr, /* in: buffer */
  261. byte* end_ptr,/* in: buffer end */
  262. byte* page) /* in: page where to apply the log record, or NULL */
  263. {
  264. ulint offset;
  265. ulint len;
  266. if (end_ptr < ptr + 4) {
  267. return(NULL);
  268. }
  269. offset = mach_read_from_2(ptr);
  270. ptr += 2;
  271. if (offset >= UNIV_PAGE_SIZE) {
  272. recv_sys->found_corrupt_log = TRUE;
  273. return(NULL);
  274. }
  275. len = mach_read_from_2(ptr);
  276. ptr += 2;
  277. ut_a(len + offset < UNIV_PAGE_SIZE);
  278. if (end_ptr < ptr + len) {
  279. return(NULL);
  280. }
  281. if (page) {
  282. ut_memcpy(page + offset, ptr, len);
  283. }
  284. return(ptr + len);
  285. }