Skip to content

Commit 06ae6c6

Browse files
author
Sergei Golubchik
committed
5.6.22
1 parent 23326c5 commit 06ae6c6

File tree

20 files changed

+743
-247
lines changed

20 files changed

+743
-247
lines changed

btr/btr0cur.cc

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2363,6 +2363,38 @@ btr_cur_pess_upd_restore_supremum(
23632363
page_rec_get_heap_no(rec));
23642364
}
23652365

2366+
/*************************************************************//**
2367+
Check if the total length of the modified blob for the row is within 10%
2368+
of the total redo log size. This constraint on the blob length is to
2369+
avoid overwriting the redo logs beyond the last checkpoint lsn.
2370+
@return DB_SUCCESS or DB_TOO_BIG_RECORD. */
2371+
static
2372+
dberr_t
2373+
btr_check_blob_limit(const big_rec_t* big_rec_vec)
2374+
{
2375+
const ib_uint64_t redo_size = srv_n_log_files * srv_log_file_size
2376+
* UNIV_PAGE_SIZE;
2377+
const ulint redo_10p = redo_size / 10;
2378+
ulint total_blob_len = 0;
2379+
dberr_t err = DB_SUCCESS;
2380+
2381+
/* Calculate the total number of bytes for blob data */
2382+
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
2383+
total_blob_len += big_rec_vec->fields[i].len;
2384+
}
2385+
2386+
if (total_blob_len > redo_10p) {
2387+
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data"
2388+
" length (" ULINTPF ") is greater than"
2389+
" 10%% of the total redo log size (" UINT64PF
2390+
"). Please increase total redo log size.",
2391+
total_blob_len, redo_size);
2392+
err = DB_TOO_BIG_RECORD;
2393+
}
2394+
2395+
return(err);
2396+
}
2397+
23662398
/*************************************************************//**
23672399
Performs an update of a record on a page of a tree. It is assumed
23682400
that mtr holds an x-latch on the tree and on the cursor page. If the
@@ -2578,26 +2610,14 @@ btr_cur_pessimistic_update(
25782610
}
25792611

25802612
if (big_rec_vec) {
2581-
const ulint redo_10p = srv_log_file_size * UNIV_PAGE_SIZE / 10;
2582-
ulint total_blob_len = 0;
25832613

2584-
/* Calculate the total number of bytes for blob data */
2585-
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
2586-
total_blob_len += big_rec_vec->fields[i].len;
2587-
}
2614+
err = btr_check_blob_limit(big_rec_vec);
25882615

