Skip to content

Commit 6010a27

Browse files
committed
5.5.52-38.3
1 parent e316c46 commit 6010a27

File tree

11 files changed

+179
-46
lines changed

11 files changed

+179
-46
lines changed

storage/xtradb/btr/btr0btr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ btr_corruption_report(
7676
buf_block_get_zip_size(block),
7777
BUF_PAGE_PRINT_NO_CRASH);
7878
}
79-
buf_page_print(buf_block_get_frame(block), 0, 0);
79+
buf_page_print(buf_nonnull_block_get_frame(block), 0, 0);
8080
}
8181

8282
#ifndef UNIV_HOTBACKUP
@@ -1077,7 +1077,7 @@ btr_get_size(
10771077
SRV_CORRUPT_TABLE_CHECK(root,
10781078
{
10791079
mtr_commit(mtr);
1080-
return(0);
1080+
return(ULINT_UNDEFINED);
10811081
});
10821082

10831083
if (flag == BTR_N_LEAF_PAGES) {

storage/xtradb/handler/ha_innodb.cc

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,19 @@ innobase_is_fake_change(
475475
THD* thd); /*!< in: MySQL thread handle of the user for
476476
whom the transaction is being committed */
477477

478+
/** Get the list of foreign keys referencing a specified table
479+
table.
480+
@param thd The thread handle
481+
@param path Path to the table
482+
@param f_key_list[out] The list of foreign keys
483+
484+
@return error code or zero for success */
485+
static
486+
int
487+
innobase_get_parent_fk_list(
488+
THD* thd,
489+
const char* path,
490+
List<FOREIGN_KEY_INFO>* f_key_list);
478491

479492
/******************************************************************//**
480493
Maps a MySQL trx isolation level code to the InnoDB isolation level code
@@ -2710,6 +2723,7 @@ innobase_init(
27102723
innobase_hton->purge_changed_page_bitmaps
27112724
= innobase_purge_changed_page_bitmaps;
27122725
innobase_hton->is_fake_change = innobase_is_fake_change;
2726+
innobase_hton->get_parent_fk_list = innobase_get_parent_fk_list;
27132727

27142728
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
27152729

@@ -9721,7 +9735,14 @@ ha_innobase::check(
97219735

97229736
prebuilt->select_lock_type = LOCK_NONE;
97239737

9724-
if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) {
9738+
bool check_result
9739+
= row_check_index_for_mysql(prebuilt, index, &n_rows);
9740+
DBUG_EXECUTE_IF(
9741+
"dict_set_index_corrupted",
9742+
if (!(index->type & DICT_CLUSTERED)) {
9743+
check_result = false;
9744+
});
9745+
if (!check_result) {
97259746
innobase_format_name(
97269747
index_name, sizeof index_name,
97279748
index->name, TRUE);
@@ -10057,6 +10078,73 @@ get_foreign_key_info(
1005710078
return(pf_key_info);
1005810079
}
1005910080

10081+
/** Get the list of foreign keys referencing a specified table
10082+
table.
10083+
@param thd The thread handle
10084+
@param path Path to the table
10085+
@param f_key_list[out] The list of foreign keys */
10086+
static
10087+
void
10088+
fill_foreign_key_list(THD* thd,
10089+
const dict_table_t* table,
10090+
List<FOREIGN_KEY_INFO>* f_key_list)
10091+
{
10092+
ut_ad(mutex_own(&dict_sys->mutex));
10093+
10094+
for (dict_foreign_t* foreign
10095+
= UT_LIST_GET_FIRST(table->referenced_list);
10096+
foreign != NULL;
10097+
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
10098+
10099+
FOREIGN_KEY_INFO* pf_key_info
10100+
= get_foreign_key_info(thd, foreign);
10101+
if (pf_key_info) {
10102+
f_key_list->push_back(pf_key_info);
10103+
}
10104+
}
10105+
}
10106+
10107+
/** Get the list of foreign keys referencing a specified table
10108+
table.
10109+
@param thd The thread handle
10110+
@param path Path to the table
10111+
@param f_key_list[out] The list of foreign keys
10112+
10113+
@return error code or zero for success */
10114+
static
10115+
int
10116+
innobase_get_parent_fk_list(
10117+
THD* thd,
10118+
const char* path,
10119+
List<FOREIGN_KEY_INFO>* f_key_list)
10120+
{
10121+
ut_a(strlen(path) <= FN_REFLEN);
10122+
char norm_name[FN_REFLEN + 1];
10123+
normalize_table_name(norm_name, path);
10124+
10125+
trx_t* parent_trx = check_trx_exists(thd);
10126+
parent_trx->op_info = "getting list of referencing foreign keys";
10127+
trx_search_latch_release_if_reserved(parent_trx);
10128+
10129+
mutex_enter(&dict_sys->mutex);
10130+
10131+
dict_table_t* table
10132+
= dict_table_get_low(norm_name,
10133+
static_cast<dict_err_ignore_t>(
10134+
DICT_ERR_IGNORE_INDEX_ROOT
10135+
| DICT_ERR_IGNORE_CORRUPT));
10136+
if (!table) {
10137+
mutex_exit(&dict_sys->mutex);
10138+
return(HA_ERR_NO_SUCH_TABLE);
10139+
}
10140+
10141+
fill_foreign_key_list(thd, table, f_key_list);
10142+
10143+
mutex_exit(&dict_sys->mutex);
10144+
parent_trx->op_info = "";
10145+
return(0);
10146+
}
10147+
1006010148
/*******************************************************************//**
1006110149
Gets the list of foreign keys in this table.
1006210150
@return always 0, that is, always succeeds */
@@ -10105,9 +10193,6 @@ ha_innobase::get_parent_foreign_key_list(
1010510193
THD* thd, /*!< in: user thread handle */
1010610194
List<FOREIGN_KEY_INFO>* f_key_list) /*!< out: foreign key list */
1010710195
{
10108-
FOREIGN_KEY_INFO* pf_key_info;
10109-
dict_foreign_t* foreign;
10110-
1011110196
ut_a(prebuilt != NULL);
1011210197
update_thd(ha_thd());
1011310198

@@ -10116,16 +10201,7 @@ ha_innobase::get_parent_foreign_key_list(
1011610201
trx_search_latch_release_if_reserved(prebuilt->trx);
1011710202

1011810203
mutex_enter(&(dict_sys->mutex));
10119-
10120-
for (foreign = UT_LIST_GET_FIRST(prebuilt->table->referenced_list);
10121-
foreign != NULL;
10122-
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
10123-
pf_key_info = get_foreign_key_info(thd, foreign);
10124-
if (pf_key_info) {
10125-
f_key_list->push_back(pf_key_info);
10126-
}
10127-
}
10128-
10204+
fill_foreign_key_list(thd, prebuilt->table, f_key_list);
1012910205
mutex_exit(&(dict_sys->mutex));
1013010206

1013110207
prebuilt->trx->op_info = "";
@@ -12539,16 +12615,14 @@ innodb_track_changed_pages_validate(
1253912615
for update function */
1254012616
struct st_mysql_value* value) /*!< in: incoming bool */
1254112617
{
12542-
static bool enabled_on_startup = false;
1254312618
long long intbuf = 0;
1254412619

1254512620
if (value->val_int(value, &intbuf)) {
1254612621
/* The value is NULL. That is invalid. */
1254712622
return 1;
1254812623
}
1254912624

12550-
if (srv_track_changed_pages || enabled_on_startup) {
12551-
enabled_on_startup = true;
12625+
if (srv_redo_log_thread_started) {
1255212626
*reinterpret_cast<ulong*>(save)
1255312627
= static_cast<ulong>(intbuf);
1255412628
return 0;

storage/xtradb/include/buf0buf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,8 +1110,20 @@ buf_block_get_frame(
11101110
/*================*/
11111111
const buf_block_t* block) /*!< in: pointer to the control block */
11121112
__attribute__((pure));
1113+
1114+
/*********************************************************************//**
1115+
Gets a pointer to the memory frame of a block, where block is known not to be
1116+
NULL.
1117+
@return pointer to the frame */
1118+
UNIV_INLINE
1119+
buf_frame_t*
1120+
buf_nonnull_block_get_frame(
1121+
const buf_block_t* block) /*!< in: pointer to the control block */
1122+
__attribute__((pure));
1123+
11131124
#else /* UNIV_DEBUG */
11141125
# define buf_block_get_frame(block) (block ? (block)->frame : 0)
1126+
# define buf_nonnull_block_get_frame(block) ((block)->frame)
11151127
#endif /* UNIV_DEBUG */
11161128
/*********************************************************************//**
11171129
Gets the space id of a block.

storage/xtradb/include/buf0buf.ic

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,19 @@ buf_block_get_frame(
718718
{
719719
SRV_CORRUPT_TABLE_CHECK(block, return(0););
720720

721+
return(buf_nonnull_block_get_frame(block));
722+
}
723+
724+
/*********************************************************************//**
725+
Gets a pointer to the memory frame of a block, where block is known not to be
726+
NULL.
727+
@return pointer to the frame */
728+
UNIV_INLINE
729+
buf_frame_t*
730+
buf_nonnull_block_get_frame(
731+
/*========================*/
732+
const buf_block_t* block) /*!< in: pointer to the control block */
733+
{
721734
switch (buf_block_get_state(block)) {
722735
case BUF_BLOCK_ZIP_FREE:
723736
case BUF_BLOCK_ZIP_PAGE:
@@ -739,6 +752,7 @@ buf_block_get_frame(
739752
ok:
740753
return((buf_frame_t*) block->frame);
741754
}
755+
742756
#endif /* UNIV_DEBUG */
743757

744758
/*********************************************************************//**

storage/xtradb/include/srv0srv.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ extern os_event_t srv_checkpoint_completed_event;
7474
that the (slow) shutdown may proceed */
7575
extern os_event_t srv_redo_log_thread_finished_event;
7676

77+
/** Whether the redo log tracker thread has been started. Does not take into
78+
account whether the tracking is currently enabled (see srv_track_changed_pages
79+
for that) */
80+
extern my_bool srv_redo_log_thread_started;
81+
7782
/* If the last data file is auto-extended, we add this many pages to it
7883
at a time */
7984
#define SRV_AUTO_EXTEND_INCREMENT \
@@ -141,6 +146,9 @@ extern char* srv_doublewrite_file;
141146

142147
extern ibool srv_recovery_stats;
143148

149+
/** Whether the redo log tracking is currently enabled. Note that it is
150+
possible for the log tracker thread to be running and the tracking to be
151+
disabled */
144152
extern my_bool srv_track_changed_pages;
145153
extern ib_uint64_t srv_max_bitmap_file_size;
146154

storage/xtradb/include/univ.i

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */
6464
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
6565

6666
#ifndef PERCONA_INNODB_VERSION
67-
#define PERCONA_INNODB_VERSION 38.0
67+
#define PERCONA_INNODB_VERSION 38.3
6868
#endif
6969

7070
#define INNODB_VERSION_STR MYSQL_SERVER_VERSION

storage/xtradb/log/log0log.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,8 @@ logs_empty_and_mark_files_at_shutdown(void)
33263326
algorithm only works if the server is idle at shutdown */
33273327

33283328
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
3329+
3330+
srv_wake_purge_thread();
33293331
loop:
33303332
os_thread_sleep(100000);
33313333

@@ -3499,7 +3501,7 @@ logs_empty_and_mark_files_at_shutdown(void)
34993501
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
35003502
/* Wake the log tracking thread which will then immediatelly
35013503
quit because of srv_shutdown_state value */
3502-
if (srv_track_changed_pages) {
3504+
if (srv_redo_log_thread_started) {
35033505
os_event_set(srv_checkpoint_completed_event);
35043506
os_event_wait(srv_redo_log_thread_finished_event);
35053507
}
@@ -3576,7 +3578,7 @@ logs_empty_and_mark_files_at_shutdown(void)
35763578
srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE;
35773579

35783580
/* Signal the log following thread to quit */
3579-
if (srv_track_changed_pages) {
3581+
if (srv_redo_log_thread_started) {
35803582
os_event_set(srv_checkpoint_completed_event);
35813583
}
35823584

@@ -3600,7 +3602,7 @@ logs_empty_and_mark_files_at_shutdown(void)
36003602

36013603
fil_flush_file_spaces(FIL_TABLESPACE);
36023604

3603-
if (srv_track_changed_pages) {
3605+
if (srv_redo_log_thread_started) {
36043606
os_event_wait(srv_redo_log_thread_finished_event);
36053607
}
36063608

storage/xtradb/log/log0online.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,21 +1813,21 @@ log_online_purge_changed_page_bitmaps(
18131813
lsn = IB_ULONGLONG_MAX;
18141814
}
18151815

1816-
if (srv_track_changed_pages) {
1816+
if (srv_redo_log_thread_started) {
18171817
/* User requests might happen with both enabled and disabled
18181818
tracking */
18191819
mutex_enter(&log_bmp_sys->mutex);
18201820
}
18211821

18221822
if (!log_online_setup_bitmap_file_range(&bitmap_files, 0,
18231823
IB_ULONGLONG_MAX)) {
1824-
if (srv_track_changed_pages) {
1824+
if (srv_redo_log_thread_started) {
18251825
mutex_exit(&log_bmp_sys->mutex);
18261826
}
18271827
return TRUE;
18281828
}
18291829

1830-
if (srv_track_changed_pages && lsn > log_bmp_sys->end_lsn) {
1830+
if (srv_redo_log_thread_started && lsn > log_bmp_sys->end_lsn) {
18311831
/* If we have to delete the current output file, close it
18321832
first. */
18331833
os_file_close(log_bmp_sys->out.file);
@@ -1858,7 +1858,7 @@ log_online_purge_changed_page_bitmaps(
18581858
}
18591859
}
18601860

1861-
if (srv_track_changed_pages) {
1861+
if (srv_redo_log_thread_started) {
18621862
if (lsn > log_bmp_sys->end_lsn) {
18631863
ib_uint64_t new_file_lsn;
18641864
if (lsn == IB_ULONGLONG_MAX) {
@@ -1869,9 +1869,7 @@ log_online_purge_changed_page_bitmaps(
18691869
new_file_lsn = log_bmp_sys->end_lsn;
18701870
}
18711871
if (!log_online_rotate_bitmap_file(new_file_lsn)) {
1872-
/* If file create failed, signal the log
1873-
tracking thread to quit next time it wakes
1874-
up. */
1872+
/* If file create failed, stop log tracking */
18751873
srv_track_changed_pages = FALSE;
18761874
}
18771875
}

storage/xtradb/log/log0recv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3015,7 +3015,7 @@ recv_recovery_from_checkpoint_start_func(
30153015
ib_uint64_t checkpoint_lsn;
30163016
ib_uint64_t checkpoint_no;
30173017
ib_uint64_t old_scanned_lsn;
3018-
ib_uint64_t group_scanned_lsn;
3018+
ib_uint64_t group_scanned_lsn = 0;
30193019
ib_uint64_t contiguous_lsn;
30203020
#ifdef UNIV_LOG_ARCHIVE
30213021
ib_uint64_t archived_lsn;

storage/xtradb/mach/mach0data.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,18 @@ mach_parse_compressed(
5656
*val = flag;
5757
return(ptr + 1);
5858

59-
} else if (flag < 0xC0UL) {
59+
}
60+
61+
/* Workaround GCC bug
62+
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673:
63+
the compiler moves mach_read_from_4 right to the beginning of the
64+
function, causing and out-of-bounds read if we are reading a short
65+
integer close to the end of buffer. */
66+
#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__)
67+
asm volatile("": : :"memory");
68+
#endif
69+
70+
if (flag < 0xC0UL) {
6071
if (end_ptr < ptr + 2) {
6172
return(NULL);
6273
}

0 commit comments

Comments
 (0)