diff options
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/btr/btr0cur.cc | 9 | ||||
-rw-r--r-- | storage/xtradb/dict/dict0dict.cc | 11 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 27 | ||||
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 19 | ||||
-rw-r--r-- | storage/xtradb/include/page0zip.ic | 5 | ||||
-rw-r--r-- | storage/xtradb/include/rem0rec.h | 12 |
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( |