Commit 121623c1 authored by marko's avatar marko

branches/zip: Write the compressed page size to SYS_TABLES.TYPE

and to the file space header (FSP_PAGE_ZIP_SIZE, renamed from
FSP_LOWEST_NO_WRITE).

fil_space_struct: Add zip_size.

dict_table_struct: Embed zip_size in flags.

dict_table_zip_size(): Infer zip_size from table->flags.

dict_sys_tables_get_zip_size(): Read zip_size from SYS_TABLES.TYPE.

fil_space_get_zip_size(): Read zip_size from the file space header.

Add the redo log entry type MLOG_ZIP_FILE_CREATE.
parent f72f850b
......@@ -3515,7 +3515,7 @@ btr_store_big_rec_extern_fields(
space_id = buf_frame_get_space_id(rec);
page_zip = buf_block_get_page_zip(buf_block_align(rec));
ut_a(!dict_table_is_zip(index->table) == !page_zip);
ut_a(!dict_table_zip_size(index->table) == !page_zip);
if (UNIV_LIKELY_NULL(page_zip)) {
int err;
......@@ -3859,7 +3859,7 @@ btr_free_externally_stored_field(
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_EXTERN_STORAGE);
#endif /* UNIV_SYNC_DEBUG */
if (dict_table_is_zip(index->table)) {
if (dict_table_zip_size(index->table)) {
/* Note that page_zip will be NULL
in row_purge_upd_exist_or_extern(). */
next_page_no = mach_read_from_4(page + FIL_PAGE_NEXT);
......
......@@ -455,7 +455,7 @@ buf_flush_init_for_writing(
{
page_zip_des_t* page_zip = page_zip_;
if (0/*space/* TODO: space_is_zip */) {
if (fil_space_get_zip_size(space)) {
switch (fil_page_get_type(page)) {
case FIL_PAGE_TYPE_ZBLOB:
ut_ad(!page_zip);
......
......@@ -253,6 +253,7 @@ dict_build_table_def_step(
error = fil_create_new_single_table_tablespace(
&(table->space), path_or_name, is_path,
dict_table_zip_size(table),
FIL_IBD_FILE_INITIAL_SIZE);
if (error != DB_SUCCESS) {
......@@ -261,7 +262,8 @@ dict_build_table_def_step(
mtr_start(&mtr);
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE,
dict_table_zip_size(table), &mtr);
mtr_commit(&mtr);
}
......
......@@ -205,6 +205,45 @@ dict_print(void)
goto loop;
}
/************************************************************************
Determine the compressed page size of a table described in SYS_TABLES. */
static
ulint
dict_sys_tables_get_zip_size(
/*=========================*/
/* out: compressed page size in kilobytes;
or 0 if the tablespace is uncompressed,
ULINT_UNDEFINED on error */
rec_t* rec) /* in: a record of SYS_TABLES */
{
byte* field;
ulint len;
ulint n_cols;
ulint table_type;
field = rec_get_nth_field_old(rec, 5, &len);
ut_a(len == 4);
table_type = mach_read_from_4(field);
field = rec_get_nth_field_old(rec, 4, &len);
n_cols = mach_read_from_4(field);
if (UNIV_EXPECT(n_cols & 0x80000000UL, 0x80000000UL)
&& UNIV_LIKELY(table_type > DICT_TABLE_COMPRESSED_BASE)
&& UNIV_LIKELY(table_type
<= DICT_TABLE_COMPRESSED_BASE + 16)) {
return(table_type - DICT_TABLE_COMPRESSED_BASE);
}
if (UNIV_LIKELY(table_type == DICT_TABLE_ORDINARY)) {
return(0);
}
return(ULINT_UNDEFINED);
}
/************************************************************************
In a crash recovery we already have all the tablespace objects created.
This function compares the space id information in the InnoDB data dictionary
......@@ -223,9 +262,6 @@ dict_check_tablespaces_and_store_max_id(
dict_index_t* sys_index;
btr_pcur_t pcur;
rec_t* rec;
byte* field;
ulint len;
ulint space_id;
ulint max_space_id = 0;
mtr_t mtr;
......@@ -262,13 +298,20 @@ dict_check_tablespaces_and_store_max_id(
return;
}
field = rec_get_nth_field_old(rec, 0, &len);
if (!rec_get_deleted_flag(rec, 0)) {
/* We found one */
byte* field;
ulint len;
ulint space_id;
ulint zip_size;
char* name;
field = rec_get_nth_field_old(rec, 0, &len);
name = mem_strdupl((char*) field, len);
char* name = mem_strdupl((char*) field, len);
zip_size = dict_sys_tables_get_zip_size(rec);
ut_a(zip_size != ULINT_UNDEFINED);
field = rec_get_nth_field_old(rec, 9, &len);
ut_a(len == 4);
......@@ -292,7 +335,7 @@ dict_check_tablespaces_and_store_max_id(
object and check that the .ibd file exists. */
fil_open_single_table_tablespace(FALSE, space_id,
name);
zip_size, name);
}
mem_free(name);
......@@ -741,6 +784,7 @@ dict_load_table(
ulint n_cols;
ulint flags;
ulint err;
ulint zip_size;
mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG
......@@ -793,6 +837,9 @@ dict_load_table(
/* Check if the tablespace exists and has the right name */
if (space != 0) {
ulint zip_size = dict_sys_tables_get_zip_size(rec);
ut_a(zip_size != ULINT_UNDEFINED);
if (fil_space_for_table_exists_in_mem(space, name, FALSE,
FALSE, FALSE)) {
/* Ok; (if we did a crash recovery then the tablespace
......@@ -809,7 +856,7 @@ dict_load_table(
name, (ulong)space);
/* Try to open the tablespace */
if (!fil_open_single_table_tablespace(TRUE,
space, name)) {
space, zip_size, name)) {
/* We failed to find a sensible tablespace
file */
......@@ -844,8 +891,10 @@ dict_load_table(
field = rec_get_nth_field_old(rec, 3, &len);
table->id = mach_read_from_8(field);
field = rec_get_nth_field_old(rec, 5, &len);
if (UNIV_UNLIKELY(mach_read_from_4(field) != DICT_TABLE_ORDINARY)) {
zip_size = dict_sys_tables_get_zip_size(rec);
if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
field = rec_get_nth_field_old(rec, 5, &len);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: table %s: unknown table type %lu\n",
......
......@@ -42,7 +42,6 @@ dict_mem_table_create(
mem_heap_t* heap;
ut_ad(name);
ut_ad(!(flags & ~(DICT_TF_COMPACT | DICT_TF_COMPRESSED)));
heap = mem_heap_create(DICT_HEAP_SIZE);
......
This diff is collapsed.
......@@ -60,11 +60,9 @@ descriptor page, but used only in the first. */
about the first extent, but have not
physically allocted those pages to the
file */
#define FSP_LOWEST_NO_WRITE 16 /* The lowest page offset for which
the page has not been written to disk
(if it has been written, we know that
the OS has really reserved the
physical space for the page) */
#define FSP_PAGE_ZIP_SIZE 16 /* The size of the compressed page
in bytes, or 0 for uncompressed
tablespaces */
#define FSP_FRAG_N_USED 20 /* number of used pages in the
FSP_FREE_FRAG list */
#define FSP_FREE 24 /* list of free extents */
......@@ -794,17 +792,26 @@ fsp_init_file_page_low(
/*===================*/
byte* ptr) /* in: pointer to a page */
{
page_t* page;
page = buf_frame_align(ptr);
buf_block_t* block = buf_block_align(ptr);
buf_block_align(page)->check_index_page_at_flush = FALSE;
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip;
block->check_index_page_at_flush = FALSE;
page_zip = buf_block_get_page_zip(block);
if (UNIV_LIKELY_NULL(page_zip)) {
memset(page, 0, UNIV_PAGE_SIZE);
memset(page_zip->data, 0, page_zip->size);
return;
}
#ifdef UNIV_BASIC_LOG_DEBUG
memset(page, 0xff, UNIV_PAGE_SIZE);
#endif
mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
ut_dulint_zero);
mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);
memset(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, 0, 8);
memset(page + FIL_PAGE_LSN, 0, 8);
}
/***************************************************************
......@@ -871,9 +878,10 @@ insert buffer tree root if space == 0. */
void
fsp_header_init(
/*============*/
ulint space, /* in: space id */
ulint size, /* in: current size in blocks */
mtr_t* mtr) /* in: mini-transaction handle */
ulint space, /* in: space id */
ulint size, /* in: current size in blocks */
ulint zip_size, /* in: compressed page size, or 0 */
mtr_t* mtr) /* in: mini-transaction handle */
{
fsp_header_t* header;
page_t* page;
......@@ -902,7 +910,8 @@ fsp_header_init(
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_LOWEST_NO_WRITE, 0, MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_PAGE_ZIP_SIZE, zip_size,
MLOG_4BYTES, mtr);
mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);
flst_init(header + FSP_FREE, mtr);
......@@ -949,6 +958,18 @@ fsp_header_get_space_id(
return(id);
}
/**************************************************************************
Reads the compressed page size from the first page of a tablespace. */
ulint
fsp_header_get_zip_size(
/*=====================*/
/* out: compressed page size, or 0 if uncompressed */
page_t* page) /* in: first page of a tablespace */
{
return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_PAGE_ZIP_SIZE + page));
}
/**************************************************************************
Increases the space size field of a space. */
......
......@@ -2772,7 +2772,7 @@ ibuf_insert(
ut_ad(dtuple_check_typed(entry));
ut_a(!dict_index_is_clust(index));
ut_a(!dict_table_is_zip(index->table));
ut_a(!dict_table_zip_size(index->table));
if (rec_get_converted_size(index, entry)
>= page_get_free_space_of_empty(
......
......@@ -535,11 +535,11 @@ dict_table_is_comp_noninline(
/************************************************************************
Check whether the table uses the compressed compact page format. */
UNIV_INLINE
ibool
dict_table_is_zip(
/*==============*/
/* out: TRUE if table uses the
compressed compact page format */
ulint
dict_table_zip_size(
/*================*/
/* out: compressed page size,
or 0 if not compressed */
const dict_table_t* table); /* in: table */
/************************************************************************
Checks if a column is in the ordering columns of the clustered index of a
......
......@@ -225,16 +225,17 @@ dict_table_is_comp(
/************************************************************************
Check whether the table uses the compressed compact page format. */
UNIV_INLINE
ibool
dict_table_is_zip(
/*==============*/
/* out: TRUE if table uses the
compressed compact page format */
ulint
dict_table_zip_size(
/*================*/
/* out: compressed page size,
or 0 if not compressed */
const dict_table_t* table) /* in: table */
{
ut_ad(table);
return(!!UNIV_UNLIKELY(table->flags & DICT_TF_COMPRESSED));
return(UNIV_UNLIKELY((table->flags & DICT_TF_COMPRESSED_MASK)
<< (10 - DICT_TF_COMPRESSED_SHIFT)));
}
/************************************************************************
......
......@@ -40,10 +40,12 @@ combination of types */
#define DICT_TABLE_CLUSTER 3 /* this means that the table is
really a cluster definition */
#endif
#define DICT_TABLE_COMPRESSED_BASE 0x8000 /* compressed tablespace */
/* Table flags */
#define DICT_TF_COMPACT 1 /* compact page format */
#define DICT_TF_COMPRESSED 2 /* compressed compact format */
#define DICT_TF_COMPRESSED_MASK 62 /* compressed page size, KiB */
#define DICT_TF_COMPRESSED_SHIFT 1
/**************************************************************************
Creates a table memory object. */
......
......@@ -183,6 +183,8 @@ fil_space_create(
/* out: TRUE if success */
const char* name, /* in: space name */
ulint id, /* in: space id */
ulint zip_size,/* in: compressed page size, or
0 for uncompressed tablespaces */
ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */
/***********************************************************************
Frees a space object from a the tablespace memory cache. Closes the files in
......@@ -203,6 +205,16 @@ fil_space_get_size(
/* out: space size, 0 if space not found */
ulint id); /* in: space id */
/***********************************************************************
Returns the compressed page size of the space, or 0 if the space
is not compressed. The tablespace must be cached in the memory cache. */
ulint
fil_space_get_zip_size(
/*===================*/
/* out: compressed page size, ULINT_UNDEFINED
if space not found */
ulint id); /* in: space id */
/***********************************************************************
Checks if the pair space, page_no refers to an existing page in a tablespace
file space. The tablespace must be cached in the memory cache. */
......@@ -319,11 +331,9 @@ fil_op_log_parse_or_replay(
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
ibool do_replay, /* in: TRUE if we want to replay the
operation, and not just parse the log record */
ulint space_id); /* in: if do_replay is TRUE, the space id of
the tablespace in question; otherwise
ignored */
ulint space_id); /* in: the space id of the tablespace in
question, or 0 if the log record should
only be parsed but not replayed */
/***********************************************************************
Deletes a single-table tablespace. The tablespace must be cached in the
memory cache. */
......@@ -384,6 +394,8 @@ fil_create_new_single_table_tablespace(
table */
ibool is_temp, /* in: TRUE if a table created with
CREATE TEMPORARY TABLE */
ulint zip_size, /* in: compressed page size,
or 0 if uncompressed tablespace */
ulint size); /* in: the initial size of the
tablespace file in pages,
must be >= FIL_IBD_FILE_INITIAL_SIZE */
......@@ -409,6 +421,8 @@ fil_open_single_table_tablespace(
faster (the OS caches them) than
accessing the first page of the file */
ulint id, /* in: space id */
ulint zip_size, /* in: compressed page size,
or 0 if uncompressed tablespace */
const char* name); /* in: table name in the
databasename/tablename format */
/************************************************************************
......
......@@ -83,6 +83,14 @@ fsp_header_get_space_id(
/* out: space id, ULINT UNDEFINED if error */
page_t* page); /* in: first page of a tablespace */
/**************************************************************************
Reads the compressed page size from the first page of a tablespace. */
ulint
fsp_header_get_zip_size(
/*=====================*/
/* out: compressed page size, or 0 if uncompressed */
page_t* page); /* in: first page of a tablespace */
/**************************************************************************
Writes the space id to a tablespace header. This function is used past the
buffer pool when we in fil0fil.c create a new single-table tablespace. */
......@@ -98,9 +106,10 @@ insert buffer tree root if space == 0. */
void
fsp_header_init(
/*============*/
ulint space, /* in: space id */
ulint size, /* in: current size in blocks */
mtr_t* mtr); /* in: mini-transaction handle */
ulint space, /* in: space id */
ulint size, /* in: current size in blocks */
ulint zip_size, /* in: compressed page size, or 0 */
mtr_t* mtr); /* in: mini-transaction handle */
/**************************************************************************
Increases the space size field of a space. */
......
......@@ -88,7 +88,7 @@ ibuf_should_try(
decide */
{
if (!dict_index_is_clust(index)
&& !dict_table_is_zip(index->table)
&& !dict_table_zip_size(index->table)
&& (ignore_sec_unique || !(index->type & DICT_UNIQUE))
&& ibuf->meter > IBUF_THRESHOLD) {
......
......@@ -129,16 +129,18 @@ flag value must give the length also! */
/* copy compact record list end
to a new created index page */
#define MLOG_COMP_PAGE_REORGANIZE ((byte)46) /* reorganize an index page */
#define MLOG_ZIP_WRITE_NODE_PTR ((byte)47) /* write the node pointer of
#define MLOG_ZIP_FILE_CREATE ((byte)47) /* log record about creating a
compressed .ibd file */
#define MLOG_ZIP_WRITE_NODE_PTR ((byte)48) /* write the node pointer of
a record on a compressed
non-leaf B-tree page */
#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)48) /* write the BLOB pointer
#define MLOG_ZIP_WRITE_BLOB_PTR ((byte)49) /* write the BLOB pointer
of an externally stored column
on a compressed page */
#define MLOG_ZIP_WRITE_HEADER ((byte)49) /* write to compressed page
#define MLOG_ZIP_WRITE_HEADER ((byte)50) /* write to compressed page
header */
#define MLOG_ZIP_PAGE_COMPRESS ((byte)50) /* compress an index page */
#define MLOG_BIGGEST_TYPE ((byte)50) /* biggest value (used in
#define MLOG_ZIP_PAGE_COMPRESS ((byte)51) /* compress an index page */
#define MLOG_BIGGEST_TYPE ((byte)51) /* biggest value (used in
asserts) */
/*******************************************************************
......
......@@ -890,8 +890,8 @@ recv_parse_or_apply_log_rec_body(
case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
case MLOG_FILE_DELETE:
ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE,
ULINT_UNDEFINED);
case MLOG_ZIP_FILE_CREATE:
ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0);
break;
case MLOG_ZIP_WRITE_NODE_PTR:
ptr = page_zip_parse_write_node_ptr(
......@@ -2086,9 +2086,24 @@ recv_parse_log_recs(
if (type == MLOG_DUMMY_RECORD) {
/* Do nothing */
} else if (store_to_hash && (type == MLOG_FILE_CREATE
} else if (!store_to_hash) {
/* In debug checking, update a replicate page
according to the log record, and check that it
becomes identical with the original page */
#ifdef UNIV_LOG_DEBUG
recv_check_incomplete_log_recs(ptr, len);
#endif/* UNIV_LOG_DEBUG */
#ifdef UNIV_LOG_REPLICATE
recv_update_replicate(type, space, page_no, body,
ptr + len);
recv_compare_replicate(space, page_no);
#endif /* UNIV_LOG_REPLICATE */
} else if (type == MLOG_FILE_CREATE
|| type == MLOG_ZIP_FILE_CREATE
|| type == MLOG_FILE_RENAME
|| type == MLOG_FILE_DELETE)) {
|| type == MLOG_FILE_DELETE) {
ut_a(space);
#ifdef UNIV_HOTBACKUP
if (recv_replay_file_ops) {
......@@ -2098,34 +2113,21 @@ recv_parse_log_recs(
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(body,
end_ptr, type, TRUE, space)) {
end_ptr, type, space)) {
fprintf(stderr,
"InnoDB: Error: file op log record of type %lu space %lu not complete in\n"
"InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2));
ut_a(0);
ut_error;
}
}
#endif
/* In normal mysqld crash recovery we do not try to
replay file operations */
} else if (store_to_hash) {
} else {
recv_add_to_hash_table(type, space, page_no, body,
ptr + len, old_lsn,
recv_sys->recovered_lsn);
} else {
/* In debug checking, update a replicate page
according to the log record, and check that it
becomes identical with the original page */
#ifdef UNIV_LOG_DEBUG
recv_check_incomplete_log_recs(ptr, len);
#endif/* UNIV_LOG_DEBUG */
#ifdef UNIV_LOG_REPLICATE
recv_update_replicate(type, space, page_no, body,
ptr + len);
recv_compare_replicate(space, page_no);
#endif /* UNIV_LOG_REPLICATE */
}
} else {
/* Check that all the records associated with the single mtr
......
......@@ -963,7 +963,7 @@ page_zip_fields_decode(
}
table = dict_mem_table_create("ZIP_DUMMY", DICT_HDR_SPACE, n,
DICT_TF_COMPACT | DICT_TF_COMPRESSED);
DICT_TF_COMPACT);
index = dict_mem_index_create("ZIP_DUMMY", "ZIP_DUMMY",
DICT_HDR_SPACE, 0, n);
index->table = table;
......
......@@ -2689,7 +2689,7 @@ row_import_tablespace_for_mysql(
ibuf_delete_for_discarded_space(table->space);
success = fil_open_single_table_tablespace(TRUE, table->space,
table->name);
dict_table_zip_size(table), table->name);
if (success) {
table->ibd_file_missing = FALSE;
table->tablespace_discarded = FALSE;
......
......@@ -663,7 +663,7 @@ open_or_create_log_file(
which is for this log group */
fil_space_create(name,
2 * k + SRV_LOG_SPACE_FIRST_ID, FIL_LOG);
2 * k + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG);
}
ut_a(fil_validate());
......@@ -926,7 +926,7 @@ open_or_create_data_files(
ut_a(ret);
if (i == 0) {
fil_space_create(name, 0, FIL_TABLESPACE);
fil_space_create(name, 0, 0, FIL_TABLESPACE);
}
ut_a(fil_validate());
......@@ -1411,8 +1411,7 @@ NetWare. */
if (create_new_db) {
mtr_start(&mtr);
fsp_header_init(0, sum_of_new_sizes, &mtr);
fsp_header_init(0, sum_of_new_sizes, 0, &mtr);
mtr_commit(&mtr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment