MySQL 8.0.39
Source Code Documentation
|
Compressed page interface. More...
#include "page0zip.h"
#include "page0size.h"
#include <zlib.h>
#include "btr0cur.h"
#include "dict0dict.h"
#include "log0recv.h"
#include "mtr0log.h"
#include "page0page.h"
#include "page0types.h"
#include "btr0sea.h"
#include "buf0buf.h"
#include "buf0lru.h"
#include "dict0boot.h"
#include "lock0lock.h"
#include "srv0mon.h"
#include "srv0srv.h"
#include "ut0crc32.h"
#include <algorithm>
#include <map>
Macros | |
#define | ASSERT_ZERO(b, s) |
Assert that a block of memory is filled with zero bytes. More... | |
#define | ASSERT_ZERO_BLOB(b) ut_ad(!memcmp(b, field_ref_zero, sizeof field_ref_zero)) |
Assert that a BLOB pointer is filled with zero bytes. More... | |
#define | PAGE_ZIP_COMPRESS_DBG |
Symbol for enabling compression and decompression diagnostics. More... | |
#define | deflate(strm, flush) page_zip_compress_deflate(logfile, strm, flush) |
Debug wrapper for the zlib compression routine deflate(). More... | |
#define | FILE_LOGFILE FILE *logfile, |
Declaration of the logfile parameter. More... | |
#define | LOGFILE logfile, |
The logfile parameter. More... | |
Functions | |
ulint | page_zip_empty_size (ulint n_fields, ulint zip_size) |
Determine the guaranteed free space on an empty page. More... | |
bool | page_zip_is_too_big (const dict_index_t *index, const dtuple_t *entry) |
Check whether a tuple is too big for compressed table. More... | |
static byte * | page_zip_dir_find (page_zip_des_t *page_zip, ulint offset) |
Find the slot of the given non-free record in the dense page directory. More... | |
static void | page_zip_compress_write_log (const page_zip_des_t *page_zip, const page_t *page, dict_index_t *index, mtr_t *mtr) |
Write a log record of compressing an index page. More... | |
static ulint | page_zip_get_n_prev_extern (const page_zip_des_t *page_zip, const rec_t *rec, const dict_index_t *index) |
Determine how many externally stored columns are contained in existing records with smaller heap_no than rec. More... | |
static byte * | page_zip_fixed_field_encode (byte *buf, ulint val) |
Encode the length of a fixed-length column. More... | |
ulint | page_zip_fields_encode (ulint n, const dict_index_t *index, ulint trx_id_pos, byte *buf) |
Write the index information for the compressed page. More... | |
static void | page_zip_dir_encode (const page_t *page, byte *buf, const rec_t **recs) |
Populate the dense page directory from the sparse directory. More... | |
static int | page_zip_compress_deflate (FILE *logfile, z_streamp strm, int flush) |
Wrapper for deflate(). More... | |
static int | page_zip_compress_node_ptrs (FILE_LOGFILE z_stream *c_stream, const rec_t **recs, ulint n_dense, dict_index_t *index, byte *storage, mem_heap_t *heap) |
Compress the records of a node pointer page. More... | |
static int | page_zip_compress_sec (FILE_LOGFILE z_stream *c_stream, const rec_t **recs, ulint n_dense) |
Compress the records of a leaf node of a secondary index. More... | |
static int | page_zip_compress_clust_ext (FILE_LOGFILE z_stream *c_stream, const dict_index_t *index, const rec_t *rec, const ulint *offsets, ulint trx_id_col, byte *deleted, byte *storage, byte **externs, ulint *n_blobs) |
Compress a record of a leaf node of a clustered index that contains externally stored columns. More... | |
static int | page_zip_compress_clust (FILE_LOGFILE z_stream *c_stream, const rec_t **recs, ulint n_dense, dict_index_t *index, ulint *n_blobs, ulint trx_id_col, byte *deleted, byte *storage, mem_heap_t *heap) |
Compress the records of a leaf node of a clustered index. More... | |
bool | page_zip_compress (page_zip_des_t *page_zip, const page_t *page, dict_index_t *index, ulint level, mtr_t *mtr) |
Compress a page. More... | |
bool | page_zip_decompress (page_zip_des_t *page_zip, page_t *page, bool all) |
Decompress a page. More... | |
static void | page_zip_header_cmp (const page_zip_des_t *page_zip, const byte *page) |
Assert that the compressed and decompressed page headers match. More... | |
static byte * | page_zip_write_rec_ext (page_zip_des_t *page_zip, const page_t *page, const byte *rec, const dict_index_t *index, const ulint *offsets, ulint create, ulint trx_id_col, ulint heap_no, byte *storage, byte *data) |
Write a record on the compressed page that contains externally stored columns. More... | |
void | page_zip_write_rec (page_zip_des_t *page_zip, const byte *rec, const dict_index_t *index, const ulint *offsets, ulint create) |
Write an entire record on the compressed page. More... | |
byte * | page_zip_parse_write_blob_ptr (byte *ptr, byte *end_ptr, page_t *page, page_zip_des_t *page_zip) |
Parses a log record of writing a BLOB pointer of a record. More... | |
void | page_zip_write_blob_ptr (page_zip_des_t *page_zip, const byte *rec, const dict_index_t *index, const ulint *offsets, ulint n, mtr_t *mtr) |
Write a BLOB pointer of a record on the leaf page of a clustered index. More... | |
byte * | page_zip_parse_write_node_ptr (byte *ptr, byte *end_ptr, page_t *page, page_zip_des_t *page_zip) |
Parses a log record of writing the node pointer of a record. More... | |
void | page_zip_write_node_ptr (page_zip_des_t *page_zip, byte *rec, ulint size, ulint ptr, mtr_t *mtr) |
Write the node pointer of a record on a non-leaf compressed page. More... | |
void | page_zip_write_trx_id_and_roll_ptr (page_zip_des_t *page_zip, byte *rec, const ulint *offsets, ulint trx_id_col, trx_id_t trx_id, roll_ptr_t roll_ptr) |
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. More... | |
static void | page_zip_clear_rec (page_zip_des_t *page_zip, byte *rec, const dict_index_t *index, const ulint *offsets) |
Clear an area on the uncompressed and compressed page. More... | |
void | page_zip_rec_set_deleted (page_zip_des_t *page_zip, const byte *rec, bool flag) |
Write the "deleted" flag of a record on a compressed page. More... | |
void | page_zip_rec_set_owned (page_zip_des_t *page_zip, const byte *rec, ulint flag) |
Write the "owned" flag of a record on a compressed page. More... | |
void | page_zip_dir_insert (page_zip_des_t *page_zip, const byte *prev_rec, const byte *free_rec, byte *rec) |
Insert a record to the dense page directory. More... | |
void | page_zip_dir_delete (page_zip_des_t *page_zip, byte *rec, const dict_index_t *index, const ulint *offsets, const byte *free) |
Shift the dense page directory and the array of BLOB pointers when a record is deleted. More... | |
void | page_zip_dir_add_slot (page_zip_des_t *page_zip, bool is_clustered) |
Add a slot to the dense page directory. More... | |
byte * | page_zip_parse_write_header (byte *ptr, byte *end_ptr, page_t *page, page_zip_des_t *page_zip) |
Parses a log record of writing to the header of a page. More... | |
void | page_zip_write_header_log (const byte *data, ulint length, mtr_t *mtr) |
Write a log record of writing to the uncompressed header portion of a page. More... | |
bool | page_zip_reorganize (buf_block_t *block, dict_index_t *index, mtr_t *mtr) |
Reorganize and compress a page. More... | |
void | page_zip_copy_recs (page_zip_des_t *page_zip, page_t *page, const page_zip_des_t *src_zip, const page_t *src, dict_index_t *index, mtr_t *mtr) |
Copy the records of a page byte for byte. More... | |
byte * | page_zip_parse_compress (byte *ptr, byte *end_ptr, page_t *page, page_zip_des_t *page_zip) |
Parses a log record of compressing an index page. More... | |
Variables | |
const byte | field_ref_zero [FIELD_REF_SIZE] |
A BLOB field reference full of zero, for use in assertions and tests. More... | |
page_zip_stat_t | page_zip_stat [PAGE_ZIP_SSIZE_MAX] |
Statistics on compression, indexed by page_zip_des_t::ssize - 1. More... | |
page_zip_stat_per_index_t | page_zip_stat_per_index |
Statistics on compression, indexed by index->id. More... | |
uint | page_zip_level = DEFAULT_COMPRESSION_LEVEL |
Default Zip compression level. More... | |
bool | page_zip_log_pages = true |
static bool | page_zip_compress_dbg |
Set this variable in a debugger to enable excessive logging in page_zip_compress(). More... | |
static unsigned | page_zip_compress_log |
Set this variable in a debugger to enable binary logging of the data passed to deflate(). More... | |
Compressed page interface.
Created June 2005 by Marko Makela
#define ASSERT_ZERO | ( | b, | |
s | |||
) |
Assert that a block of memory is filled with zero bytes.
Compare at most sizeof(field_ref_zero) bytes.
b | in: memory block |
s | in: size of the memory block, in bytes |
#define ASSERT_ZERO_BLOB | ( | b | ) | ut_ad(!memcmp(b, field_ref_zero, sizeof field_ref_zero)) |
Assert that a BLOB pointer is filled with zero bytes.
b | in: BLOB pointer |
#define deflate | ( | strm, | |
flush | |||
) | page_zip_compress_deflate(logfile, strm, flush) |
Debug wrapper for the zlib compression routine deflate().
Log the operation if page_zip_compress_dbg is set.
strm | in/out: compressed stream |
flush | in: flushing method |
#define FILE_LOGFILE FILE *logfile, |
Declaration of the logfile parameter.
#define LOGFILE logfile, |
The logfile parameter.
#define PAGE_ZIP_COMPRESS_DBG |
Symbol for enabling compression and decompression diagnostics.
|
static |
Clear an area on the uncompressed and compressed page.
Do not clear the data payload, as that would grow the modification log.
page_zip | in/out: compressed page |
rec | in: record to clear |
index | in: index of rec |
offsets | in: rec_get_offsets(rec, index) |
bool page_zip_compress | ( | page_zip_des_t * | page_zip, |
const page_t * | page, | ||
dict_index_t * | index, | ||
ulint | level, | ||
mtr_t * | mtr | ||
) |
Compress a page.
< index field information
< compressed payload of the page
< dense page directory, sorted by address
page_zip | in: size; out: data, n_blobs, m_start, m_end, m_nonempty |
page | in: uncompressed page |
index | in: index tree |
level | in: compression level |
mtr | in/out: mini-transaction, or NULL |
|
static |
Compress the records of a leaf node of a clustered index.
c_stream | in/out: compressed page stream |
recs | in: dense page directory sorted by address |
n_dense | in: size of recs[] |
index | in: the index of the page |
n_blobs | in: 0; out: number of externally stored columns |
trx_id_col | index of the trx_id column |
deleted | in: dense directory entry pointing to the head of the free list |
storage | in: end of dense page directory |
heap | in: temporary memory heap |
|
static |
Compress a record of a leaf node of a clustered index that contains externally stored columns.
[in,out] | c_stream | compressed page stream |
[in] | index | index |
[in] | rec | record |
[in] | offsets | rec_get_offsets(rec) |
[in] | trx_id_col | position of of DB_TRX_ID |
[in] | deleted | dense directory entry pointing to the head of the free list |
[in] | storage | pointer to the next available BLOB pointer |
[in,out] | externs | pointer to the next available BLOB pointer |
[in,out] | n_blobs | number of externally stored columns |
|
static |
Wrapper for deflate().
Log the operation if page_zip_compress_dbg is set.
logfile | in: log file, or NULL |
strm | in/out: compressed stream for deflate() |
flush | in: deflate() flushing method |
|
static |
Compress the records of a node pointer page.
c_stream | in/out: compressed page stream |
recs | in: dense page directory sorted by address |
n_dense | in: size of recs[] |
index | in: the index of the page |
storage | in: end of dense page directory |
heap | in: temporary memory heap |
|
static |
Compress the records of a leaf node of a secondary index.
c_stream | in/out: compressed page stream |
recs | in: dense page directory sorted by address |
n_dense | in: size of recs[] |
|
static |
Write a log record of compressing an index page.
page_zip | in: compressed page |
page | in: uncompressed page |
index | in: index of the B-tree node |
mtr | in: mini-transaction |
void page_zip_copy_recs | ( | page_zip_des_t * | page_zip, |
page_t * | page, | ||
const page_zip_des_t * | src_zip, | ||
const page_t * | src, | ||
dict_index_t * | index, | ||
mtr_t * | mtr | ||
) |
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.
page_zip | out: copy of src_zip (n_blobs, m_start, m_end, m_nonempty, data[0..size-1]) |
page | out: copy of src |
src_zip | in: compressed page |
src | in: page |
index | in: index of the B-tree |
mtr | in: mini-transaction |
bool page_zip_decompress | ( | page_zip_des_t * | page_zip, |
page_t * | page, | ||
bool | all | ||
) |
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.
page_zip | in: data, ssize; out: m_start, m_end, m_nonempty, n_blobs |
page | out: uncompressed page, may be trashed |
all | in: true=decompress the whole page; false=verify but do not copy some page header fields that should not change after page creation |
void page_zip_dir_add_slot | ( | page_zip_des_t * | page_zip, |
bool | is_clustered | ||
) |
Add a slot to the dense page directory.
[in,out] | page_zip | Compressed page |
[in] | is_clustered | Nonzero for clustered index, zero for others |
void page_zip_dir_delete | ( | page_zip_des_t * | page_zip, |
byte * | rec, | ||
const dict_index_t * | index, | ||
const ulint * | offsets, | ||
const byte * | free | ||
) |
Shift the dense page directory and the array of BLOB pointers when a record is deleted.
[in,out] | page_zip | compressed page |
[in] | rec | deleted record |
[in] | index | index of rec |
[in] | offsets | rec_get_offsets(rec) |
[in] | free | previous start of the free list |
Populate the dense page directory from the sparse directory.
page | in: compact page |
buf | in: pointer to dense page directory[-1]; out: dense directory on compressed page |
recs | in: pointer to an array of 0, or NULL; out: dense page directory sorted by ascending address (and heap_no) |
|
inlinestatic |
Find the slot of the given non-free record in the dense page directory.
page_zip | in: compressed page |
offset | in: offset of user record |
void page_zip_dir_insert | ( | page_zip_des_t * | page_zip, |
const byte * | prev_rec, | ||
const byte * | free_rec, | ||
byte * | rec | ||
) |
Insert a record to the dense page directory.
[in,out] | page_zip | Compressed page |
[in] | prev_rec | Record after which to insert |
[in] | free_rec | Record from which rec was allocated, or null |
[in] | rec | Record to insert |
Determine the guaranteed free space on an empty page.
n_fields | in: number of columns in the index |
zip_size | in: compressed page size in bytes |
ulint page_zip_fields_encode | ( | ulint | n, |
const dict_index_t * | index, | ||
ulint | trx_id_pos, | ||
byte * | buf | ||
) |
Write the index information for the compressed page.
n | in: number of fields to compress |
index | in: index comprising at least n fields |
trx_id_pos | in: position of the trx_id column in the index, or ULINT_UNDEFINED if this is a non-leaf page |
buf | out: buffer of (n + 1) * 2 bytes |
Encode the length of a fixed-length column.
buf | in: pointer to buffer where to write |
val | in: value to write |
|
static |
Determine how many externally stored columns are contained in existing records with smaller heap_no than rec.
[in] | page_zip | Dense page directory on compressed page |
[in] | rec | Compact physical record on a b-tree leaf page |
[in] | index | Record descriptor |
|
static |
Assert that the compressed and decompressed page headers match.
[in] | page_zip | compressed page |
[in] | page | uncompressed page |
bool page_zip_is_too_big | ( | const dict_index_t * | index, |
const dtuple_t * | entry | ||
) |
Check whether a tuple is too big for compressed table.
[in] | index | dict index object |
[in] | entry | entry for the index |
byte * page_zip_parse_compress | ( | byte * | ptr, |
byte * | end_ptr, | ||
page_t * | page, | ||
page_zip_des_t * | page_zip | ||
) |
Parses a log record of compressing an index page.
ptr | in: buffer |
end_ptr | in: buffer end |
page | out: uncompressed page |
page_zip | out: compressed page |
byte * page_zip_parse_write_blob_ptr | ( | byte * | ptr, |
byte * | end_ptr, | ||
page_t * | page, | ||
page_zip_des_t * | page_zip | ||
) |
Parses a log record of writing a BLOB pointer of a record.
ptr | in: redo log buffer |
end_ptr | in: redo log buffer end |
page | in/out: uncompressed page |
page_zip | in/out: compressed page |
byte * page_zip_parse_write_header | ( | byte * | ptr, |
byte * | end_ptr, | ||
page_t * | page, | ||
page_zip_des_t * | page_zip | ||
) |
Parses a log record of writing to the header of a page.
ptr | in: redo log buffer |
end_ptr | in: redo log buffer end |
page | in/out: uncompressed page |
page_zip | in/out: compressed page |
byte * page_zip_parse_write_node_ptr | ( | byte * | ptr, |
byte * | end_ptr, | ||
page_t * | page, | ||
page_zip_des_t * | page_zip | ||
) |
Parses a log record of writing the node pointer of a record.
ptr | in: redo log buffer |
end_ptr | in: redo log buffer end |
page | in/out: uncompressed page |
page_zip | in/out: compressed page |
void page_zip_rec_set_deleted | ( | page_zip_des_t * | page_zip, |
const byte * | rec, | ||
bool | flag | ||
) |
Write the "deleted" flag of a record on a compressed page.
The flag must already have been written on the uncompressed page.
page_zip | in/out: compressed page |
rec | in: record on the uncompressed page |
flag | in: the deleted flag (nonzero=true) |
void page_zip_rec_set_owned | ( | page_zip_des_t * | page_zip, |
const byte * | rec, | ||
ulint | flag | ||
) |
Write the "owned" flag of a record on a compressed page.
The n_owned field must already have been written on the uncompressed page.
[in,out] | page_zip | Compressed page |
[in] | rec | Record on the uncompressed page |
[in] | flag | The owned flag (nonzero=true) |
bool page_zip_reorganize | ( | buf_block_t * | block, |
dict_index_t * | index, | ||
mtr_t * | mtr | ||
) |
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.
block | in/out: page with compressed page; on the compressed page, in: size; out: data, n_blobs, m_start, m_end, m_nonempty |
index | in: index of the B-tree node |
mtr | in: mini-transaction |
void page_zip_write_blob_ptr | ( | page_zip_des_t * | page_zip, |
const byte * | rec, | ||
const dict_index_t * | index, | ||
const ulint * | offsets, | ||
ulint | n, | ||
mtr_t * | mtr | ||
) |
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.
page_zip | in/out: compressed page |
rec | in/out: record whose data is being written |
index | in: index of the page |
offsets | in: rec_get_offsets(rec, index) |
n | in: column index |
mtr | in: mini-transaction handle, or NULL if no logging is needed |
Write a log record of writing to the uncompressed header portion of a page.
in: mini-transaction
data | in: data on the uncompressed page |
length | in: length of the data |
mtr | in: mini-transaction |
void page_zip_write_node_ptr | ( | page_zip_des_t * | page_zip, |
byte * | rec, | ||
ulint | size, | ||
ulint | ptr, | ||
mtr_t * | mtr | ||
) |
Write the node pointer of a record on a non-leaf compressed page.
[in,out] | page_zip | Compressed page |
[in,out] | rec | Record |
[in] | size | Data size of rec |
[in] | ptr | Node pointer |
[in] | mtr | Mini-transaction, or null |
void page_zip_write_rec | ( | page_zip_des_t * | page_zip, |
const byte * | rec, | ||
const dict_index_t * | index, | ||
const ulint * | offsets, | ||
ulint | create | ||
) |
Write an entire record on the compressed page.
The data must already have been written to the uncompressed page.
page_zip | in/out: compressed page |
rec | in: record being written |
index | in: the index the record belongs to |
offsets | in: rec_get_offsets(rec, index) |
create | in: nonzero=insert, zero=update |
|
static |
Write a record on the compressed page that contains externally stored columns.
The data must already have been written to the uncompressed page.
page_zip | in/out: compressed page |
page | in: page containing rec |
rec | in: record being written |
index | in: record descriptor |
offsets | in: rec_get_offsets(rec, index) |
create | in: nonzero=insert, zero=update |
trx_id_col | in: position of DB_TRX_ID |
heap_no | in: heap number of rec |
storage | in: end of dense page directory |
data | in: end of modification log |
void page_zip_write_trx_id_and_roll_ptr | ( | page_zip_des_t * | page_zip, |
byte * | rec, | ||
const ulint * | offsets, | ||
ulint | trx_id_col, | ||
trx_id_t | trx_id, | ||
roll_ptr_t | roll_ptr | ||
) |
Write the trx_id and roll_ptr of a record on a B-tree leaf node page.
[in,out] | page_zip | Compressed page |
[in,out] | rec | Record |
[in] | offsets | Rec_get_offsets(rec, index) |
[in] | trx_id_col | Column number of trx_id in rec |
[in] | trx_id | Transaction identifier |
[in] | roll_ptr | Roll_ptr |
const byte field_ref_zero[FIELD_REF_SIZE] |
A BLOB field reference full of zero, for use in assertions and tests.
A BLOB field reference full of zero, for use in assertions and tests.Initially, BLOB field references are set to zero, in dtuple_convert_big_rec().
Initially, BLOB field references are set to zero, in dtuple_convert_big_rec().
|
static |
Set this variable in a debugger to enable excessive logging in page_zip_compress().
|
static |
Set this variable in a debugger to enable binary logging of the data passed to deflate().
When this variable is nonzero, it will act as a log file name generator.
uint page_zip_level = DEFAULT_COMPRESSION_LEVEL |
Default Zip compression level.
bool page_zip_log_pages = true |
page_zip_stat_t page_zip_stat[PAGE_ZIP_SSIZE_MAX] |
Statistics on compression, indexed by page_zip_des_t::ssize - 1.
page_zip_stat_per_index_t page_zip_stat_per_index |
Statistics on compression, indexed by index->id.
Statistics on compression, indexed by dict_index_t::id.