Skip to content

Commit 71189c7

Browse files
author
Arun Kuruvila
committed
Bug#26929724: REPAIR BY SORTING INCLUDING BULK INSERT
CAUSES INDEX CORRUPTION Description: MYISAM index corruption occurs for bulk insert and repair table which involves "repair by sorting" algorithm. Analysis: The index corruption happens because of the incorrect sorting done by "my_qsort2()" in 5.7. This happens for a bulk insert with more than 450001959 rows or repair table with more than 450001959 rows. In 8.0, "my_qsort2()" is replaced by std::sort() as part of Bug#25965593. Fix:- Backported Bug#25965593 fix partially to ensure MyISAM repair by sorting algorithm uses std::sort().
1 parent 8162de5 commit 71189c7

File tree

4 files changed

+42
-19
lines changed

4 files changed

+42
-19
lines changed

include/my_sys.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -763,12 +763,10 @@ File create_temp_file(char *to, const char *dir, const char *pfx,
763763
int mode, myf MyFlags);
764764

765765
// Use Prealloced_array or std::vector or something similar in C++
766-
#if defined(__cplusplus)
767766

768-
#define init_dynamic_array please_use_an_appropriately_typed_container
769-
#define my_init_dynamic_array please_use_an_appropriately_typed_container
770-
771-
#else
767+
#ifdef __cplusplus
768+
extern "C" {
769+
#endif
772770

773771
extern my_bool my_init_dynamic_array(DYNAMIC_ARRAY *array,
774772
PSI_memory_key key,
@@ -782,7 +780,9 @@ extern my_bool init_dynamic_array(DYNAMIC_ARRAY *array, uint element_size,
782780
#define dynamic_element(array,array_index,type) \
783781
((type)((array)->buffer) +(array_index))
784782

785-
#endif /* __cplusplus */
783+
#ifdef __cplusplus
784+
}
785+
#endif
786786

787787
/* Some functions are still in use in C++, because HASH uses DYNAMIC_ARRAY */
788788
extern my_bool insert_dynamic(DYNAMIC_ARRAY *array, const void *element);

storage/myisam/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
22
#
33
# This program is free software; you can redistribute it and/or modify
44
# it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c
2424
mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c
2525
mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c
2626
mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c
27-
rt_split.c sort.c sp_key.c mi_extrafunc.h myisamdef.h
27+
rt_split.c sort.cc sp_key.c mi_extrafunc.h myisamdef.h
2828
rt_index.h mi_rkey.c)
2929

3030
MYSQL_ADD_PLUGIN(myisam ${MYISAM_SOURCES}

storage/myisam/myisamdef.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
2+
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License as published by
@@ -473,6 +473,10 @@ typedef struct st_mi_sort_param
473473

474474
extern mysql_mutex_t THR_LOCK_myisam;
475475

476+
#ifdef __cplusplus
477+
extern "C" {
478+
#endif
479+
476480
/* Some extern variables */
477481

478482
extern LIST *myisam_open_list;
@@ -634,6 +638,10 @@ extern ulonglong mi_safe_mul(ulonglong a,ulonglong b);
634638
extern int _mi_ft_update(MI_INFO *info, uint keynr, uchar *keybuf,
635639
const uchar *oldrec, const uchar *newrec, my_off_t pos);
636640

641+
#ifdef __cplusplus
642+
}
643+
#endif
644+
637645
struct st_sort_info;
638646

639647

storage/myisam/sort.c renamed to storage/myisam/sort.cc

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -18,6 +18,8 @@
1818
them in sorted order through SORT_INFO functions.
1919
*/
2020

21+
#include <algorithm>
22+
2123
#include "fulltext.h"
2224
#if defined(_WIN32)
2325
#include <fcntl.h>
@@ -37,6 +39,19 @@
3739
#define DISK_BUFFER_SIZE (IO_SIZE*16)
3840

3941

42+
class Key_compare :
43+
public std::binary_function<const uchar*, const uchar*, bool>
44+
{
45+
public:
46+
Key_compare(MI_SORT_PARAM *param) : info(param) {}
47+
bool operator()(const uchar *a, const uchar *b)
48+
{
49+
return info->key_cmp(info, &a, &b) < 0;
50+
}
51+
MI_SORT_PARAM *info;
52+
};
53+
54+
4055
/*
4156
Pointers of functions for store and read keys from temp file
4257
*/
@@ -581,8 +596,8 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
581596
length= (size_t)param->sort_buffer_length;
582597
while (length >= MIN_SORT_BUFFER)
583598
{
584-
if ((mergebuf= my_malloc(PSI_NOT_INSTRUMENTED,
585-
length, MYF(0))))
599+
if ((mergebuf= (uchar *) my_malloc(PSI_NOT_INSTRUMENTED,
600+
length, MYF(0))))
586601
break;
587602
length=length*3/4;
588603
}
@@ -669,8 +684,8 @@ static int write_keys(MI_SORT_PARAM *info, uchar **sort_keys,
669684
uint sort_length=info->key_length;
670685
DBUG_ENTER("write_keys");
671686

672-
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
673-
info);
687+
std::sort(sort_keys, sort_keys + count, Key_compare(info));
688+
674689
if (!my_b_inited(tempfile) &&
675690
open_cached_file(tempfile, my_tmpdir(info->tmpdir), "ST",
676691
DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
@@ -712,8 +727,8 @@ static int write_keys_varlen(MI_SORT_PARAM *info,
712727
int err;
713728
DBUG_ENTER("write_keys_varlen");
714729

715-
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
716-
info);
730+
std::sort(sort_keys, sort_keys + count, Key_compare(info));
731+
717732
if (!my_b_inited(tempfile) &&
718733
open_cached_file(tempfile, my_tmpdir(info->tmpdir), "ST",
719734
DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
@@ -754,8 +769,8 @@ static int write_index(MI_SORT_PARAM *info, uchar **sort_keys,
754769
{
755770
DBUG_ENTER("write_index");
756771

757-
my_qsort2((uchar*) sort_keys,(size_t) count,sizeof(uchar*),
758-
(qsort2_cmp) info->key_cmp,info);
772+
std::sort(sort_keys, sort_keys + count, Key_compare(info));
773+
759774
while (count--)
760775
{
761776
if ((*info->key_write)(info,*sort_keys++))

0 commit comments

Comments
 (0)