summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-11-05 09:42:23 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2015-11-05 10:30:48 +0200
commit25f8738112b05f33cfa45eabfebf6edfc80e6d8a (patch)
treed712ae201455bdefc223d22717c11bcd01000a8a /storage/innobase
parentf9e320c82daec5acc21884c2b09a139e19632c45 (diff)
downloadmariadb-git-25f8738112b05f33cfa45eabfebf6edfc80e6d8a.tar.gz
MDEV-9040: 10.1.8 fails after upgrade from 10.0.21
Analysis: Lengths which are not UNIV_SQL_NULL, but bigger than the following number indicate that a field contains a reference to an externally stored part of the field in the tablespace. The length field then contains the sum of the following flag and the locally stored len. This was incorrectly set to define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_MAX) When it should be define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_DEF) Additionally, we need to disable support for > 16K page size for row compressed tables because a compressed page directory entry reserves 14 bits for the start offset and 2 bits for flags. This limits the uncompressed page size to 16k. To support larger pages page directory entry needs to be larger.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0cur.cc6
-rw-r--r--storage/innobase/fil/fil0fil.cc13
-rw-r--r--storage/innobase/handler/ha_innodb.cc33
-rw-r--r--storage/innobase/include/fsp0types.h18
-rw-r--r--storage/innobase/include/rem0rec.h2
-rw-r--r--storage/innobase/include/univ.i8
-rw-r--r--storage/innobase/page/page0zip.cc4
-rw-r--r--storage/innobase/row/row0ftsort.cc2
8 files changed, 66 insertions, 20 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 9588efcca27..6765290d87f 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -2276,6 +2276,12 @@ any_extern:
#endif /* UNIV_ZIP_DEBUG */
if (page_zip) {
+ if (page_zip_rec_needs_ext(new_rec_size, page_is_comp(page),
+ dict_index_get_n_fields(index),
+ page_zip_get_size(page_zip))) {
+ goto any_extern;
+ }
+
if (!btr_cur_update_alloc_zip(
page_zip, page_cursor, index, *offsets,
new_rec_size, true, mtr)) {
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index db304203a18..50ff4d76fb6 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -745,9 +745,7 @@ fil_node_open_file(
}
if (!fsp_flags_is_compressed(flags)) {
- node->size = (ulint)
- (size_bytes
- / fsp_flags_get_page_size(flags));
+ node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE);
} else {
node->size = (ulint)
(size_bytes
@@ -4113,8 +4111,11 @@ fil_user_tablespace_find_space_id(
false, page, 0);
}
- bool compressed_ok = !buf_page_is_corrupted(
- false, page, page_size);
+ bool compressed_ok = false;
+ if (page_size <= UNIV_PAGE_SIZE_DEF) {
+ compressed_ok = !buf_page_is_corrupted(
+ false, page, page_size);
+ }
if (uncompressed_ok || compressed_ok) {
@@ -5846,6 +5847,8 @@ fil_io(
case 4096: zip_size_shift = 12; break;
case 8192: zip_size_shift = 13; break;
case 16384: zip_size_shift = 14; break;
+ case 32768: zip_size_shift = 15; break;
+ case 65536: zip_size_shift = 16; break;
default: ut_error;
}
offset = ((os_offset_t) block_offset << zip_size_shift)
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 078f9c9d781..454b2be1755 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4772,7 +4772,10 @@ ha_innobase::max_supported_key_length() const
For page sizes = 16k, InnoDB historically reported 3500 bytes here,
But the MySQL limit of 3072 was always used through the handler
- interface. */
+ interface.
+
+ Note: Handle 16k and 32k pages the same here since the limits
+ are higher than imposed by MySQL. */
switch (UNIV_PAGE_SIZE) {
case 4096:
@@ -10992,6 +10995,21 @@ create_options_are_invalid(
ret = "INDEX DIRECTORY";
}
+ if ((kbs_specified || row_format == ROW_TYPE_COMPRESSED)
+ && UNIV_PAGE_SIZE > (1<<14)) {
+ push_warning(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: Cannot create a COMPRESSED table"
+ " when innodb_page_size > 16k.");
+
+ if (kbs_specified) {
+ ret = "KEY_BLOCK_SIZE";
+ } else {
+ ret = "ROW_TYPE";
+ }
+ }
+
return(ret);
}
@@ -11349,6 +11367,17 @@ index_bad:
break;
}
+ /* Don't support compressed table when page size > 16k. */
+ if (zip_allowed && zip_ssize && UNIV_PAGE_SIZE > UNIV_PAGE_SIZE_DEF) {
+ push_warning(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: Cannot create a COMPRESSED table"
+ " when innodb_page_size > 16k."
+ " Assuming ROW_FORMAT=COMPACT.");
+ zip_allowed = FALSE;
+ }
+
/* Set the table flags */
if (!zip_allowed) {
zip_ssize = 0;
@@ -18934,7 +18963,7 @@ static MYSQL_SYSVAR_ULONG(page_size, srv_page_size,
static MYSQL_SYSVAR_LONG(log_buffer_size, innobase_log_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
- NULL, NULL, 8*1024*1024L, 256*1024L, LONG_MAX, 1024);
+ NULL, NULL, 16*1024*1024L, 256*1024L, LONG_MAX, 1024);
static MYSQL_SYSVAR_LONGLONG(log_file_size, innobase_log_file_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
diff --git a/storage/innobase/include/fsp0types.h b/storage/innobase/include/fsp0types.h
index a6797cd66de..4f2ca2594cb 100644
--- a/storage/innobase/include/fsp0types.h
+++ b/storage/innobase/include/fsp0types.h
@@ -42,11 +42,21 @@ fseg_alloc_free_page) */
#define FSP_NO_DIR ((byte)113) /*!< no order */
/* @} */
+/** File space extent size in pages
+page size | file space extent size
+----------+-----------------------
+ 4 KiB | 256 pages = 1 MiB
+ 8 KiB | 128 pages = 1 MiB
+ 16 KiB | 64 pages = 1 MiB
+ 32 KiB | 64 pages = 2 MiB
+ 64 KiB | 64 pages = 4 MiB
+*/
/** File space extent size (one megabyte if default two or four if not) in pages */
-#define FSP_EXTENT_SIZE ((UNIV_PAGE_SIZE <= (1 << 14) ? \
- (1048576U / UNIV_PAGE_SIZE) : \
- ((UNIV_PAGE_SIZE <= 1 << 15) ? \
- (2097152U / UNIV_PAGE_SIZE) : (4194304U / UNIV_PAGE_SIZE))))
+#define FSP_EXTENT_SIZE ((UNIV_PAGE_SIZE <= (16384) ? \
+ (1048576U / UNIV_PAGE_SIZE) : \
+ ((UNIV_PAGE_SIZE <= (32768)) ? \
+ (2097152U / UNIV_PAGE_SIZE) : \
+ (4194304U / UNIV_PAGE_SIZE))))
/** File space extent size (four megabytes) in pages for MAX page size */
#define FSP_EXTENT_SIZE_MAX (4194304U / UNIV_PAGE_SIZE_MAX)
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index 94453cc7b89..22899c2a815 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -982,7 +982,7 @@ are given in one byte (resp. two byte) format. */
/* The data size of record must be smaller than this because we reserve
two upmost bits in a two byte offset for special purposes */
-#define REC_MAX_DATA_SIZE (16 * 1024)
+#define REC_MAX_DATA_SIZE (16384)
#ifdef WITH_WSREP
int wsrep_rec_get_foreign_key(
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index a6804c71344..a957b2cc98f 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -372,10 +372,8 @@ Note: This must never change! */
/** log2 of largest compressed page size (1<<14 == 16384 bytes).
A compressed page directory entry reserves 14 bits for the start offset
and 2 bits for flags. This limits the uncompressed page size to 16k.
-Even though a 16k uncompressed page can theoretically be compressed
-into a larger compressed page, it is not a useful feature so we will
-limit both with this same constant. */
-#define UNIV_ZIP_SIZE_SHIFT_MAX 15
+*/
+#define UNIV_ZIP_SIZE_SHIFT_MAX 14
/* Define the Min, Max, Default page sizes. */
/** Minimum Page Size Shift (power of 2) */
@@ -559,7 +557,7 @@ number indicate that a field contains a reference to an externally
stored part of the field in the tablespace. The length field then
contains the sum of the following flag and the locally stored len. */
-#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_MAX)
+#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_DEF)
#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
#define HAVE_GCC_GT_2
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 94e3f645cbe..0842971c8d0 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -672,8 +672,8 @@ page_zip_dir_encode(
#if PAGE_ZIP_DIR_SLOT_MASK & (PAGE_ZIP_DIR_SLOT_MASK + 1)
# error "PAGE_ZIP_DIR_SLOT_MASK is not 1 less than a power of 2"
#endif
-#if PAGE_ZIP_DIR_SLOT_MASK < UNIV_PAGE_SIZE_DEF - 1
-# error "PAGE_ZIP_DIR_SLOT_MASK < UNIV_PAGE_SIZE_MAX - 1"
+#if PAGE_ZIP_DIR_SLOT_MASK < UNIV_PAGE_ZIP_SIZE_MAX - 1
+# error "PAGE_ZIP_DIR_SLOT_MASK < UNIV_ZIP_SIZE_MAX - 1"
#endif
if (UNIV_UNLIKELY(rec_get_n_owned_new(rec))) {
offs |= PAGE_ZIP_DIR_SLOT_OWNED;
diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc
index 2dba7081d09..f970938f729 100644
--- a/storage/innobase/row/row0ftsort.cc
+++ b/storage/innobase/row/row0ftsort.cc
@@ -1479,7 +1479,7 @@ row_fts_merge_insert(
fd[i] = psort_info[i].merge_file[id]->fd;
foffs[i] = 0;
- buf[i] = static_cast<unsigned char (*)[65536]>(
+ buf[i] = static_cast<mrec_buf_t*>(
mem_heap_alloc(heap, sizeof *buf[i]));
count_diag += (int) psort_info[i].merge_file[id]->n_rec;