Commit b34b37b5 authored by marko's avatar marko

branches/zip:

Initial import of the zip-like compression of B-tree pages.
parent 4979fcae
This diff is collapsed.
This diff is collapsed.
......@@ -37,6 +37,7 @@ Created 11/5/1995 Heikki Tuuri
#include "log0log.h"
#include "trx0undo.h"
#include "srv0srv.h"
#include "page0zip.h"
/*
IMPLEMENTATION OF THE BUFFER POOL
......@@ -482,6 +483,8 @@ buf_block_init(
block->n_pointers = 0;
page_zip_des_init(&block->page_zip);
rw_lock_create(&(block->lock));
ut_ad(rw_lock_validate(&(block->lock)));
......
......@@ -264,9 +264,11 @@ buf_flush_buffered_writes(void)
"InnoDB: before posting to the doublewrite buffer.\n");
}
if (block->check_index_page_at_flush
&& !page_simple_validate(block->frame)) {
if (!block->check_index_page_at_flush) {
} else if (page_is_comp(block->frame)
&& UNIV_UNLIKELY(!page_simple_validate_new(
block->frame))) {
corrupted_page:
buf_page_print(block->frame);
ut_print_timestamp(stderr);
......@@ -278,6 +280,10 @@ buf_flush_buffered_writes(void)
(ulong) block->offset, (ulong) block->space);
ut_error;
} else if (UNIV_UNLIKELY(!page_simple_validate_old(
block->frame))) {
goto corrupted_page;
}
}
......
......@@ -2761,6 +2761,7 @@ ibuf_insert(
ut_ad(dtuple_check_typed(entry));
ut_a(!(index->type & DICT_CLUSTERED));
ut_a(!index->table->zip);
if (rec_get_converted_size(index, entry)
>= page_get_free_space_of_empty(index->table->comp) / 2) {
......@@ -2846,9 +2847,10 @@ ibuf_insert_to_index_page(
btr_cur_del_unmark_for_ibuf(rec, mtr);
} else {
rec = page_cur_tuple_insert(&page_cur, entry, index, mtr);
rec = page_cur_tuple_insert(&page_cur, NULL,
entry, index, mtr);
if (rec == NULL) {
if (UNIV_UNLIKELY(rec == NULL)) {
/* If the record did not fit, reorganize */
btr_page_reorganize(page, index, mtr);
......@@ -2858,7 +2860,8 @@ ibuf_insert_to_index_page(
/* This time the record must fit */
if (UNIV_UNLIKELY(!page_cur_tuple_insert(
&page_cur, entry, index, mtr))) {
&page_cur, NULL,
entry, index, mtr))) {
ut_print_timestamp(stderr);
......
......@@ -265,9 +265,10 @@ Sets a record as the predefined minimum record. */
void
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /* in: record */
ulint comp, /* in: nonzero=compact page format */
mtr_t* mtr); /* in: mtr */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 5 bytes available, or NULL */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Deletes on the upper level the node pointer to a page. */
......@@ -295,11 +296,12 @@ conditions, looks at the right brother. If the page is the only one on that
level lifts the records of the page to the father page, thus reducing the
tree height. It is assumed that mtr holds an x-latch on the tree and on the
page. If cursor is on the leaf level, mtr must also hold x-latches to
the brothers, if they exist. NOTE: it is assumed that the caller has reserved
enough free extents so that the compression will always succeed if done! */
void
the brothers, if they exist. */
ibool
btr_compress(
/*=========*/
/* out: TRUE on success */
btr_cur_t* cursor, /* in: cursor on the page to merge or lift;
the page must not be empty: in record delete
use btr_discard_page if the page would become
......
......@@ -286,19 +286,6 @@ btr_cur_del_unmark_for_ibuf(
rec_t* rec, /* in: record to delete unmark */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Tries to compress a page of the tree on the leaf level. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
brothers exist. NOTE: it is assumed that the caller has reserved enough
free extents so that the compression will always succeed if done! */
void
btr_cur_compress(
/*=============*/
btr_cur_t* cursor, /* in: cursor on the page to compress;
cursor does not stay valid */
mtr_t* mtr); /* in: mtr */
/*****************************************************************
Tries to compress a page of the tree if it seems useful. It is assumed
that mtr holds an x-latch on the tree and on the cursor page. To avoid
deadlocks, mtr must also own x-latches to brothers of page, if those
......@@ -364,7 +351,8 @@ btr_cur_parse_update_in_place(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page, /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
dict_index_t* index); /* in: index corresponding to page */
/********************************************************************
Parses the redo log record for delete marking or unmarking of a clustered
......@@ -376,8 +364,9 @@ btr_cur_parse_del_mark_set_clust_rec(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: index corresponding to page */
page_t* page); /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
dict_index_t* index); /* in: index corresponding to page */
/********************************************************************
Parses the redo log record for delete marking or unmarking of a secondary
index record. */
......@@ -388,7 +377,8 @@ btr_cur_parse_del_mark_set_sec_rec(
/* out: end of log record or NULL */
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
page_t* page); /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip);/* in/out: compressed page, or NULL */
/***********************************************************************
Estimates the number of rows in a given index range. */
......
......@@ -31,6 +31,7 @@ Created 11/5/1995 Heikki Tuuri
#include "hash0hash.h"
#include "ut0byte.h"
#include "os0proc.h"
#include "page0types.h"
/* Flags for flush types */
#define BUF_FLUSH_LRU 1
......@@ -612,6 +613,14 @@ buf_block_get_page_no(
/*==================*/
/* out: page number */
buf_block_t* block); /* in: pointer to the control block */
/*************************************************************************
Gets the compressed page descriptor of a block if applicable. */
UNIV_INLINE
page_zip_des_t*
buf_block_get_page_zip(
/*===================*/
/* out: compressed page descriptor, or NULL */
buf_block_t* block); /* in: pointer to the control block */
/***********************************************************************
Gets the block to whose frame the pointer is pointing to. */
UNIV_INLINE
......@@ -850,6 +859,7 @@ struct buf_block_struct{
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
BTR_SEARCH_RIGHT_SIDE in hash
indexing */
page_zip_des_t page_zip; /* compressed page info */
/* 6. Debug fields */
#ifdef UNIV_SYNC_DEBUG
rw_lock_t debug_latch; /* in the debug version, each thread
......
......@@ -191,6 +191,24 @@ buf_block_get_page_no(
return(block->offset);
}
/*************************************************************************
Gets the compressed page descriptor of a block if applicable. */
UNIV_INLINE
page_zip_des_t*
buf_block_get_page_zip(
/*===================*/
/* out: compressed page descriptor, or NULL */
buf_block_t* block) /* in: pointer to the control block */
{
ut_ad(block);
if (UNIV_LIKELY_NULL(block->page_zip.data)) {
return(&block->page_zip);
}
return(NULL);
}
/***********************************************************************
Gets the block to whose frame the pointer is pointing to. */
UNIV_INLINE
......@@ -614,8 +632,6 @@ buf_page_release(
RW_NO_LATCH */
mtr_t* mtr) /* in: mtr */
{
ulint buf_fix_count;
ut_ad(block);
mutex_enter_fast(&(buf_pool->mutex));
......@@ -631,8 +647,7 @@ buf_page_release(
#ifdef UNIV_SYNC_DEBUG
rw_lock_s_unlock(&(block->debug_latch));
#endif
buf_fix_count = block->buf_fix_count;
block->buf_fix_count = buf_fix_count - 1;
block->buf_fix_count--;
mutex_exit(&(buf_pool->mutex));
......
......@@ -329,6 +329,7 @@ struct dict_table_struct{
user calls DISCARD TABLESPACE on this table,
and reset to FALSE in IMPORT TABLESPACE */
ibool comp; /* flag: TRUE=compact page format */
ibool zip; /* flag: TRUE=compressed page format */
hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */
ulint n_def; /* number of columns defined so far */
......
......@@ -88,6 +88,7 @@ ibuf_should_try(
decide */
{
if (!(index->type & DICT_CLUSTERED)
&& !index->table->zip
&& (ignore_sec_unique || !(index->type & DICT_UNIQUE))
&& ibuf->meter > IBUF_THRESHOLD) {
......
......@@ -129,8 +129,11 @@ flag value must give the length also! */
/* copy compact record list end
to a new created index page */
#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
#define MLOG_COMP_DECOMPRESS ((byte)47) /* decompress a page
to undo a compressed page
overflow */
#define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in
#define MLOG_BIGGEST_TYPE ((byte)47) /* biggest value (used in
asserts) */
/*******************************************************************
......
......@@ -130,6 +130,8 @@ page_cur_tuple_insert(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, or NULL */
dtuple_t* tuple, /* in: pointer to a data tuple */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mini-transaction handle */
......@@ -144,6 +146,8 @@ page_cur_rec_insert(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, or NULL */
rec_t* rec, /* in: record to insert */
dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: rec_get_offsets(rec, index) */
......@@ -160,6 +164,8 @@ page_cur_insert_rec_low(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, 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 */
......@@ -173,7 +179,6 @@ 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 */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr); /* in: mtr */
......@@ -184,9 +189,11 @@ next record after the deleted one. */
void
page_cur_delete_rec(
/*================*/
page_cur_t* cursor, /* in: a page cursor */
page_cur_t* cursor, /* in/out: a page cursor */
dict_index_t* index, /* in: record descriptor */
const ulint* offsets,/* in: rec_get_offsets(cursor->rec, index) */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
32 bytes available, or NULL */
mtr_t* mtr); /* in: mini-transaction handle */
/********************************************************************
Searches the right position for a page cursor. */
......@@ -245,7 +252,9 @@ page_cur_parse_insert_rec(
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */
page_t* page, /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/**************************************************************
Parses a log record of copying a record list end to a new created page. */
......@@ -257,7 +266,8 @@ page_parse_copy_rec_list_to_created_page(
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */
page_t* page, /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/***************************************************************
Parses log record of a record delete on a page. */
......@@ -269,7 +279,9 @@ page_cur_parse_delete_rec(
byte* ptr, /* in: buffer */
byte* end_ptr,/* in: buffer end */
dict_index_t* index, /* in: record descriptor */
page_t* page, /* in: page or NULL */
page_t* page, /* in/out: page or NULL */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
32 bytes available, or NULL */
mtr_t* mtr); /* in: mtr or NULL */
/* Index page cursor */
......
......@@ -181,11 +181,14 @@ page_cur_tuple_insert(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, or NULL */
dtuple_t* tuple, /* in: pointer to a data tuple */
dict_index_t* index, /* in: record descriptor */
mtr_t* mtr) /* in: mini-transaction handle */
{
return(page_cur_insert_rec_low(cursor, tuple, index, NULL, NULL, mtr));
return(page_cur_insert_rec_low(cursor, page_zip, tuple,
index, NULL, NULL, mtr));
}
/***************************************************************
......@@ -199,12 +202,14 @@ page_cur_rec_insert(
/* out: pointer to record if succeed, NULL
otherwise */
page_cur_t* cursor, /* in: a page cursor */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
25 + rec_size bytes available, or NULL */
rec_t* rec, /* in: record to insert */
dict_index_t* index, /* in: record descriptor */
ulint* offsets,/* in: rec_get_offsets(rec, index) */
mtr_t* mtr) /* in: mini-transaction handle */
{
return(page_cur_insert_rec_low(cursor, NULL, index, rec,
offsets, mtr));
return(page_cur_insert_rec_low(cursor, page_zip, NULL,
index, rec, offsets, mtr));
}
This diff is collapsed.
......@@ -35,7 +35,7 @@ UNIV_INLINE
void
page_update_max_trx_id(
/*===================*/
page_t* page, /* in: page */
page_t* page, /* in/out: page */
dulint trx_id) /* in: transaction id */
{
ut_ad(page);
......@@ -67,9 +67,10 @@ UNIV_INLINE
void
page_header_set_field(
/*==================*/
page_t* page, /* in: page */
ulint field, /* in: PAGE_LEVEL, ... */
ulint val) /* in: value */
page_t* page, /* in/out: page */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
ulint field, /* in: PAGE_N_DIR_SLOTS, ... */
ulint val) /* in: value */
{
ut_ad(page);
ut_ad(field <= PAGE_N_RECS);
......@@ -77,6 +78,9 @@ page_header_set_field(
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < UNIV_PAGE_SIZE);
mach_write_to_2(page + PAGE_HEADER + field, val);
if (UNIV_LIKELY_NULL(page_zip)) {
page_zip_write_header(page_zip, page + PAGE_HEADER + field, 2);
}
}
/*****************************************************************
......@@ -114,9 +118,10 @@ UNIV_INLINE
void
page_header_set_ptr(
/*================*/
page_t* page, /* in: page */
ulint field, /* in: PAGE_FREE, ... */
byte* ptr) /* in: pointer or NULL*/
page_t* page, /* in: page */
page_zip_des_t* page_zip,/* in: compressed page, or NULL */
ulint field, /* in: PAGE_FREE, ... */
const byte* ptr) /* in: pointer or NULL*/
{
ulint offs;
......@@ -133,7 +138,7 @@ page_header_set_ptr(
ut_ad((field != PAGE_HEAP_TOP) || offs);
page_header_set_field(page, field, offs);
page_header_set_field(page, page_zip, field, offs);
}
/*****************************************************************
......@@ -413,11 +418,11 @@ UNIV_INLINE
void
page_dir_set_n_slots(
/*=================*/
/* out: number of slots */
page_t* page, /* in: index page */
ulint n_slots)/* in: number of slots */
page_t* page, /* in/out: page */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
ulint n_slots)/* in: number of slots */
{
page_header_set_field(page, PAGE_N_DIR_SLOTS, n_slots);
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots);
}
/*****************************************************************
......@@ -438,12 +443,13 @@ UNIV_INLINE
void
page_dir_set_n_heap(
/*================*/
page_t* page, /* in: index page */
ulint n_heap) /* in: number of records */
page_t* page, /* in/out: index page */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
ulint n_heap) /* in: number of records */
{
ut_ad(n_heap < 0x8000);
page_header_set_field(page, PAGE_N_HEAP, n_heap | (0x8000 &
page_header_set_field(page, page_zip, PAGE_N_HEAP, n_heap | (0x8000 &
page_header_get_field(page, PAGE_N_HEAP)));
}
......@@ -520,7 +526,11 @@ page_dir_slot_get_n_owned(
page_dir_slot_t* slot) /* in: page directory slot */
{
rec_t* rec = page_dir_slot_get_rec(slot);
return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
if (page_rec_is_comp(slot)) {
return(rec_get_n_owned_new(rec));
} else {
return(rec_get_n_owned_old(rec));
}
}
/*******************************************************************
......@@ -529,12 +539,18 @@ UNIV_INLINE
void
page_dir_slot_set_n_owned(
/*======================*/
page_dir_slot_t* slot, /* in: directory slot */
ulint n) /* in: number of records owned
by the slot */
page_dir_slot_t*slot, /* in/out: directory slot */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 5 bytes available, or NULL */
ulint n) /* in: number of records owned by the slot */
{
rec_t* rec = page_dir_slot_get_rec(slot);
rec_set_n_owned(rec, page_rec_is_comp(rec), n);
if (page_rec_is_comp(slot)) {
rec_set_n_owned_new(rec, page_zip, n);
} else {
ut_ad(!page_zip);
rec_set_n_owned_old(rec, n);
}
}
/****************************************************************
......@@ -597,26 +613,29 @@ UNIV_INLINE
void
page_rec_set_next(
/*==============*/
rec_t* rec, /* in: pointer to record, must not be page supremum */
rec_t* next) /* in: pointer to next record, must not be page
infimum */
rec_t* rec, /* in: pointer to record,
must not be page supremum */
rec_t* next, /* in: pointer to next record,
must not be page infimum */
page_zip_des_t* page_zip) /* in/out: compressed page with
at least 6 bytes available, or NULL */
{
page_t* page;
ulint offs;
ut_ad(page_rec_check(rec));
ut_ad(!page_rec_is_supremum(rec));
page = ut_align_down(rec, UNIV_PAGE_SIZE);
if (next) {
ut_ad(!page_rec_is_infimum(next));
ut_ad(page == ut_align_down(next, UNIV_PAGE_SIZE));
offs = (ulint) (next - page);
ut_ad(!next || !page_rec_is_infimum(next));
ut_ad(!next || ut_align_down(rec, UNIV_PAGE_SIZE)
== ut_align_down(next, UNIV_PAGE_SIZE));
offs = ut_align_offset(next, UNIV_PAGE_SIZE);
if (page_rec_is_comp(rec)) {
rec_set_next_offs_new(rec, page_zip, offs);
} else {
offs = 0;
rec_set_next_offs_old(rec, offs);
ut_ad(!page_zip);
}
rec_set_next_offs(rec, page_is_comp(page), offs);
}
/****************************************************************
......@@ -671,11 +690,11 @@ page_rec_find_owner_rec(
ut_ad(page_rec_check(rec));
if (page_rec_is_comp(rec)) {
while (rec_get_n_owned(rec, TRUE) == 0) {
while (rec_get_n_owned_new(rec) == 0) {
rec = page_rec_get_next(rec);
}
} else {
while (rec_get_n_owned(rec, FALSE) == 0) {
while (rec_get_n_owned_old(rec) == 0) {
rec = page_rec_get_next(rec);
}
}
......@@ -683,6 +702,23 @@ page_rec_find_owner_rec(
return(rec);
}
/**************************************************************
Returns the base extra size of a physical record. This is the
size of the fixed header, independent of the record size. */
UNIV_INLINE
ulint
page_rec_get_base_extra_size(
/*=========================*/
/* out: REC_N_NEW_EXTRA_BYTES
or REC_N_OLD_EXTRA_BYTES */
const rec_t* rec) /* in: physical record */
{
#if REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES
# error "REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES"
#endif
return(REC_N_NEW_EXTRA_BYTES + (ulint) !page_rec_is_comp(rec));
}
/****************************************************************
Returns the sum of the sizes of the records in the record list, excluding
the infimum and supremum records. */
......@@ -805,7 +841,9 @@ UNIV_INLINE
void
page_mem_free(
/*==========*/
page_t* page, /* in: index page */
page_t* page, /* in/out: index page */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
6 bytes available, or NULL */
rec_t* rec, /* in: pointer to the (origin of) record */
const ulint* offsets)/* in: array returned by rec_get_offsets() */
{
......@@ -816,8 +854,8 @@ page_mem_free(
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
free = page_header_get_ptr(page, PAGE_FREE);
page_rec_set_next(rec, free);
page_header_set_ptr(page, PAGE_FREE, rec);
page_rec_set_next(rec, free, page_zip);
page_header_set_ptr(page, page_zip, PAGE_FREE, rec);
#if 0 /* It's better not to destroy the user's data. */
......@@ -827,11 +865,18 @@ page_mem_free(
cannot be cleared, because page_mem_alloc() needs them in order
to determine the size of the deleted record. */
memset(rec, 0, rec_offs_data_size(offsets));
/* If you enable this code, make sure that the callers of
page_mem_free() account for the increased usage of space. */
if (UNIV_LIKELY_NULL(page_zip)) {
page_zip_write(page_zip, page, rec, rec - page,
rec_offs_data_size(offsets));
}
#endif
garbage = page_header_get_field(page, PAGE_GARBAGE);
page_header_set_field(page, PAGE_GARBAGE,
page_header_set_field(page, page_zip, PAGE_GARBAGE,
garbage + rec_offs_size(offsets));
}
......
......@@ -18,5 +18,71 @@ typedef byte page_t;
typedef struct page_search_struct page_search_t;
typedef struct page_cur_struct page_cur_t;
typedef byte page_zip_t;
typedef struct page_zip_des_struct page_zip_des_t;
/* The following definitions would better belong to page0zip.h,
but we cannot include page0zip.h from rem0rec.ic, because
page0*.h includes rem0rec.h and may include rem0rec.ic. */
/* Compressed page descriptor */
struct page_zip_des_struct
{
page_zip_t* data; /* compressed page data */
ulint size; /* total size of compressed page */
ulint m_start; /* start offset of modification log */
ulint m_end; /* end offset of modification log */
};
/**************************************************************************
Write data to the compressed page. The data must already be written to
the uncompressed page. */
void
page_zip_write(
/*===========*/
page_zip_des_t* page_zip,/* out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
/**************************************************************************
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_header(
/*==================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
/**************************************************************************
Write data to the uncompressed trailer portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_trailer(
/*===================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
#ifdef UNIV_DEBUG
/**************************************************************************
Determine if enough space is available in the modification log. */
ibool
page_zip_available_noninline(
/*=========================*/
/* out: TRUE if enough space
is available */
const page_zip_des_t* page_zip,/* in: compressed page */
ulint size)
__attribute__((warn_unused_result, nonnull, pure));
#endif /* UNIV_DEBUG */
#endif
/******************************************************
Compressed page interface
(c) 2005 Innobase Oy
Created June 2005 by Marko Makela
*******************************************************/
#ifndef page0zip_h
#define page0zip_h
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE
#endif
#include "mtr0types.h"
#include "page0types.h"
/**************************************************************************
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
page_zip_des_t* page_zip); /* in/out: compressed page
descriptor */
/**************************************************************************
Compress a page. */
ibool
page_zip_compress(
/*==============*/
/* out: TRUE on success, FALSE on failure;
page_zip will be left intact on failure. */
page_zip_des_t* page_zip,/* out: compressed page */
const page_t* page); /* in: uncompressed page */
/**************************************************************************
Decompress a page. */
ibool
page_zip_decompress(
/*================*/
/* out: TRUE on success, FALSE on failure */
page_zip_des_t* page_zip,/* in: data, size; out: m_start, m_end */
page_t* page, /* out: uncompressed page, may be trashed */
mtr_t* mtr) /* in: mini-transaction handle,
or NULL if no logging is needed */
__attribute__((warn_unused_result, nonnull(1, 2)));
#ifdef UNIV_DEBUG
/**************************************************************************
Validate a compressed page descriptor. */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
/* out: TRUE if ok */
const page_zip_des_t* page_zip); /* in: compressed page
descriptor */
/**************************************************************************
Check that the compressed and decompressed pages match. */
ibool
page_zip_validate(
/*==============*/
const page_zip_des_t* page_zip,/* in: compressed page */
const page_t* page); /* in: uncompressed page */
#endif /* UNIV_DEBUG */
/**************************************************************************
Determine the encoded length of an integer in the modification log. */
UNIV_INLINE
ulint
page_zip_ulint_size(
/*================*/
/* out: length of the integer, in bytes */
ulint num) /* in: the integer */
__attribute__((const));
/**************************************************************************
Determine the size of a modification log entry. */
UNIV_INLINE
ulint
page_zip_entry_size(
/*================*/
/* out: length of the log entry, in bytes */
ulint pos, /* in: offset of the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((const));
/**************************************************************************
Ensure that enough space is available in the modification log.
If not, try to compress the page. */
UNIV_INLINE
ibool
page_zip_alloc(
/*===========*/
/* out: TRUE if enough space is available */
page_zip_des_t* page_zip,/* in/out: compressed page;
will only be modified if compression is needed
and successful */
const page_t* page, /* in: uncompressed page */
ulint size) /* in: size of modification log entries */
__attribute__((nonnull));
/**************************************************************************
Determine if enough space is available in the modification log. */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
/* out: TRUE if enough space
is available */
const page_zip_des_t* page_zip,/* in: compressed page */
ulint size) /* in: requested size of
modification log entries */
__attribute__((warn_unused_result, nonnull, pure));
#ifdef UNIV_DEBUG
/**************************************************************************
Determine if enough space is available in the modification log. */
ibool
page_zip_available_noninline(
/*=========================*/
/* out: TRUE if enough space
is available */
const page_zip_des_t* page_zip,/* in: compressed page */
ulint size)
__attribute__((warn_unused_result, nonnull, pure));
#endif /* UNIV_DEBUG */
/**************************************************************************
Write data to the compressed portion of a page. The data must already
have been written to the uncompressed page. */
void
page_zip_write(
/*===========*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
/**************************************************************************
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_header(
/*==================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
/**************************************************************************
Write data to the uncompressed trailer portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_trailer(
/*===================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
__attribute__((nonnull));
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
#endif
#ifndef UNIV_NONINL
# include "page0zip.ic"
#endif
#endif /* page0zip_h */
/******************************************************
Compressed page interface
(c) 2005 Innobase Oy
Created June 2005 by Marko Makela
*******************************************************/
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE
#endif
#include "page0zip.h"
#include "page0page.h"
/* The format of compressed pages is as follows.
The header and trailer of the uncompressed pages, including the page
directory in the trailer, are copied as is to the header and trailer
of the compressed page. Immediately preceding the page trailer,
we store a 32-bit checksum of the compressed data.
The data between PAGE_DATA and the last page directory entry
will be written in compressed format, starting at offset PAGE_DATA.
The compressed data stream may be followed by a modification log
covering the compressed portion of the page, as follows.
MODIFICATION LOG ENTRY FORMAT
- length (1..2 bytes), not zero
- offset - PAGE_DATA (1..2 bytes)
- data bytes
The length and the offset are stored in a variable-length format:
- 0xxxxxxxx : 0..127
- 10xxxxxxx xxxxxxxx: 0..16383
- 11xxxxxxx xxxxxxxx: reserved
The end of the modification log is marked by length=0. */
/**************************************************************************
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
page_zip_des_t* page_zip) /* in/out: compressed page
descriptor */
{
memset(page_zip, 0, sizeof *page_zip);
}
/**************************************************************************
Determine the encoded length of an integer in the modification log. */
UNIV_INLINE
ulint
page_zip_ulint_size(
/*================*/
/* out: length of the integer, in bytes */
ulint num) /* in: the integer */
{
if (num < 128) { /* 0xxxxxxx: 0..127 */
return(1);
}
if (num < 16384) { /* 10xxxxxx xxxxxxxx: 0..16383 */
return(2);
}
ut_error;
return(0);
}
/**************************************************************************
Determine the size of a modification log entry. */
UNIV_INLINE
ulint
page_zip_entry_size(
/*================*/
/* out: length of the log entry, in bytes */
ulint pos, /* in: offset of the uncompressed page */
ulint length) /* in: length of the data */
{
ut_ad(pos >= PAGE_DATA);
ut_ad(pos + length <= UNIV_PAGE_SIZE - PAGE_DATA /* - trailer_len */);
return(page_zip_ulint_size(pos - PAGE_DATA)
+ page_zip_ulint_size(length)
+ length);
}
#ifdef UNIV_DEBUG
/**************************************************************************
Validate a compressed page descriptor. */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
/* out: TRUE if ok */
const page_zip_des_t* page_zip)/* in: compressed page descriptor */
{
ut_ad(page_zip);
ut_ad(page_zip->data);
ut_ad(!(page_zip->size & (page_zip->size - 1)));
ut_ad(page_zip->size < UNIV_PAGE_SIZE);
ut_ad(page_zip->size > PAGE_DATA + PAGE_EMPTY_DIR_START);
ut_ad(page_zip->m_start <= page_zip->m_end);
ut_ad(page_zip->m_end < page_zip->size);
return(TRUE);
}
#endif /* UNIV_DEBUG */
/**************************************************************************
Ensure that enough space is available in the modification log.
If not, try to compress the page. */
UNIV_INLINE
ibool
page_zip_alloc(
/*===========*/
/* out: TRUE if enough space is available */
page_zip_des_t* page_zip,/* in/out: compressed page;
will only be modified if compression is needed
and successful */
const page_t* page, /* in: uncompressed page */
ulint size) /* in: size of modification log entries */
{
ulint trailer_len = PAGE_DIR + PAGE_DIR_SLOT_SIZE
* page_dir_get_n_slots((page_t*) page_zip->data);
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip->m_end + trailer_len < page_zip->size);
ut_ad(size >= 3); /* modification log entries are >= 1+1+1 bytes */
ut_ad(size < page_zip->size);
if (size < page_zip->size - page_zip->m_end - trailer_len) {
return(TRUE);
}
if (page_zip->m_start == page_zip->m_end) {
/* The page has been freshly compressed, so
recompressing it will not help. */
return(FALSE);
}
return(page_zip_compress(page_zip, page));
}
/**************************************************************************
Determine if enough space is available in the modification log. */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
/* out: TRUE if enough space
is available */
const page_zip_des_t* page_zip,/* in: compressed page */
ulint size) /* in: requested size of
modification log entries */
{
ulint trailer_len = PAGE_DIR + PAGE_DIR_SLOT_SIZE
* page_dir_get_n_slots((page_t*) page_zip->data);
ut_ad(page_zip_simple_validate(page_zip));
ut_ad(page_zip->m_end + trailer_len < page_zip->size);
ut_ad(size >= 3); /* modification log entries are >= 1+1+1 bytes */
ut_ad(size < page_zip->size);
return(UNIV_LIKELY(
size < page_zip->size - page_zip->m_end - trailer_len));
}
/**************************************************************************
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_header(
/*==================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
{
ulint pos;
ut_ad(buf_block_get_page_zip(buf_block_align((byte*)str)) == page_zip);
ut_ad(page_zip_simple_validate(page_zip));
pos = ut_align_offset(str, UNIV_PAGE_SIZE);
ut_ad(pos < PAGE_DATA);
memcpy(page_zip + pos, str, length);
ut_ad(page_zip_validate(page_zip, str - pos));
}
/**************************************************************************
Write data to the uncompressed trailer portion of a page. The data must
already have been written to the uncompressed page. */
UNIV_INLINE
void
page_zip_write_trailer(
/*===================*/
page_zip_des_t* page_zip,/* in/out: compressed page */
const byte* str, /* in: address on the uncompressed page */
ulint length) /* in: length of the data */
{
ulint pos;
ut_ad(buf_block_get_page_zip(buf_block_align((byte*)str)) == page_zip);
ut_ad(page_zip_simple_validate(page_zip));
pos = ut_align_offset(str, UNIV_PAGE_SIZE);
ut_ad(pos < PAGE_DATA);/* TODO */
memcpy(page_zip + pos/* TODO */, str, length);
ut_ad(page_zip_validate(page_zip, str - pos));
}
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -45,7 +45,9 @@ UNIV_INLINE
void
row_set_rec_trx_id(
/*===============*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 10 bytes available,, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint trx_id);/* in: value of the field */
......@@ -55,7 +57,9 @@ UNIV_INLINE
void
row_set_rec_roll_ptr(
/*=================*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 11 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint roll_ptr);/* in: value of the field */
......
......@@ -29,9 +29,10 @@ is slower than the specialized inline functions. */
void
row_set_rec_sys_field(
/*==================*/
/* out: value of the field */
ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
10 or 11 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint val); /* in: value to set */
......@@ -94,7 +95,9 @@ UNIV_INLINE
void
row_set_rec_trx_id(
/*===============*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 10 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint trx_id) /* in: value of the field */
......@@ -107,10 +110,10 @@ row_set_rec_trx_id(
offset = index->trx_id_offset;
if (offset) {
trx_write_trx_id(rec + offset, trx_id);
trx_write_trx_id(rec + offset, page_zip, trx_id);
} else {
row_set_rec_sys_field(DATA_TRX_ID,
rec, index, offsets, trx_id);
rec, page_zip, index, offsets, trx_id);
}
}
......@@ -120,7 +123,9 @@ UNIV_INLINE
void
row_set_rec_roll_ptr(
/*=================*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 11 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint roll_ptr)/* in: value of the field */
......@@ -133,10 +138,11 @@ row_set_rec_roll_ptr(
offset = index->trx_id_offset;
if (offset) {
trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr);
trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN,
page_zip, roll_ptr);
} else {
row_set_rec_sys_field(DATA_ROLL_PTR,
rec, index, offsets, roll_ptr);
rec, page_zip, index, offsets, roll_ptr);
}
}
......
......@@ -78,7 +78,9 @@ UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 21 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
trx_t* trx, /* in: transaction */
......@@ -276,7 +278,8 @@ recovery. */
void
row_upd_rec_sys_fields_in_recovery(
/*===============================*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
const ulint* offsets,/* in: array returned by rec_get_offsets() */
ulint pos, /* in: TRX_ID position in rec */
dulint trx_id, /* in: transaction id */
......
......@@ -11,6 +11,7 @@ Created 12/27/1996 Heikki Tuuri
#include "trx0undo.h"
#include "row0row.h"
#include "btr0sea.h"
#include "page0zip.h"
/*************************************************************************
Creates an update vector object. */
......@@ -104,7 +105,9 @@ UNIV_INLINE
void
row_upd_rec_sys_fields(
/*===================*/
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 21 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
trx_t* trx, /* in: transaction */
......@@ -116,7 +119,8 @@ row_upd_rec_sys_fields(
ut_ad(!buf_block_align(rec)->is_hashed
|| rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(!page_zip || page_zip_available(page_zip, 21));
row_set_rec_trx_id(rec, index, offsets, trx->id);
row_set_rec_roll_ptr(rec, index, offsets, roll_ptr);
row_set_rec_trx_id(rec, page_zip, index, offsets, trx->id);
row_set_rec_roll_ptr(rec, page_zip, index, offsets, roll_ptr);
}
......@@ -23,6 +23,7 @@ Created 3/26/1996 Heikki Tuuri
#include "fut0lst.h"
#include "fsp0fsp.h"
#include "read0types.h"
#include "page0types.h"
/* In a MySQL replication slave, in crash recovery we store the master log
file name and position here. We have successfully got the updates to InnoDB
......@@ -210,8 +211,10 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
byte* ptr, /* in: pointer to memory where written */
dulint id); /* in: id */
byte* ptr, /* in: pointer to memory where written */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 10 bytes available, or NULL */
dulint id); /* in: id */
/*********************************************************************
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
......
......@@ -9,6 +9,7 @@ Created 3/26/1996 Heikki Tuuri
#include "srv0srv.h"
#include "trx0trx.h"
#include "data0type.h"
#include "page0zip.h"
/* The typedef for rseg slot in the file copy */
typedef byte trx_sysf_rseg_t;
......@@ -213,12 +214,18 @@ UNIV_INLINE
void
trx_write_trx_id(
/*=============*/
byte* ptr, /* in: pointer to memory where written */
dulint id) /* in: id */
byte* ptr, /* in: pointer to memory where written */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 10 bytes available, or NULL */
dulint id) /* in: id */
{
ut_ad(DATA_TRX_ID_LEN == 6);
mach_write_to_6(ptr, id);
if (UNIV_LIKELY_NULL(page_zip)) {
ut_ad(page_zip_available(page_zip, 4 + DATA_TRX_ID_LEN));
page_zip_write(page_zip, ptr, DATA_TRX_ID_LEN);
}
}
/*********************************************************************
......
......@@ -55,6 +55,8 @@ void
trx_write_roll_ptr(
/*===============*/
byte* ptr, /* in: pointer to memory where written */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 11 bytes available, or NULL */
dulint roll_ptr); /* in: roll ptr */
/*********************************************************************
Reads a roll ptr from an index page. In case that the roll ptr size
......
......@@ -7,6 +7,7 @@ Created 3/26/1996 Heikki Tuuri
*******************************************************/
#include "data0type.h"
#include "page0zip.h"
/***************************************************************************
Builds a roll pointer dulint. */
......@@ -87,12 +88,18 @@ UNIV_INLINE
void
trx_write_roll_ptr(
/*===============*/
byte* ptr, /* in: pointer to memory where written */
dulint roll_ptr) /* in: roll ptr */
byte* ptr, /* in: pointer to memory where written */
page_zip_des_t* page_zip,/* in/out: compressed page with
at least 11 bytes available, or NULL */
dulint roll_ptr)/* in: roll ptr */
{
ut_ad(DATA_ROLL_PTR_LEN == 7);
mach_write_to_7(ptr, roll_ptr);
if (UNIV_LIKELY_NULL(page_zip)) {
ut_ad(page_zip_available(page_zip, 4 + DATA_ROLL_PTR_LEN));
page_zip_write(page_zip, ptr, DATA_ROLL_PTR_LEN);
}
}
/*********************************************************************
......
This diff is collapsed.
......@@ -22,6 +22,7 @@ Created 9/20/1997 Heikki Tuuri
#include "mtr0log.h"
#include "page0page.h"
#include "page0cur.h"
#include "page0zip.h"
#include "btr0btr.h"
#include "btr0cur.h"
#include "ibuf0ibuf.h"
......@@ -753,9 +754,10 @@ recv_parse_or_apply_log_rec_body(
byte type, /* in: type */
byte* ptr, /* in: pointer to a buffer */
byte* end_ptr,/* in: pointer to the buffer end */
page_t* page, /* in: buffer page or NULL; if not NULL, then the log
record is applied to the page, and the log record
page_t* page, /* in/out: buffer page or NULL; if not NULL, then the
log record is applied to the page, and the log record
should be complete then */
page_zip_des_t* page_zip,/* in/out: compressed page or NULL */
mtr_t* mtr) /* in: mtr or NULL; should be non-NULL if and only if
page is non-NULL */
{
......@@ -771,7 +773,7 @@ recv_parse_or_apply_log_rec_body(
ut_a(!page
|| (ibool)!!page_is_comp(page)==index->table->comp);
ptr = page_cur_parse_insert_rec(FALSE, ptr, end_ptr,
index, page, mtr);
index, page, page_zip, mtr);
}
break;
case MLOG_REC_CLUST_DELETE_MARK: case MLOG_COMP_REC_CLUST_DELETE_MARK:
......@@ -780,7 +782,7 @@ recv_parse_or_apply_log_rec_body(
ut_a(!page
|| (ibool)!!page_is_comp(page)==index->table->comp);
ptr = btr_cur_parse_del_mark_set_clust_rec(ptr,
end_ptr, index, page);
end_ptr, page, page_zip, index);
}
break;
case MLOG_COMP_REC_SEC_DELETE_MARK:
......@@ -793,7 +795,8 @@ recv_parse_or_apply_log_rec_body(
}
/* Fall through */
case MLOG_REC_SEC_DELETE_MARK:
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr, page);
ptr = btr_cur_parse_del_mark_set_sec_rec(ptr, end_ptr,
page, page_zip);
break;
case MLOG_REC_UPDATE_IN_PLACE: case MLOG_COMP_REC_UPDATE_IN_PLACE:
if (NULL != (ptr = mlog_parse_index(ptr, end_ptr,
......@@ -801,7 +804,7 @@ recv_parse_or_apply_log_rec_body(
ut_a(!page
|| (ibool)!!page_is_comp(page)==index->table->comp);
ptr = btr_cur_parse_update_in_place(ptr, end_ptr,
page, index);
page, page_zip, index);
}
break;
case MLOG_LIST_END_DELETE: case MLOG_COMP_LIST_END_DELETE:
......@@ -821,7 +824,7 @@ recv_parse_or_apply_log_rec_body(
ut_a(!page
|| (ibool)!!page_is_comp(page)==index->table->comp);
ptr = page_parse_copy_rec_list_to_created_page(ptr,
end_ptr, index, page, mtr);
end_ptr, index, page, page_zip, mtr);
}
break;
case MLOG_PAGE_REORGANIZE: case MLOG_COMP_PAGE_REORGANIZE:
......@@ -864,7 +867,7 @@ recv_parse_or_apply_log_rec_body(
ut_a(!page
|| (ibool)!!page_is_comp(page)==index->table->comp);
ptr = page_cur_parse_delete_rec(ptr, end_ptr,
index, page, mtr);
index, page, page_zip, mtr);
}
break;
case MLOG_IBUF_BITMAP_INIT:
......@@ -882,6 +885,16 @@ recv_parse_or_apply_log_rec_body(
ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE,
ULINT_UNDEFINED);
break;
case MLOG_COMP_DECOMPRESS:
if (page) {
ut_a(page_is_comp(page));
ut_a(page_zip);
if (UNIV_UNLIKELY(!page_zip_decompress(
page_zip, page, NULL))) {
ut_error;
}
}
break;
default:
ptr = NULL;
recv_sys->found_corrupt_log = TRUE;
......@@ -1089,6 +1102,7 @@ recv_recover_page(
ulint page_no) /* in: page number */
{
buf_block_t* block = NULL;
page_zip_des_t* page_zip = NULL;
recv_addr_t* recv_addr;
recv_t* recv;
byte* buf;
......@@ -1133,6 +1147,7 @@ recv_recover_page(
if (!recover_backup) {
block = buf_block_align(page);
page_zip = buf_block_get_page_zip(block);
if (just_read_in) {
/* Move the ownership of the x-latch on the page to this OS
......@@ -1220,7 +1235,8 @@ recv_recover_page(
#endif /* UNIV_DEBUG */
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len, page, &mtr);
buf + recv->len,
page, page_zip, &mtr);
mach_write_to_8(page + UNIV_PAGE_SIZE
- FIL_PAGE_END_LSN_OLD_CHKSUM,
ut_dulint_add(recv->start_lsn,
......@@ -1613,8 +1629,8 @@ recv_update_replicate(
buf_page_dbg_add_level(replica, SYNC_NO_ORDER_CHECK);
#endif /* UNIV_SYNC_DEBUG */
ptr = recv_parse_or_apply_log_rec_body(type, body, end_ptr, replica,
&mtr);
ptr = recv_parse_or_apply_log_rec_body(type, body, end_ptr,
replica, NULL, &mtr);
ut_a(ptr == end_ptr);
/* Notify the buffer manager that the page has been updated */
......@@ -1845,7 +1861,7 @@ recv_parse_log_rec(
}
new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
NULL, NULL);
NULL, NULL, NULL);
if (UNIV_UNLIKELY(new_ptr == NULL)) {
return(0);
......
......@@ -19,6 +19,6 @@ include ../include/Makefile.i
noinst_LIBRARIES = libpage.a
libpage_a_SOURCES = page0page.c page0cur.c
libpage_a_SOURCES = page0page.c page0cur.c page0zip.c
EXTRA_PROGRAMS =
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -2409,7 +2409,7 @@ row_ins_step(
goto same_trx;
}
trx_write_trx_id(node->trx_id_buf, trx->id);
trx_write_trx_id(node->trx_id_buf, NULL, trx->id);
err = lock_table(0, node->table, LOCK_IX, thr);
......
......@@ -67,9 +67,10 @@ is slower than the specialized inline functions. */
void
row_set_rec_sys_field(
/*==================*/
/* out: value of the field */
ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
rec_t* rec, /* in: record */
rec_t* rec, /* in/out: record */
page_zip_des_t* page_zip,/* in/out: compressed page with at least
10 or 11 bytes available, or NULL */
dict_index_t* index, /* in: clustered index */
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
dulint val) /* in: value to set */
......@@ -87,11 +88,11 @@ row_set_rec_sys_field(
if (type == DATA_TRX_ID) {
trx_write_trx_id(field, val);
trx_write_trx_id(field, page_zip/* 10 bytes */, val);
} else {
ut_ad(type == DATA_ROLL_PTR);
trx_write_roll_ptr(field, val);
trx_write_roll_ptr(field, page_zip/* 11 bytes */, val);
}
}
......
......@@ -2059,7 +2059,7 @@ row_sel_convert_mysql_key_to_innobase(
dfield = dtuple_get_nth_field(tuple, 0);
field = dict_index_get_nth_field(index, 0);
if (dfield_get_type(dfield)->mtype == DATA_SYS) {
if (UNIV_UNLIKELY(dfield_get_type(dfield)->mtype == DATA_SYS)) {
/* A special case: we are looking for a position in the
generated clustered index which InnoDB automatically added
to a table with no primary key: the first and the only
......@@ -2077,8 +2077,9 @@ row_sel_convert_mysql_key_to_innobase(
while (key_ptr < key_end) {
ut_a(dict_col_get_type(field->col)->mtype
== dfield_get_type(dfield)->mtype);
type = dfield_get_type(dfield)->mtype;
ut_a(dict_col_get_type(field->col)->mtype == type);
data_offset = 0;
is_null = FALSE;
......@@ -2096,8 +2097,6 @@ row_sel_convert_mysql_key_to_innobase(
}
}
type = dfield_get_type(dfield)->mtype;
/* Calculate data length and data field total length */
if (type == DATA_BLOB) {
......@@ -2143,9 +2142,9 @@ row_sel_convert_mysql_key_to_innobase(
data_field_len = data_offset + data_len;
}
if (dtype_get_mysql_type(dfield_get_type(dfield))
== DATA_MYSQL_TRUE_VARCHAR
&& dfield_get_type(dfield)->mtype != DATA_INT) {
if (UNIV_UNLIKELY(dtype_get_mysql_type(dfield_get_type(dfield))
== DATA_MYSQL_TRUE_VARCHAR)
&& UNIV_LIKELY(type != DATA_INT)) {
/* In a MySQL key value format, a true VARCHAR is
always preceded by 2 bytes of a length field.
dfield_get_type(dfield)->len returns the maximum
......@@ -2161,7 +2160,7 @@ row_sel_convert_mysql_key_to_innobase(
/* Storing may use at most data_len bytes of buf */
if (!is_null) {
if (UNIV_LIKELY(!is_null)) {
row_mysql_store_col_in_innobase_format(
dfield,
buf,
......@@ -2174,7 +2173,7 @@ row_sel_convert_mysql_key_to_innobase(
key_ptr += data_field_len;
if (key_ptr > key_end) {
if (UNIV_UNLIKELY(key_ptr > key_end)) {
/* The last field in key was not a complete key field
but a prefix of it.
......
This diff is collapsed.
......@@ -807,7 +807,7 @@ trx_undo_update_rec_get_update(
upd_field = upd_get_nth_field(update, n_fields);
buf = mem_heap_alloc(heap, DATA_TRX_ID_LEN);
trx_write_trx_id(buf, trx_id);
trx_write_trx_id(buf, NULL, trx_id);
upd_field_set_field_no(upd_field,
dict_index_get_sys_col_pos(index, DATA_TRX_ID),
......@@ -816,7 +816,7 @@ trx_undo_update_rec_get_update(
upd_field = upd_get_nth_field(update, n_fields + 1);
buf = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN);
trx_write_roll_ptr(buf, roll_ptr);
trx_write_roll_ptr(buf, NULL, roll_ptr);
upd_field_set_field_no(upd_field,
dict_index_get_sys_col_pos(index, DATA_ROLL_PTR),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment