summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/btr/btr0cur.cc9
-rw-r--r--storage/xtradb/dict/dict0dict.cc11
-rw-r--r--storage/xtradb/handler/ha_innodb.cc27
-rw-r--r--storage/xtradb/handler/handler0alter.cc19
-rw-r--r--storage/xtradb/include/page0zip.ic5
-rw-r--r--storage/xtradb/include/rem0rec.h12
6 files changed, 64 insertions, 19 deletions
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index a3aec7e8c47..6480b756f4e 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -2466,6 +2466,15 @@ any_extern:
rec = page_cur_get_rec(page_cursor);
}
+ /* We limit max record size to 16k for 64k page size. */
+ if (!dict_table_is_comp(index->table)
+ && new_rec_size > REDUNDANT_REC_MAX_DATA_SIZE) {
+ ut_ad(srv_page_size == UNIV_PAGE_SIZE_MAX);
+ err = DB_OVERFLOW;
+
+ goto func_exit;
+ }
+
if (UNIV_UNLIKELY(new_rec_size
>= (page_get_free_space_of_empty(page_is_comp(page))
/ 2))) {
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index a1cfeb3860f..f7a2ae423f8 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -2430,9 +2430,13 @@ dict_index_too_big_for_tree(
rec_max_size = 2;
} else {
/* The maximum allowed record size is half a B-tree
- page. No additional sparse page directory entry will
- be generated for the first few user records. */
- page_rec_max = page_get_free_space_of_empty(comp) / 2;
+ page(16k for 64k page size). No additional sparse
+ page directory entry will be generated for the first
+ few user records. */
+ page_rec_max = (comp || UNIV_PAGE_SIZE < UNIV_PAGE_SIZE_MAX)
+ ? page_get_free_space_of_empty(comp) / 2
+ : REDUNDANT_REC_MAX_DATA_SIZE;
+
page_ptr_max = page_rec_max;
/* Each record has a header. */
rec_max_size = comp
@@ -2516,7 +2520,6 @@ add_field_size:
/* Check the size limit on leaf pages. */
if (UNIV_UNLIKELY(rec_max_size >= page_rec_max)) {
-
return(TRUE);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 0dfa2a50654..d4ece1de49e 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -2299,18 +2299,33 @@ convert_error_code_to_mysql(
case DB_TOO_BIG_RECORD: {
/* If prefix is true then a 768-byte prefix is stored
- locally for BLOB fields. Refer to dict_table_get_format() */
+ locally for BLOB fields. Refer to dict_table_get_format().
+ Note that in page0zip.ic page_zip_rec_needs_ext() rec_size
+ is limited to COMPRESSED_REC_MAX_DATA_SIZE (16K) or
+ REDUNDANT_REC_MAX_DATA_SIZE (16K-1). */
bool prefix = (dict_tf_get_format(flags) == UNIV_FORMAT_A);
+ bool comp = !!(flags & DICT_TF_COMPACT);
+ ulint free_space = page_get_free_space_of_empty(comp) / 2;
+
+ if (free_space >= (comp ? COMPRESSED_REC_MAX_DATA_SIZE :
+ REDUNDANT_REC_MAX_DATA_SIZE)) {
+ free_space = (comp ? COMPRESSED_REC_MAX_DATA_SIZE :
+ REDUNDANT_REC_MAX_DATA_SIZE) - 1;
+ }
+
my_printf_error(ER_TOO_BIG_ROWSIZE,
"Row size too large (> %lu). Changing some columns "
"to TEXT or BLOB %smay help. In current row "
"format, BLOB prefix of %d bytes is stored inline.",
MYF(0),
- page_get_free_space_of_empty(flags &
- DICT_TF_COMPACT) / 2,
- prefix ? "or using ROW_FORMAT=DYNAMIC "
- "or ROW_FORMAT=COMPRESSED ": "",
- prefix ? DICT_MAX_FIXED_COL_LEN : 0);
+ free_space,
+ prefix
+ ? "or using ROW_FORMAT=DYNAMIC or"
+ " ROW_FORMAT=COMPRESSED "
+ : "",
+ prefix
+ ? DICT_MAX_FIXED_COL_LEN
+ : 0);
return(HA_ERR_TO_BIG_ROW);
}
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 75d1c772dea..ef2478bd239 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -157,11 +157,22 @@ my_error_innodb(
case DB_CORRUPTION:
my_error(ER_NOT_KEYFILE, MYF(0), table);
break;
- case DB_TOO_BIG_RECORD:
- my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
- page_get_free_space_of_empty(
- flags & DICT_TF_COMPACT) / 2);
+ case DB_TOO_BIG_RECORD: {
+ /* Note that in page0zip.ic page_zip_rec_needs_ext() rec_size
+ is limited to COMPRESSED_REC_MAX_DATA_SIZE (16K) or
+ REDUNDANT_REC_MAX_DATA_SIZE (16K-1). */
+ bool comp = !!(flags & DICT_TF_COMPACT);
+ ulint free_space = page_get_free_space_of_empty(comp) / 2;
+
+ if (free_space >= (comp ? COMPRESSED_REC_MAX_DATA_SIZE :
+ REDUNDANT_REC_MAX_DATA_SIZE)) {
+ free_space = (comp ? COMPRESSED_REC_MAX_DATA_SIZE :
+ REDUNDANT_REC_MAX_DATA_SIZE) - 1;
+ }
+
+ my_error(ER_TOO_BIG_ROWSIZE, MYF(0), free_space);
break;
+ }
case DB_INVALID_NULL:
/* TODO: report the row, as we do for DB_DUPLICATE_KEY */
my_error(ER_INVALID_USE_OF_NULL, MYF(0));
diff --git a/storage/xtradb/include/page0zip.ic b/storage/xtradb/include/page0zip.ic
index 9a583086925..bee35a48cc2 100644
--- a/storage/xtradb/include/page0zip.ic
+++ b/storage/xtradb/include/page0zip.ic
@@ -178,8 +178,9 @@ page_zip_rec_needs_ext(
ut_ad(ut_is_2pow(zip_size));
ut_ad(comp || !zip_size);
-#if UNIV_PAGE_SIZE_MAX > REC_MAX_DATA_SIZE
- if (rec_size >= REC_MAX_DATA_SIZE) {
+#if UNIV_PAGE_SIZE_MAX > COMPRESSED_REC_MAX_DATA_SIZE
+ if (comp ? rec_size >= COMPRESSED_REC_MAX_DATA_SIZE :
+ rec_size >= REDUNDANT_REC_MAX_DATA_SIZE) {
return(TRUE);
}
#endif
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index 9baf0ab380a..afc191e632d 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -976,9 +976,15 @@ are given in one byte (resp. two byte) format. */
#define REC_1BYTE_OFFS_LIMIT 0x7FUL
#define REC_2BYTE_OFFS_LIMIT 0x7FFFUL
-/* 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 (16384)
+/* The data size of record must not be larger than this on
+REDUNDANT row format because we reserve two upmost bits in a
+two byte offset for special purposes */
+#define REDUNDANT_REC_MAX_DATA_SIZE (16383)
+
+/* The data size of record must be smaller than this on
+COMPRESSED row format because we reserve two upmost bits in a
+two byte offset for special purposes */
+#define COMPRESSED_REC_MAX_DATA_SIZE (16384)
#ifdef WITH_WSREP
int wsrep_rec_get_foreign_key(