📄 ibuf0ibuf.c
字号:
mtr_commit(&mtr); return(ret);}/***************************************************************************Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */iboolibuf_page_low(/*==========*/ /* out: TRUE if level 2 or level 3 page */ ulint space, /* in: space id */ ulint page_no,/* in: page number */ mtr_t* mtr) /* in: mtr which will contain an x-latch to the bitmap page if the page is not one of the fixed address ibuf pages */{ page_t* bitmap_page; ibool ret;#ifdef UNIV_LOG_DEBUG if (space % 2 != 0) { fputs("No ibuf in a replicate space\n", stderr); return(FALSE); }#endif if (ibuf_fixed_addr_page(page_no)) { return(TRUE); } bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr); ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF, mtr); return(ret);}/************************************************************************Returns the page number field of an ibuf record. */staticulintibuf_rec_get_page_no(/*=================*/ /* out: page number */ rec_t* rec) /* in: ibuf record */{ byte* field; ulint len; ut_ad(ibuf_inside()); ut_ad(rec_get_n_fields_old(rec) > 2); field = rec_get_nth_field_old(rec, 1, &len); if (len == 1) { /* This is of the >= 4.1.x record format */ ut_a(trx_sys_multiple_tablespace_format); field = rec_get_nth_field_old(rec, 2, &len); } else { ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); field = rec_get_nth_field_old(rec, 0, &len); } ut_a(len == 4); return(mach_read_from_4(field));}/************************************************************************Returns the space id field of an ibuf record. For < 4.1.x format recordsreturns 0. */staticulintibuf_rec_get_space(/*===============*/ /* out: space id */ rec_t* rec) /* in: ibuf record */{ byte* field; ulint len; ut_ad(ibuf_inside()); ut_ad(rec_get_n_fields_old(rec) > 2); field = rec_get_nth_field_old(rec, 1, &len); if (len == 1) { /* This is of the >= 4.1.x record format */ ut_a(trx_sys_multiple_tablespace_format); field = rec_get_nth_field_old(rec, 0, &len); ut_a(len == 4); return(mach_read_from_4(field)); } ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); return(0);}/************************************************************************Creates a dummy index for inserting a record to a non-clustered index.*/staticdict_index_t*ibuf_dummy_index_create(/*====================*/ /* out: dummy index */ ulint n, /* in: number of fields */ ibool comp) /* in: TRUE=use compact record format */{ dict_table_t* table; dict_index_t* index; table = dict_mem_table_create("IBUF_DUMMY", DICT_HDR_SPACE, n, comp); index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY", DICT_HDR_SPACE, 0, n); index->table = table; /* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */ index->cached = TRUE; return(index);}/************************************************************************Add a column to the dummy index */staticvoidibuf_dummy_index_add_col(/*====================*/ dict_index_t* index, /* in: dummy index */ dtype_t* type, /* in: the data type of the column */ ulint len) /* in: length of the column */{ ulint i = index->table->n_def; dict_mem_table_add_col(index->table, "DUMMY", dtype_get_mtype(type), dtype_get_prtype(type), dtype_get_len(type), dtype_get_prec(type)); dict_index_add_col(index, dict_table_get_nth_col(index->table, i), 0, len);}/************************************************************************Deallocates a dummy index for inserting a record to a non-clustered index.*/staticvoidibuf_dummy_index_free(/*====================*/ dict_index_t* index) /* in: dummy index */{ dict_table_t* table = index->table; mem_heap_free(index->heap); mutex_free(&(table->autoinc_mutex)); mem_heap_free(table->heap);}/*************************************************************************Builds the entry to insert into a non-clustered index when we have thecorresponding record in an ibuf index. */staticdtuple_t*ibuf_build_entry_from_ibuf_rec(/*===========================*/ /* out, own: entry to insert to a non-clustered index; NOTE that as we copy pointers to fields in ibuf_rec, the caller must hold a latch to the ibuf_rec page as long as the entry is used! */ rec_t* ibuf_rec, /* in: record in an insert buffer */ mem_heap_t* heap, /* in: heap where built */ dict_index_t** pindex) /* out, own: dummy index that describes the entry */{ dtuple_t* tuple; dfield_t* field; ulint n_fields; byte* types; const byte* data; ulint len; ulint i; dict_index_t* index; data = rec_get_nth_field_old(ibuf_rec, 1, &len); if (len > 1) { /* This a < 4.1.x format record */ ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); n_fields = rec_get_n_fields_old(ibuf_rec) - 2; tuple = dtuple_create(heap, n_fields); types = rec_get_nth_field_old(ibuf_rec, 1, &len); ut_a(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(tuple, i); data = rec_get_nth_field_old(ibuf_rec, i + 2, &len); dfield_set_data(field, data, len); dtype_read_for_order_and_null_size( dfield_get_type(field), types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE); } *pindex = ibuf_dummy_index_create(n_fields, FALSE); return(tuple); } /* This a >= 4.1.x format record */ ut_a(trx_sys_multiple_tablespace_format); ut_a(*data == 0); ut_a(rec_get_n_fields_old(ibuf_rec) > 4); n_fields = rec_get_n_fields_old(ibuf_rec) - 4; tuple = dtuple_create(heap, n_fields); types = rec_get_nth_field_old(ibuf_rec, 3, &len); ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1); index = ibuf_dummy_index_create(n_fields, len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) { /* compact record format */ len--; ut_a(*types == 0); types++; } ut_a(len == n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(tuple, i); data = rec_get_nth_field_old(ibuf_rec, i + 4, &len); dfield_set_data(field, data, len); dtype_new_read_for_order_and_null_size( dfield_get_type(field), types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); ibuf_dummy_index_add_col(index, dfield_get_type(field), len); } *pindex = index; return(tuple);}/************************************************************************Returns the space taken by a stored non-clustered index entry if converted toan index record. */staticulintibuf_rec_get_volume(/*================*/ /* out: size of index record in bytes + an upper limit of the space taken in the page directory */ rec_t* ibuf_rec)/* in: ibuf record */{ dtype_t dtype; ibool new_format = FALSE; ulint data_size = 0; ulint n_fields; byte* types; byte* data; ulint len; ulint i; ut_ad(ibuf_inside()); ut_ad(rec_get_n_fields_old(ibuf_rec) > 2); data = rec_get_nth_field_old(ibuf_rec, 1, &len); if (len > 1) { /* < 4.1.x format record */ ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); n_fields = rec_get_n_fields_old(ibuf_rec) - 2; types = rec_get_nth_field_old(ibuf_rec, 1, &len); ut_ad(len == n_fields * DATA_ORDER_NULL_TYPE_BUF_SIZE); } else { /* >= 4.1.x format record */ ut_a(trx_sys_multiple_tablespace_format); ut_a(*data == 0); types = rec_get_nth_field_old(ibuf_rec, 3, &len); ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1); if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) { /* compact record format */ ulint volume; dict_index_t* dummy_index; mem_heap_t* heap = mem_heap_create(500); dtuple_t* entry = ibuf_build_entry_from_ibuf_rec( ibuf_rec, heap, &dummy_index); volume = rec_get_converted_size(dummy_index, entry); ibuf_dummy_index_free(dummy_index); mem_heap_free(heap); return(volume + page_dir_calc_reserved_space(1)); } n_fields = rec_get_n_fields_old(ibuf_rec) - 4; new_format = TRUE; } for (i = 0; i < n_fields; i++) { if (new_format) { data = rec_get_nth_field_old(ibuf_rec, i + 4, &len); dtype_new_read_for_order_and_null_size(&dtype, types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE); } else { data = rec_get_nth_field_old(ibuf_rec, i + 2, &len); dtype_read_for_order_and_null_size(&dtype, types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE); } if (len == UNIV_SQL_NULL) { data_size += dtype_get_sql_null_size(&dtype); } else { data_size += len; } } return(data_size + rec_get_converted_extra_size(data_size, n_fields) + page_dir_calc_reserved_space(1));}/*************************************************************************Builds the tuple to insert to an ibuf tree when we have an entry for anon-clustered index. */staticdtuple_t*ibuf_entry_build(/*=============*/ /* out, own: entry to insert into an ibuf index tree; NOTE that the original entry must be kept because we copy pointers to its fields */ dtuple_t* entry, /* in: entry for a non-clustered index */ ibool comp, /* in: flag: TRUE=compact record format */ ulint space, /* in: space id */ ulint page_no,/* in: index page number where entry should be inserted */ mem_heap_t* heap) /* in: heap into which to build */{ dtuple_t* tuple; dfield_t* field; dfield_t* entry_field; ulint n_fields; byte* buf; byte* buf2; ulint i; /* Starting from 4.1.x, we have to build a tuple whose (1) first field is the space id, (2) the second field a single marker byte (0) to tell that this is a new format record, (3) the third contains the page number, and (4) the fourth contains the relevent type information of each data field; the length of this field % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE is (a) 0 for b-trees in the old format, and (b) 1 for b-trees in the compact format, the first byte of the field being the marker (0); (5) and the rest of the fields are copied from entry. All fields in the tuple are ordered like the type binary in our insert buffer tree. */ n_fields = dtuple_get_n_fields(entry); tuple = dtuple_create(heap, n_fields + 4); /* Store the space id in tuple */ field = dtuple_get_nth_field(tuple, 0); buf = mem_heap_alloc(heap, 4); mach_write_to_4(buf, space); dfield_set_data(field, buf, 4); /* Store the marker byte field in tuple */ field = dtuple_get_nth_field(tuple, 1); buf = mem_heap_alloc(heap, 1); /* We set the marker byte zero */ mach_write_to_1(buf, 0); dfield_set_data(field, buf, 1); /* Store the page number in tuple */ field = dtuple_get_nth_field(tuple, 2); buf = mem_heap_alloc(heap, 4); mach_write_to_4(buf, page_no); dfield_set_data(field, buf, 4); ut_ad(comp == 0 || comp == 1); /* Store the type info in buf2, and add the fields from entry to tuple */ buf2 = mem_heap_alloc(heap, n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE + comp); if (comp) { *buf2++ = 0; /* write the compact format indicator */ } for (i = 0; i < n_fields; i++) { /* We add 4 below because we have the 4 extra fields at the start of an ibuf record */ field = dtuple_get_nth_field(tuple, i + 4); entry_field = dtuple_get_nth_field(entry, i); dfield_copy(field, entry_field); dtype_new_store_for_order_and_null_size( buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE, dfield_get_type(entry_field)); } /* Store the type info in buf2 to field 3 of tuple */ field = dtuple_get_nth_field(tuple, 3); if (comp) { buf2--; } dfield_set_data(field, buf2, n_fields * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE + comp); /* Set all the types in the new tuple binary */ dtuple_set_types_binary(tuple, n_fields + 4); return(tuple);} /*************************************************************************Builds a search tuple used to search buffered inserts for an index page.This is for < 4.1.x format records */staticdtuple_t*ibuf_search_tuple_build(/*====================*/ /* out, own: search tuple */ ulint space, /* in: space id */ ulint page_no,/* in: index page number */ mem_heap_t* heap) /* in: heap into which to build */{ dtuple_t* tuple; dfield_t* field; byte* buf; ut_a(space == 0); ut_a(trx_doublewrite_must_reset_space_ids); ut_a(!trx_sys_multiple_tablespace_format); tuple = dtuple_create(heap, 1); /* Store the page number in tuple */ field = dtuple_get_nth_field(tuple, 0); buf = mem_heap_alloc(heap, 4); mach_write_to_4(buf, page_no); dfield_set_data(field, buf, 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -