Skip to content

Commit 8d69ce7

Browse files
committed
5.6.35-80.0
1 parent 7436c3d commit 8d69ce7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+717
-480
lines changed

storage/xtradb/btr/btr0btr.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3400,7 +3400,7 @@ Removes a page from the level list of pages.
34003400

34013401
/*************************************************************//**
34023402
Removes a page from the level list of pages. */
3403-
static MY_ATTRIBUTE((nonnull))
3403+
static
34043404
void
34053405
btr_level_list_remove_func(
34063406
/*=======================*/

storage/xtradb/btr/btr0cur.cc

Lines changed: 89 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,7 @@ btr_cur_pessimistic_insert(
17821782
/*************************************************************//**
17831783
For an update, checks the locks and does the undo logging.
17841784
@return DB_SUCCESS, DB_WAIT_LOCK, or error number */
1785-
UNIV_INLINE MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,6,7)))
1785+
UNIV_INLINE MY_ATTRIBUTE((warn_unused_result))
17861786
dberr_t
17871787
btr_cur_upd_lock_and_undo(
17881788
/*======================*/
@@ -3855,18 +3855,40 @@ btr_estimate_n_rows_in_range_on_level(
38553855
return(n_rows);
38563856
}
38573857

3858-
/*******************************************************************//**
3859-
Estimates the number of rows in a given index range.
3860-
@return estimated number of rows */
3861-
UNIV_INTERN
3862-
ib_int64_t
3863-
btr_estimate_n_rows_in_range(
3864-
/*=========================*/
3865-
dict_index_t* index, /*!< in: index */
3866-
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
3867-
ulint mode1, /*!< in: search mode for range start */
3868-
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
3869-
ulint mode2) /*!< in: search mode for range end */
3858+
/** If the tree gets changed too much between the two dives for the left
3859+
and right boundary then btr_estimate_n_rows_in_range_low() will retry
3860+
that many times before giving up and returning the value stored in
3861+
rows_in_range_arbitrary_ret_val. */
3862+
static const unsigned rows_in_range_max_retries = 4;
3863+
3864+
/** We pretend that a range has that many records if the tree keeps changing
3865+
for rows_in_range_max_retries retries while we try to estimate the records
3866+
in a given range. */
3867+
static const int64_t rows_in_range_arbitrary_ret_val = 10;
3868+
3869+
/** Estimates the number of rows in a given index range.
3870+
@param[in] index index
3871+
@param[in] tuple1 range start, may also be empty tuple
3872+
@param[in] mode1 search mode for range start
3873+
@param[in] tuple2 range end, may also be empty tuple
3874+
@param[in] mode2 search mode for range end
3875+
@param[in] nth_attempt if the tree gets modified too much while
3876+
we are trying to analyze it, then we will retry (this function will call
3877+
itself, incrementing this parameter)
3878+
@return estimated number of rows; if after rows_in_range_max_retries
3879+
retries the tree keeps changing, then we will just return
3880+
rows_in_range_arbitrary_ret_val as a result (if
3881+
nth_attempt >= rows_in_range_max_retries and the tree is modified between
3882+
the two dives). */
3883+
static
3884+
int64_t
3885+
btr_estimate_n_rows_in_range_low(
3886+
dict_index_t* index,
3887+
const dtuple_t* tuple1,
3888+
ulint mode1,
3889+
const dtuple_t* tuple2,
3890+
ulint mode2,
3891+
unsigned nth_attempt)
38703892
{
38713893
btr_path_t path1[BTR_PATH_ARRAY_N_SLOTS];
38723894
btr_path_t path2[BTR_PATH_ARRAY_N_SLOTS];
@@ -3902,6 +3924,12 @@ btr_estimate_n_rows_in_range(
39023924

39033925
mtr_commit(&mtr);
39043926

3927+
#ifdef UNIV_DEBUG
3928+
if (!strcmp(index->name, "iC")) {
3929+
DEBUG_SYNC_C("btr_estimate_n_rows_in_range_between_dives");
3930+
}
3931+
#endif
3932+
39053933
mtr_start(&mtr);
39063934

39073935
cursor.path_arr = path2;
@@ -3970,6 +3998,32 @@ btr_estimate_n_rows_in_range(
39703998

39713999
if (!diverged && slot1->nth_rec != slot2->nth_rec) {
39724000

4001+
/* If both slots do not point to the same page or if
4002+
the paths have crossed and the same page on both
4003+
apparently contains a different number of records,
4004+
this means that the tree must have changed between
4005+
the dive for slot1 and the dive for slot2 at the
4006+
beginning of this function. */
4007+
if (slot1->page_no != slot2->page_no
4008+
|| slot1->page_level != slot2->page_level
4009+
|| (slot1->nth_rec >= slot2->nth_rec
4010+
&& slot1->n_recs != slot2->n_recs)) {
4011+
4012+
/* If the tree keeps changing even after a
4013+
few attempts, then just return some arbitrary
4014+
number. */
4015+
if (nth_attempt >= rows_in_range_max_retries) {
4016+
return(rows_in_range_arbitrary_ret_val);
4017+
}
4018+
4019+
const int64_t ret =
4020+
btr_estimate_n_rows_in_range_low(
4021+
index, tuple1, mode1,
4022+
tuple2, mode2, nth_attempt + 1);
4023+
4024+
return(ret);
4025+
}
4026+
39734027
diverged = TRUE;
39744028

39754029
if (slot1->nth_rec < slot2->nth_rec) {
@@ -3988,7 +4042,7 @@ btr_estimate_n_rows_in_range(
39884042
in this case slot1->nth_rec will point
39894043
to the supr record and slot2->nth_rec
39904044
will point to 6 */
3991-
n_rows = 0;
4045+
return(0);
39924046
}
39934047

39944048
} else if (diverged && !diverged_lot) {
@@ -4019,6 +4073,27 @@ btr_estimate_n_rows_in_range(
40194073
}
40204074
}
40214075

4076+
/** Estimates the number of rows in a given index range.
4077+
@param[in] index index
4078+
@param[in] tuple1 range start, may also be empty tuple
4079+
@param[in] mode1 search mode for range start
4080+
@param[in] tuple2 range end, may also be empty tuple
4081+
@param[in] mode2 search mode for range end
4082+
@return estimated number of rows */
4083+
int64_t
4084+
btr_estimate_n_rows_in_range(
4085+
dict_index_t* index,
4086+
const dtuple_t* tuple1,
4087+
ulint mode1,
4088+
const dtuple_t* tuple2,
4089+
ulint mode2)
4090+
{
4091+
const int64_t ret = btr_estimate_n_rows_in_range_low(
4092+
index, tuple1, mode1, tuple2, mode2, 1 /* first attempt */);
4093+
4094+
return(ret);
4095+
}
4096+
40224097
/*******************************************************************//**
40234098
Record the number of non_null key values in a given index for
40244099
each n-column prefix of the index where 1 <= n <= dict_index_get_n_unique(index).

storage/xtradb/buf/buf0lru.cc

Lines changed: 104 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,71 @@ buf_LRU_check_size_of_non_data_objects(
13011301
}
13021302
}
13031303

1304+
/** Diagnose failure to get a free page and request InnoDB monitor output in
1305+
the error log if more than two seconds have been spent already.
1306+
@param[in] n_iterations how many buf_LRU_get_free_page iterations
1307+
already completed
1308+
@param[in] started_ms timestamp in ms of when the attempt to get the
1309+
free page started
1310+
@param[in] flush_failures how many times single-page flush, if allowed,
1311+
has failed
1312+
@param[out] mon_value_was previous srv_print_innodb_monitor value
1313+
@param[out] started_monitor whether InnoDB monitor print has been requested
1314+
*/
1315+
static
1316+
void
1317+
buf_LRU_handle_lack_of_free_blocks(ulint n_iterations, ulint started_ms,
1318+
ulint flush_failures,
1319+
ibool *mon_value_was,
1320+
ibool *started_monitor)
1321+
{
1322+
static ulint last_printout_ms = 0;
1323+
1324+
/* Legacy algorithm started warning after at least 2 seconds, we
1325+
emulate this. */
1326+
const ulint current_ms = ut_time_ms();
1327+
1328+
if ((current_ms > started_ms + 2000)
1329+
&& (current_ms > last_printout_ms + 2000)) {
1330+
1331+
ut_print_timestamp(stderr);
1332+
fprintf(stderr,
1333+
" InnoDB: Warning: difficult to find free blocks in\n"
1334+
"InnoDB: the buffer pool (%lu search iterations)!\n"
1335+
"InnoDB: %lu failed attempts to flush a page!"
1336+
" Consider\n"
1337+
"InnoDB: increasing the buffer pool size.\n"
1338+
"InnoDB: It is also possible that"
1339+
" in your Unix version\n"
1340+
"InnoDB: fsync is very slow, or"
1341+
" completely frozen inside\n"
1342+
"InnoDB: the OS kernel. Then upgrading to"
1343+
" a newer version\n"
1344+
"InnoDB: of your operating system may help."
1345+
" Look at the\n"
1346+
"InnoDB: number of fsyncs in diagnostic info below.\n"
1347+
"InnoDB: Pending flushes (fsync) log: %lu;"
1348+
" buffer pool: %lu\n"
1349+
"InnoDB: %lu OS file reads, %lu OS file writes,"
1350+
" %lu OS fsyncs\n"
1351+
"InnoDB: Starting InnoDB Monitor to print further\n"
1352+
"InnoDB: diagnostics to the standard output.\n",
1353+
(ulong) n_iterations,
1354+
(ulong) flush_failures,
1355+
(ulong) fil_n_pending_log_flushes,
1356+
(ulong) fil_n_pending_tablespace_flushes,
1357+
(ulong) os_n_file_reads, (ulong) os_n_file_writes,
1358+
(ulong) os_n_fsyncs);
1359+
1360+
last_printout_ms = current_ms;
1361+
*mon_value_was = srv_print_innodb_monitor;
1362+
*started_monitor = TRUE;
1363+
srv_print_innodb_monitor = TRUE;
1364+
os_event_set(lock_sys->timeout_event);
1365+
}
1366+
1367+
}
1368+
13041369
/** The maximum allowed backoff sleep time duration, microseconds */
13051370
#define MAX_FREE_LIST_BACKOFF_SLEEP 10000
13061371

@@ -1348,6 +1413,7 @@ buf_LRU_get_free_block(
13481413
ulint flush_failures = 0;
13491414
ibool mon_value_was = FALSE;
13501415
ibool started_monitor = FALSE;
1416+
ulint started_ms = 0;
13511417

13521418
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
13531419

@@ -1356,7 +1422,24 @@ buf_LRU_get_free_block(
13561422
buf_LRU_check_size_of_non_data_objects(buf_pool);
13571423

13581424
/* If there is a block in the free list, take it */
1359-
block = buf_LRU_get_free_only(buf_pool);
1425+
if (DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
1426+
1427+
block = NULL;
1428+
1429+
if (srv_debug_monitor_printed)
1430+
DBUG_SET("-d,simulate_lack_of_pages");
1431+
1432+
} else if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages",
1433+
recv_recovery_on, false)) {
1434+
1435+
block = NULL;
1436+
1437+
if (srv_debug_monitor_printed)
1438+
DBUG_SUICIDE();
1439+
} else {
1440+
1441+
block = buf_LRU_get_free_only(buf_pool);
1442+
}
13601443

13611444
if (block) {
13621445

@@ -1371,6 +1454,9 @@ buf_LRU_get_free_block(
13711454
return(block);
13721455
}
13731456

1457+
if (!started_ms)
1458+
started_ms = ut_time_ms();
1459+
13741460
if (srv_empty_free_list_algorithm == SRV_EMPTY_FREE_LIST_BACKOFF
13751461
&& buf_lru_manager_is_active
13761462
&& (srv_shutdown_state == SRV_SHUTDOWN_NONE
@@ -1408,11 +1494,17 @@ buf_LRU_get_free_block(
14081494
: FREE_LIST_BACKOFF_LOW_PRIO_DIVIDER));
14091495
}
14101496

1411-
/* In case of backoff, do not ever attempt single page flushes
1412-
and wait for the cleaner to free some pages instead. */
1497+
buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
1498+
flush_failures,
1499+
&mon_value_was,
1500+
&started_monitor);
14131501

14141502
n_iterations++;
14151503

1504+
srv_stats.buf_pool_wait_free.add(n_iterations, 1);
1505+
1506+
/* In case of backoff, do not ever attempt single page flushes
1507+
and wait for the cleaner to free some pages instead. */
14161508
goto loop;
14171509
} else {
14181510

@@ -1444,6 +1536,12 @@ buf_LRU_get_free_block(
14441536

14451537
mutex_exit(&buf_pool->flush_state_mutex);
14461538

1539+
if (DBUG_EVALUATE_IF("simulate_recovery_lack_of_pages", true, false)
1540+
|| DBUG_EVALUATE_IF("simulate_lack_of_pages", true, false)) {
1541+
1542+
buf_pool->try_LRU_scan = false;
1543+
}
1544+
14471545
freed = FALSE;
14481546
if (buf_pool->try_LRU_scan || n_iterations > 0) {
14491547

@@ -1469,41 +1567,9 @@ buf_LRU_get_free_block(
14691567

14701568
}
14711569

1472-
if (n_iterations > 20) {
1473-
ut_print_timestamp(stderr);
1474-
fprintf(stderr,
1475-
" InnoDB: Warning: difficult to find free blocks in\n"
1476-
"InnoDB: the buffer pool (%lu search iterations)!\n"
1477-
"InnoDB: %lu failed attempts to flush a page!"
1478-
" Consider\n"
1479-
"InnoDB: increasing the buffer pool size.\n"
1480-
"InnoDB: It is also possible that"
1481-
" in your Unix version\n"
1482-
"InnoDB: fsync is very slow, or"
1483-
" completely frozen inside\n"
1484-
"InnoDB: the OS kernel. Then upgrading to"
1485-
" a newer version\n"
1486-
"InnoDB: of your operating system may help."
1487-
" Look at the\n"
1488-
"InnoDB: number of fsyncs in diagnostic info below.\n"
1489-
"InnoDB: Pending flushes (fsync) log: %lu;"
1490-
" buffer pool: %lu\n"
1491-
"InnoDB: %lu OS file reads, %lu OS file writes,"
1492-
" %lu OS fsyncs\n"
1493-
"InnoDB: Starting InnoDB Monitor to print further\n"
1494-
"InnoDB: diagnostics to the standard output.\n",
1495-
(ulong) n_iterations,
1496-
(ulong) flush_failures,
1497-
(ulong) fil_n_pending_log_flushes,
1498-
(ulong) fil_n_pending_tablespace_flushes,
1499-
(ulong) os_n_file_reads, (ulong) os_n_file_writes,
1500-
(ulong) os_n_fsyncs);
1501-
1502-
mon_value_was = srv_print_innodb_monitor;
1503-
started_monitor = TRUE;
1504-
srv_print_innodb_monitor = TRUE;
1505-
os_event_set(lock_sys->timeout_event);
1506-
}
1570+
buf_LRU_handle_lack_of_free_blocks(n_iterations, started_ms,
1571+
flush_failures, &mon_value_was,
1572+
&started_monitor);
15071573

15081574
/* If we have scanned the whole LRU and still are unable to
15091575
find a free block then we should sleep here to let the

storage/xtradb/dict/dict0dict.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6269,6 +6269,20 @@ dict_table_schema_check(
62696269

62706270
return(DB_ERROR);
62716271
}
6272+
6273+
/* check whether column has the same COMPRESSED attriute */
6274+
if ((req_schema->columns[i].prtype_mask & DATA_COMPRESSED) !=
6275+
(table->cols[j].prtype & DATA_COMPRESSED)) {
6276+
6277+
ut_snprintf(errstr, errstr_sz,
6278+
"Column %s in table %s has "
6279+
"unexpected COMPRESSED attribute.",
6280+
req_schema->columns[i].name,
6281+
ut_format_name(req_schema->table_name,
6282+
TRUE, buf, sizeof(buf)));
6283+
6284+
return(DB_ERROR);
6285+
}
62726286
}
62736287

62746288
if (req_schema->n_foreign != table->foreign_set.size()) {

0 commit comments

Comments
 (0)