2009-05-27 15:15:59 +05:30
|
|
|
/*****************************************************************************
|
|
|
|
|
2016-06-21 14:21:03 +02:00
|
|
|
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
2013-03-26 00:03:13 +02:00
|
|
|
Copyright (c) 2012, Facebook Inc.
|
2017-03-01 08:27:39 +02:00
|
|
|
Copyright (c) 2017, MariaDB Corporation.
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
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
|
2012-08-01 17:27:34 +03:00
|
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/**************************************************//**
|
|
|
|
@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
|
|
|
|
|
2016-08-12 11:17:45 +03:00
|
|
|
#ifdef UNIV_INNOCHECKSUM
|
|
|
|
#include "univ.i"
|
|
|
|
#include "buf0buf.h"
|
|
|
|
#include "ut0crc32.h"
|
|
|
|
#include "buf0checksum.h"
|
|
|
|
#include "mach0data.h"
|
|
|
|
#include "zlib.h"
|
|
|
|
#endif /* UNIV_INNOCHECKSUM */
|
|
|
|
|
|
|
|
#ifndef UNIV_INNOCHECKSUM
|
|
|
|
#include "mtr0types.h"
|
2009-05-27 15:15:59 +05:30
|
|
|
#include "page0types.h"
|
2016-08-12 11:17:45 +03:00
|
|
|
#endif /* !UNIV_INNOCHECKSUM */
|
|
|
|
|
2009-05-27 15:15:59 +05:30
|
|
|
#include "buf0types.h"
|
2016-08-12 11:17:45 +03:00
|
|
|
|
2015-01-19 12:39:17 +02:00
|
|
|
#ifndef UNIV_INNOCHECKSUM
|
2009-05-27 15:15:59 +05:30
|
|
|
#include "dict0types.h"
|
2012-08-01 17:27:34 +03:00
|
|
|
#include "srv0srv.h"
|
2009-05-27 15:15:59 +05:30
|
|
|
#include "trx0types.h"
|
|
|
|
#include "mem0mem.h"
|
|
|
|
|
2013-03-26 00:03:13 +02:00
|
|
|
/* Compression level to be used by zlib. Settable by user. */
|
2014-02-01 09:33:26 +01:00
|
|
|
extern uint page_zip_level;
|
2013-03-26 00:03:13 +02:00
|
|
|
|
|
|
|
/* Default compression level. */
|
|
|
|
#define DEFAULT_COMPRESSION_LEVEL 6
|
2016-08-12 11:17:45 +03:00
|
|
|
/** Start offset of the area that will be compressed */
|
|
|
|
#define PAGE_ZIP_START PAGE_NEW_SUPREMUM_END
|
|
|
|
/** Size of an compressed page directory entry */
|
|
|
|
#define PAGE_ZIP_DIR_SLOT_SIZE 2
|
|
|
|
/** Predefine the sum of DIR_SLOT, TRX_ID & ROLL_PTR */
|
|
|
|
#define PAGE_ZIP_CLUST_LEAF_SLOT_SIZE \
|
|
|
|
(PAGE_ZIP_DIR_SLOT_SIZE \
|
|
|
|
+ DATA_TRX_ID_LEN \
|
|
|
|
+ DATA_ROLL_PTR_LEN)
|
|
|
|
/** Mask of record offsets */
|
2017-03-01 08:27:39 +02:00
|
|
|
#define PAGE_ZIP_DIR_SLOT_MASK 0x3fffU
|
2016-08-12 11:17:45 +03:00
|
|
|
/** 'owned' flag */
|
2017-03-01 08:27:39 +02:00
|
|
|
#define PAGE_ZIP_DIR_SLOT_OWNED 0x4000U
|
2016-08-12 11:17:45 +03:00
|
|
|
/** 'deleted' flag */
|
2017-03-01 08:27:39 +02:00
|
|
|
#define PAGE_ZIP_DIR_SLOT_DEL 0x8000U
|
2013-03-26 00:03:13 +02:00
|
|
|
|
|
|
|
/* Whether or not to log compressed page images to avoid possible
|
|
|
|
compression algorithm changes in zlib. */
|
2014-02-01 09:33:26 +01:00
|
|
|
extern my_bool page_zip_log_pages;
|
2013-03-26 00:03:13 +02:00
|
|
|
|
2009-05-27 15:15:59 +05:30
|
|
|
/**********************************************************************//**
|
|
|
|
Determine the size of a compressed page in bytes.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return size in bytes */
|
2009-05-27 15:15:59 +05:30
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
page_zip_get_size(
|
|
|
|
/*==============*/
|
|
|
|
const page_zip_des_t* page_zip) /*!< in: compressed page */
|
2016-09-06 09:43:16 +03:00
|
|
|
MY_ATTRIBUTE((warn_unused_result));
|
2009-05-27 15:15:59 +05:30
|
|
|
/**********************************************************************//**
|
|
|
|
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 */
|
|
|
|
|
2016-08-12 11:17:45 +03:00
|
|
|
/** Determine if a record is so big that it needs to be stored externally.
|
|
|
|
@param[in] rec_size length of the record in bytes
|
|
|
|
@param[in] comp nonzero=compact format
|
|
|
|
@param[in] n_fields number of fields in the record; ignored if
|
|
|
|
tablespace is not compressed
|
|
|
|
@param[in] page_size page size
|
|
|
|
@return FALSE if the entire record can be stored locally on the page */
|
2009-05-27 15:15:59 +05:30
|
|
|
UNIV_INLINE
|
|
|
|
ibool
|
|
|
|
page_zip_rec_needs_ext(
|
2016-08-12 11:17:45 +03:00
|
|
|
ulint rec_size,
|
|
|
|
ulint comp,
|
|
|
|
ulint n_fields,
|
|
|
|
const page_size_t& page_size)
|
2016-09-06 09:43:16 +03:00
|
|
|
MY_ATTRIBUTE((warn_unused_result));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Determine the guaranteed free space on an empty page.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return minimum payload size on the page */
|
2009-05-27 15:15:59 +05:30
|
|
|
ulint
|
|
|
|
page_zip_empty_size(
|
|
|
|
/*================*/
|
|
|
|
ulint n_fields, /*!< in: number of columns in the index */
|
|
|
|
ulint zip_size) /*!< in: compressed page size in bytes */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((const));
|
2016-09-06 09:43:16 +03:00
|
|
|
|
|
|
|
/** Check whether a tuple is too big for compressed table
|
|
|
|
@param[in] index dict index object
|
|
|
|
@param[in] entry entry for the index
|
|
|
|
@return true if it's too big, otherwise false */
|
|
|
|
bool
|
|
|
|
page_zip_is_too_big(
|
|
|
|
const dict_index_t* index,
|
|
|
|
const dtuple_t* entry);
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
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. */
|
|
|
|
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. */
|
|
|
|
ibool
|
|
|
|
page_zip_compress(
|
|
|
|
/*==============*/
|
2016-08-12 11:17:45 +03:00
|
|
|
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 */
|
|
|
|
ulint level, /*!< in: commpression level */
|
|
|
|
const redo_page_compress_t* page_comp_info,
|
|
|
|
/*!< in: used for applying
|
|
|
|
TRUNCATE log
|
|
|
|
record during recovery */
|
|
|
|
mtr_t* mtr); /*!< in/out: mini-transaction,
|
|
|
|
or NULL */
|
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Write the index information for the compressed page.
|
|
|
|
@return used size of buf */
|
|
|
|
ulint
|
|
|
|
page_zip_fields_encode(
|
|
|
|
/*===================*/
|
|
|
|
ulint n, /*!< in: number of fields
|
|
|
|
to compress */
|
|
|
|
const dict_index_t* index, /*!< in: index comprising
|
|
|
|
at least n fields */
|
|
|
|
ulint trx_id_pos,
|
|
|
|
/*!< in: position of the trx_id column
|
|
|
|
in the index, or ULINT_UNDEFINED if
|
|
|
|
this is a non-leaf page */
|
|
|
|
byte* buf); /*!< out: buffer of (n + 1) * 2 bytes */
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
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.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return TRUE on success, FALSE on failure */
|
2009-05-27 15:15:59 +05:30
|
|
|
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 19:43:15 +05:30
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
#ifdef UNIV_DEBUG
|
|
|
|
/**********************************************************************//**
|
|
|
|
Validate a compressed page descriptor.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return TRUE if ok */
|
2009-05-27 15:15:59 +05:30
|
|
|
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.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return TRUE if valid, FALSE if not */
|
2009-05-27 15:15:59 +05:30
|
|
|
ibool
|
|
|
|
page_zip_validate_low(
|
|
|
|
/*==================*/
|
|
|
|
const page_zip_des_t* page_zip,/*!< in: compressed page */
|
|
|
|
const page_t* page, /*!< in: uncompressed page */
|
2012-09-17 14:21:00 +03:00
|
|
|
const dict_index_t* index, /*!< in: index of the page, if known */
|
2009-05-27 15:15:59 +05:30
|
|
|
ibool sloppy) /*!< in: FALSE=strict,
|
|
|
|
TRUE=ignore the MIN_REC_FLAG */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2009-05-27 15:15:59 +05:30
|
|
|
/**********************************************************************//**
|
|
|
|
Check that the compressed and decompressed pages match. */
|
|
|
|
ibool
|
|
|
|
page_zip_validate(
|
|
|
|
/*==============*/
|
|
|
|
const page_zip_des_t* page_zip,/*!< in: compressed page */
|
2012-09-17 14:21:00 +03:00
|
|
|
const page_t* page, /*!< in: uncompressed page */
|
|
|
|
const dict_index_t* index) /*!< in: index of the page, if known */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2009-05-27 15:15:59 +05:30
|
|
|
#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 */
|
2016-09-06 09:43:16 +03:00
|
|
|
MY_ATTRIBUTE((warn_unused_result));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Determine if enough space is available in the modification log.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return TRUE if page_zip_write_rec() will succeed */
|
2009-05-27 15:15:59 +05:30
|
|
|
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 */
|
2016-09-06 09:43:16 +03:00
|
|
|
MY_ATTRIBUTE((warn_unused_result));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Write an entire record on the compressed page. The data must already
|
|
|
|
have been written to the uncompressed page. */
|
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/***********************************************************//**
|
|
|
|
Parses a log record of writing a BLOB pointer of a record.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return end of log record or NULL */
|
2009-05-27 15:15:59 +05:30
|
|
|
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. */
|
|
|
|
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 */
|
2016-08-12 11:17:45 +03:00
|
|
|
mtr_t* mtr); /*!< in: mini-transaction handle,
|
2009-05-27 15:15:59 +05:30
|
|
|
or NULL if no logging is needed */
|
|
|
|
|
|
|
|
/***********************************************************//**
|
|
|
|
Parses a log record of writing the node pointer of a record.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return end of log record or NULL */
|
2009-05-27 15:15:59 +05:30
|
|
|
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. */
|
|
|
|
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 */
|
2016-08-12 11:17:45 +03:00
|
|
|
mtr_t* mtr); /*!< in: mini-transaction, or NULL */
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
|
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Write the "deleted" flag of a record on a compressed page. The flag must
|
|
|
|
already have been written on the uncompressed page. */
|
|
|
|
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) */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Write the "owned" flag of a record on a compressed page. The n_owned field
|
|
|
|
must already have been written on the uncompressed page. */
|
|
|
|
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) */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Insert a record to the dense page directory. */
|
|
|
|
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. */
|
|
|
|
void
|
|
|
|
page_zip_dir_delete(
|
|
|
|
/*================*/
|
2013-03-26 00:03:13 +02: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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2,3,4)));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Add a slot to the dense page directory. */
|
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/***********************************************************//**
|
|
|
|
Parses a log record of writing to the header of a page.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return end of log record or NULL */
|
2009-05-27 15:15:59 +05:30
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
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 19:43:15 +05:30
|
|
|
@return TRUE on success, FALSE on failure; page_zip will be left
|
|
|
|
intact on failure, but page will be overwritten. */
|
2009-05-27 15:15:59 +05:30
|
|
|
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 */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull));
|
2016-12-30 15:04:10 +02:00
|
|
|
|
2009-05-27 15:15:59 +05:30
|
|
|
/**********************************************************************//**
|
|
|
|
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. */
|
|
|
|
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 */
|
2016-08-12 11:17:45 +03:00
|
|
|
mtr_t* mtr); /*!< in: mini-transaction */
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Parses a log record of compressing an index page.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return end of log record or NULL */
|
2009-05-27 15:15:59 +05:30
|
|
|
byte*
|
|
|
|
page_zip_parse_compress(
|
|
|
|
/*====================*/
|
2016-08-12 11:17:45 +03:00
|
|
|
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 */
|
2009-05-27 15:15:59 +05:30
|
|
|
|
2016-08-12 11:17:45 +03:00
|
|
|
#endif /* !UNIV_INNOCHECKSUM */
|
|
|
|
|
|
|
|
/** Calculate the compressed page checksum.
|
|
|
|
@param[in] data compressed page
|
|
|
|
@param[in] size size of compressed page
|
|
|
|
@param[in] algo algorithm to use
|
|
|
|
@param[in] use_legacy_big_endian only used if algo is
|
|
|
|
SRV_CHECKSUM_ALGORITHM_CRC32 or SRV_CHECKSUM_ALGORITHM_STRICT_CRC32 - if true
|
|
|
|
then use big endian byteorder when converting byte strings to integers.
|
|
|
|
@return page checksum */
|
|
|
|
uint32_t
|
2009-05-27 15:15:59 +05:30
|
|
|
page_zip_calc_checksum(
|
2016-08-12 11:17:45 +03:00
|
|
|
const void* data,
|
|
|
|
ulint size,
|
|
|
|
srv_checksum_algorithm_t algo,
|
|
|
|
bool use_legacy_big_endian = false);
|
2009-05-27 15:15:59 +05:30
|
|
|
|
2012-08-01 17:27:34 +03:00
|
|
|
/**********************************************************************//**
|
|
|
|
Verify a compressed page's checksum.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return TRUE if the stored checksum is valid according to the value of
|
2012-08-01 17:27:34 +03:00
|
|
|
innodb_checksum_algorithm */
|
|
|
|
ibool
|
|
|
|
page_zip_verify_checksum(
|
|
|
|
/*=====================*/
|
|
|
|
const void* data, /*!< in: compressed page */
|
2016-08-12 11:17:45 +03:00
|
|
|
ulint size /*!< in: size of compressed page */
|
|
|
|
#ifdef UNIV_INNOCHECKSUM
|
|
|
|
/* these variables are used only for innochecksum tool. */
|
|
|
|
,uintmax_t page_no, /*!< in: page number of
|
|
|
|
given read_buf */
|
|
|
|
bool strict_check, /*!< in: true if strict-check
|
|
|
|
option is enable */
|
|
|
|
bool is_log_enabled, /*!< in: true if log option is
|
|
|
|
enable */
|
|
|
|
FILE* log_file /*!< in: file pointer to
|
|
|
|
log_file */
|
|
|
|
#endif /* UNIV_INNOCHECKSUM */
|
|
|
|
);
|
2015-01-19 12:39:17 +02:00
|
|
|
|
|
|
|
#ifndef UNIV_INNOCHECKSUM
|
2013-03-26 00:03:13 +02: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.
|
2016-08-12 11:17:45 +03:00
|
|
|
@return end of log record or NULL */
|
2013-03-26 00:03:13 +02:00
|
|
|
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 */
|
2014-02-01 09:33:26 +01:00
|
|
|
dict_index_t* index) /*!< in: index */
|
2016-06-21 14:21:03 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1,2)));
|
2013-03-26 00:03:13 +02:00
|
|
|
|
|
|
|
/**********************************************************************//**
|
|
|
|
Reset the counters used for filling
|
|
|
|
INFORMATION_SCHEMA.innodb_cmp_per_index. */
|
|
|
|
UNIV_INLINE
|
|
|
|
void
|
|
|
|
page_zip_reset_stat_per_index();
|
|
|
|
/*===========================*/
|
2012-08-01 17:27:34 +03:00
|
|
|
|
2009-05-27 15:15:59 +05:30
|
|
|
#ifdef UNIV_MATERIALIZE
|
|
|
|
# undef UNIV_INLINE
|
|
|
|
# define UNIV_INLINE UNIV_INLINE_ORIGINAL
|
|
|
|
#endif
|
|
|
|
|
2016-08-12 11:17:45 +03:00
|
|
|
#ifndef UNIV_NONINL
|
|
|
|
# include "page0zip.ic"
|
|
|
|
#endif
|
2015-01-19 12:39:17 +02:00
|
|
|
#endif /* !UNIV_INNOCHECKSUM */
|
2009-05-27 15:15:59 +05:30
|
|
|
|
|
|
|
#endif /* page0zip_h */
|