You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
13 KiB

20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Clean up the insert buffer subsystem. Originally, there were provisions in InnoDB for multiple insert buffer B-trees, apparently one for each tablespace. When Heikki implemented innodb_file_per_table (multiple InnoDB tablespaces) in MySQL 4.1, he made the insert buffer live only in the system tablespace (space 0) but left the provisions in the code. When Osku Salerma implemented delete buffering, he also cleaned up the insert buffer subsystem so that only one insert buffer B-tree exists. This patch applies the clean-up to the InnoDB Plugin. Having a separate patch of the insert buffer clean-up should help us better compare the essential changes of the InnoDB Plugin and InnoDB+ and to track down bugs that are specific to InnoDB+. IBUF_SPACE_ID: New constant, defined as 0. ibuf_data_t: Remove. ibuf_t: Add the applicable fields from ibuf_data_t. There is only one insert buffer tree from now on. ibuf_page_low(), ibuf_page(): Merge to a single function ibuf_page(). fil_space_t: Remove ibuf_data. fil_space_get_ibuf_data(): Remove. There is only one ibuf_data, for space IBUF_SPACE_ID. fil_ibuf_init_at_db_start(): Remove. ibuf_init_at_db_start(): Fuse with ibuf_data_init_for_space(). ibuf_validate_low(): Remove. There is only one ibuf tree. ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_free_excess_pages(): Remove the parameter space, which was always 0. ibuf_tree_root_get(): Remove the parameters space and data. There is only one ibuf tree, for space IBUF_SPACE_ID. ibuf_data_sizes_update(): Rename to ibuf_size_update(), and remove the parameter data. There is only one ibuf data struct. ibuf_build_entry_pre_4_1_x(): New function, refactored from ibuf_build_entry_from_ibuf_rec(). ibuf_data_enough_free_for_insert(), ibuf_data_too_much_free(): Remove the parameter data. There is only one insert buffer tree. ibuf_add_free_page(), ibuf_remove_free_page(): Remove the parameters space and data. There is only one insert buffer tree. ibuf_get_merge_page_nos(): Add parenthesis, to reduce diffs to branches/innodb+. ibuf_contract_ext(): Do not pick an insert buffer tree at random. There is only one. ibuf_print(): Print the single insert buffer tree. rb://19 approved by Heikki on IM
17 years ago
20 years ago
20 years ago
branches/zip: Clean up the insert buffer subsystem. Originally, there were provisions in InnoDB for multiple insert buffer B-trees, apparently one for each tablespace. When Heikki implemented innodb_file_per_table (multiple InnoDB tablespaces) in MySQL 4.1, he made the insert buffer live only in the system tablespace (space 0) but left the provisions in the code. When Osku Salerma implemented delete buffering, he also cleaned up the insert buffer subsystem so that only one insert buffer B-tree exists. This patch applies the clean-up to the InnoDB Plugin. Having a separate patch of the insert buffer clean-up should help us better compare the essential changes of the InnoDB Plugin and InnoDB+ and to track down bugs that are specific to InnoDB+. IBUF_SPACE_ID: New constant, defined as 0. ibuf_data_t: Remove. ibuf_t: Add the applicable fields from ibuf_data_t. There is only one insert buffer tree from now on. ibuf_page_low(), ibuf_page(): Merge to a single function ibuf_page(). fil_space_t: Remove ibuf_data. fil_space_get_ibuf_data(): Remove. There is only one ibuf_data, for space IBUF_SPACE_ID. fil_ibuf_init_at_db_start(): Remove. ibuf_init_at_db_start(): Fuse with ibuf_data_init_for_space(). ibuf_validate_low(): Remove. There is only one ibuf tree. ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_free_excess_pages(): Remove the parameter space, which was always 0. ibuf_tree_root_get(): Remove the parameters space and data. There is only one ibuf tree, for space IBUF_SPACE_ID. ibuf_data_sizes_update(): Rename to ibuf_size_update(), and remove the parameter data. There is only one ibuf data struct. ibuf_build_entry_pre_4_1_x(): New function, refactored from ibuf_build_entry_from_ibuf_rec(). ibuf_data_enough_free_for_insert(), ibuf_data_too_much_free(): Remove the parameter data. There is only one insert buffer tree. ibuf_add_free_page(), ibuf_remove_free_page(): Remove the parameters space and data. There is only one insert buffer tree. ibuf_get_merge_page_nos(): Add parenthesis, to reduce diffs to branches/innodb+. ibuf_contract_ext(): Do not pick an insert buffer tree at random. There is only one. ibuf_print(): Print the single insert buffer tree. rb://19 approved by Heikki on IM
17 years ago
20 years ago
20 years ago
branches/zip: Clean up the insert buffer subsystem. Originally, there were provisions in InnoDB for multiple insert buffer B-trees, apparently one for each tablespace. When Heikki implemented innodb_file_per_table (multiple InnoDB tablespaces) in MySQL 4.1, he made the insert buffer live only in the system tablespace (space 0) but left the provisions in the code. When Osku Salerma implemented delete buffering, he also cleaned up the insert buffer subsystem so that only one insert buffer B-tree exists. This patch applies the clean-up to the InnoDB Plugin. Having a separate patch of the insert buffer clean-up should help us better compare the essential changes of the InnoDB Plugin and InnoDB+ and to track down bugs that are specific to InnoDB+. IBUF_SPACE_ID: New constant, defined as 0. ibuf_data_t: Remove. ibuf_t: Add the applicable fields from ibuf_data_t. There is only one insert buffer tree from now on. ibuf_page_low(), ibuf_page(): Merge to a single function ibuf_page(). fil_space_t: Remove ibuf_data. fil_space_get_ibuf_data(): Remove. There is only one ibuf_data, for space IBUF_SPACE_ID. fil_ibuf_init_at_db_start(): Remove. ibuf_init_at_db_start(): Fuse with ibuf_data_init_for_space(). ibuf_validate_low(): Remove. There is only one ibuf tree. ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_free_excess_pages(): Remove the parameter space, which was always 0. ibuf_tree_root_get(): Remove the parameters space and data. There is only one ibuf tree, for space IBUF_SPACE_ID. ibuf_data_sizes_update(): Rename to ibuf_size_update(), and remove the parameter data. There is only one ibuf data struct. ibuf_build_entry_pre_4_1_x(): New function, refactored from ibuf_build_entry_from_ibuf_rec(). ibuf_data_enough_free_for_insert(), ibuf_data_too_much_free(): Remove the parameter data. There is only one insert buffer tree. ibuf_add_free_page(), ibuf_remove_free_page(): Remove the parameters space and data. There is only one insert buffer tree. ibuf_get_merge_page_nos(): Add parenthesis, to reduce diffs to branches/innodb+. ibuf_contract_ext(): Do not pick an insert buffer tree at random. There is only one. ibuf_print(): Print the single insert buffer tree. rb://19 approved by Heikki on IM
17 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
20 years ago
branches/zip: Clean up the insert buffer subsystem. Originally, there were provisions in InnoDB for multiple insert buffer B-trees, apparently one for each tablespace. When Heikki implemented innodb_file_per_table (multiple InnoDB tablespaces) in MySQL 4.1, he made the insert buffer live only in the system tablespace (space 0) but left the provisions in the code. When Osku Salerma implemented delete buffering, he also cleaned up the insert buffer subsystem so that only one insert buffer B-tree exists. This patch applies the clean-up to the InnoDB Plugin. Having a separate patch of the insert buffer clean-up should help us better compare the essential changes of the InnoDB Plugin and InnoDB+ and to track down bugs that are specific to InnoDB+. IBUF_SPACE_ID: New constant, defined as 0. ibuf_data_t: Remove. ibuf_t: Add the applicable fields from ibuf_data_t. There is only one insert buffer tree from now on. ibuf_page_low(), ibuf_page(): Merge to a single function ibuf_page(). fil_space_t: Remove ibuf_data. fil_space_get_ibuf_data(): Remove. There is only one ibuf_data, for space IBUF_SPACE_ID. fil_ibuf_init_at_db_start(): Remove. ibuf_init_at_db_start(): Fuse with ibuf_data_init_for_space(). ibuf_validate_low(): Remove. There is only one ibuf tree. ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_free_excess_pages(): Remove the parameter space, which was always 0. ibuf_tree_root_get(): Remove the parameters space and data. There is only one ibuf tree, for space IBUF_SPACE_ID. ibuf_data_sizes_update(): Rename to ibuf_size_update(), and remove the parameter data. There is only one ibuf data struct. ibuf_build_entry_pre_4_1_x(): New function, refactored from ibuf_build_entry_from_ibuf_rec(). ibuf_data_enough_free_for_insert(), ibuf_data_too_much_free(): Remove the parameter data. There is only one insert buffer tree. ibuf_add_free_page(), ibuf_remove_free_page(): Remove the parameters space and data. There is only one insert buffer tree. ibuf_get_merge_page_nos(): Add parenthesis, to reduce diffs to branches/innodb+. ibuf_contract_ext(): Do not pick an insert buffer tree at random. There is only one. ibuf_print(): Print the single insert buffer tree. rb://19 approved by Heikki on IM
17 years ago
20 years ago
  1. /******************************************************
  2. Insert buffer
  3. (c) 1997 Innobase Oy
  4. Created 7/19/1997 Heikki Tuuri
  5. *******************************************************/
  6. #ifndef ibuf0ibuf_h
  7. #define ibuf0ibuf_h
  8. #include "univ.i"
  9. #include "dict0mem.h"
  10. #include "dict0dict.h"
  11. #include "mtr0mtr.h"
  12. #include "que0types.h"
  13. #include "ibuf0types.h"
  14. #include "fsp0fsp.h"
  15. extern ibuf_t* ibuf;
  16. /* The purpose of the insert buffer is to reduce random disk access.
  17. When we wish to insert a record into a non-unique secondary index and
  18. the B-tree leaf page where the record belongs to is not in the buffer
  19. pool, we insert the record into the insert buffer B-tree, indexed by
  20. (space_id, page_no). When the page is eventually read into the buffer
  21. pool, we look up the insert buffer B-tree for any modifications to the
  22. page, and apply these upon the completion of the read operation. This
  23. is called the insert buffer merge. */
  24. /* The insert buffer merge must always succeed. To guarantee this,
  25. the insert buffer subsystem keeps track of the free space in pages for
  26. which it can buffer operations. Two bits per page in the insert
  27. buffer bitmap indicate the available space in coarse increments. The
  28. free bits in the insert buffer bitmap must never exceed the free space
  29. on a page. It is safe to decrement or reset the bits in the bitmap in
  30. a mini-transaction that is committed before the mini-transaction that
  31. affects the free space. It is unsafe to increment the bits in a
  32. separately committed mini-transaction, because in crash recovery, the
  33. free bits could momentarily be set too high. */
  34. /**********************************************************************
  35. Creates the insert buffer data structure at a database startup and
  36. initializes the data structures for the insert buffer of each tablespace. */
  37. UNIV_INTERN
  38. void
  39. ibuf_init_at_db_start(void);
  40. /*=======================*/
  41. /*************************************************************************
  42. Reads the biggest tablespace id from the high end of the insert buffer
  43. tree and updates the counter in fil_system. */
  44. UNIV_INTERN
  45. void
  46. ibuf_update_max_tablespace_id(void);
  47. /*===============================*/
  48. /*************************************************************************
  49. Initializes an ibuf bitmap page. */
  50. UNIV_INTERN
  51. void
  52. ibuf_bitmap_page_init(
  53. /*==================*/
  54. buf_block_t* block, /* in: bitmap page */
  55. mtr_t* mtr); /* in: mtr */
  56. /****************************************************************************
  57. Resets the free bits of the page in the ibuf bitmap. This is done in a
  58. separate mini-transaction, hence this operation does not restrict
  59. further work to only ibuf bitmap operations, which would result if the
  60. latch to the bitmap page were kept. NOTE: The free bits in the insert
  61. buffer bitmap must never exceed the free space on a page. It is safe
  62. to decrement or reset the bits in the bitmap in a mini-transaction
  63. that is committed before the mini-transaction that affects the free
  64. space. */
  65. UNIV_INTERN
  66. void
  67. ibuf_reset_free_bits(
  68. /*=================*/
  69. buf_block_t* block); /* in: index page; free bits are set to 0
  70. if the index is a non-clustered
  71. non-unique, and page level is 0 */
  72. /****************************************************************************
  73. Updates the free bits of an uncompressed page in the ibuf bitmap if
  74. there is not enough free on the page any more. This is done in a
  75. separate mini-transaction, hence this operation does not restrict
  76. further work to only ibuf bitmap operations, which would result if the
  77. latch to the bitmap page were kept. NOTE: The free bits in the insert
  78. buffer bitmap must never exceed the free space on a page. It is
  79. unsafe to increment the bits in a separately committed
  80. mini-transaction, because in crash recovery, the free bits could
  81. momentarily be set too high. It is only safe to use this function for
  82. decrementing the free bits. Should more free space become available,
  83. we must not update the free bits here, because that would break crash
  84. recovery. */
  85. UNIV_INLINE
  86. void
  87. ibuf_update_free_bits_if_full(
  88. /*==========================*/
  89. buf_block_t* block, /* in: index page to which we have added new
  90. records; the free bits are updated if the
  91. index is non-clustered and non-unique and
  92. the page level is 0, and the page becomes
  93. fuller */
  94. ulint max_ins_size,/* in: value of maximum insert size with
  95. reorganize before the latest operation
  96. performed to the page */
  97. ulint increase);/* in: upper limit for the additional space
  98. used in the latest operation, if known, or
  99. ULINT_UNDEFINED */
  100. /**************************************************************************
  101. Updates the free bits for an uncompressed page to reflect the present
  102. state. Does this in the mtr given, which means that the latching
  103. order rules virtually prevent any further operations for this OS
  104. thread until mtr is committed. NOTE: The free bits in the insert
  105. buffer bitmap must never exceed the free space on a page. It is safe
  106. to set the free bits in the same mini-transaction that updated the
  107. page. */
  108. UNIV_INTERN
  109. void
  110. ibuf_update_free_bits_low(
  111. /*======================*/
  112. const buf_block_t* block, /* in: index page */
  113. ulint max_ins_size, /* in: value of
  114. maximum insert size
  115. with reorganize before
  116. the latest operation
  117. performed to the page */
  118. mtr_t* mtr); /* in/out: mtr */
  119. /**************************************************************************
  120. Updates the free bits for a compressed page to reflect the present
  121. state. Does this in the mtr given, which means that the latching
  122. order rules virtually prevent any further operations for this OS
  123. thread until mtr is committed. NOTE: The free bits in the insert
  124. buffer bitmap must never exceed the free space on a page. It is safe
  125. to set the free bits in the same mini-transaction that updated the
  126. page. */
  127. UNIV_INTERN
  128. void
  129. ibuf_update_free_bits_zip(
  130. /*======================*/
  131. buf_block_t* block, /* in/out: index page */
  132. mtr_t* mtr); /* in/out: mtr */
  133. /**************************************************************************
  134. Updates the free bits for the two pages to reflect the present state.
  135. Does this in the mtr given, which means that the latching order rules
  136. virtually prevent any further operations until mtr is committed.
  137. NOTE: The free bits in the insert buffer bitmap must never exceed the
  138. free space on a page. It is safe to set the free bits in the same
  139. mini-transaction that updated the pages. */
  140. UNIV_INTERN
  141. void
  142. ibuf_update_free_bits_for_two_pages_low(
  143. /*====================================*/
  144. ulint zip_size,/* in: compressed page size in bytes;
  145. 0 for uncompressed pages */
  146. buf_block_t* block1, /* in: index page */
  147. buf_block_t* block2, /* in: index page */
  148. mtr_t* mtr); /* in: mtr */
  149. /**************************************************************************
  150. A basic partial test if an insert to the insert buffer could be possible and
  151. recommended. */
  152. UNIV_INLINE
  153. ibool
  154. ibuf_should_try(
  155. /*============*/
  156. dict_index_t* index, /* in: index where to insert */
  157. ulint ignore_sec_unique); /* in: if != 0, we should
  158. ignore UNIQUE constraint on
  159. a secondary index when we
  160. decide */
  161. /**********************************************************************
  162. Returns TRUE if the current OS thread is performing an insert buffer
  163. routine. */
  164. UNIV_INTERN
  165. ibool
  166. ibuf_inside(void);
  167. /*=============*/
  168. /* out: TRUE if inside an insert buffer routine: for instance,
  169. a read-ahead of non-ibuf pages is then forbidden */
  170. /***************************************************************************
  171. Checks if a page address is an ibuf bitmap page (level 3 page) address. */
  172. UNIV_INLINE
  173. ibool
  174. ibuf_bitmap_page(
  175. /*=============*/
  176. /* out: TRUE if a bitmap page */
  177. ulint zip_size,/* in: compressed page size in bytes;
  178. 0 for uncompressed pages */
  179. ulint page_no);/* in: page number */
  180. /***************************************************************************
  181. Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
  182. Must not be called when recv_no_ibuf_operations==TRUE. */
  183. UNIV_INTERN
  184. ibool
  185. ibuf_page(
  186. /*======*/
  187. /* out: TRUE if level 2 or level 3 page */
  188. ulint space, /* in: space id */
  189. ulint zip_size,/* in: compressed page size in bytes, or 0 */
  190. ulint page_no,/* in: page number */
  191. mtr_t* mtr); /* in: mtr which will contain an x-latch to the
  192. bitmap page if the page is not one of the fixed
  193. address ibuf pages, or NULL, in which case a new
  194. transaction is created. */
  195. /***************************************************************************
  196. Frees excess pages from the ibuf free list. This function is called when an OS
  197. thread calls fsp services to allocate a new file segment, or a new page to a
  198. file segment, and the thread did not own the fsp latch before this call. */
  199. UNIV_INTERN
  200. void
  201. ibuf_free_excess_pages(void);
  202. /*========================*/
  203. /*************************************************************************
  204. Makes an index insert to the insert buffer, instead of directly to the disk
  205. page, if this is possible. Does not do insert if the index is clustered
  206. or unique. */
  207. UNIV_INTERN
  208. ibool
  209. ibuf_insert(
  210. /*========*/
  211. /* out: TRUE if success */
  212. const dtuple_t* entry, /* in: index entry to insert */
  213. dict_index_t* index, /* in: index where to insert */
  214. ulint space, /* in: space id where to insert */
  215. ulint zip_size,/* in: compressed page size in bytes, or 0 */
  216. ulint page_no,/* in: page number where to insert */
  217. que_thr_t* thr); /* in: query thread */
  218. /*************************************************************************
  219. When an index page is read from a disk to the buffer pool, this function
  220. inserts to the page the possible index entries buffered in the insert buffer.
  221. The entries are deleted from the insert buffer. If the page is not read, but
  222. created in the buffer pool, this function deletes its buffered entries from
  223. the insert buffer; there can exist entries for such a page if the page
  224. belonged to an index which subsequently was dropped. */
  225. UNIV_INTERN
  226. void
  227. ibuf_merge_or_delete_for_page(
  228. /*==========================*/
  229. buf_block_t* block, /* in: if page has been read from
  230. disk, pointer to the page x-latched,
  231. else NULL */
  232. ulint space, /* in: space id of the index page */
  233. ulint page_no,/* in: page number of the index page */
  234. ulint zip_size,/* in: compressed page size in bytes,
  235. or 0 */
  236. ibool update_ibuf_bitmap);/* in: normally this is set
  237. to TRUE, but if we have deleted or are
  238. deleting the tablespace, then we
  239. naturally do not want to update a
  240. non-existent bitmap page */
  241. /*************************************************************************
  242. Deletes all entries in the insert buffer for a given space id. This is used
  243. in DISCARD TABLESPACE and IMPORT TABLESPACE.
  244. NOTE: this does not update the page free bitmaps in the space. The space will
  245. become CORRUPT when you call this function! */
  246. UNIV_INTERN
  247. void
  248. ibuf_delete_for_discarded_space(
  249. /*============================*/
  250. ulint space); /* in: space id */
  251. /*************************************************************************
  252. Contracts insert buffer trees by reading pages to the buffer pool. */
  253. UNIV_INTERN
  254. ulint
  255. ibuf_contract(
  256. /*==========*/
  257. /* out: a lower limit for the combined size in bytes
  258. of entries which will be merged from ibuf trees to the
  259. pages read, 0 if ibuf is empty */
  260. ibool sync); /* in: TRUE if the caller wants to wait for the
  261. issued read with the highest tablespace address
  262. to complete */
  263. /*************************************************************************
  264. Contracts insert buffer trees by reading pages to the buffer pool. */
  265. UNIV_INTERN
  266. ulint
  267. ibuf_contract_for_n_pages(
  268. /*======================*/
  269. /* out: a lower limit for the combined size in bytes
  270. of entries which will be merged from ibuf trees to the
  271. pages read, 0 if ibuf is empty */
  272. ibool sync, /* in: TRUE if the caller wants to wait for the
  273. issued read with the highest tablespace address
  274. to complete */
  275. ulint n_pages);/* in: try to read at least this many pages to
  276. the buffer pool and merge the ibuf contents to
  277. them */
  278. /*************************************************************************
  279. Parses a redo log record of an ibuf bitmap page init. */
  280. UNIV_INTERN
  281. byte*
  282. ibuf_parse_bitmap_init(
  283. /*===================*/
  284. /* out: end of log record or NULL */
  285. byte* ptr, /* in: buffer */
  286. byte* end_ptr,/* in: buffer end */
  287. buf_block_t* block, /* in: block or NULL */
  288. mtr_t* mtr); /* in: mtr or NULL */
  289. #ifdef UNIV_IBUF_COUNT_DEBUG
  290. /**********************************************************************
  291. Gets the ibuf count for a given page. */
  292. UNIV_INTERN
  293. ulint
  294. ibuf_count_get(
  295. /*===========*/
  296. /* out: number of entries in the insert buffer
  297. currently buffered for this page */
  298. ulint space, /* in: space id */
  299. ulint page_no);/* in: page number */
  300. #endif
  301. /**********************************************************************
  302. Looks if the insert buffer is empty. */
  303. UNIV_INTERN
  304. ibool
  305. ibuf_is_empty(void);
  306. /*===============*/
  307. /* out: TRUE if empty */
  308. /**********************************************************************
  309. Prints info of ibuf. */
  310. UNIV_INTERN
  311. void
  312. ibuf_print(
  313. /*=======*/
  314. FILE* file); /* in: file where to print */
  315. #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
  316. #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
  317. /* The ibuf header page currently contains only the file segment header
  318. for the file segment from which the pages for the ibuf tree are allocated */
  319. #define IBUF_HEADER PAGE_DATA
  320. #define IBUF_TREE_SEG_HEADER 0 /* fseg header for ibuf tree */
  321. /* The insert buffer tree itself is always located in space 0. */
  322. #define IBUF_SPACE_ID 0
  323. #ifndef UNIV_NONINL
  324. #include "ibuf0ibuf.ic"
  325. #endif
  326. #endif