2589-
if (total_blob_len > redo_10p) {
2590-
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data"
2591-
" length (" ULINTPF ") is greater than"
2592-
" 10%% of the redo log file size (" UINT64PF
2593-
"). Please increase innodb_log_file_size.",
2594-
total_blob_len, srv_log_file_size);
2616+
if (err != DB_SUCCESS) {
25952617
if (n_reserved > 0) {
25962618
fil_space_release_free_extents(
25972619
index->space, n_reserved);
25982620
}
2599-
2600-
err = DB_TOO_BIG_RECORD;
26012621
goto err_exit;
26022622
}
26032623
}
@@ -4423,7 +4443,6 @@ btr_store_big_rec_extern_fields(
44234443
buf_block_t** freed_pages = NULL;
44244444
ulint n_freed_pages = 0;
44254445
dberr_t error = DB_SUCCESS;
4426-
ulint total_blob_len = 0;
44274446

44284447
ut_ad(rec_offs_validate(rec, index, offsets));
44294448
ut_ad(rec_offs_any_extern(offsets));
@@ -4443,21 +4462,11 @@ btr_store_big_rec_extern_fields(
44434462
rec_page_no = buf_block_get_page_no(rec_block);
44444463
ut_a(fil_page_get_type(page_align(rec)) == FIL_PAGE_INDEX);
44454464

4446-
const ulint redo_10p = (srv_log_file_size * UNIV_PAGE_SIZE / 10);
4465+
error = btr_check_blob_limit(big_rec_vec);
44474466

4448-
/* Calculate the total number of bytes for blob data */
4449-
for (ulint i = 0; i < big_rec_vec->n_fields; i++) {
4450-
total_blob_len += big_rec_vec->fields[i].len;
4451-
}
4452-
4453-
if (total_blob_len > redo_10p) {
4467+
if (error != DB_SUCCESS) {
44544468
ut_ad(op == BTR_STORE_INSERT);
4455-
ib_logf(IB_LOG_LEVEL_ERROR, "The total blob data length"
4456-
" (" ULINTPF ") is greater than 10%% of the"
4457-
" redo log file size (" UINT64PF "). Please"
4458-
" increase innodb_log_file_size.",
4459-
total_blob_len, srv_log_file_size);
4460-
return(DB_TOO_BIG_RECORD);
4469+
return(error);
44614470
}
44624471

44634472
if (page_zip) {

buf/buf0buf.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,9 +564,14 @@ buf_page_is_corrupted(
564564
checksum_field2 = mach_read_from_4(
565565
read_buf + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM);
566566

567+
#if FIL_PAGE_LSN % 8
568+
#error "FIL_PAGE_LSN must be 64 bit aligned"
569+
#endif
570+
567571
/* declare empty pages non-corrupted */
568572
if (checksum_field1 == 0 && checksum_field2 == 0
569-
&& mach_read_from_4(read_buf + FIL_PAGE_LSN) == 0) {
573+
&& *reinterpret_cast<const ib_uint64_t*>(read_buf +
574+
FIL_PAGE_LSN) == 0) {
570575
/* make sure that the page is really empty */
571576
for (ulint i = 0; i < UNIV_PAGE_SIZE; i++) {
572577
if (read_buf[i] != 0) {

buf/buf0flu.cc

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -828,39 +828,35 @@ buf_flush_init_for_writing(
828828
case SRV_CHECKSUM_ALGORITHM_CRC32:
829829
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
830830
checksum = buf_calc_page_crc32(page);
831+
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
831832
break;
832833
case SRV_CHECKSUM_ALGORITHM_INNODB:
833834
case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
834835
checksum = (ib_uint32_t) buf_calc_page_new_checksum(page);
836+
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
837+
checksum = (ib_uint32_t) buf_calc_page_old_checksum(page);
835838
break;
836839
case SRV_CHECKSUM_ALGORITHM_NONE:
837840
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
838841
checksum = BUF_NO_CHECKSUM_MAGIC;
842+
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
839843
break;
840844
/* no default so the compiler will emit a warning if new enum
841845
is added and not handled here */
842846
}
843847

844-
mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, checksum);
845-
846-
/* We overwrite the first 4 bytes of the end lsn field to store
847-
the old formula checksum. Since it depends also on the field
848-
FIL_PAGE_SPACE_OR_CHKSUM, it has to be calculated after storing the
849-
new formula checksum. */
850-
851-
if (srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_STRICT_INNODB
852-
|| srv_checksum_algorithm == SRV_CHECKSUM_ALGORITHM_INNODB) {
848+
/* With the InnoDB checksum, we overwrite the first 4 bytes of
849+
the end lsn field to store the old formula checksum. Since it
850+
depends also on the field FIL_PAGE_SPACE_OR_CHKSUM, it has to
851+
be calculated after storing the new formula checksum.
853852
854-
checksum = (ib_uint32_t) buf_calc_page_old_checksum(page);
855-
856-
/* In other cases we use the value assigned from above.
857-
If CRC32 is used then it is faster to use that checksum
858-
(calculated above) instead of calculating another one.
859-
We can afford to store something other than
860-
buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in
861-
this field because the file will not be readable by old
862-
versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */
863-
}
853+
In other cases we write the same value to both fields.
854+
If CRC32 is used then it is faster to use that checksum
855+
(calculated above) instead of calculating another one.
856+
We can afford to store something other than
857+
buf_calc_page_old_checksum() or BUF_NO_CHECKSUM_MAGIC in
858+
this field because the file will not be readable by old
859+
versions of MySQL/InnoDB anyway (older than MySQL 5.6.3) */
864860

865861
mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
866862
checksum);

dict/dict0dict.cc

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ UNIV_INTERN dict_index_t* dict_ind_redundant;
3939
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
4040
UNIV_INTERN dict_index_t* dict_ind_compact;
4141

42+
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
43+
/** Flag to control insert buffer debugging. */
44+
extern UNIV_INTERN uint ibuf_debug;
45+
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
46+
47+
/**********************************************************************
48+
Issue a warning that the row is too big. */
49+
void
50+
ib_warn_row_too_big(const dict_table_t* table);
51+
4252
#ifndef UNIV_HOTBACKUP
4353
#include "buf0buf.h"
4454
#include "data0type.h"
@@ -2406,11 +2416,18 @@ dict_index_add_to_cache(
24062416
new_index->n_fields = new_index->n_def;
24072417
new_index->trx_id = index->trx_id;
24082418

2409-
if (strict && dict_index_too_big_for_tree(table, new_index)) {
2419+
if (dict_index_too_big_for_tree(table, new_index)) {
2420+
2421+
if (strict) {
24102422
too_big:
2411-
dict_mem_index_free(new_index);
2412-
dict_mem_index_free(index);
2413-
return(DB_TOO_BIG_RECORD);
2423+
dict_mem_index_free(new_index);
2424+
dict_mem_index_free(index);
2425+
return(DB_TOO_BIG_RECORD);
2426+
} else {
2427+
2428+
ib_warn_row_too_big(table);
2429+
2430+
}
24142431
}
24152432

24162433
if (dict_index_is_univ(index)) {
@@ -5679,11 +5696,11 @@ dict_set_corrupted(
56795696

56805697
dict_index_copy_types(tuple, sys_index, 2);
56815698

5682-
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_GE,
5699+
btr_cur_search_to_nth_level(sys_index, 0, tuple, PAGE_CUR_LE,
56835700
BTR_MODIFY_LEAF,
56845701
&cursor, 0, __FILE__, __LINE__, &mtr);
56855702

5686-
if (cursor.up_match == dtuple_get_n_fields(tuple)) {
5703+
if (cursor.low_match == dtuple_get_n_fields(tuple)) {
56875704
/* UPDATE SYS_INDEXES SET TYPE=index->type
56885705
WHERE TABLE_ID=index->table->id AND INDEX_ID=index->id */
56895706
ulint len;

fil/fil0fil.cc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,8 @@ UNIV_INTERN
21122112
ibool
21132113
fil_inc_pending_ops(
21142114
/*================*/
2115-
ulint id) /*!< in: space id */
2115+
ulint id, /*!< in: space id */
2116+
ibool print_err) /*!< in: need to print error or not */
21162117
{
21172118
fil_space_t* space;
21182119

@@ -2121,10 +2122,12 @@ fil_inc_pending_ops(
21212122
space = fil_space_get_by_id(id);
21222123

21232124
if (space == NULL) {
2124-
fprintf(stderr,
2125-
"InnoDB: Error: trying to do an operation on a"
2126-
" dropped tablespace %lu\n",
2127-
(ulong) id);
2125+
if (print_err) {
2126+
fprintf(stderr,
2127+
"InnoDB: Error: trying to do an operation on a"
2128+
" dropped tablespace %lu\n",
2129+
(ulong) id);
2130+
}
21282131
}
21292132

21302133
if (space == NULL || space->stop_new_ops) {
@@ -4280,7 +4283,18 @@ fil_load_single_table_tablespace(
42804283
/* Build up the tablename in the standard form database/table. */
42814284
tablename = static_cast<char*>(
42824285
mem_alloc(dbname_len + filename_len + 2));
4283-
sprintf(tablename, "%s/%s", dbname, filename);
4286+
4287+
/* When lower_case_table_names = 2 it is possible that the
4288+
dbname is in upper case ,but while storing it in fil_space_t
4289+
we must convert it into lower case */
4290+
sprintf(tablename, "%s" , dbname);
4291+
tablename[dbname_len] = '\0';
4292+
4293+
if (lower_case_file_system) {
4294+
dict_casedn_str(tablename);
4295+
}
4296+
4297+
sprintf(tablename+dbname_len,"/%s",filename);
42844298
tablename_len = strlen(tablename) - strlen(".ibd");
42854299
tablename[tablename_len] = '\0';
42864300

0 commit comments

Comments
 (0)