mariadb/storage/innobase/include/page0zip.h

539 lines
20 KiB
C
Raw Normal View History

/*****************************************************************************
2013-03-25 23:03:13 +01:00
Copyright (c) 2005, 2012, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/page0zip.h
Compressed page interface
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"
#include "buf0types.h"
#include "dict0types.h"
#include "srv0srv.h"
#include "trx0types.h"
#include "mem0mem.h"
2013-03-25 23:03:13 +01:00
/* Compression level to be used by zlib. Settable by user. */
extern uint page_zip_level;
2013-03-25 23:03:13 +01:00
/* Default compression level. */
#define DEFAULT_COMPRESSION_LEVEL 6
/* Whether or not to log compressed page images to avoid possible
compression algorithm changes in zlib. */
extern bool page_log_compressed_pages;
/**********************************************************************//**
Determine the size of a compressed page in bytes.
@return size in bytes */
UNIV_INLINE
ulint
page_zip_get_size(
/*==============*/
const page_zip_des_t* page_zip) /*!< in: compressed page */
__attribute__((nonnull, pure));
/**********************************************************************//**
Set the size of a compressed page in bytes. */
UNIV_INLINE
void
page_zip_set_size(
/*==============*/
page_zip_des_t* page_zip, /*!< in/out: compressed page */
ulint size); /*!< in: size in bytes */
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Determine if a record is so big that it needs to be stored externally.
@return FALSE if the entire record can be stored locally on the page */
UNIV_INLINE
ibool
page_zip_rec_needs_ext(
/*===================*/
ulint rec_size, /*!< in: length of the record in bytes */
ulint comp, /*!< in: nonzero=compact format */
ulint n_fields, /*!< in: number of fields in the record;
ignored if zip_size == 0 */
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
__attribute__((const));
/**********************************************************************//**
Determine the guaranteed free space on an empty page.
@return minimum payload size on the page */
UNIV_INTERN
ulint
page_zip_empty_size(
/*================*/
ulint n_fields, /*!< in: number of columns in the index */
ulint zip_size) /*!< in: compressed page size in bytes */
__attribute__((const));
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Initialize a compressed page descriptor. */
UNIV_INLINE
void
page_zip_des_init(
/*==============*/
page_zip_des_t* page_zip); /*!< in/out: compressed page
descriptor */
/**********************************************************************//**
Configure the zlib allocator to use the given memory heap. */
UNIV_INTERN
void
page_zip_set_alloc(
/*===============*/
void* stream, /*!< in/out: zlib stream */
mem_heap_t* heap); /*!< in: memory heap to use */
/**********************************************************************//**
Compress a page.
@return TRUE on success, FALSE on failure; page_zip will be left
intact on failure. */
UNIV_INTERN
ibool
page_zip_compress(
/*==============*/
page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
m_start, m_end, m_nonempty */
const page_t* page, /*!< in: uncompressed page */
dict_index_t* index, /*!< in: index of the B-tree node */
2013-03-25 23:03:13 +01:00
ulint level, /*!< in: commpression level */
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2,3)));
/**********************************************************************//**
Decompress a page. This function should tolerate errors on the compressed
page. Instead of letting assertions fail, it will return FALSE if an
inconsistency is detected.
@return TRUE on success, FALSE on failure */
UNIV_INTERN
ibool
page_zip_decompress(
/*================*/
page_zip_des_t* page_zip,/*!< in: data, ssize;
out: m_start, m_end, m_nonempty, n_blobs */
Applying InnoDB Plugin 1.0.5 snapshot ,part 12 From r5995 to r6043 Detailed revision comments: r5995 | marko | 2009-09-28 03:52:25 -0500 (Mon, 28 Sep 2009) | 17 lines branches/zip: Do not write to PAGE_INDEX_ID after page creation, not even when restoring an uncompressed page after a compression failure. btr_page_reorganize_low(): On compression failure, do not restore those page header fields that should not be affected by the reorganization. Instead, compare the fields. page_zip_decompress(): Add the parameter ibool all, for copying all page header fields. Pass the parameter all=TRUE on block read completion, redo log application, and page_zip_validate(); pass all=FALSE in all other cases. page_zip_reorganize(): Do not restore the uncompressed page on failure. It will be restored (to pre-modification state) by the caller anyway. rb://167, Issue #346 r5996 | marko | 2009-09-28 07:46:02 -0500 (Mon, 28 Sep 2009) | 4 lines branches/zip: Address Issue #350 in comments. lock_rec_queue_validate(), lock_rec_queue_validate(): Note that this debug code may violate the latching order and cause deadlocks. r5997 | marko | 2009-09-28 08:03:58 -0500 (Mon, 28 Sep 2009) | 12 lines branches/zip: Remove an assertion failure when the InnoDB data dictionary is inconsistent with the MySQL .frm file. ha_innobase::index_read(): When the index cannot be found, return an error. ha_innobase::change_active_index(): When prebuilt->index == NULL, set also prebuilt->index_usable = FALSE. This is not needed for correctness, because prebuilt->index_usable is only checked by row_search_for_mysql(), which requires prebuilt->index != NULL. This addresses Issue #349. Approved by Heikki Tuuri over IM. r6005 | vasil | 2009-09-29 03:09:52 -0500 (Tue, 29 Sep 2009) | 4 lines branches/zip: ChangeLog: wrap around 78th column, not earlier. r6006 | vasil | 2009-09-29 05:15:25 -0500 (Tue, 29 Sep 2009) | 4 lines branches/zip: Add ChangeLog entry for the release of 1.0.4. r6007 | vasil | 2009-09-29 08:19:59 -0500 (Tue, 29 Sep 2009) | 6 lines branches/zip: Fix the year, should be 2009. Pointed by: Calvin r6026 | marko | 2009-09-30 02:18:24 -0500 (Wed, 30 Sep 2009) | 1 line branches/zip: Add some debug assertions for checking FSEG_MAGIC_N. r6028 | marko | 2009-09-30 08:55:23 -0500 (Wed, 30 Sep 2009) | 3 lines branches/zip: recv_no_log_write: New debug flag for tracking down Mantis Issue #347. No modifications should be made to the database while recv_apply_hashed_log_recs() is about to complete. r6029 | calvin | 2009-09-30 15:32:02 -0500 (Wed, 30 Sep 2009) | 4 lines branches/zip: non-functional changes Fix typo. r6031 | marko | 2009-10-01 06:24:33 -0500 (Thu, 01 Oct 2009) | 49 lines branches/zip: Clean up after a crash during DROP INDEX. When InnoDB crashes while dropping an index, ensure that the index will be completely dropped during crash recovery. row_merge_drop_index(): Before dropping an index, rename the index to start with TEMP_INDEX_PREFIX_STR and commit the change, so that row_merge_drop_temp_indexes() will drop the index after crash recovery if the server crashes while dropping the index. fseg_inode_try_get(): New function, forked from fseg_inode_get(). Return NULL if the file segment index node is free. fseg_inode_get(): Assert that the file segment index node is not free. fseg_free_step(): If the file segment index node is already free, print a diagnostic message and return TRUE. fsp_free_seg_inode(): Write a nonzero number to FSEG_MAGIC_N, so that allocated-and-freed file segment index nodes can be better distinguished from uninitialized ones. This is rb://174, addressing Issue #348. Tested by restarting mysqld upon the completion of the added log_write_up_to() invocation below, during DROP INDEX. The index was dropped after crash recovery, and re-issuing the DROP INDEX did not crash the server. Index: btr/btr0btr.c =================================================================== --- btr/btr0btr.c (revision 6026) +++ btr/btr0btr.c (working copy) @@ -42,6 +42,7 @@ Created 6/2/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "trx0trx.h" +#include "log0log.h" /* Latching strategy of the InnoDB B-tree -------------------------------------- @@ -873,6 +874,8 @@ leaf_loop: goto leaf_loop; } + + log_write_up_to(mtr.end_lsn, LOG_WAIT_ALL_GROUPS, TRUE); top_loop: mtr_start(&mtr); r6033 | calvin | 2009-10-01 15:19:46 -0500 (Thu, 01 Oct 2009) | 4 lines branches/zip: fix a typo in error message Reported as bug#47763. r6043 | inaam | 2009-10-05 09:45:35 -0500 (Mon, 05 Oct 2009) | 12 lines branches/zip rb://176 Do not invalidate buffer pool while an LRU batch is active. Added code to buf_pool_invalidate() to wait for the running batches to finish. This patch also resets the state of buf_pool struct at invalidation. This addresses the concern where buf_pool->freed_page_clock becomes non-zero because we read in a system tablespace page for file format info at startup. Approved by: Marko
2009-10-09 16:13:15 +02:00
page_t* page, /*!< out: uncompressed page, may be trashed */
ibool all) /*!< in: TRUE=decompress the whole page;
FALSE=verify but do not copy some
page header fields that should not change
after page creation */
__attribute__((nonnull(1,2)));
#ifdef UNIV_DEBUG
/**********************************************************************//**
Validate a compressed page descriptor.
@return TRUE if ok */
UNIV_INLINE
ibool
page_zip_simple_validate(
/*=====================*/
const page_zip_des_t* page_zip); /*!< in: compressed page
descriptor */
#endif /* UNIV_DEBUG */
#ifdef UNIV_ZIP_DEBUG
/**********************************************************************//**
Check that the compressed and decompressed pages match.
@return TRUE if valid, FALSE if not */
UNIV_INTERN
ibool
page_zip_validate_low(
/*==================*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
const page_t* page, /*!< in: uncompressed page */
const dict_index_t* index, /*!< in: index of the page, if known */
ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Check that the compressed and decompressed pages match. */
UNIV_INTERN
ibool
page_zip_validate(
/*==============*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
const page_t* page, /*!< in: uncompressed page */
const dict_index_t* index) /*!< in: index of the page, if known */
__attribute__((nonnull(1,2)));
#endif /* UNIV_ZIP_DEBUG */
/**********************************************************************//**
Determine how big record can be inserted without recompressing the page.
@return a positive number indicating the maximum size of a record
whose insertion is guaranteed to succeed, or zero or negative */
UNIV_INLINE
lint
page_zip_max_ins_size(
/*==================*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
ibool is_clust)/*!< in: TRUE if clustered index */
__attribute__((nonnull, pure));
/**********************************************************************//**
Determine if enough space is available in the modification log.
@return TRUE if page_zip_write_rec() will succeed */
UNIV_INLINE
ibool
page_zip_available(
/*===============*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
ibool is_clust,/*!< in: TRUE if clustered index */
ulint length, /*!< in: combined size of the record */
ulint create) /*!< in: nonzero=add the record to
the heap */
__attribute__((nonnull, pure));
/**********************************************************************//**
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 */
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Write an entire record on the compressed page. The data must already
have been written to the uncompressed page. */
UNIV_INTERN
void
page_zip_write_rec(
/*===============*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in: record being written */
dict_index_t* index, /*!< in: the index the record belongs to */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint create) /*!< in: nonzero=insert, zero=update */
__attribute__((nonnull));
/***********************************************************//**
Parses a log record of writing a BLOB pointer of a record.
@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_blob_ptr(
/*==========================*/
byte* ptr, /*!< in: redo log buffer */
byte* end_ptr,/*!< in: redo log buffer end */
page_t* page, /*!< in/out: uncompressed page */
page_zip_des_t* page_zip);/*!< in/out: compressed page */
/**********************************************************************//**
Write a BLOB pointer of a record on the leaf page of a clustered index.
The information must already have been updated on the uncompressed page. */
UNIV_INTERN
void
page_zip_write_blob_ptr(
/*====================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in/out: record whose data is being
written */
dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint n, /*!< in: column index */
mtr_t* mtr) /*!< in: mini-transaction handle,
or NULL if no logging is needed */
__attribute__((nonnull(1,2,3,4)));
/***********************************************************//**
Parses a log record of writing the node pointer of a record.
@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_node_ptr(
/*==========================*/
byte* ptr, /*!< in: redo log buffer */
byte* end_ptr,/*!< in: redo log buffer end */
page_t* page, /*!< in/out: uncompressed page */
page_zip_des_t* page_zip);/*!< in/out: compressed page */
/**********************************************************************//**
Write the node pointer of a record on a non-leaf compressed page. */
UNIV_INTERN
void
page_zip_write_node_ptr(
/*====================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
byte* rec, /*!< in/out: record */
ulint size, /*!< in: data size of rec */
ulint ptr, /*!< in: node pointer */
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
UNIV_INTERN
void
page_zip_write_trx_id_and_roll_ptr(
/*===============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
byte* rec, /*!< in/out: record */
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
trx_id_t trx_id, /*!< in: transaction identifier */
roll_ptr_t roll_ptr)/*!< in: roll_ptr */
__attribute__((nonnull));
/**********************************************************************//**
Write the "deleted" flag of a record on a compressed page. The flag must
already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_deleted(
/*=====================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in: record on the uncompressed page */
ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */
__attribute__((nonnull));
/**********************************************************************//**
Write the "owned" flag of a record on a compressed page. The n_owned field
must already have been written on the uncompressed page. */
UNIV_INTERN
void
page_zip_rec_set_owned(
/*===================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* rec, /*!< in: record on the uncompressed page */
ulint flag) /*!< in: the owned flag (nonzero=TRUE) */
__attribute__((nonnull));
/**********************************************************************//**
Insert a record to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_insert(
/*================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page */
const byte* prev_rec,/*!< in: record after which to insert */
const byte* free_rec,/*!< in: record from which rec was
allocated, or NULL */
byte* rec); /*!< in: record to insert */
/**********************************************************************//**
Shift the dense page directory and the array of BLOB pointers
when a record is deleted. */
UNIV_INTERN
void
page_zip_dir_delete(
/*================*/
2013-03-25 23:03:13 +01:00
page_zip_des_t* page_zip, /*!< in/out: compressed page */
byte* rec, /*!< in: deleted record */
const dict_index_t* index, /*!< in: index of rec */
const ulint* offsets, /*!< in: rec_get_offsets(rec) */
const byte* free) /*!< in: previous start of
the free list */
__attribute__((nonnull(1,2,3,4)));
/**********************************************************************//**
Add a slot to the dense page directory. */
UNIV_INTERN
void
page_zip_dir_add_slot(
/*==================*/
page_zip_des_t* page_zip, /*!< in/out: compressed page */
ulint is_clustered) /*!< in: nonzero for clustered index,
zero for others */
__attribute__((nonnull));
/***********************************************************//**
Parses a log record of writing to the header of a page.
@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_write_header(
/*========================*/
byte* ptr, /*!< in: redo log buffer */
byte* end_ptr,/*!< in: redo log buffer end */
page_t* page, /*!< in/out: uncompressed page */
page_zip_des_t* page_zip);/*!< in/out: compressed page */
/**********************************************************************//**
Write data to the uncompressed header portion of a page. The data must
already have been written to the uncompressed page.
However, the data portion of the uncompressed page may differ from
the compressed page when a record is being inserted in
page_cur_insert_rec_low(). */
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 */
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Reorganize and compress a page. This is a low-level operation for
compressed pages, to be used when page_zip_compress() fails.
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.
The function btr_page_reorganize() should be preferred whenever possible.
IMPORTANT: if page_zip_reorganize() is invoked on a leaf page of a
non-clustered index, the caller must update the insert buffer free
bits in the same mini-transaction in such a way that the modification
will be redo-logged.
Applying InnoDB Plugin 1.0.5 snapshot ,part 12 From r5995 to r6043 Detailed revision comments: r5995 | marko | 2009-09-28 03:52:25 -0500 (Mon, 28 Sep 2009) | 17 lines branches/zip: Do not write to PAGE_INDEX_ID after page creation, not even when restoring an uncompressed page after a compression failure. btr_page_reorganize_low(): On compression failure, do not restore those page header fields that should not be affected by the reorganization. Instead, compare the fields. page_zip_decompress(): Add the parameter ibool all, for copying all page header fields. Pass the parameter all=TRUE on block read completion, redo log application, and page_zip_validate(); pass all=FALSE in all other cases. page_zip_reorganize(): Do not restore the uncompressed page on failure. It will be restored (to pre-modification state) by the caller anyway. rb://167, Issue #346 r5996 | marko | 2009-09-28 07:46:02 -0500 (Mon, 28 Sep 2009) | 4 lines branches/zip: Address Issue #350 in comments. lock_rec_queue_validate(), lock_rec_queue_validate(): Note that this debug code may violate the latching order and cause deadlocks. r5997 | marko | 2009-09-28 08:03:58 -0500 (Mon, 28 Sep 2009) | 12 lines branches/zip: Remove an assertion failure when the InnoDB data dictionary is inconsistent with the MySQL .frm file. ha_innobase::index_read(): When the index cannot be found, return an error. ha_innobase::change_active_index(): When prebuilt->index == NULL, set also prebuilt->index_usable = FALSE. This is not needed for correctness, because prebuilt->index_usable is only checked by row_search_for_mysql(), which requires prebuilt->index != NULL. This addresses Issue #349. Approved by Heikki Tuuri over IM. r6005 | vasil | 2009-09-29 03:09:52 -0500 (Tue, 29 Sep 2009) | 4 lines branches/zip: ChangeLog: wrap around 78th column, not earlier. r6006 | vasil | 2009-09-29 05:15:25 -0500 (Tue, 29 Sep 2009) | 4 lines branches/zip: Add ChangeLog entry for the release of 1.0.4. r6007 | vasil | 2009-09-29 08:19:59 -0500 (Tue, 29 Sep 2009) | 6 lines branches/zip: Fix the year, should be 2009. Pointed by: Calvin r6026 | marko | 2009-09-30 02:18:24 -0500 (Wed, 30 Sep 2009) | 1 line branches/zip: Add some debug assertions for checking FSEG_MAGIC_N. r6028 | marko | 2009-09-30 08:55:23 -0500 (Wed, 30 Sep 2009) | 3 lines branches/zip: recv_no_log_write: New debug flag for tracking down Mantis Issue #347. No modifications should be made to the database while recv_apply_hashed_log_recs() is about to complete. r6029 | calvin | 2009-09-30 15:32:02 -0500 (Wed, 30 Sep 2009) | 4 lines branches/zip: non-functional changes Fix typo. r6031 | marko | 2009-10-01 06:24:33 -0500 (Thu, 01 Oct 2009) | 49 lines branches/zip: Clean up after a crash during DROP INDEX. When InnoDB crashes while dropping an index, ensure that the index will be completely dropped during crash recovery. row_merge_drop_index(): Before dropping an index, rename the index to start with TEMP_INDEX_PREFIX_STR and commit the change, so that row_merge_drop_temp_indexes() will drop the index after crash recovery if the server crashes while dropping the index. fseg_inode_try_get(): New function, forked from fseg_inode_get(). Return NULL if the file segment index node is free. fseg_inode_get(): Assert that the file segment index node is not free. fseg_free_step(): If the file segment index node is already free, print a diagnostic message and return TRUE. fsp_free_seg_inode(): Write a nonzero number to FSEG_MAGIC_N, so that allocated-and-freed file segment index nodes can be better distinguished from uninitialized ones. This is rb://174, addressing Issue #348. Tested by restarting mysqld upon the completion of the added log_write_up_to() invocation below, during DROP INDEX. The index was dropped after crash recovery, and re-issuing the DROP INDEX did not crash the server. Index: btr/btr0btr.c =================================================================== --- btr/btr0btr.c (revision 6026) +++ btr/btr0btr.c (working copy) @@ -42,6 +42,7 @@ Created 6/2/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "trx0trx.h" +#include "log0log.h" /* Latching strategy of the InnoDB B-tree -------------------------------------- @@ -873,6 +874,8 @@ leaf_loop: goto leaf_loop; } + + log_write_up_to(mtr.end_lsn, LOG_WAIT_ALL_GROUPS, TRUE); top_loop: mtr_start(&mtr); r6033 | calvin | 2009-10-01 15:19:46 -0500 (Thu, 01 Oct 2009) | 4 lines branches/zip: fix a typo in error message Reported as bug#47763. r6043 | inaam | 2009-10-05 09:45:35 -0500 (Mon, 05 Oct 2009) | 12 lines branches/zip rb://176 Do not invalidate buffer pool while an LRU batch is active. Added code to buf_pool_invalidate() to wait for the running batches to finish. This patch also resets the state of buf_pool struct at invalidation. This addresses the concern where buf_pool->freed_page_clock becomes non-zero because we read in a system tablespace page for file format info at startup. Approved by: Marko
2009-10-09 16:13:15 +02:00
@return TRUE on success, FALSE on failure; page_zip will be left
intact on failure, but page will be overwritten. */
UNIV_INTERN
ibool
page_zip_reorganize(
/*================*/
buf_block_t* block, /*!< in/out: page with compressed page;
on the compressed page, in: size;
out: data, n_blobs,
m_start, m_end, m_nonempty */
dict_index_t* index, /*!< in: index of the B-tree node */
mtr_t* mtr) /*!< in: mini-transaction */
__attribute__((nonnull));
#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Copy the records of a page byte for byte. Do not copy the page header
or trailer, except those B-tree header fields that are directly
related to the storage of records. Also copy PAGE_MAX_TRX_ID.
NOTE: The caller must update the lock table and the adaptive hash index. */
UNIV_INTERN
void
page_zip_copy_recs(
/*===============*/
page_zip_des_t* page_zip, /*!< out: copy of src_zip
(n_blobs, m_start, m_end,
m_nonempty, data[0..size-1]) */
page_t* page, /*!< out: copy of src */
const page_zip_des_t* src_zip, /*!< in: compressed page */
const page_t* src, /*!< in: page */
dict_index_t* index, /*!< in: index of the B-tree */
mtr_t* mtr) /*!< in: mini-transaction */
Implement UNIV_BLOB_DEBUG. An early version of this caught Bug #55284. This option is known to be broken when tablespaces contain off-page columns after crash recovery. It has only been tested when creating the data files from the scratch. btr_blob_dbg_t: A map from page_no:heap_no:field_no to first_blob_page_no. This map is instantiated for every clustered index in index->blobs. It is protected by index->blobs_mutex. btr_blob_dbg_msg_issue(): Issue a diagnostic message. Invoked when btr_blob_dbg_msg is set. btr_blob_dbg_rbt_insert(): Insert a btr_blob_dbg_t into index->blobs. btr_blob_dbg_rbt_delete(): Remove a btr_blob_dbg_t from index->blobs. btr_blob_dbg_cmp(): Comparator for btr_blob_dbg_t. btr_blob_dbg_add_blob(): Add a BLOB reference to the map. btr_blob_dbg_add_rec(): Add all BLOB references from a record to the map. btr_blob_dbg_print(): Display the map of BLOB references in an index. btr_blob_dbg_remove_rec(): Remove all BLOB references of a record from the map. btr_blob_dbg_is_empty(): Check that no BLOB references exist to or from a page. Disowned references from delete-marked records are tolerated. btr_blob_dbg_op(): Perform an operation on all BLOB references on a B-tree page. btr_blob_dbg_add(): Add all BLOB references from a B-tree page to the map. btr_blob_dbg_remove(): Remove all BLOB references from a B-tree page from the map. btr_blob_dbg_restore(): Restore the BLOB references after a failed page reorganize. btr_blob_dbg_set_deleted_flag(): Modify the 'deleted' flag in the BLOB references of a record. btr_blob_dbg_owner(): Own or disown a BLOB reference. btr_page_create(), btr_page_free_low(): Assert that no BLOB references exist. btr_create(): Create index->blobs for clustered indexes. btr_page_reorganize_low(): Invoke btr_blob_dbg_remove() before copying the records. Invoke btr_blob_dbg_restore() if the operation fails. btr_page_empty(), btr_lift_page_up(), btr_compress(), btr_discard_page(): Invoke btr_blob_dbg_remove(). btr_cur_del_mark_set_clust_rec(): Invoke btr_blob_dbg_set_deleted_flag(). Other cases of modifying the delete mark are either in the secondary index or during crash recovery, which we do not promise to support. btr_cur_set_ownership_of_extern_field(): Invoke btr_blob_dbg_owner(). btr_store_big_rec_extern_fields(): Invoke btr_blob_dbg_add_blob(). btr_free_externally_stored_field(): Invoke btr_blob_dbg_assert_empty() on the first BLOB page. page_cur_insert_rec_low(), page_cur_insert_rec_zip(), page_copy_rec_list_end_to_created_page(): Invoke btr_blob_dbg_add_rec(). page_cur_insert_rec_zip_reorg(), page_copy_rec_list_end(), page_copy_rec_list_start(): After failure, invoke btr_blob_dbg_remove() and btr_blob_dbg_add(). page_cur_delete_rec(): Invoke btr_blob_dbg_remove_rec(). page_delete_rec_list_end(): Invoke btr_blob_dbg_op(btr_blob_dbg_remove_rec). page_zip_reorganize(): Invoke btr_blob_dbg_remove() before copying the records. page_zip_copy_recs(): Invoke btr_blob_dbg_add(). row_upd_rec_in_place(): Invoke btr_blob_dbg_rbt_delete() and btr_blob_dbg_rbt_insert(). innobase_start_or_create_for_mysql(): Warn when UNIV_BLOB_DEBUG is enabled. rb://550 approved by Jimmy Yang
2011-02-08 11:56:23 +01:00
__attribute__((nonnull));
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Parses a log record of compressing an index page.
@return end of log record or NULL */
UNIV_INTERN
byte*
page_zip_parse_compress(
/*====================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr,/*!< in: buffer end */
page_t* page, /*!< out: uncompressed page */
page_zip_des_t* page_zip)/*!< out: compressed page */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Calculate the compressed page checksum.
@return page checksum */
UNIV_INTERN
ulint
page_zip_calc_checksum(
/*===================*/
const void* data, /*!< in: compressed page */
ulint size, /*!< in: size of compressed page */
srv_checksum_algorithm_t algo) /*!< in: algorithm to use */
__attribute__((nonnull));
/**********************************************************************//**
Verify a compressed page's checksum.
@return TRUE if the stored checksum is valid according to the value of
innodb_checksum_algorithm */
UNIV_INTERN
ibool
page_zip_verify_checksum(
/*=====================*/
const void* data, /*!< in: compressed page */
ulint size); /*!< in: size of compressed page */
2013-03-25 23:03:13 +01:00
/**********************************************************************//**
Write a log record of compressing an index page without the data on the page. */
UNIV_INLINE
void
page_zip_compress_write_log_no_data(
/*================================*/
ulint level, /*!< in: compression level */
const page_t* page, /*!< in: page that is compressed */
dict_index_t* index, /*!< in: index */
mtr_t* mtr); /*!< in: mtr */
/**********************************************************************//**
Parses a log record of compressing an index page without the data.
@return end of log record or NULL */
UNIV_INLINE
byte*
page_zip_parse_compress_no_data(
/*============================*/
byte* ptr, /*!< in: buffer */
byte* end_ptr, /*!< in: buffer end */
page_t* page, /*!< in: uncompressed page */
page_zip_des_t* page_zip, /*!< out: compressed page */
dict_index_t* index) /*!< in: index */
__attribute__((nonnull(1,2)));
/**********************************************************************//**
Reset the counters used for filling
INFORMATION_SCHEMA.innodb_cmp_per_index. */
UNIV_INLINE
void
page_zip_reset_stat_per_index();
/*===========================*/
#ifndef UNIV_HOTBACKUP
2009-07-30 14:42:56 +02:00
/** Check if a pointer to an uncompressed page matches a compressed page.
2013-03-25 23:03:13 +01:00
When we IMPORT a tablespace the blocks and accompanying frames are allocted
from outside the buffer pool.
2009-07-30 14:42:56 +02:00
@param ptr pointer to an uncompressed page frame
@param page_zip compressed page descriptor
@return TRUE if ptr and page_zip refer to the same block */
2013-03-25 23:03:13 +01:00
# define PAGE_ZIP_MATCH(ptr, page_zip) \
(((page_zip)->m_external \
&& (page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)) \
|| buf_frame_get_page_zip(ptr) == (page_zip))
#else /* !UNIV_HOTBACKUP */
2009-07-30 14:42:56 +02:00
/** Check if a pointer to an uncompressed page matches a compressed page.
@param ptr pointer to an uncompressed page frame
@param page_zip compressed page descriptor
@return TRUE if ptr and page_zip refer to the same block */
# define PAGE_ZIP_MATCH(ptr, page_zip) \
(page_align(ptr) + UNIV_PAGE_SIZE == (page_zip)->data)
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
#endif
#ifndef UNIV_NONINL
# include "page0zip.ic"
#endif
#endif /* page0zip_h */