Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
d183f510
Commit
d183f510
authored
Sep 15, 2011
by
Mattias Jonsson
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
e771dca7
ab761db8
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
282 additions
and
48 deletions
+282
-48
mysql-test/r/partition_innodb_plugin.result
mysql-test/r/partition_innodb_plugin.result
+12
-1
mysql-test/suite/parts/r/partition_debug_innodb.result
mysql-test/suite/parts/r/partition_debug_innodb.result
+71
-0
mysql-test/suite/parts/t/partition_debug_innodb.test
mysql-test/suite/parts/t/partition_debug_innodb.test
+35
-0
mysql-test/t/partition_innodb_plugin.test
mysql-test/t/partition_innodb_plugin.test
+2
-1
sql/ha_partition.cc
sql/ha_partition.cc
+158
-44
sql/handler.h
sql/handler.h
+4
-2
No files found.
mysql-test/r/partition_innodb_plugin.result
View file @
d183f510
#
# Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
# PARTITONING, ON INDEX CREATE
# Bug#12696518: MEMORY LEAKS IN HA_PARTITION (VALGRIND TESTS ON TRUNK)
#
call mtr.add_suppression("contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL");
CREATE TABLE t1 (
id bigint NOT NULL AUTO_INCREMENT,
time date,
...
...
@@ -20,6 +20,17 @@ ERROR 23000: Duplicate entry '2011-07-25-1' for key 'uk_time_id2'
SELECT COUNT(*) FROM t1;
COUNT(*)
3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`time` date NOT NULL DEFAULT '0000-00-00',
`id2` bigint(20) NOT NULL,
PRIMARY KEY (`id`,`time`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY RANGE (TO_DAYS(time))
(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */
DROP TABLE t1;
call mtr.add_suppression("nnoDB: Error: table `test`.`t1` .* Partition.* InnoDB internal");
#
...
...
mysql-test/suite/parts/r/partition_debug_innodb.result
View file @
d183f510
DROP TABLE IF EXISTS t1;
#
# Bug#12696518/Bug#11766879/60106:DIFF BETWEEN # OF INDEXES IN MYSQL
# VS INNODB, PARTITONING, ON INDEX CREATE
#
CREATE TABLE t1
(a INT PRIMARY KEY,
b VARCHAR(64))
ENGINE = InnoDB
PARTITION BY HASH (a) PARTITIONS 3;
INSERT INTO t1 VALUES (0, 'first row'), (1, 'second row'), (2, 'Third row');
INSERT INTO t1 VALUES (3, 'row id 3'), (4, '4 row'), (5, 'row5');
INSERT INTO t1 VALUES (6, 'X 6 row'), (7, 'Seventh row'), (8, 'Last row');
ALTER TABLE t1 ADD INDEX new_b_index (b);
ALTER TABLE t1 DROP INDEX new_b_index;
SET SESSION debug= "+d,ha_partition_fail_final_add_index";
ALTER TABLE t1 ADD INDEX (b);
ERROR HY000: Table has no partition for value 0
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(64) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
PARTITIONS 3 */
SELECT * FROM t1;
a b
0 first row
1 second row
2 Third row
3 row id 3
4 4 row
5 row5
6 X 6 row
7 Seventh row
8 Last row
FLUSH TABLES;
CREATE INDEX new_index ON t1 (b);
ERROR HY000: Table has no partition for value 0
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(64) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
PARTITIONS 3 */
SELECT * FROM t1;
a b
0 first row
1 second row
2 Third row
3 row id 3
4 4 row
5 row5
6 X 6 row
7 Seventh row
8 Last row
SET SESSION debug= "-d,ha_partition_fail_final_add_index";
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` varchar(64) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY HASH (a)
PARTITIONS 3 */
DROP TABLE t1;
call mtr.add_suppression("InnoDB: Warning: allocated tablespace .*, old maximum was");
call mtr.add_suppression("InnoDB: Error: table .* does not exist in the InnoDB internal");
call mtr.add_suppression("InnoDB: Warning: MySQL is trying to drop table ");
...
...
mysql-test/suite/parts/t/partition_debug_innodb.test
View file @
d183f510
...
...
@@ -12,6 +12,41 @@ DROP TABLE IF EXISTS t1;
--
let
$DATADIR
=
`SELECT @@datadir;`
--
echo
#
--
echo
# Bug#12696518/Bug#11766879/60106:DIFF BETWEEN # OF INDEXES IN MYSQL
--
echo
# VS INNODB, PARTITONING, ON INDEX CREATE
--
echo
#
CREATE
TABLE
t1
(
a
INT
PRIMARY
KEY
,
b
VARCHAR
(
64
))
ENGINE
=
InnoDB
PARTITION
BY
HASH
(
a
)
PARTITIONS
3
;
INSERT
INTO
t1
VALUES
(
0
,
'first row'
),
(
1
,
'second row'
),
(
2
,
'Third row'
);
INSERT
INTO
t1
VALUES
(
3
,
'row id 3'
),
(
4
,
'4 row'
),
(
5
,
'row5'
);
INSERT
INTO
t1
VALUES
(
6
,
'X 6 row'
),
(
7
,
'Seventh row'
),
(
8
,
'Last row'
);
ALTER
TABLE
t1
ADD
INDEX
new_b_index
(
b
);
ALTER
TABLE
t1
DROP
INDEX
new_b_index
;
SET
SESSION
debug
=
"+d,ha_partition_fail_final_add_index"
;
--
error
ER_NO_PARTITION_FOR_GIVEN_VALUE
ALTER
TABLE
t1
ADD
INDEX
(
b
);
SHOW
CREATE
TABLE
t1
;
--
sorted_result
SELECT
*
FROM
t1
;
FLUSH
TABLES
;
--
error
ER_NO_PARTITION_FOR_GIVEN_VALUE
CREATE
INDEX
new_index
ON
t1
(
b
);
SHOW
CREATE
TABLE
t1
;
--
sorted_result
SELECT
*
FROM
t1
;
SET
SESSION
debug
=
"-d,ha_partition_fail_final_add_index"
;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
# Checking with #innodb what this is...
call
mtr
.
add_suppression
(
"InnoDB: Warning: allocated tablespace .*, old maximum was"
);
# If there is a crash or failure between the ddl_log is written and the
...
...
mysql-test/t/partition_innodb_plugin.test
View file @
d183f510
...
...
@@ -6,8 +6,8 @@ let $MYSQLD_DATADIR= `SELECT @@datadir`;
--
echo
#
--
echo
# Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
--
echo
# PARTITONING, ON INDEX CREATE
--
echo
# Bug#12696518: MEMORY LEAKS IN HA_PARTITION (VALGRIND TESTS ON TRUNK)
--
echo
#
call
mtr
.
add_suppression
(
"contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL"
);
CREATE
TABLE
t1
(
id
bigint
NOT
NULL
AUTO_INCREMENT
,
time
date
,
...
...
@@ -26,6 +26,7 @@ INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
CREATE
UNIQUE
INDEX
uk_time_id2
on
t1
(
time
,
id2
);
SELECT
COUNT
(
*
)
FROM
t1
;
SHOW
CREATE
TABLE
t1
;
DROP
TABLE
t1
;
...
...
sql/ha_partition.cc
View file @
d183f510
...
...
@@ -6662,50 +6662,82 @@ bool ha_partition::check_if_incompatible_data(HA_CREATE_INFO *create_info,
}
/**
Helper class for [final_]add_index, see handler.h
*/
class
ha_partition_add_index
:
public
handler_add_index
{
public:
handler_add_index
**
add_array
;
ha_partition_add_index
(
TABLE
*
table_arg
,
KEY
*
key_info_arg
,
uint
num_of_keys_arg
)
:
handler_add_index
(
table_arg
,
key_info_arg
,
num_of_keys_arg
)
{}
~
ha_partition_add_index
()
{}
};
/**
Support of in-place add/drop index
@param table_arg Table to add index to
@param key_info Struct over the new keys to add
@param num_of_keys Number of keys to add
@param[out] add Data to be submitted with final_add_index
@return Operation status
@retval 0 Success
@retval != 0 Failure (error code returned, and all operations rollbacked)
*/
int
ha_partition
::
add_index
(
TABLE
*
table_arg
,
KEY
*
key_info
,
uint
num_of_keys
,
handler_add_index
**
add
)
{
handler
**
file
;
uint
i
;
int
ret
=
0
;
THD
*
thd
=
ha_thd
();
ha_partition_add_index
*
part_add_index
;
DBUG_ENTER
(
"ha_partition::add_index"
);
*
add
=
new
handler_add_index
(
table
,
key_info
,
num_of_keys
);
/*
There has already been a check in fix_partition_func in mysql_alter_table
before this call, which checks for unique/primary key violations of the
partitioning function. So no need for extra check here.
*/
for
(
file
=
m_file
;
*
file
;
file
++
)
/*
This will be freed at the end of the statement.
And destroyed at final_add_index. (Sql_alloc does not free in delete).
*/
part_add_index
=
new
(
thd
->
mem_root
)
ha_partition_add_index
(
table_arg
,
key_info
,
num_of_keys
);
if
(
!
part_add_index
)
DBUG_RETURN
(
HA_ERR_OUT_OF_MEM
);
part_add_index
->
add_array
=
(
handler_add_index
**
)
thd
->
alloc
(
sizeof
(
void
*
)
*
m_tot_parts
);
if
(
!
part_add_index
->
add_array
)
{
handler_add_index
*
add_index
;
if
((
ret
=
(
*
file
)
->
add_index
(
table_arg
,
key_info
,
num_of_keys
,
&
add_index
)))
goto
err
;
if
((
ret
=
(
*
file
)
->
final_add_index
(
add_index
,
true
)))
delete
part_add_index
;
DBUG_RETURN
(
HA_ERR_OUT_OF_MEM
);
}
for
(
i
=
0
;
i
<
m_tot_parts
;
i
++
)
{
if
((
ret
=
m_file
[
i
]
->
add_index
(
table_arg
,
key_info
,
num_of_keys
,
&
part_add_index
->
add_array
[
i
])))
goto
err
;
}
*
add
=
part_add_index
;
DBUG_RETURN
(
ret
);
err:
if
(
file
>
m_file
)
/* Rollback all prepared partitions. i - 1 .. 0 */
while
(
i
)
{
uint
*
key_numbers
=
(
uint
*
)
ha_thd
()
->
alloc
(
sizeof
(
uint
)
*
num_of_keys
);
uint
old_num_of_keys
=
table_arg
->
s
->
keys
;
uint
i
;
/* The newly created keys have the last id's */
for
(
i
=
0
;
i
<
num_of_keys
;
i
++
)
key_numbers
[
i
]
=
i
+
old_num_of_keys
;
if
(
!
table_arg
->
key_info
)
table_arg
->
key_info
=
key_info
;
while
(
--
file
>=
m_file
)
{
(
void
)
(
*
file
)
->
prepare_drop_index
(
table_arg
,
key_numbers
,
num_of_keys
);
(
void
)
(
*
file
)
->
final_drop_index
(
table_arg
);
}
if
(
table_arg
->
key_info
==
key_info
)
table_arg
->
key_info
=
NULL
;
i
--
;
(
void
)
m_file
[
i
]
->
final_add_index
(
part_add_index
->
add_array
[
i
],
false
);
}
delete
part_add_index
;
DBUG_RETURN
(
ret
);
}
...
...
@@ -6713,37 +6745,119 @@ int ha_partition::add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys,
/**
Second phase of in-place add index.
@param add Info from add_index
@param commit Should we commit or rollback the add_index operation
@return Operation status
@retval 0 Success
@retval != 0 Failure (error code returned)
@note If commit is false, index changes are rolled back by dropping the
added indexes. If commit is true, nothing is done as the indexes
were already made active in ::add_index()
*/
*/
int
ha_partition
::
final_add_index
(
handler_add_index
*
add
,
bool
commit
)
{
ha_partition_add_index
*
part_add_index
;
uint
i
;
int
ret
=
0
;
DBUG_ENTER
(
"ha_partition::final_add_index"
);
// Rollback by dropping indexes.
if
(
!
commit
)
{
TABLE
*
table_arg
=
add
->
table
;
uint
num_of_keys
=
add
->
num_of_keys
;
handler
**
file
;
uint
*
key_numbers
=
(
uint
*
)
ha_thd
()
->
alloc
(
sizeof
(
uint
)
*
num_of_keys
);
uint
old_num_of_keys
=
table_arg
->
s
->
keys
;
uint
i
;
/* The newly created keys have the last id's */
for
(
i
=
0
;
i
<
num_of_keys
;
i
++
)
key_numbers
[
i
]
=
i
+
old_num_of_keys
;
if
(
!
table_arg
->
key_info
)
table_arg
->
key_info
=
add
->
key_info
;
for
(
file
=
m_file
;
*
file
;
file
++
)
if
(
!
add
)
{
DBUG_ASSERT
(
!
commit
);
DBUG_RETURN
(
0
);
}
part_add_index
=
static_cast
<
class
ha_partition_add_index
*>
(
add
);
for
(
i
=
0
;
i
<
m_tot_parts
;
i
++
)
{
if
((
ret
=
m_file
[
i
]
->
final_add_index
(
part_add_index
->
add_array
[
i
],
commit
)))
goto
err
;
DBUG_EXECUTE_IF
(
"ha_partition_fail_final_add_index"
,
{
/* Simulate a failure by rollback the second partition */
if
(
m_tot_parts
>
1
)
{
i
++
;
m_file
[
i
]
->
final_add_index
(
part_add_index
->
add_array
[
i
],
false
);
/* Set an error that is specific to ha_partition. */
ret
=
HA_ERR_NO_PARTITION_FOUND
;
goto
err
;
}
});
}
delete
part_add_index
;
DBUG_RETURN
(
ret
);
err:
uint
j
;
uint
*
key_numbers
=
NULL
;
KEY
*
old_key_info
=
NULL
;
uint
num_of_keys
=
0
;
int
error
;
/* How could this happen? Needed to create a covering test case :) */
DBUG_ASSERT
(
ret
==
HA_ERR_NO_PARTITION_FOUND
);
if
(
i
>
0
)
{
num_of_keys
=
part_add_index
->
num_of_keys
;
key_numbers
=
(
uint
*
)
ha_thd
()
->
alloc
(
sizeof
(
uint
)
*
num_of_keys
);
if
(
!
key_numbers
)
{
sql_print_error
(
"Failed with error handling of adding index:
\n
"
"committing index failed, and when trying to revert "
"already committed partitions we failed allocating
\n
"
"memory for the index for table '%s'"
,
table_share
->
table_name
.
str
);
DBUG_RETURN
(
HA_ERR_OUT_OF_MEM
);
}
old_key_info
=
table
->
key_info
;
/*
Use the newly added key_info as table->key_info to remove them.
Note that this requires the subhandlers to use name lookup of the
index. They must use given table->key_info[key_number], they cannot
use their local view of the keys, since table->key_info only include
the indexes to be removed here.
*/
for
(
j
=
0
;
j
<
num_of_keys
;
j
++
)
key_numbers
[
j
]
=
j
;
table
->
key_info
=
part_add_index
->
key_info
;
}
for
(
j
=
0
;
j
<
m_tot_parts
;
j
++
)
{
if
(
j
<
i
)
{
(
void
)
(
*
file
)
->
prepare_drop_index
(
table_arg
,
key_numbers
,
num_of_keys
);
(
void
)
(
*
file
)
->
final_drop_index
(
table_arg
);
/* Remove the newly added index */
error
=
m_file
[
j
]
->
prepare_drop_index
(
table
,
key_numbers
,
num_of_keys
);
if
(
error
||
m_file
[
j
]
->
final_drop_index
(
table
))
{
sql_print_error
(
"Failed with error handling of adding index:
\n
"
"committing index failed, and when trying to revert "
"already committed partitions we failed removing
\n
"
"the index for table '%s' partition nr %d"
,
table_share
->
table_name
.
str
,
j
);
}
}
else
if
(
j
>
i
)
{
/* Rollback non finished partitions */
if
(
m_file
[
j
]
->
final_add_index
(
part_add_index
->
add_array
[
j
],
false
))
{
/* How could this happen? */
sql_print_error
(
"Failed with error handling of adding index:
\n
"
"Rollback of add_index failed for table
\n
"
"'%s' partition nr %d"
,
table_share
->
table_name
.
str
,
j
);
}
}
if
(
table_arg
->
key_info
==
add
->
key_info
)
table_arg
->
key_info
=
NULL
;
}
DBUG_RETURN
(
0
);
if
(
i
>
0
)
table
->
key_info
=
old_key_info
;
delete
part_add_index
;
DBUG_RETURN
(
ret
);
}
int
ha_partition
::
prepare_drop_index
(
TABLE
*
table_arg
,
uint
*
key_num
,
...
...
sql/handler.h
View file @
d183f510
...
...
@@ -1163,10 +1163,12 @@ uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
/**
Index creation context.
Created by handler::add_index() and freed by handler::final_add_index().
Created by handler::add_index() and destroyed by handler::final_add_index().
And finally freed at the end of the statement.
(Sql_alloc does not free in delete).
*/
class
handler_add_index
class
handler_add_index
:
public
Sql_alloc
{
public:
/* Table where the indexes are added */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment