summaryrefslogtreecommitdiff
path: root/innobase/page
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-12-02 19:45:07 +0200
committerunknown <marko@hundin.mysql.fi>2004-12-02 19:45:07 +0200
commitd2c4b545405845900af52e033240040ee2ab83dd (patch)
treec3c716219a8f464ef096a6dd06835d4bfb627c8a /innobase/page
parent4a9ef43a4961ee8795f143be4d390ab67bbf65d7 (diff)
downloadmariadb-git-d2c4b545405845900af52e033240040ee2ab83dd.tar.gz
Many files:
Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0btr.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0cur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0pcur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/btr/btr0sea.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/data/data0data.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/data/data0type.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0boot.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0crea.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0dict.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0load.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/dict/dict0mem.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/fil/fil0fil.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/fsp/fsp0fsp.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/ibuf/ibuf0ibuf.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0btr.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0btr.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0cur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0cur.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0pcur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/btr0sea.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/data0type.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0dict.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0dict.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/dict0mem.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/lock0lock.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/lock0lock.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/mtr0log.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/mtr0mtr.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0cur.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0cur.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0page.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/page0page.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0cmp.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0cmp.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0rec.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/rem0rec.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0row.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0row.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0upd.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0upd.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0vers.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/row0vers.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/srv0srv.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/trx0rec.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/ut0byte.h: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/include/ut0byte.ic: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/lock/lock0lock.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/log/log0recv.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/mtr/mtr0log.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/page/page0cur.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/page/page0page.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/pars/pars0pars.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/rem/rem0cmp.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/rem/rem0rec.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0ins.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0mysql.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0purge.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0row.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0sel.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0umod.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0undo.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0upd.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/row/row0vers.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/srv/srv0srv.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/trx/trx0rec.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. innobase/trx/trx0undo.c: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC. sql/ha_innodb.cc: Implement more compact InnoDB record format. Old format is available as CREATE TABLE ... ROW_FORMAT=DYNAMIC.
Diffstat (limited to 'innobase/page')
-rw-r--r--innobase/page/page0cur.c408
-rw-r--r--innobase/page/page0page.c520
2 files changed, 600 insertions, 328 deletions
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index 459ab986610..8def8474d9a 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -30,6 +30,7 @@ ibool
page_cur_try_search_shortcut(
/*=========================*/
page_t* page, /* in: index page */
+ dict_index_t* index, /* in: record descriptor */
dtuple_t* tuple, /* in: data tuple */
ulint* iup_matched_fields,
/* in/out: already matched fields in upper
@@ -55,9 +56,14 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_DEBUG
page_cur_t cursor2;
#endif
+ mem_heap_t* heap;
+ ulint* offsets;
ut_ad(dtuple_check_typed(tuple));
rec = page_header_get_ptr(page, PAGE_LAST_INSERT);
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(rec, index,
+ dtuple_get_n_fields(tuple), heap);
ut_ad(rec);
ut_ad(page_rec_is_user_rec(rec));
@@ -69,26 +75,30 @@ page_cur_try_search_shortcut(
up_match = low_match;
up_bytes = low_bytes;
- cmp = page_cmp_dtuple_rec_with_match(tuple, rec, &low_match,
+ cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match,
&low_bytes);
if (cmp == -1) {
+ mem_heap_free(heap);
return(FALSE);
}
next_rec = page_rec_get_next(rec);
+ offsets = rec_reget_offsets(next_rec, index, offsets,
+ dtuple_get_n_fields(tuple), heap);
- cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, &up_match,
- &up_bytes);
+ cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets,
+ &up_match, &up_bytes);
if (cmp != -1) {
+ mem_heap_free(heap);
return(FALSE);
}
cursor->rec = rec;
#ifdef UNIV_SEARCH_DEBUG
- page_cur_search_with_match(page, tuple, PAGE_CUR_DBG,
+ page_cur_search_with_match(page, index, tuple, PAGE_CUR_DBG,
iup_matched_fields,
iup_matched_bytes,
ilow_matched_fields,
@@ -117,6 +127,7 @@ page_cur_try_search_shortcut(
#ifdef UNIV_SEARCH_PERF_STAT
page_cur_short_succ++;
#endif
+ mem_heap_free(heap);
return(TRUE);
}
@@ -130,22 +141,24 @@ static
ibool
page_cur_rec_field_extends(
/*=======================*/
- /* out: TRUE if rec field extends tuple
- field */
- dtuple_t* tuple, /* in: data tuple */
- rec_t* rec, /* in: record */
- ulint n) /* in: compare nth field */
+ /* out: TRUE if rec field
+ extends tuple field */
+ dtuple_t* tuple, /* in: data tuple */
+ rec_t* rec, /* in: record */
+ const ulint* offsets,/* in: array returned by rec_get_offsets() */
+ ulint n) /* in: compare nth field */
{
dtype_t* type;
dfield_t* dfield;
byte* rec_f;
ulint rec_f_len;
+ ut_ad(rec_offs_validate(rec, NULL, offsets));
dfield = dtuple_get_nth_field(tuple, n);
type = dfield_get_type(dfield);
- rec_f = rec_get_nth_field(rec, n, &rec_f_len);
+ rec_f = rec_get_nth_field(rec, offsets, n, &rec_f_len);
if (type->mtype == DATA_VARCHAR
|| type->mtype == DATA_CHAR
@@ -176,6 +189,7 @@ void
page_cur_search_with_match(
/*=======================*/
page_t* page, /* in: index page */
+ dict_index_t* index, /* in: record descriptor */
dtuple_t* tuple, /* in: data tuple */
ulint mode, /* in: PAGE_CUR_L, PAGE_CUR_LE, PAGE_CUR_G,
or PAGE_CUR_GE */
@@ -212,6 +226,9 @@ page_cur_search_with_match(
ulint dbg_matched_fields;
ulint dbg_matched_bytes;
#endif
+ mem_heap_t* heap;
+ ulint* offsets = NULL;
+
ut_ad(page && tuple && iup_matched_fields && iup_matched_bytes
&& ilow_matched_fields && ilow_matched_bytes && cursor);
ut_ad(dtuple_validate(tuple));
@@ -229,7 +246,7 @@ page_cur_search_with_match(
&& (page_header_get_ptr(page, PAGE_LAST_INSERT))
&& (page_header_get_field(page, PAGE_DIRECTION) == PAGE_RIGHT)) {
- if (page_cur_try_search_shortcut(page, tuple,
+ if (page_cur_try_search_shortcut(page, index, tuple,
iup_matched_fields,
iup_matched_bytes,
ilow_matched_fields,
@@ -245,6 +262,8 @@ page_cur_search_with_match(
/*#endif */
#endif
+ heap = mem_heap_create(100);
+
/* The following flag does not work for non-latin1 char sets because
cmp_full_field does not tell how many bytes matched */
ut_a(mode != PAGE_CUR_LE_OR_EXTENDS);
@@ -279,7 +298,10 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes);
- cmp = cmp_dtuple_rec_with_match(tuple, mid_rec,
+ offsets = rec_reget_offsets(mid_rec, index, offsets,
+ dtuple_get_n_fields_cmp(tuple), heap);
+
+ cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields,
&cur_matched_bytes);
if (cmp == 1) {
@@ -288,10 +310,12 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
+ offsets = rec_reget_offsets(mid_rec, index,
+ offsets, dtuple_get_n_fields_cmp(tuple), heap);
if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec,
- cur_matched_fields)) {
+ offsets, cur_matched_fields)) {
low = mid;
low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes;
@@ -329,7 +353,10 @@ page_cur_search_with_match(
low_matched_fields, low_matched_bytes,
up_matched_fields, up_matched_bytes);
- cmp = cmp_dtuple_rec_with_match(tuple, mid_rec,
+ offsets = rec_reget_offsets(mid_rec, index,
+ offsets, dtuple_get_n_fields_cmp(tuple), heap);
+
+ cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets,
&cur_matched_fields,
&cur_matched_bytes);
if (cmp == 1) {
@@ -338,9 +365,12 @@ page_cur_search_with_match(
low_matched_bytes = cur_matched_bytes;
} else if (cmp == -1) {
+ offsets = rec_reget_offsets(mid_rec, index,
+ offsets, dtuple_get_n_fields_cmp(tuple), heap);
+
if (mode == PAGE_CUR_LE_OR_EXTENDS
&& page_cur_rec_field_extends(tuple, mid_rec,
- cur_matched_fields)) {
+ offsets, cur_matched_fields)) {
low_rec = mid_rec;
low_matched_fields = cur_matched_fields;
low_matched_bytes = cur_matched_bytes;
@@ -368,7 +398,9 @@ page_cur_search_with_match(
dbg_matched_fields = 0;
dbg_matched_bytes = 0;
- dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec,
+ offsets = rec_reget_offsets(low_rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, low_rec, offsets,
&dbg_matched_fields,
&dbg_matched_bytes);
if (mode == PAGE_CUR_G) {
@@ -390,7 +422,9 @@ page_cur_search_with_match(
dbg_matched_fields = 0;
dbg_matched_bytes = 0;
- dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec,
+ offsets = rec_reget_offsets(up_rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ dbg_cmp = page_cmp_dtuple_rec_with_match(tuple, up_rec, offsets,
&dbg_matched_fields,
&dbg_matched_bytes);
if (mode == PAGE_CUR_G) {
@@ -419,6 +453,7 @@ page_cur_search_with_match(
*iup_matched_bytes = up_matched_bytes;
*ilow_matched_fields = low_matched_fields;
*ilow_matched_bytes = low_matched_bytes;
+ mem_heap_free(heap);
}
/***************************************************************
@@ -463,10 +498,12 @@ static
void
page_cur_insert_rec_write_log(
/*==========================*/
- rec_t* insert_rec, /* in: inserted physical record */
- ulint rec_size, /* in: insert_rec size */
- rec_t* cursor_rec, /* in: record the cursor is pointing to */
- mtr_t* mtr) /* in: mini-transaction handle */
+ rec_t* insert_rec, /* in: inserted physical record */
+ ulint rec_size, /* in: insert_rec size */
+ rec_t* cursor_rec, /* in: record the
+ cursor is pointing to */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mini-transaction handle */
{
ulint cur_rec_size;
ulint extra_size;
@@ -476,22 +513,29 @@ page_cur_insert_rec_write_log(
byte* cur_ptr;
ulint extra_info_yes;
byte* log_ptr;
+ byte* log_end;
ulint i;
ut_a(rec_size < UNIV_PAGE_SIZE);
- ut_ad(rec_size == rec_get_size(insert_rec));
- log_ptr = mlog_open(mtr, 30 + MLOG_BUF_MARGIN);
+ {
+ mem_heap_t* heap;
+ ulint* cur_offs;
+ ulint* ins_offs;
- if (log_ptr == NULL) {
+ heap = mem_heap_create(100);
+ cur_offs = rec_get_offsets(cursor_rec, index,
+ ULINT_UNDEFINED, heap);
+ ins_offs = rec_get_offsets(insert_rec, index,
+ ULINT_UNDEFINED, heap);
- return;
- }
-
- extra_size = rec_get_extra_size(insert_rec);
+ extra_size = rec_offs_extra_size(ins_offs);
+ cur_extra_size = rec_offs_extra_size(cur_offs);
+ ut_ad(rec_size == rec_offs_size(ins_offs));
+ cur_rec_size = rec_offs_size(cur_offs);
- cur_extra_size = rec_get_extra_size(cursor_rec);
- cur_rec_size = rec_get_size(cursor_rec);
+ mem_heap_free(heap);
+ }
ins_ptr = insert_rec - extra_size;
@@ -514,7 +558,9 @@ page_cur_insert_rec_write_log(
ins_ptr++;
cur_ptr++;
} else if ((i < extra_size)
- && (i >= extra_size - REC_N_EXTRA_BYTES)) {
+ && (i >= extra_size - (index->table->comp
+ ? REC_N_NEW_EXTRA_BYTES
+ : REC_N_OLD_EXTRA_BYTES))) {
i = extra_size;
ins_ptr = insert_rec;
cur_ptr = cursor_rec;
@@ -525,16 +571,35 @@ page_cur_insert_rec_write_log(
}
if (mtr_get_log_mode(mtr) != MTR_LOG_SHORT_INSERTS) {
-
- log_ptr = mlog_write_initial_log_record_fast(insert_rec,
- MLOG_REC_INSERT, log_ptr, mtr);
+
+ log_ptr = mlog_open_and_write_index(mtr, insert_rec, index,
+ index->table->comp
+ ? MLOG_COMP_REC_INSERT : MLOG_REC_INSERT,
+ 2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
+
+ if (!log_ptr) {
+ /* Logging in mtr is switched off during crash
+ recovery: in that case mlog_open returns NULL */
+ return;
+ }
+
+ log_end = &log_ptr[2 + 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN];
/* Write the cursor rec offset as a 2-byte ulint */
mach_write_to_2(log_ptr, cursor_rec
- buf_frame_align(cursor_rec));
log_ptr += 2;
+ } else {
+ log_ptr = mlog_open(mtr, 5 + 1 + 5 + 5 + MLOG_BUF_MARGIN);
+ if (!log_ptr) {
+ /* Logging in mtr is switched off during crash
+ recovery: in that case mlog_open returns NULL */
+ return;
+ }
+ log_end = &log_ptr[5 + 1 + 5 + 5 + MLOG_BUF_MARGIN];
}
- if ((rec_get_info_bits(insert_rec) != rec_get_info_bits(cursor_rec))
+ if ((rec_get_info_bits(insert_rec, index->table->comp) !=
+ rec_get_info_bits(cursor_rec, index->table->comp))
|| (extra_size != cur_extra_size)
|| (rec_size != cur_rec_size)) {
@@ -549,7 +614,8 @@ page_cur_insert_rec_write_log(
+ extra_info_yes);
if (extra_info_yes) {
/* Write the info bits */
- mach_write_to_1(log_ptr, rec_get_info_bits(insert_rec));
+ mach_write_to_1(log_ptr,
+ rec_get_info_bits(insert_rec, index->table->comp));
log_ptr++;
/* Write the record origin offset */
@@ -565,17 +631,15 @@ page_cur_insert_rec_write_log(
/* Write to the log the inserted index record end segment which
differs from the cursor record */
- if (rec_size - i < MLOG_BUF_MARGIN) {
- ut_memcpy(log_ptr, ins_ptr, rec_size - i);
- log_ptr += rec_size - i;
- }
-
- mlog_close(mtr, log_ptr);
-
- ut_a(rec_size - i < UNIV_PAGE_SIZE);
+ rec_size -= i;
- if (rec_size - i >= MLOG_BUF_MARGIN) {
- mlog_catenate_string(mtr, ins_ptr, rec_size - i);
+ if (log_ptr + rec_size <= log_end) {
+ memcpy(log_ptr, ins_ptr, rec_size);
+ mlog_close(mtr, log_ptr + rec_size);
+ } else {
+ mlog_close(mtr, log_ptr);
+ ut_a(rec_size < UNIV_PAGE_SIZE);
+ mlog_catenate_string(mtr, ins_ptr, rec_size);
}
}
@@ -585,12 +649,13 @@ Parses a log record of a record insert on a page. */
byte*
page_cur_parse_insert_rec(
/*======================*/
- /* out: end of log record or NULL */
- ibool is_short,/* in: TRUE if short inserts */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /* out: end of log record or NULL */
+ ibool is_short,/* in: TRUE if short inserts */
+ byte* ptr, /* in: buffer */
+ byte* end_ptr,/* in: buffer end */
+ dict_index_t* index, /* in: record descriptor */
+ page_t* page, /* in: page or NULL */
+ mtr_t* mtr) /* in: mtr or NULL */
{
ulint extra_info_yes;
ulint offset = 0; /* remove warning */
@@ -603,6 +668,8 @@ page_cur_parse_insert_rec(
byte* ptr2 = ptr;
ulint info_bits = 0; /* remove warning */
page_cur_t cursor;
+ mem_heap_t* heap;
+ ulint* offsets;
if (!is_short) {
/* Read the cursor rec offset as a 2-byte ulint */
@@ -689,11 +756,14 @@ page_cur_parse_insert_rec(
cursor_rec = page + offset;
}
+ heap = mem_heap_create(100);
+ offsets = rec_get_offsets(cursor_rec, index, ULINT_UNDEFINED, heap);
+
if (extra_info_yes == 0) {
- info_bits = rec_get_info_bits(cursor_rec);
- origin_offset = rec_get_extra_size(cursor_rec);
- mismatch_index = rec_get_size(cursor_rec) - end_seg_len;
- }
+ info_bits = rec_get_info_bits(cursor_rec, index->table->comp);
+ origin_offset = rec_offs_extra_size(offsets);
+ mismatch_index = rec_offs_size(offsets) - end_seg_len;
+ }
if (mismatch_index + end_seg_len < sizeof buf1) {
buf = buf1;
@@ -722,14 +792,24 @@ page_cur_parse_insert_rec(
ut_error;
}
- ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index);
+ ut_memcpy(buf, rec_get_start(cursor_rec, offsets), mismatch_index);
ut_memcpy(buf + mismatch_index, ptr, end_seg_len);
- rec_set_info_bits(buf + origin_offset, info_bits);
+ rec_set_info_bits(buf + origin_offset, index->table->comp, info_bits);
+
+ /* Set the status bits for new-style records. */
+ if (index->table->comp) {
+ /* Leaf pages (level 0) contain ordinary records;
+ non-leaf pages contain node pointer records. */
+ ulint level = page_header_get_field(
+ buf_frame_align(cursor_rec), PAGE_LEVEL);
+ rec_set_status(buf + origin_offset,
+ level ? REC_STATUS_NODE_PTR : REC_STATUS_ORDINARY);
+ }
page_cur_position(cursor_rec, &cursor);
- page_cur_rec_insert(&cursor, buf + origin_offset, mtr);
+ page_cur_rec_insert(&cursor, buf + origin_offset, index, mtr);
if (buf != buf1) {
@@ -751,68 +831,80 @@ page_cur_insert_rec_low(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
- dtuple_t* tuple, /* in: pointer to a data tuple or NULL */
- ulint data_size,/* in: data size of tuple */
- rec_t* rec, /* in: pointer to a physical record or NULL */
+ dtuple_t* tuple, /* in: pointer to a data tuple or NULL */
+ dict_index_t* index, /* in: record descriptor */
+ rec_t* rec, /* in: pointer to a physical record or NULL */
mtr_t* mtr) /* in: mini-transaction handle */
{
- byte* insert_buf = NULL;
- ulint rec_size;
- byte* page; /* the relevant page */
- rec_t* last_insert; /* cursor position at previous insert */
- rec_t* insert_rec; /* inserted record */
- ulint heap_no; /* heap number of the inserted record */
- rec_t* current_rec; /* current record after which the
- new record is inserted */
- rec_t* next_rec; /* next record after current before
- the insertion */
- ulint owner_slot; /* the slot which owns the inserted record */
- rec_t* owner_rec;
- ulint n_owned;
-
+ byte* insert_buf = NULL;
+ ulint rec_size;
+ byte* page; /* the relevant page */
+ rec_t* last_insert; /* cursor position at previous insert */
+ rec_t* insert_rec; /* inserted record */
+ ulint heap_no; /* heap number of the inserted record */
+ rec_t* current_rec; /* current record after which the
+ new record is inserted */
+ rec_t* next_rec; /* next record after current before
+ the insertion */
+ ulint owner_slot; /* the slot which owns the
+ inserted record */
+ rec_t* owner_rec;
+ ulint n_owned;
+ mem_heap_t* heap;
+ ulint* offsets;
+ ibool comp = index->table->comp;
+
ut_ad(cursor && mtr);
ut_ad(tuple || rec);
ut_ad(!(tuple && rec));
ut_ad(rec || dtuple_check_typed(tuple));
- ut_ad(rec || (dtuple_get_data_size(tuple) == data_size));
page = page_cur_get_page(cursor);
+ ut_ad(page_is_comp(page) == comp);
+
ut_ad(cursor->rec != page_get_supremum_rec(page));
+ heap = mem_heap_create(100);
+
/* 1. Get the size of the physical record in the page */
if (tuple != NULL) {
- rec_size = data_size + rec_get_converted_extra_size(
- data_size,
- dtuple_get_n_fields(tuple));
+ offsets = NULL;
+ rec_size = rec_get_converted_size(index, tuple);
} else {
- rec_size = rec_get_size(rec);
+ offsets = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+ rec_size = rec_offs_size(offsets);
}
/* 2. Try to find suitable space from page memory management */
- insert_buf = page_mem_alloc(page, rec_size, &heap_no);
+ insert_buf = page_mem_alloc(page, rec_size, index, &heap_no);
if (insert_buf == NULL) {
-
+ mem_heap_free(heap);
return(NULL);
}
/* 3. Create the record */
if (tuple != NULL) {
- insert_rec = rec_convert_dtuple_to_rec_low(insert_buf, tuple,
- data_size);
+ insert_rec = rec_convert_dtuple_to_rec(insert_buf,
+ index, tuple);
} else {
- insert_rec = rec_copy(insert_buf, rec);
+ insert_rec = rec_copy(insert_buf, rec, offsets);
}
ut_ad(insert_rec);
- ut_ad(rec_size == rec_get_size(insert_rec));
+ offsets = rec_reget_offsets(insert_rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ ut_ad(rec_size == rec_offs_size(offsets));
/* 4. Insert the record in the linked list of records */
-
current_rec = cursor->rec;
+ ut_ad(!comp || rec_get_status(current_rec) <= REC_STATUS_INFIMUM);
+ ut_ad(!comp || rec_get_status(insert_rec) < REC_STATUS_INFIMUM);
+
next_rec = page_rec_get_next(current_rec);
+ ut_ad(!comp || rec_get_status(next_rec) != REC_STATUS_INFIMUM);
page_rec_set_next(insert_rec, next_rec);
page_rec_set_next(current_rec, insert_rec);
@@ -821,12 +913,15 @@ page_cur_insert_rec_low(
/* 5. Set the n_owned field in the inserted record to zero,
and set the heap_no field */
- rec_set_n_owned(insert_rec, 0);
- rec_set_heap_no(insert_rec, heap_no);
+ rec_set_n_owned(insert_rec, comp, 0);
+ rec_set_heap_no(insert_rec, comp, heap_no);
/* 6. Update the last insertion info in page header */
last_insert = page_header_get_ptr(page, PAGE_LAST_INSERT);
+ ut_ad(!last_insert || !comp
+ || rec_get_node_ptr_flag(last_insert)
+ == rec_get_node_ptr_flag(insert_rec));
if (last_insert == NULL) {
page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION);
@@ -855,8 +950,8 @@ page_cur_insert_rec_low(
/* 7. It remains to update the owner record. */
owner_rec = page_rec_find_owner_rec(insert_rec);
- n_owned = rec_get_n_owned(owner_rec);
- rec_set_n_owned(owner_rec, n_owned + 1);
+ n_owned = rec_get_n_owned(owner_rec, comp);
+ rec_set_n_owned(owner_rec, comp, n_owned + 1);
/* 8. Now we have incremented the n_owned field of the owner
record. If the number exceeds PAGE_DIR_SLOT_MAX_N_OWNED,
@@ -868,8 +963,10 @@ page_cur_insert_rec_low(
}
/* 9. Write log record of the insert */
- page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec, mtr);
+ page_cur_insert_rec_write_log(insert_rec, rec_size, current_rec,
+ index, mtr);
+ mem_heap_free(heap);
return(insert_rec);
}
@@ -879,17 +976,19 @@ UNIV_INLINE
byte*
page_copy_rec_list_to_created_page_write_log(
/*=========================================*/
- /* out: 4-byte field where to write the log data
- length */
- page_t* page, /* in: index page */
- mtr_t* mtr) /* in: mtr */
+ /* out: 4-byte field where to
+ write the log data length */
+ page_t* page, /* in: index page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
byte* log_ptr;
-
- mlog_write_initial_log_record(page, MLOG_LIST_END_COPY_CREATED, mtr);
-
- log_ptr = mlog_open(mtr, 4);
+ log_ptr = mlog_open_and_write_index(mtr, page, index,
+ index->table->comp
+ ? MLOG_COMP_LIST_END_COPY_CREATED
+ : MLOG_LIST_END_COPY_CREATED, 4);
+ ut_a(log_ptr);
mlog_close(mtr, log_ptr + 4);
return(log_ptr);
@@ -901,11 +1000,12 @@ Parses a log record of copying a record list end to a new created page. */
byte*
page_parse_copy_rec_list_to_created_page(
/*=====================================*/
- /* out: end of log record or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /* out: end of log record or NULL */
+ byte* ptr, /* in: buffer */
+ byte* end_ptr,/* in: buffer end */
+ dict_index_t* index, /* in: record descriptor */
+ page_t* page, /* in: page or NULL */
+ mtr_t* mtr) /* in: mtr or NULL */
{
byte* rec_end;
ulint log_data_len;
@@ -931,7 +1031,8 @@ page_parse_copy_rec_list_to_created_page(
}
while (ptr < rec_end) {
- ptr = page_cur_parse_insert_rec(TRUE, ptr, end_ptr, page, mtr);
+ ptr = page_cur_parse_insert_rec(TRUE, ptr, end_ptr,
+ index, page, mtr);
}
ut_a(ptr == rec_end);
@@ -950,10 +1051,11 @@ including that record. Infimum and supremum records are not copied. */
void
page_copy_rec_list_end_to_created_page(
/*===================================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: first record to copy */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: first record to copy */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_dir_slot_t* slot = 0; /* remove warning */
byte* heap_top;
@@ -966,9 +1068,13 @@ page_copy_rec_list_end_to_created_page(
ulint log_mode;
byte* log_ptr;
ulint log_data_len;
+ ibool comp = page_is_comp(page);
+ mem_heap_t* heap;
+ ulint* offsets = NULL;
- ut_ad(page_header_get_field(new_page, PAGE_N_HEAP) == 2);
+ ut_ad(page_dir_get_n_heap(new_page) == 2);
ut_ad(page != new_page);
+ ut_ad(comp == page_is_comp(new_page));
if (rec == page_get_infimum_rec(page)) {
@@ -983,12 +1089,13 @@ page_copy_rec_list_end_to_created_page(
#ifdef UNIV_DEBUG
/* To pass the debug tests we have to set these dummy values
in the debug version */
- page_header_set_field(new_page, PAGE_N_DIR_SLOTS, UNIV_PAGE_SIZE / 2);
+ page_dir_set_n_slots(new_page, UNIV_PAGE_SIZE / 2);
page_header_set_ptr(new_page, PAGE_HEAP_TOP,
new_page + UNIV_PAGE_SIZE - 1);
#endif
- log_ptr = page_copy_rec_list_to_created_page_write_log(new_page, mtr);
+ log_ptr = page_copy_rec_list_to_created_page_write_log(new_page,
+ index, mtr);
log_data_len = dyn_array_get_data_size(&(mtr->log));
@@ -997,22 +1104,29 @@ page_copy_rec_list_end_to_created_page(
log_mode = mtr_set_log_mode(mtr, MTR_LOG_SHORT_INSERTS);
prev_rec = page_get_infimum_rec(new_page);
- heap_top = new_page + PAGE_SUPREMUM_END;
+ if (comp) {
+ heap_top = new_page + PAGE_NEW_SUPREMUM_END;
+ } else {
+ heap_top = new_page + PAGE_OLD_SUPREMUM_END;
+ }
count = 0;
slot_index = 0;
n_recs = 0;
+ heap = mem_heap_create(100);
+
/* should be do ... until, comment by Jani */
while (rec != page_get_supremum_rec(page)) {
-
- insert_rec = rec_copy(heap_top, rec);
+ offsets = rec_reget_offsets(rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ insert_rec = rec_copy(heap_top, rec, offsets);
- rec_set_next_offs(prev_rec, insert_rec - new_page);
+ rec_set_next_offs(prev_rec, comp, insert_rec - new_page);
- rec_set_n_owned(insert_rec, 0);
- rec_set_heap_no(insert_rec, 2 + n_recs);
+ rec_set_n_owned(insert_rec, comp, 0);
+ rec_set_heap_no(insert_rec, comp, 2 + n_recs);
- rec_size = rec_get_size(insert_rec);
+ rec_size = rec_offs_size(offsets);
heap_top = heap_top + rec_size;
@@ -1034,7 +1148,7 @@ page_copy_rec_list_end_to_created_page(
}
page_cur_insert_rec_write_log(insert_rec, rec_size, prev_rec,
- mtr);
+ index, mtr);
prev_rec = insert_rec;
rec = page_rec_get_next(rec);
}
@@ -1056,22 +1170,25 @@ page_copy_rec_list_end_to_created_page(
slot_index--;
}
+ mem_heap_free(heap);
+
log_data_len = dyn_array_get_data_size(&(mtr->log)) - log_data_len;
ut_a(log_data_len < 100 * UNIV_PAGE_SIZE);
mach_write_to_4(log_ptr, log_data_len);
- rec_set_next_offs(insert_rec, PAGE_SUPREMUM);
+ rec_set_next_offs(insert_rec, comp,
+ comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM);
slot = page_dir_get_nth_slot(new_page, 1 + slot_index);
page_dir_slot_set_rec(slot, page_get_supremum_rec(new_page));
page_dir_slot_set_n_owned(slot, count + 1);
- page_header_set_field(new_page, PAGE_N_DIR_SLOTS, 2 + slot_index);
+ page_dir_set_n_slots(new_page, 2 + slot_index);
page_header_set_ptr(new_page, PAGE_HEAP_TOP, heap_top);
- page_header_set_field(new_page, PAGE_N_HEAP, 2 + n_recs);
+ page_dir_set_n_heap(new_page, 2 + n_recs);
page_header_set_field(new_page, PAGE_N_RECS, n_recs);
page_header_set_ptr(new_page, PAGE_LAST_INSERT, NULL);
@@ -1089,14 +1206,27 @@ UNIV_INLINE
void
page_cur_delete_rec_write_log(
/*==========================*/
- rec_t* cursor_rec, /* in: record to be deleted */
- mtr_t* mtr) /* in: mini-transaction handle */
+ rec_t* rec, /* in: record to be deleted */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mini-transaction handle */
{
- mlog_write_initial_log_record(cursor_rec, MLOG_REC_DELETE, mtr);
+ byte* log_ptr;
+
+ log_ptr = mlog_open_and_write_index(mtr, rec, index,
+ index->table->comp
+ ? MLOG_COMP_REC_DELETE
+ : MLOG_REC_DELETE, 2);
+
+ if (!log_ptr) {
+ /* Logging in mtr is switched off during crash recovery:
+ in that case mlog_open returns NULL */
+ return;
+ }
/* Write the cursor rec offset as a 2-byte ulint */
- mlog_catenate_ulint(mtr, cursor_rec - buf_frame_align(cursor_rec),
- MLOG_2BYTES);
+ mach_write_to_2(log_ptr, rec - buf_frame_align(rec));
+
+ mlog_close(mtr, log_ptr + 2);
}
/***************************************************************
@@ -1105,11 +1235,12 @@ Parses log record of a record delete on a page. */
byte*
page_cur_parse_delete_rec(
/*======================*/
- /* out: pointer to record end or NULL */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /* out: pointer to record end or NULL */
+ byte* ptr, /* in: buffer */
+ byte* end_ptr,/* in: buffer end */
+ dict_index_t* index, /* in: record descriptor */
+ page_t* page, /* in: page or NULL */
+ mtr_t* mtr) /* in: mtr or NULL */
{
ulint offset;
page_cur_t cursor;
@@ -1128,7 +1259,7 @@ page_cur_parse_delete_rec(
if (page) {
page_cur_position(page + offset, &cursor);
- page_cur_delete_rec(&cursor, mtr);
+ page_cur_delete_rec(&cursor, index, mtr);
}
return(ptr);
@@ -1142,6 +1273,7 @@ void
page_cur_delete_rec(
/*================*/
page_cur_t* cursor, /* in: a page cursor */
+ dict_index_t* index, /* in: record descriptor */
mtr_t* mtr) /* in: mini-transaction handle */
{
page_dir_slot_t* cur_dir_slot;
@@ -1169,7 +1301,7 @@ page_cur_delete_rec(
cur_n_owned = page_dir_slot_get_n_owned(cur_dir_slot);
/* 0. Write the log record */
- page_cur_delete_rec_write_log(current_rec, mtr);
+ page_cur_delete_rec_write_log(current_rec, index, mtr);
/* 1. Reset the last insert info in the page header and increment
the modify clock for the frame */
@@ -1223,7 +1355,7 @@ page_cur_delete_rec(
page_dir_slot_set_n_owned(cur_dir_slot, cur_n_owned - 1);
/* 6. Free the memory occupied by the record */
- page_mem_free(page, current_rec);
+ page_mem_free(page, current_rec, index);
/* 7. Now we have decremented the number of owned records of the slot.
If the number drops below PAGE_DIR_SLOT_MIN_N_OWNED, we balance the
diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c
index 343f300fc77..38b1e503c8f 100644
--- a/innobase/page/page0page.c
+++ b/innobase/page/page0page.c
@@ -18,6 +18,8 @@ Created 2/2/1994 Heikki Tuuri
#include "fut0lst.h"
#include "btr0sea.h"
#include "buf0buf.h"
+#include "srv0srv.h"
+#include "btr0btr.h"
/* THE INDEX PAGE
==============
@@ -75,10 +77,14 @@ page_dir_find_owner_slot(
page_t* page;
page_dir_slot_t* slot;
rec_t* original_rec = rec;
+ ibool comp;
ut_ad(page_rec_check(rec));
- while (rec_get_n_owned(rec) == 0) {
+ page = buf_frame_align(rec);
+ comp = page_is_comp(page);
+
+ while (rec_get_n_owned(rec, comp) == 0) {
steps++;
rec = page_rec_get_next(rec);
}
@@ -96,14 +102,18 @@ page_dir_find_owner_slot(
"InnoDB: Original record ",
(ulong) buf_frame_get_page_no(page));
- rec_print(stderr, original_rec);
+ if (comp) {
+ fputs("(compact record)\n", stderr);
+ } else {
+ rec_print_old(stderr, original_rec);
+ }
fprintf(stderr, "\n"
"InnoDB: on that page. Steps %lu.\n", (ulong) steps);
fputs(
"InnoDB: Cannot find the dir slot for record ",
stderr);
- rec_print(stderr, rec);
+ rec_print(stderr, rec, NULL);
fputs("\n"
"InnoDB: on that page!\n", stderr);
@@ -136,14 +146,15 @@ page_dir_slot_check(
page = buf_frame_align(slot);
- n_slots = page_header_get_field(page, PAGE_N_DIR_SLOTS);
+ n_slots = page_dir_get_n_slots(page);
ut_a(slot <= page_dir_get_nth_slot(page, 0));
ut_a(slot >= page_dir_get_nth_slot(page, n_slots - 1));
- ut_a(page_rec_check(page + mach_read_from_2(slot)));
+ ut_a(page_rec_check(page_dir_slot_get_rec(slot)));
- n_owned = rec_get_n_owned(page + mach_read_from_2(slot));
+ n_owned = rec_get_n_owned(page_dir_slot_get_rec(slot),
+ page_is_comp(page));
if (slot == page_dir_get_nth_slot(page, 0)) {
ut_a(n_owned == 1);
@@ -194,12 +205,14 @@ Allocates a block of memory from an index page. */
byte*
page_mem_alloc(
/*===========*/
- /* out: pointer to start of allocated
- buffer, or NULL if allocation fails */
- page_t* page, /* in: index page */
- ulint need, /* in: number of bytes needed */
- ulint* heap_no)/* out: this contains the heap number
- of the allocated record if allocation succeeds */
+ /* out: pointer to start of allocated
+ buffer, or NULL if allocation fails */
+ page_t* page, /* in: index page */
+ ulint need, /* in: number of bytes needed */
+ dict_index_t* index, /* in: record descriptor */
+ ulint* heap_no)/* out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
{
rec_t* rec;
byte* block;
@@ -213,18 +226,30 @@ page_mem_alloc(
rec = page_header_get_ptr(page, PAGE_FREE);
- if (rec && (rec_get_size(rec) >= need)) {
+ if (rec) {
+ mem_heap_t* heap
+ = mem_heap_create(100);
+ const ulint* offsets
+ = rec_get_offsets(rec, index, ULINT_UNDEFINED, heap);
+
+ if (rec_offs_size(offsets) >= need) {
+ page_header_set_ptr(page, PAGE_FREE,
+ page_rec_get_next(rec));
- page_header_set_ptr(page, PAGE_FREE, page_rec_get_next(rec));
+ garbage = page_header_get_field(page, PAGE_GARBAGE);
+ ut_ad(garbage >= need);
- garbage = page_header_get_field(page, PAGE_GARBAGE);
- ut_ad(garbage >= need);
+ page_header_set_field(page, PAGE_GARBAGE,
+ garbage - need);
- page_header_set_field(page, PAGE_GARBAGE, garbage - need);
+ *heap_no = rec_get_heap_no(rec, page_is_comp(page));
- *heap_no = rec_get_heap_no(rec);
+ block = rec_get_start(rec, offsets);
+ mem_heap_free(heap);
+ return(block);
+ }
- return(rec_get_start(rec));
+ mem_heap_free(heap);
}
/* Could not find space from the free list, try top of heap */
@@ -235,9 +260,9 @@ page_mem_alloc(
block = page_header_get_ptr(page, PAGE_HEAP_TOP);
page_header_set_ptr(page, PAGE_HEAP_TOP, block + need);
- *heap_no = page_header_get_field(page, PAGE_N_HEAP);
+ *heap_no = page_dir_get_n_heap(page);
- page_header_set_field(page, PAGE_N_HEAP, 1 + *heap_no);
+ page_dir_set_n_heap(page, 1 + *heap_no);
return(block);
}
@@ -253,9 +278,11 @@ page_create_write_log(
/*==================*/
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr, /* in: mini-transaction handle */
+ ibool comp) /* in: TRUE=compact page format */
{
- mlog_write_initial_log_record(frame, MLOG_PAGE_CREATE, mtr);
+ mlog_write_initial_log_record(frame,
+ comp ? MLOG_COMP_PAGE_CREATE : MLOG_PAGE_CREATE, mtr);
}
/***************************************************************
@@ -267,6 +294,7 @@ page_parse_create(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr __attribute__((unused)), /* in: buffer end */
+ ibool comp, /* in: TRUE=compact page format */
page_t* page, /* in: page or NULL */
mtr_t* mtr) /* in: mtr or NULL */
{
@@ -275,7 +303,7 @@ page_parse_create(
/* The record is empty, except for the record initial part */
if (page) {
- page_create(page, mtr);
+ page_create(page, mtr, comp);
}
return(ptr);
@@ -290,7 +318,8 @@ page_create(
/* out: pointer to the page */
buf_frame_t* frame, /* in: a buffer frame where the page is
created */
- mtr_t* mtr) /* in: mini-transaction handle */
+ mtr_t* mtr, /* in: mini-transaction handle */
+ ibool comp) /* in: TRUE=compact page format */
{
page_dir_slot_t* slot;
mem_heap_t* heap;
@@ -300,6 +329,10 @@ page_create(
rec_t* infimum_rec;
rec_t* supremum_rec;
page_t* page;
+ dict_index_t* index;
+ ulint* offsets;
+
+ index = comp ? srv_sys->dummy_ind2 : srv_sys->dummy_ind1;
ut_ad(frame && mtr);
ut_ad(PAGE_BTR_IBUF_FREE_LIST + FLST_BASE_NODE_SIZE
@@ -311,7 +344,7 @@ page_create(
buf_frame_modify_clock_inc(frame);
/* 2. WRITE LOG INFORMATION */
- page_create_write_log(frame, mtr);
+ page_create_write_log(frame, mtr, comp);
page = frame;
@@ -323,43 +356,52 @@ page_create(
/* Create first a data tuple for infimum record */
tuple = dtuple_create(heap, 1);
+ dtuple_set_info_bits(tuple, REC_STATUS_INFIMUM);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "infimum", sizeof "infimum");
- dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
-
+ dfield_set_data(field, "infimum", 8);
+ dtype_set(dfield_get_type(field),
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 8, 0);
/* Set the corresponding physical record to its place in the page
record heap */
heap_top = page + PAGE_DATA;
- infimum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
+ infimum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
+
+ ut_a(infimum_rec ==
+ page + (comp ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
+
+ rec_set_n_owned(infimum_rec, comp, 1);
+ rec_set_heap_no(infimum_rec, comp, 0);
+ offsets = rec_get_offsets(infimum_rec, index, ULINT_UNDEFINED, heap);
+
+ heap_top = rec_get_end(infimum_rec, offsets);
- ut_a(infimum_rec == page + PAGE_INFIMUM);
-
- rec_set_n_owned(infimum_rec, 1);
- rec_set_heap_no(infimum_rec, 0);
-
- heap_top = rec_get_end(infimum_rec);
-
/* Create then a tuple for supremum */
tuple = dtuple_create(heap, 1);
+ dtuple_set_info_bits(tuple, REC_STATUS_SUPREMUM);
field = dtuple_get_nth_field(tuple, 0);
- dfield_set_data(field, "supremum", sizeof "supremum");
- dtype_set(dfield_get_type(field), DATA_VARCHAR, DATA_ENGLISH, 20, 0);
+ dfield_set_data(field, "supremum", 9 - comp);
+ dtype_set(dfield_get_type(field),
+ DATA_VARCHAR, DATA_ENGLISH | DATA_NOT_NULL, 9 - comp, 0);
- supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple);
+ supremum_rec = rec_convert_dtuple_to_rec(heap_top, index, tuple);
- ut_a(supremum_rec == page + PAGE_SUPREMUM);
+ ut_a(supremum_rec ==
+ page + (comp ? PAGE_NEW_SUPREMUM : PAGE_OLD_SUPREMUM));
- rec_set_n_owned(supremum_rec, 1);
- rec_set_heap_no(supremum_rec, 1);
-
- heap_top = rec_get_end(supremum_rec);
+ rec_set_n_owned(supremum_rec, comp, 1);
+ rec_set_heap_no(supremum_rec, comp, 1);
- ut_ad(heap_top == page + PAGE_SUPREMUM_END);
+ offsets = rec_reget_offsets(supremum_rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ heap_top = rec_get_end(supremum_rec, offsets);
+
+ ut_ad(heap_top ==
+ page + (comp ? PAGE_NEW_SUPREMUM_END : PAGE_OLD_SUPREMUM_END));
mem_heap_free(heap);
@@ -367,7 +409,7 @@ page_create(
page_header_set_field(page, PAGE_N_DIR_SLOTS, 2);
page_header_set_ptr(page, PAGE_HEAP_TOP, heap_top);
- page_header_set_field(page, PAGE_N_HEAP, 2);
+ page_header_set_field(page, PAGE_N_HEAP, comp ? 0x8002 : 2);
page_header_set_ptr(page, PAGE_FREE, NULL);
page_header_set_field(page, PAGE_GARBAGE, 0);
page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);
@@ -388,8 +430,8 @@ page_create(
/* Set the next pointers in infimum and supremum */
- rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page));
- rec_set_next_offs(supremum_rec, 0);
+ rec_set_next_offs(infimum_rec, comp, (ulint)(supremum_rec - page));
+ rec_set_next_offs(supremum_rec, comp, 0);
return(page);
}
@@ -401,10 +443,11 @@ touch the lock table and max trx id on page. */
void
page_copy_rec_list_end_no_locks(
/*============================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
page_cur_t cur2;
@@ -416,8 +459,11 @@ page_copy_rec_list_end_no_locks(
page_cur_move_to_next(&cur1);
}
-
- ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM);
+
+ ut_a(index->table->comp == page_is_comp(page));
+ ut_a(index->table->comp == page_is_comp(new_page));
+ ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == (ulint)
+ (index->table->comp ? PAGE_NEW_INFIMUM : PAGE_OLD_INFIMUM));
page_cur_set_before_first(new_page, &cur2);
@@ -427,7 +473,7 @@ page_copy_rec_list_end_no_locks(
while (sup != page_cur_get_rec(&cur1)) {
if (!page_cur_rec_insert(&cur2,
- page_cur_get_rec(&cur1), mtr)) {
+ page_cur_get_rec(&cur1), index, mtr)) {
/* Track an assertion failure reported on the mailing
list on June 18th, 2003 */
@@ -456,16 +502,18 @@ The records are copied to the start of the record list on new_page. */
void
page_copy_rec_list_end(
/*===================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
- if (page_header_get_field(new_page, PAGE_N_HEAP) == 2) {
+ if (page_dir_get_n_heap(new_page) == 2) {
page_copy_rec_list_end_to_created_page(new_page, page, rec,
- mtr);
+ index, mtr);
} else {
- page_copy_rec_list_end_no_locks(new_page, page, rec, mtr);
+ page_copy_rec_list_end_no_locks(new_page, page, rec,
+ index, mtr);
}
/* Update the lock table, MAX_TRX_ID, and possible hash index */
@@ -474,7 +522,7 @@ page_copy_rec_list_end(
page_update_max_trx_id(new_page, page_get_max_trx_id(page));
- btr_search_move_or_delete_hash_entries(new_page, page);
+ btr_search_move_or_delete_hash_entries(new_page, page, index);
}
/*****************************************************************
@@ -485,10 +533,11 @@ The records are copied to the end of the record list on new_page. */
void
page_copy_rec_list_start(
/*=====================*/
- page_t* new_page, /* in: index page to copy to */
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page to copy to */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
page_cur_t cur2;
@@ -510,8 +559,8 @@ page_copy_rec_list_start(
/* Copy records from the original page to the new page */
while (page_cur_get_rec(&cur1) != rec) {
- ut_a(
- page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr));
+ ut_a(page_cur_rec_insert(&cur2,
+ page_cur_get_rec(&cur1), index, mtr));
page_cur_move_to_next(&cur1);
page_cur_move_to_next(&cur2);
@@ -523,7 +572,7 @@ page_copy_rec_list_start(
page_update_max_trx_id(new_page, page_get_max_trx_id(page));
- btr_search_move_or_delete_hash_entries(new_page, page);
+ btr_search_move_or_delete_hash_entries(new_page, page, index);
}
/**************************************************************
@@ -532,18 +581,25 @@ UNIV_INLINE
void
page_delete_rec_list_write_log(
/*===========================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- byte type, /* in: operation type: MLOG_LIST_END_DELETE, ... */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ byte type, /* in: operation type:
+ MLOG_LIST_END_DELETE, ... */
+ mtr_t* mtr) /* in: mtr */
{
- ut_ad((type == MLOG_LIST_END_DELETE)
- || (type == MLOG_LIST_START_DELETE));
-
- mlog_write_initial_log_record(page, type, mtr);
-
- /* Write the parameter as a 2-byte ulint */
- mlog_catenate_ulint(mtr, rec - page, MLOG_2BYTES);
+ byte* log_ptr;
+ ut_ad(type == MLOG_LIST_END_DELETE
+ || type == MLOG_LIST_START_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_START_DELETE);
+
+ log_ptr = mlog_open_and_write_index(mtr, page, index, type, 2);
+ if (log_ptr) {
+ /* Write the parameter as a 2-byte ulint */
+ mach_write_to_2(log_ptr, rec - page);
+ mlog_close(mtr, log_ptr + 2);
+ }
}
/**************************************************************
@@ -552,18 +608,23 @@ Parses a log record of a record list end or start deletion. */
byte*
page_parse_delete_rec_list(
/*=======================*/
- /* out: end of log record or NULL */
- byte type, /* in: MLOG_LIST_END_DELETE or
- MLOG_LIST_START_DELETE */
- byte* ptr, /* in: buffer */
- byte* end_ptr,/* in: buffer end */
- page_t* page, /* in: page or NULL */
- mtr_t* mtr) /* in: mtr or NULL */
+ /* out: end of log record or NULL */
+ byte type, /* in: MLOG_LIST_END_DELETE,
+ MLOG_LIST_START_DELETE,
+ MLOG_COMP_LIST_END_DELETE or
+ MLOG_COMP_LIST_START_DELETE */
+ byte* ptr, /* in: buffer */
+ byte* end_ptr,/* in: buffer end */
+ dict_index_t* index, /* in: record descriptor */
+ page_t* page, /* in: page or NULL */
+ mtr_t* mtr) /* in: mtr or NULL */
{
ulint offset;
- ut_ad((type == MLOG_LIST_END_DELETE)
- || (type == MLOG_LIST_START_DELETE));
+ ut_ad(type == MLOG_LIST_END_DELETE
+ || type == MLOG_LIST_START_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_START_DELETE);
/* Read the record offset as a 2-byte ulint */
@@ -580,11 +641,12 @@ page_parse_delete_rec_list(
return(ptr);
}
- if (type == MLOG_LIST_END_DELETE) {
- page_delete_rec_list_end(page, page + offset, ULINT_UNDEFINED,
- ULINT_UNDEFINED, mtr);
+ if (type == MLOG_LIST_END_DELETE
+ || type == MLOG_COMP_LIST_END_DELETE) {
+ page_delete_rec_list_end(page, page + offset, index,
+ ULINT_UNDEFINED, ULINT_UNDEFINED, mtr);
} else {
- page_delete_rec_list_start(page, page + offset, mtr);
+ page_delete_rec_list_start(page, page + offset, index, mtr);
}
return(ptr);
@@ -597,14 +659,15 @@ The infimum and supremum records are not deleted. */
void
page_delete_rec_list_end(
/*=====================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- ulint n_recs, /* in: number of records to delete, or ULINT_UNDEFINED
- if not known */
- ulint size, /* in: the sum of the sizes of the records in the end
- of the chain to delete, or ULINT_UNDEFINED if not
- known */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ ulint n_recs, /* in: number of records to delete,
+ or ULINT_UNDEFINED if not known */
+ ulint size, /* in: the sum of the sizes of the
+ records in the end of the chain to
+ delete, or ULINT_UNDEFINED if not known */
+ mtr_t* mtr) /* in: mtr */
{
page_dir_slot_t* slot;
ulint slot_index;
@@ -615,10 +678,12 @@ page_delete_rec_list_end(
ulint count;
ulint n_owned;
rec_t* sup;
+ ibool comp;
/* Reset the last insert info in the page header and increment
the modify clock for the frame */
+ ut_ad(size == ULINT_UNDEFINED || size < UNIV_PAGE_SIZE);
page_header_set_ptr(page, PAGE_LAST_INSERT, NULL);
/* The page gets invalid for optimistic searches: increment the
@@ -632,7 +697,9 @@ page_delete_rec_list_end(
rec = page_rec_get_next(rec);
}
- page_delete_rec_list_write_log(page, rec, MLOG_LIST_END_DELETE, mtr);
+ comp = page_is_comp(page);
+ page_delete_rec_list_write_log(page, rec, index,
+ comp ? MLOG_COMP_LIST_END_DELETE : MLOG_LIST_END_DELETE, mtr);
if (rec == sup) {
@@ -644,19 +711,32 @@ page_delete_rec_list_end(
last_rec = page_rec_get_prev(sup);
if ((size == ULINT_UNDEFINED) || (n_recs == ULINT_UNDEFINED)) {
+ mem_heap_t* heap = mem_heap_create(100);
+ ulint* offsets = NULL;
/* Calculate the sum of sizes and the number of records */
size = 0;
n_recs = 0;
rec2 = rec;
while (rec2 != sup) {
- size += rec_get_size(rec2);
+ ulint s;
+ offsets = rec_reget_offsets(rec2, index,
+ offsets, ULINT_UNDEFINED, heap);
+ s = rec_offs_size(offsets);
+ ut_ad(rec2 - page + s - rec_offs_extra_size(offsets)
+ < UNIV_PAGE_SIZE);
+ ut_ad(size + s < UNIV_PAGE_SIZE);
+ size += s;
n_recs++;
rec2 = page_rec_get_next(rec2);
}
+
+ mem_heap_free(heap);
}
+ ut_ad(size < UNIV_PAGE_SIZE);
+
/* Update the page directory; there is no need to balance the number
of the records owned by the supremum record, as it is allowed to be
less than PAGE_DIR_SLOT_MIN_N_OWNED */
@@ -664,15 +744,15 @@ page_delete_rec_list_end(
rec2 = rec;
count = 0;
- while (rec_get_n_owned(rec2) == 0) {
+ while (rec_get_n_owned(rec2, comp) == 0) {
count++;
rec2 = page_rec_get_next(rec2);
}
- ut_ad(rec_get_n_owned(rec2) - count > 0);
+ ut_ad(rec_get_n_owned(rec2, comp) - count > 0);
- n_owned = rec_get_n_owned(rec2) - count;
+ n_owned = rec_get_n_owned(rec2, comp) - count;
slot_index = page_dir_find_owner_slot(rec2);
slot = page_dir_get_nth_slot(page, slot_index);
@@ -680,7 +760,7 @@ page_delete_rec_list_end(
page_dir_slot_set_rec(slot, sup);
page_dir_slot_set_n_owned(slot, n_owned);
- page_header_set_field(page, PAGE_N_DIR_SLOTS, slot_index + 1);
+ page_dir_set_n_slots(page, slot_index + 1);
/* Remove the record chain segment from the record chain */
page_rec_set_next(prev_rec, page_get_supremum_rec(page));
@@ -706,14 +786,19 @@ that record. Infimum and supremum records are not deleted. */
void
page_delete_rec_list_start(
/*=======================*/
- page_t* page, /* in: index page */
- rec_t* rec, /* in: record on page */
- mtr_t* mtr) /* in: mtr */
+ page_t* page, /* in: index page */
+ rec_t* rec, /* in: record on page */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
page_cur_t cur1;
ulint log_mode;
- page_delete_rec_list_write_log(page, rec, MLOG_LIST_START_DELETE, mtr);
+ page_delete_rec_list_write_log(page, rec, index,
+ index->table->comp
+ ? MLOG_COMP_LIST_START_DELETE
+ : MLOG_LIST_START_DELETE,
+ mtr);
page_cur_set_before_first(page, &cur1);
@@ -730,7 +815,7 @@ page_delete_rec_list_start(
while (page_cur_get_rec(&cur1) != rec) {
- page_cur_delete_rec(&cur1, mtr);
+ page_cur_delete_rec(&cur1, index, mtr);
}
/* Restore log mode */
@@ -745,10 +830,11 @@ split_rec. */
void
page_move_rec_list_end(
/*===================*/
- page_t* new_page, /* in: index page where to move */
- page_t* page, /* in: index page */
- rec_t* split_rec, /* in: first record to move */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page where to move */
+ page_t* page, /* in: index page */
+ rec_t* split_rec, /* in: first record to move */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
ulint old_data_size;
ulint new_data_size;
@@ -758,15 +844,15 @@ page_move_rec_list_end(
old_data_size = page_get_data_size(new_page);
old_n_recs = page_get_n_recs(new_page);
- page_copy_rec_list_end(new_page, page, split_rec, mtr);
+ page_copy_rec_list_end(new_page, page, split_rec, index, mtr);
new_data_size = page_get_data_size(new_page);
new_n_recs = page_get_n_recs(new_page);
ut_ad(new_data_size >= old_data_size);
- page_delete_rec_list_end(page, split_rec, new_n_recs - old_n_recs,
- new_data_size - old_data_size, mtr);
+ page_delete_rec_list_end(page, split_rec, index,
+ new_n_recs - old_n_recs, new_data_size - old_data_size, mtr);
}
/*****************************************************************
@@ -776,14 +862,15 @@ split_rec. */
void
page_move_rec_list_start(
/*=====================*/
- page_t* new_page, /* in: index page where to move */
- page_t* page, /* in: index page */
- rec_t* split_rec, /* in: first record not to move */
- mtr_t* mtr) /* in: mtr */
+ page_t* new_page, /* in: index page where to move */
+ page_t* page, /* in: index page */
+ rec_t* split_rec, /* in: first record not to move */
+ dict_index_t* index, /* in: record descriptor */
+ mtr_t* mtr) /* in: mtr */
{
- page_copy_rec_list_start(new_page, page, split_rec, mtr);
+ page_copy_rec_list_start(new_page, page, split_rec, index, mtr);
- page_delete_rec_list_start(page, split_rec, mtr);
+ page_delete_rec_list_start(page, split_rec, index, mtr);
}
/***************************************************************************
@@ -801,7 +888,7 @@ page_rec_write_index_page_no(
byte* data;
ulint len;
- data = rec_get_nth_field(rec, i, &len);
+ data = rec_get_nth_field_old(rec, i, &len);
ut_ad(len == 4);
@@ -885,7 +972,7 @@ page_dir_add_slots(
ut_ad(start < n_slots - 1);
/* Update the page header */
- page_header_set_field(page, PAGE_N_DIR_SLOTS, n_slots + n);
+ page_dir_set_n_slots(page, n_slots + n);
/* Move slots up */
@@ -1006,8 +1093,8 @@ page_dir_balance_slot(
old_rec = page_dir_slot_get_rec(slot);
new_rec = page_rec_get_next(old_rec);
- rec_set_n_owned(old_rec, 0);
- rec_set_n_owned(new_rec, n_owned + 1);
+ rec_set_n_owned(old_rec, page_is_comp(page), 0);
+ rec_set_n_owned(new_rec, page_is_comp(page), n_owned + 1);
page_dir_slot_set_rec(slot, new_rec);
@@ -1080,13 +1167,15 @@ page_rec_get_n_recs_before(
rec_t* slot_rec;
page_t* page;
ulint i;
+ ibool comp;
lint n = 0;
ut_ad(page_rec_check(rec));
page = buf_frame_align(rec);
-
- while (rec_get_n_owned(rec) == 0) {
+ comp = page_is_comp(page);
+
+ while (rec_get_n_owned(rec, comp) == 0) {
rec = page_rec_get_next(rec);
n--;
@@ -1096,7 +1185,7 @@ page_rec_get_n_recs_before(
slot = page_dir_get_nth_slot(page, i);
slot_rec = page_dir_slot_get_rec(slot);
- n += rec_get_n_owned(slot_rec);
+ n += rec_get_n_owned(slot_rec, comp);
if (rec == slot_rec) {
@@ -1118,17 +1207,21 @@ the index page context. */
void
page_rec_print(
/*===========*/
- rec_t* rec)
+ rec_t* rec, /* in: physical record */
+ const ulint* offsets)/* in: record descriptor */
{
- rec_print(stderr, rec);
+ ibool comp = page_is_comp(buf_frame_align(rec));
+
+ ut_a(comp == rec_offs_comp(offsets));
+ rec_print(stderr, rec, offsets);
fprintf(stderr,
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
- (ulong) rec_get_n_owned(rec),
- (ulong) rec_get_heap_no(rec),
- (ulong) rec_get_next_offs(rec));
+ (ulong) rec_get_n_owned(rec, comp),
+ (ulong) rec_get_heap_no(rec, comp),
+ (ulong) rec_get_next_offs(rec, comp));
page_rec_check(rec);
- rec_validate(rec);
+ rec_validate(rec, offsets);
}
/*******************************************************************
@@ -1176,12 +1269,18 @@ debugging purposes. */
void
page_print_list(
/*============*/
- page_t* page, /* in: index page */
- ulint pr_n) /* in: print n first and n last entries */
+ page_t* page, /* in: index page */
+ dict_index_t* index, /* in: dictionary index of the page */
+ ulint pr_n) /* in: print n first and n last entries */
{
page_cur_t cur;
ulint count;
ulint n_recs;
+ mem_heap_t* heap;
+ ulint* offsets = NULL;
+
+ ut_a(page_is_comp(page) == index->table->comp);
+ heap = mem_heap_create(100);
fprintf(stderr,
"--------------------------------\n"
@@ -1193,7 +1292,9 @@ page_print_list(
page_cur_set_before_first(page, &cur);
count = 0;
for (;;) {
- page_rec_print(cur.rec);
+ offsets = rec_reget_offsets(cur.rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ page_rec_print(cur.rec, offsets);
if (count == pr_n) {
break;
@@ -1213,7 +1314,9 @@ page_print_list(
page_cur_move_to_next(&cur);
if (count + pr_n >= n_recs) {
- page_rec_print(cur.rec);
+ offsets = rec_reget_offsets(cur.rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ page_rec_print(cur.rec, offsets);
}
count++;
}
@@ -1222,6 +1325,8 @@ page_print_list(
"Total of %lu records \n"
"--------------------------------\n",
(ulong) (count + 1));
+
+ mem_heap_free(heap);
}
/*******************************************************************
@@ -1235,14 +1340,15 @@ page_header_print(
fprintf(stderr,
"--------------------------------\n"
"PAGE HEADER INFO\n"
- "Page address %p, n records %lu\n"
+ "Page address %p, n records %lu (%s)\n"
"n dir slots %lu, heap top %lu\n"
"Page n heap %lu, free %lu, garbage %lu\n"
"Page last insert %lu, direction %lu, n direction %lu\n",
page, (ulong) page_header_get_field(page, PAGE_N_RECS),
+ page_is_comp(page) ? "compact format" : "original format",
(ulong) page_header_get_field(page, PAGE_N_DIR_SLOTS),
(ulong) page_header_get_field(page, PAGE_HEAP_TOP),
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) page_header_get_field(page, PAGE_FREE),
(ulong) page_header_get_field(page, PAGE_GARBAGE),
(ulong) page_header_get_field(page, PAGE_LAST_INSERT),
@@ -1257,13 +1363,16 @@ debugging purposes. */
void
page_print(
/*======*/
- page_t* page, /* in: index page */
- ulint dn, /* in: print dn first and last entries in directory */
- ulint rn) /* in: print rn first and last records on page */
+ page_t* page, /* in: index page */
+ dict_index_t* index, /* in: dictionary index of the page */
+ ulint dn, /* in: print dn first and last entries
+ in directory */
+ ulint rn) /* in: print rn first and last records
+ in directory */
{
page_header_print(page);
page_dir_print(page, dn);
- page_print_list(page, rn);
+ page_print_list(page, index, rn);
}
/*******************************************************************
@@ -1274,20 +1383,24 @@ the heap_no field. */
ibool
page_rec_validate(
/*==============*/
- /* out: TRUE if ok */
- rec_t* rec) /* in: record on the page */
+ /* out: TRUE if ok */
+ rec_t* rec, /* in: physical record */
+ const ulint* offsets)/* in: array returned by rec_get_offsets() */
{
ulint n_owned;
ulint heap_no;
- page_t* page;
+ page_t* page;
+ ibool comp;
page = buf_frame_align(rec);
+ comp = page_is_comp(page);
+ ut_a(comp == rec_offs_comp(offsets));
page_rec_check(rec);
- rec_validate(rec);
+ rec_validate(rec, offsets);
- n_owned = rec_get_n_owned(rec);
- heap_no = rec_get_heap_no(rec);
+ n_owned = rec_get_n_owned(rec, comp);
+ heap_no = rec_get_heap_no(rec, comp);
if (!(n_owned <= PAGE_DIR_SLOT_MAX_N_OWNED)) {
fprintf(stderr,
@@ -1296,11 +1409,11 @@ page_rec_validate(
return(FALSE);
}
- if (!(heap_no < page_header_get_field(page, PAGE_N_HEAP))) {
+ if (!(heap_no < page_dir_get_n_heap(page))) {
fprintf(stderr,
"InnoDB: Heap no of rec %lu too big %lu %lu\n",
(ulong)(rec - page), (ulong) heap_no,
- (ulong) page_header_get_field(page, PAGE_N_HEAP));
+ (ulong) page_dir_get_n_heap(page));
return(FALSE);
}
@@ -1358,6 +1471,7 @@ page_simple_validate(
ulint count;
ulint own_count;
ibool ret = FALSE;
+ ibool comp = page_is_comp(page);
/* Check first that the record heap and the directory do not
overlap. */
@@ -1404,13 +1518,13 @@ page_simple_validate(
goto func_exit;
}
- if (rec_get_n_owned(rec) != 0) {
+ if (rec_get_n_owned(rec, comp) != 0) {
/* This is a record pointed to by a dir slot */
- if (rec_get_n_owned(rec) != own_count) {
+ if (rec_get_n_owned(rec, comp) != own_count) {
fprintf(stderr,
"InnoDB: Wrong owned count %lu, %lu, rec %lu\n",
- (ulong) rec_get_n_owned(rec),
+ (ulong) rec_get_n_owned(rec, comp),
(ulong) own_count,
(ulong)(rec - page));
@@ -1438,11 +1552,11 @@ page_simple_validate(
break;
}
- if (rec_get_next_offs(rec) < FIL_PAGE_DATA
- || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
+ if (rec_get_next_offs(rec, comp) < FIL_PAGE_DATA
+ || rec_get_next_offs(rec, comp) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Next record offset nonsensical %lu for rec %lu\n",
- (ulong) rec_get_next_offs(rec),
+ (ulong) rec_get_next_offs(rec, comp),
(ulong)(rec - page));
goto func_exit;
@@ -1461,7 +1575,7 @@ page_simple_validate(
own_count++;
}
- if (rec_get_n_owned(rec) == 0) {
+ if (rec_get_n_owned(rec, comp) == 0) {
fprintf(stderr, "InnoDB: n owned is zero in a supremum rec\n");
goto func_exit;
@@ -1514,10 +1628,10 @@ page_simple_validate(
rec = page_rec_get_next(rec);
}
- if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
+ if (page_dir_get_n_heap(page) != count + 1) {
fprintf(stderr, "InnoDB: N heap is wrong %lu, %lu\n",
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) (count + 1));
goto func_exit;
@@ -1549,12 +1663,19 @@ page_validate(
ulint slot_no;
ulint data_size;
rec_t* rec;
- rec_t* old_rec = NULL;
+ rec_t* old_rec = NULL;
ulint offs;
ulint n_slots;
- ibool ret = FALSE;
+ ibool ret = FALSE;
ulint i;
-
+ ibool comp = page_is_comp(page);
+ ulint* offsets = NULL;
+ ulint* old_offsets = NULL;
+
+ if (comp != index->table->comp) {
+ fputs("InnoDB: 'compact format' flag mismatch\n", stderr);
+ goto func_exit2;
+ }
if (!page_simple_validate(page)) {
goto func_exit2;
}
@@ -1599,22 +1720,33 @@ page_validate(
for (;;) {
rec = cur.rec;
+ offsets = rec_reget_offsets(rec, index,
+ offsets, ULINT_UNDEFINED, heap);
- if (!page_rec_validate(rec)) {
+ if (comp && page_rec_is_user_rec(rec)
+ && rec_get_node_ptr_flag(rec)
+ == !btr_page_get_level_low(page)) {
+ fputs("InnoDB: node_ptr flag mismatch\n", stderr);
+ goto func_exit;
+ }
+
+ if (!page_rec_validate(rec, offsets)) {
goto func_exit;
}
/* Check that the records are in the ascending order */
if ((count >= 2) && (!page_cur_is_after_last(&cur))) {
- if (!(1 == cmp_rec_rec(rec, old_rec, index))) {
+ if (!(1 == cmp_rec_rec(rec, old_rec,
+ offsets, old_offsets,
+ ULINT_UNDEFINED, index))) {
fprintf(stderr,
"InnoDB: Records in wrong order on page %lu",
(ulong) buf_frame_get_page_no(page));
dict_index_name_print(stderr, NULL, index);
fputs("\nInnoDB: previous record ", stderr);
- rec_print(stderr, old_rec);
+ rec_print(stderr, old_rec, old_offsets);
fputs("\nInnoDB: record ", stderr);
- rec_print(stderr, rec);
+ rec_print(stderr, rec, offsets);
putc('\n', stderr);
goto func_exit;
@@ -1624,12 +1756,12 @@ page_validate(
if ((rec != page_get_supremum_rec(page))
&& (rec != page_get_infimum_rec(page))) {
- data_size += rec_get_size(rec);
+ data_size += rec_offs_size(offsets);
}
- offs = rec_get_start(rec) - page;
+ offs = rec_get_start(rec, offsets) - page;
- for (i = 0; i < rec_get_size(rec); i++) {
+ for (i = 0; i < rec_offs_size(offsets); i++) {
if (!buf[offs + i] == 0) {
/* No other record may overlap this */
@@ -1641,12 +1773,12 @@ page_validate(
buf[offs + i] = 1;
}
- if (rec_get_n_owned(rec) != 0) {
+ if (rec_get_n_owned(rec, comp) != 0) {
/* This is a record pointed to by a dir slot */
- if (rec_get_n_owned(rec) != own_count) {
+ if (rec_get_n_owned(rec, comp) != own_count) {
fprintf(stderr,
"InnoDB: Wrong owned count %lu, %lu\n",
- (ulong) rec_get_n_owned(rec),
+ (ulong) rec_get_n_owned(rec, comp),
(ulong) own_count);
goto func_exit;
}
@@ -1671,11 +1803,11 @@ page_validate(
break;
}
- if (rec_get_next_offs(rec) < FIL_PAGE_DATA
- || rec_get_next_offs(rec) >= UNIV_PAGE_SIZE) {
+ if (rec_get_next_offs(rec, comp) < FIL_PAGE_DATA
+ || rec_get_next_offs(rec, comp) >= UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Next record offset wrong %lu\n",
- (ulong) rec_get_next_offs(rec));
+ (ulong) rec_get_next_offs(rec, comp));
goto func_exit;
}
@@ -1683,9 +1815,15 @@ page_validate(
page_cur_move_to_next(&cur);
own_count++;
old_rec = rec;
+ /* set old_offsets to offsets; recycle offsets */
+ {
+ ulint* offs = old_offsets;
+ old_offsets = offsets;
+ offsets = offs;
+ }
}
- if (rec_get_n_owned(rec) == 0) {
+ if (rec_get_n_owned(rec, comp) == 0) {
fputs("InnoDB: n owned is zero\n", stderr);
goto func_exit;
}
@@ -1714,15 +1852,17 @@ page_validate(
rec = page_header_get_ptr(page, PAGE_FREE);
while (rec != NULL) {
- if (!page_rec_validate(rec)) {
+ offsets = rec_reget_offsets(rec, index,
+ offsets, ULINT_UNDEFINED, heap);
+ if (!page_rec_validate(rec, offsets)) {
goto func_exit;
}
count++;
- offs = rec_get_start(rec) - page;
+ offs = rec_get_start(rec, offsets) - page;
- for (i = 0; i < rec_get_size(rec); i++) {
+ for (i = 0; i < rec_offs_size(offsets); i++) {
if (buf[offs + i] != 0) {
fputs(
@@ -1736,9 +1876,9 @@ page_validate(
rec = page_rec_get_next(rec);
}
- if (page_header_get_field(page, PAGE_N_HEAP) != count + 1) {
+ if (page_dir_get_n_heap(page) != count + 1) {
fprintf(stderr, "InnoDB: N heap is wrong %lu %lu\n",
- (ulong) page_header_get_field(page, PAGE_N_HEAP),
+ (ulong) page_dir_get_n_heap(page),
(ulong) count + 1);
goto func_exit;
}
@@ -1775,7 +1915,7 @@ page_find_rec_with_heap_no(
page_cur_set_before_first(page, &cur);
for (;;) {
- if (rec_get_heap_no(cur.rec) == heap_no) {
+ if (rec_get_heap_no(cur.rec, page_is_comp(page)) == heap_no) {
return(cur.rec);
}